xref: /llvm-project/clang/lib/CodeGen/ABIInfo.cpp (revision 03744d2aaffee04bc1e4d0668c41556c3c20d406)
1992cb984SSergei Barannikov //===- ABIInfo.cpp --------------------------------------------------------===//
2992cb984SSergei Barannikov //
3992cb984SSergei Barannikov // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4992cb984SSergei Barannikov // See https://llvm.org/LICENSE.txt for license information.
5992cb984SSergei Barannikov // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6992cb984SSergei Barannikov //
7992cb984SSergei Barannikov //===----------------------------------------------------------------------===//
8992cb984SSergei Barannikov 
9992cb984SSergei Barannikov #include "ABIInfo.h"
10992cb984SSergei Barannikov #include "ABIInfoImpl.h"
11992cb984SSergei Barannikov 
12992cb984SSergei Barannikov using namespace clang;
13992cb984SSergei Barannikov using namespace clang::CodeGen;
14992cb984SSergei Barannikov 
15992cb984SSergei Barannikov // Pin the vtable to this file.
16992cb984SSergei Barannikov ABIInfo::~ABIInfo() = default;
17992cb984SSergei Barannikov 
18992cb984SSergei Barannikov CGCXXABI &ABIInfo::getCXXABI() const { return CGT.getCXXABI(); }
19992cb984SSergei Barannikov 
20992cb984SSergei Barannikov ASTContext &ABIInfo::getContext() const { return CGT.getContext(); }
21992cb984SSergei Barannikov 
22992cb984SSergei Barannikov llvm::LLVMContext &ABIInfo::getVMContext() const {
23992cb984SSergei Barannikov   return CGT.getLLVMContext();
24992cb984SSergei Barannikov }
25992cb984SSergei Barannikov 
26992cb984SSergei Barannikov const llvm::DataLayout &ABIInfo::getDataLayout() const {
27992cb984SSergei Barannikov   return CGT.getDataLayout();
28992cb984SSergei Barannikov }
29992cb984SSergei Barannikov 
30992cb984SSergei Barannikov const TargetInfo &ABIInfo::getTarget() const { return CGT.getTarget(); }
31992cb984SSergei Barannikov 
32992cb984SSergei Barannikov const CodeGenOptions &ABIInfo::getCodeGenOpts() const {
33992cb984SSergei Barannikov   return CGT.getCodeGenOpts();
34992cb984SSergei Barannikov }
35992cb984SSergei Barannikov 
36992cb984SSergei Barannikov bool ABIInfo::isAndroid() const { return getTarget().getTriple().isAndroid(); }
37992cb984SSergei Barannikov 
38992cb984SSergei Barannikov bool ABIInfo::isOHOSFamily() const {
39992cb984SSergei Barannikov   return getTarget().getTriple().isOHOSFamily();
40992cb984SSergei Barannikov }
41992cb984SSergei Barannikov 
426d973b45SMariya Podchishchaeva RValue ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr,
436d973b45SMariya Podchishchaeva                             QualType Ty, AggValueSlot Slot) const {
446d973b45SMariya Podchishchaeva   return RValue::getIgnored();
45992cb984SSergei Barannikov }
46992cb984SSergei Barannikov 
47992cb984SSergei Barannikov bool ABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const {
48992cb984SSergei Barannikov   return false;
49992cb984SSergei Barannikov }
50992cb984SSergei Barannikov 
51992cb984SSergei Barannikov bool ABIInfo::isHomogeneousAggregateSmallEnough(const Type *Base,
52992cb984SSergei Barannikov                                                 uint64_t Members) const {
53992cb984SSergei Barannikov   return false;
54992cb984SSergei Barannikov }
55992cb984SSergei Barannikov 
56992cb984SSergei Barannikov bool ABIInfo::isZeroLengthBitfieldPermittedInHomogeneousAggregate() const {
57992cb984SSergei Barannikov   // For compatibility with GCC, ignore empty bitfields in C++ mode.
58992cb984SSergei Barannikov   return getContext().getLangOpts().CPlusPlus;
59992cb984SSergei Barannikov }
60992cb984SSergei Barannikov 
61992cb984SSergei Barannikov bool ABIInfo::isHomogeneousAggregate(QualType Ty, const Type *&Base,
62992cb984SSergei Barannikov                                      uint64_t &Members) const {
63992cb984SSergei Barannikov   if (const ConstantArrayType *AT = getContext().getAsConstantArrayType(Ty)) {
6428ddbd4aSChris B     uint64_t NElements = AT->getZExtSize();
65992cb984SSergei Barannikov     if (NElements == 0)
66992cb984SSergei Barannikov       return false;
67992cb984SSergei Barannikov     if (!isHomogeneousAggregate(AT->getElementType(), Base, Members))
68992cb984SSergei Barannikov       return false;
69992cb984SSergei Barannikov     Members *= NElements;
70992cb984SSergei Barannikov   } else if (const RecordType *RT = Ty->getAs<RecordType>()) {
71992cb984SSergei Barannikov     const RecordDecl *RD = RT->getDecl();
72992cb984SSergei Barannikov     if (RD->hasFlexibleArrayMember())
73992cb984SSergei Barannikov       return false;
74992cb984SSergei Barannikov 
75992cb984SSergei Barannikov     Members = 0;
76992cb984SSergei Barannikov 
77992cb984SSergei Barannikov     // If this is a C++ record, check the properties of the record such as
78992cb984SSergei Barannikov     // bases and ABI specific restrictions
79992cb984SSergei Barannikov     if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
80992cb984SSergei Barannikov       if (!getCXXABI().isPermittedToBeHomogeneousAggregate(CXXRD))
81992cb984SSergei Barannikov         return false;
82992cb984SSergei Barannikov 
83992cb984SSergei Barannikov       for (const auto &I : CXXRD->bases()) {
84992cb984SSergei Barannikov         // Ignore empty records.
85992cb984SSergei Barannikov         if (isEmptyRecord(getContext(), I.getType(), true))
86992cb984SSergei Barannikov           continue;
87992cb984SSergei Barannikov 
88992cb984SSergei Barannikov         uint64_t FldMembers;
89992cb984SSergei Barannikov         if (!isHomogeneousAggregate(I.getType(), Base, FldMembers))
90992cb984SSergei Barannikov           return false;
91992cb984SSergei Barannikov 
92992cb984SSergei Barannikov         Members += FldMembers;
93992cb984SSergei Barannikov       }
94992cb984SSergei Barannikov     }
95992cb984SSergei Barannikov 
96992cb984SSergei Barannikov     for (const auto *FD : RD->fields()) {
97992cb984SSergei Barannikov       // Ignore (non-zero arrays of) empty records.
98992cb984SSergei Barannikov       QualType FT = FD->getType();
99992cb984SSergei Barannikov       while (const ConstantArrayType *AT =
100992cb984SSergei Barannikov              getContext().getAsConstantArrayType(FT)) {
10128ddbd4aSChris B         if (AT->isZeroSize())
102992cb984SSergei Barannikov           return false;
103992cb984SSergei Barannikov         FT = AT->getElementType();
104992cb984SSergei Barannikov       }
105992cb984SSergei Barannikov       if (isEmptyRecord(getContext(), FT, true))
106992cb984SSergei Barannikov         continue;
107992cb984SSergei Barannikov 
108992cb984SSergei Barannikov       if (isZeroLengthBitfieldPermittedInHomogeneousAggregate() &&
109cfe26358STimm Baeder           FD->isZeroLengthBitField())
110992cb984SSergei Barannikov         continue;
111992cb984SSergei Barannikov 
112992cb984SSergei Barannikov       uint64_t FldMembers;
113992cb984SSergei Barannikov       if (!isHomogeneousAggregate(FD->getType(), Base, FldMembers))
114992cb984SSergei Barannikov         return false;
115992cb984SSergei Barannikov 
116992cb984SSergei Barannikov       Members = (RD->isUnion() ?
117992cb984SSergei Barannikov                  std::max(Members, FldMembers) : Members + FldMembers);
118992cb984SSergei Barannikov     }
119992cb984SSergei Barannikov 
120992cb984SSergei Barannikov     if (!Base)
121992cb984SSergei Barannikov       return false;
122992cb984SSergei Barannikov 
123992cb984SSergei Barannikov     // Ensure there is no padding.
124992cb984SSergei Barannikov     if (getContext().getTypeSize(Base) * Members !=
125992cb984SSergei Barannikov         getContext().getTypeSize(Ty))
126992cb984SSergei Barannikov       return false;
127992cb984SSergei Barannikov   } else {
128992cb984SSergei Barannikov     Members = 1;
129992cb984SSergei Barannikov     if (const ComplexType *CT = Ty->getAs<ComplexType>()) {
130992cb984SSergei Barannikov       Members = 2;
131992cb984SSergei Barannikov       Ty = CT->getElementType();
132992cb984SSergei Barannikov     }
133992cb984SSergei Barannikov 
134992cb984SSergei Barannikov     // Most ABIs only support float, double, and some vector type widths.
135992cb984SSergei Barannikov     if (!isHomogeneousAggregateBaseType(Ty))
136992cb984SSergei Barannikov       return false;
137992cb984SSergei Barannikov 
138992cb984SSergei Barannikov     // The base type must be the same for all members.  Types that
139992cb984SSergei Barannikov     // agree in both total size and mode (float vs. vector) are
140992cb984SSergei Barannikov     // treated as being equivalent here.
141992cb984SSergei Barannikov     const Type *TyPtr = Ty.getTypePtr();
142992cb984SSergei Barannikov     if (!Base) {
143992cb984SSergei Barannikov       Base = TyPtr;
144992cb984SSergei Barannikov       // If it's a non-power-of-2 vector, its size is already a power-of-2,
145992cb984SSergei Barannikov       // so make sure to widen it explicitly.
146992cb984SSergei Barannikov       if (const VectorType *VT = Base->getAs<VectorType>()) {
147992cb984SSergei Barannikov         QualType EltTy = VT->getElementType();
148992cb984SSergei Barannikov         unsigned NumElements =
149992cb984SSergei Barannikov             getContext().getTypeSize(VT) / getContext().getTypeSize(EltTy);
150992cb984SSergei Barannikov         Base = getContext()
151992cb984SSergei Barannikov                    .getVectorType(EltTy, NumElements, VT->getVectorKind())
152992cb984SSergei Barannikov                    .getTypePtr();
153992cb984SSergei Barannikov       }
154992cb984SSergei Barannikov     }
155992cb984SSergei Barannikov 
156992cb984SSergei Barannikov     if (Base->isVectorType() != TyPtr->isVectorType() ||
157992cb984SSergei Barannikov         getContext().getTypeSize(Base) != getContext().getTypeSize(TyPtr))
158992cb984SSergei Barannikov       return false;
159992cb984SSergei Barannikov   }
160992cb984SSergei Barannikov   return Members > 0 && isHomogeneousAggregateSmallEnough(Base, Members);
161992cb984SSergei Barannikov }
162992cb984SSergei Barannikov 
163992cb984SSergei Barannikov bool ABIInfo::isPromotableIntegerTypeForABI(QualType Ty) const {
164992cb984SSergei Barannikov   if (getContext().isPromotableIntegerType(Ty))
165992cb984SSergei Barannikov     return true;
166992cb984SSergei Barannikov 
167992cb984SSergei Barannikov   if (const auto *EIT = Ty->getAs<BitIntType>())
168992cb984SSergei Barannikov     if (EIT->getNumBits() < getContext().getTypeSize(getContext().IntTy))
169992cb984SSergei Barannikov       return true;
170992cb984SSergei Barannikov 
171992cb984SSergei Barannikov   return false;
172992cb984SSergei Barannikov }
173992cb984SSergei Barannikov 
174992cb984SSergei Barannikov ABIArgInfo ABIInfo::getNaturalAlignIndirect(QualType Ty, bool ByVal,
175992cb984SSergei Barannikov                                             bool Realign,
176992cb984SSergei Barannikov                                             llvm::Type *Padding) const {
177992cb984SSergei Barannikov   return ABIArgInfo::getIndirect(getContext().getTypeAlignInChars(Ty), ByVal,
178992cb984SSergei Barannikov                                  Realign, Padding);
179992cb984SSergei Barannikov }
180992cb984SSergei Barannikov 
181992cb984SSergei Barannikov ABIArgInfo ABIInfo::getNaturalAlignIndirectInReg(QualType Ty,
182992cb984SSergei Barannikov                                                  bool Realign) const {
183992cb984SSergei Barannikov   return ABIArgInfo::getIndirectInReg(getContext().getTypeAlignInChars(Ty),
184992cb984SSergei Barannikov                                       /*ByVal*/ false, Realign);
185992cb984SSergei Barannikov }
186992cb984SSergei Barannikov 
187b42b7c8aSAlexandros Lamprineas void ABIInfo::appendAttributeMangling(TargetAttr *Attr,
188b42b7c8aSAlexandros Lamprineas                                       raw_ostream &Out) const {
189b42b7c8aSAlexandros Lamprineas   if (Attr->isDefaultVersion())
190b42b7c8aSAlexandros Lamprineas     return;
191b42b7c8aSAlexandros Lamprineas   appendAttributeMangling(Attr->getFeaturesStr(), Out);
192b42b7c8aSAlexandros Lamprineas }
193b42b7c8aSAlexandros Lamprineas 
194b42b7c8aSAlexandros Lamprineas void ABIInfo::appendAttributeMangling(TargetVersionAttr *Attr,
195b42b7c8aSAlexandros Lamprineas                                       raw_ostream &Out) const {
196b42b7c8aSAlexandros Lamprineas   appendAttributeMangling(Attr->getNamesStr(), Out);
197b42b7c8aSAlexandros Lamprineas }
198b42b7c8aSAlexandros Lamprineas 
199b42b7c8aSAlexandros Lamprineas void ABIInfo::appendAttributeMangling(TargetClonesAttr *Attr, unsigned Index,
200b42b7c8aSAlexandros Lamprineas                                       raw_ostream &Out) const {
201b42b7c8aSAlexandros Lamprineas   appendAttributeMangling(Attr->getFeatureStr(Index), Out);
202b42b7c8aSAlexandros Lamprineas   Out << '.' << Attr->getMangledIndex(Index);
203b42b7c8aSAlexandros Lamprineas }
204b42b7c8aSAlexandros Lamprineas 
205b42b7c8aSAlexandros Lamprineas void ABIInfo::appendAttributeMangling(StringRef AttrStr,
206b42b7c8aSAlexandros Lamprineas                                       raw_ostream &Out) const {
207b42b7c8aSAlexandros Lamprineas   if (AttrStr == "default") {
208b42b7c8aSAlexandros Lamprineas     Out << ".default";
209b42b7c8aSAlexandros Lamprineas     return;
210b42b7c8aSAlexandros Lamprineas   }
211b42b7c8aSAlexandros Lamprineas 
212b42b7c8aSAlexandros Lamprineas   Out << '.';
213b42b7c8aSAlexandros Lamprineas   const TargetInfo &TI = CGT.getTarget();
214b42b7c8aSAlexandros Lamprineas   ParsedTargetAttr Info = TI.parseTargetAttr(AttrStr);
215b42b7c8aSAlexandros Lamprineas 
216b42b7c8aSAlexandros Lamprineas   llvm::sort(Info.Features, [&TI](StringRef LHS, StringRef RHS) {
217b42b7c8aSAlexandros Lamprineas     // Multiversioning doesn't allow "no-${feature}", so we can
218b42b7c8aSAlexandros Lamprineas     // only have "+" prefixes here.
219b42b7c8aSAlexandros Lamprineas     assert(LHS.starts_with("+") && RHS.starts_with("+") &&
220b42b7c8aSAlexandros Lamprineas            "Features should always have a prefix.");
22188c2af80SAlexandros Lamprineas     return TI.getFMVPriority({LHS.substr(1)}) >
22288c2af80SAlexandros Lamprineas            TI.getFMVPriority({RHS.substr(1)});
223b42b7c8aSAlexandros Lamprineas   });
224b42b7c8aSAlexandros Lamprineas 
225b42b7c8aSAlexandros Lamprineas   bool IsFirst = true;
226b42b7c8aSAlexandros Lamprineas   if (!Info.CPU.empty()) {
227b42b7c8aSAlexandros Lamprineas     IsFirst = false;
228b42b7c8aSAlexandros Lamprineas     Out << "arch_" << Info.CPU;
229b42b7c8aSAlexandros Lamprineas   }
230b42b7c8aSAlexandros Lamprineas 
231b42b7c8aSAlexandros Lamprineas   for (StringRef Feat : Info.Features) {
232b42b7c8aSAlexandros Lamprineas     if (!IsFirst)
233b42b7c8aSAlexandros Lamprineas       Out << '_';
234b42b7c8aSAlexandros Lamprineas     IsFirst = false;
235b42b7c8aSAlexandros Lamprineas     Out << Feat.substr(1);
236b42b7c8aSAlexandros Lamprineas   }
237b42b7c8aSAlexandros Lamprineas }
238b42b7c8aSAlexandros Lamprineas 
239*03744d2aSShilei Tian llvm::FixedVectorType *
240*03744d2aSShilei Tian ABIInfo::getOptimalVectorMemoryType(llvm::FixedVectorType *T,
241*03744d2aSShilei Tian                                     const LangOptions &Opt) const {
242*03744d2aSShilei Tian   if (T->getNumElements() == 3 && !Opt.PreserveVec3Type)
243*03744d2aSShilei Tian     return llvm::FixedVectorType::get(T->getElementType(), 4);
244*03744d2aSShilei Tian   return T;
245*03744d2aSShilei Tian }
246*03744d2aSShilei Tian 
247992cb984SSergei Barannikov // Pin the vtable to this file.
248992cb984SSergei Barannikov SwiftABIInfo::~SwiftABIInfo() = default;
249992cb984SSergei Barannikov 
250992cb984SSergei Barannikov /// Does the given lowering require more than the given number of
251992cb984SSergei Barannikov /// registers when expanded?
252992cb984SSergei Barannikov ///
253992cb984SSergei Barannikov /// This is intended to be the basis of a reasonable basic implementation
254992cb984SSergei Barannikov /// of should{Pass,Return}Indirectly.
255992cb984SSergei Barannikov ///
256992cb984SSergei Barannikov /// For most targets, a limit of four total registers is reasonable; this
257992cb984SSergei Barannikov /// limits the amount of code required in order to move around the value
258992cb984SSergei Barannikov /// in case it wasn't produced immediately prior to the call by the caller
259992cb984SSergei Barannikov /// (or wasn't produced in exactly the right registers) or isn't used
260992cb984SSergei Barannikov /// immediately within the callee.  But some targets may need to further
261992cb984SSergei Barannikov /// limit the register count due to an inability to support that many
262992cb984SSergei Barannikov /// return registers.
263992cb984SSergei Barannikov bool SwiftABIInfo::occupiesMoreThan(ArrayRef<llvm::Type *> scalarTypes,
264992cb984SSergei Barannikov                                     unsigned maxAllRegisters) const {
265992cb984SSergei Barannikov   unsigned intCount = 0, fpCount = 0;
266992cb984SSergei Barannikov   for (llvm::Type *type : scalarTypes) {
267992cb984SSergei Barannikov     if (type->isPointerTy()) {
268992cb984SSergei Barannikov       intCount++;
269992cb984SSergei Barannikov     } else if (auto intTy = dyn_cast<llvm::IntegerType>(type)) {
270992cb984SSergei Barannikov       auto ptrWidth = CGT.getTarget().getPointerWidth(LangAS::Default);
271992cb984SSergei Barannikov       intCount += (intTy->getBitWidth() + ptrWidth - 1) / ptrWidth;
272992cb984SSergei Barannikov     } else {
273992cb984SSergei Barannikov       assert(type->isVectorTy() || type->isFloatingPointTy());
274992cb984SSergei Barannikov       fpCount++;
275992cb984SSergei Barannikov     }
276992cb984SSergei Barannikov   }
277992cb984SSergei Barannikov 
278992cb984SSergei Barannikov   return (intCount + fpCount > maxAllRegisters);
279992cb984SSergei Barannikov }
280992cb984SSergei Barannikov 
281992cb984SSergei Barannikov bool SwiftABIInfo::shouldPassIndirectly(ArrayRef<llvm::Type *> ComponentTys,
282992cb984SSergei Barannikov                                         bool AsReturnValue) const {
283992cb984SSergei Barannikov   return occupiesMoreThan(ComponentTys, /*total=*/4);
284992cb984SSergei Barannikov }
285992cb984SSergei Barannikov 
286992cb984SSergei Barannikov bool SwiftABIInfo::isLegalVectorType(CharUnits VectorSize, llvm::Type *EltTy,
287992cb984SSergei Barannikov                                      unsigned NumElts) const {
288992cb984SSergei Barannikov   // The default implementation of this assumes that the target guarantees
289992cb984SSergei Barannikov   // 128-bit SIMD support but nothing more.
290992cb984SSergei Barannikov   return (VectorSize.getQuantity() > 8 && VectorSize.getQuantity() <= 16);
291992cb984SSergei Barannikov }
292