clang 24.0.0git
ABIInfo.cpp
Go to the documentation of this file.
1//===- ABIInfo.cpp --------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "ABIInfo.h"
10#include "ABIInfoImpl.h"
11
12using namespace clang;
13using namespace clang::CodeGen;
14
15// Pin the vtable to this file.
16ABIInfo::~ABIInfo() = default;
17
18CGCXXABI &ABIInfo::getCXXABI() const { return CGT.getCXXABI(); }
19
20ASTContext &ABIInfo::getContext() const { return CGT.getContext(); }
21
22llvm::LLVMContext &ABIInfo::getVMContext() const {
23 return CGT.getLLVMContext();
24}
25
26const llvm::DataLayout &ABIInfo::getDataLayout() const {
27 return CGT.getDataLayout();
28}
29
30const TargetInfo &ABIInfo::getTarget() const { return CGT.getTarget(); }
31
33 return CGT.getCodeGenOpts();
34}
35
36bool ABIInfo::isAndroid() const { return getTarget().getTriple().isAndroid(); }
37
39 return getTarget().getTriple().isOHOSFamily();
40}
41
43 QualType Ty, AggValueSlot Slot) const {
44 return RValue::getIgnored();
45}
46
48 QualType Ty, AggValueSlot Slot) const {
49 return RValue::getIgnored();
50}
51
53 return false;
54}
55
57 uint64_t Members) const {
58 return false;
59}
60
62 // For compatibility with GCC, ignore empty bitfields in C++ mode.
63 return getContext().getLangOpts().CPlusPlus;
64}
65
67 uint64_t &Members) const {
68 if (const ConstantArrayType *AT = getContext().getAsConstantArrayType(Ty)) {
69 uint64_t NElements = AT->getZExtSize();
70 if (NElements == 0)
71 return false;
72 if (!isHomogeneousAggregate(AT->getElementType(), Base, Members))
73 return false;
74 Members *= NElements;
75 } else if (Ty->isConstantMatrixType() &&
76 getContext().getLangOpts().getClangABICompat() >
77 LangOptions::ClangABI::Ver23) {
79 uint64_t NElements = MT->getNumElementsFlattened();
80 if (NElements == 0)
81 return false;
82 if (!isHomogeneousAggregate(MT->getElementType(), Base, Members))
83 return false;
84 Members *= NElements;
85 } else if (const auto *RD = Ty->getAsRecordDecl()) {
86 if (RD->hasFlexibleArrayMember())
87 return false;
88
89 Members = 0;
90
91 // If this is a C++ record, check the properties of the record such as
92 // bases and ABI specific restrictions
93 if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
94 if (!getCXXABI().isPermittedToBeHomogeneousAggregate(CXXRD))
95 return false;
96
97 for (const auto &I : CXXRD->bases()) {
98 // Ignore empty records.
99 if (isEmptyRecord(getContext(), I.getType(), true))
100 continue;
101
102 uint64_t FldMembers;
103 if (!isHomogeneousAggregate(I.getType(), Base, FldMembers))
104 return false;
105
106 Members += FldMembers;
107 }
108 }
109
110 for (const auto *FD : RD->fields()) {
111 // Ignore (non-zero arrays of) empty records.
112 QualType FT = FD->getType();
113 while (const ConstantArrayType *AT =
114 getContext().getAsConstantArrayType(FT)) {
115 if (AT->isZeroSize())
116 return false;
117 FT = AT->getElementType();
118 }
119 if (isEmptyRecord(getContext(), FT, true))
120 continue;
121
123 FD->isZeroLengthBitField())
124 continue;
125
126 uint64_t FldMembers;
127 if (!isHomogeneousAggregate(FD->getType(), Base, FldMembers))
128 return false;
129
130 Members = (RD->isUnion() ?
131 std::max(Members, FldMembers) : Members + FldMembers);
132 }
133
134 if (!Base)
135 return false;
136
137 // Ensure there is no padding.
138 if (getContext().getTypeSize(Base) * Members !=
139 getContext().getTypeSize(Ty))
140 return false;
141 } else {
142 Members = 1;
143 if (const ComplexType *CT = Ty->getAs<ComplexType>()) {
144 Members = 2;
145 Ty = CT->getElementType();
146 }
147
148 // Most ABIs only support float, double, and some vector type widths.
150 return false;
151
152 // The base type must be the same for all members. Types that
153 // agree in both total size and mode (float vs. vector) are
154 // treated as being equivalent here.
155 const Type *TyPtr = Ty.getTypePtr();
156 if (!Base) {
157 Base = TyPtr;
158 // If it's a non-power-of-2 vector, its size is already a power-of-2,
159 // so make sure to widen it explicitly.
160 if (const VectorType *VT = Base->getAs<VectorType>()) {
161 QualType EltTy = VT->getElementType();
162 unsigned NumElements =
164 Base = getContext()
165 .getVectorType(EltTy, NumElements, VT->getVectorKind())
166 .getTypePtr();
167 }
168 }
169
170 if (Base->isVectorType() != TyPtr->isVectorType() ||
171 getContext().getTypeSize(Base) != getContext().getTypeSize(TyPtr))
172 return false;
173 }
174 return Members > 0 && isHomogeneousAggregateSmallEnough(Base, Members);
175}
176
178 if (getContext().isPromotableIntegerType(Ty))
179 return true;
180
181 if (const auto *EIT = Ty->getAs<BitIntType>())
182 if (EIT->getNumBits() < getContext().getTypeSize(getContext().IntTy))
183 return true;
184
185 return false;
186}
187
189 bool ByVal, bool Realign,
190 llvm::Type *Padding) const {
191 return ABIArgInfo::getIndirect(getContext().getTypeAlignInChars(Ty),
192 AddrSpace, ByVal, Realign, Padding);
193}
194
196 bool Realign) const {
197 return ABIArgInfo::getIndirectInReg(getContext().getTypeAlignInChars(Ty),
198 /*ByVal*/ false, Realign);
199}
200
202 raw_ostream &Out) const {
203 if (Attr->isDefaultVersion())
204 return;
205 appendAttributeMangling(Attr->getFeaturesStr(), Out);
206}
207
209 raw_ostream &Out) const {
210 appendAttributeMangling(Attr->getNamesStr(), Out);
211}
212
213void ABIInfo::appendAttributeMangling(TargetClonesAttr *Attr, unsigned Index,
214 raw_ostream &Out) const {
215 appendAttributeMangling(Attr->getFeatureStr(Index), Out);
216 Out << '.' << Attr->getMangledIndex(Index);
217}
218
219void ABIInfo::appendAttributeMangling(StringRef AttrStr,
220 raw_ostream &Out) const {
221 if (AttrStr == "default") {
222 Out << ".default";
223 return;
224 }
225
226 Out << '.';
227 const TargetInfo &TI = CGT.getTarget();
228 ParsedTargetAttr Info = TI.parseTargetAttr(AttrStr);
229
230 llvm::sort(Info.Features, [&TI](StringRef LHS, StringRef RHS) {
231 // Multiversioning doesn't allow "no-${feature}", so we can
232 // only have "+" prefixes here.
233 assert(LHS.starts_with("+") && RHS.starts_with("+") &&
234 "Features should always have a prefix.");
235 return TI.getFMVPriority({LHS.substr(1)})
236 .ugt(TI.getFMVPriority({RHS.substr(1)}));
237 });
238
239 bool IsFirst = true;
240 if (!Info.CPU.empty()) {
241 IsFirst = false;
242 Out << "arch_" << Info.CPU;
243 }
244
245 for (StringRef Feat : Info.Features) {
246 if (!IsFirst)
247 Out << '_';
248 IsFirst = false;
249 Out << Feat.substr(1);
250 }
251}
252
253llvm::FixedVectorType *
255 const LangOptions &Opt) const {
256 if (T->getNumElements() == 3 && !Opt.PreserveVec3Type)
257 return llvm::FixedVectorType::get(T->getElementType(), 4);
258 return T;
259}
260
261llvm::Value *ABIInfo::createCoercedLoad(Address SrcAddr, const ABIArgInfo &AI,
262 CodeGenFunction &CGF) const {
263 return nullptr;
264}
265
266void ABIInfo::createCoercedStore(llvm::Value *Val, Address DstAddr,
267 const ABIArgInfo &AI, bool DestIsVolatile,
268 CodeGenFunction &CGF) const {}
269
271 bool IsNamedArg) const {
272 llvm_unreachable("Only implemented for x86");
273}
274
275// Pin the vtable to this file.
277
278/// Does the given lowering require more than the given number of
279/// registers when expanded?
280///
281/// This is intended to be the basis of a reasonable basic implementation
282/// of should{Pass,Return}Indirectly.
283///
284/// For most targets, a limit of four total registers is reasonable; this
285/// limits the amount of code required in order to move around the value
286/// in case it wasn't produced immediately prior to the call by the caller
287/// (or wasn't produced in exactly the right registers) or isn't used
288/// immediately within the callee. But some targets may need to further
289/// limit the register count due to an inability to support that many
290/// return registers.
292 unsigned maxAllRegisters) const {
293 unsigned intCount = 0, fpCount = 0;
294 for (llvm::Type *type : scalarTypes) {
295 if (type->isPointerTy()) {
296 intCount++;
297 } else if (auto intTy = dyn_cast<llvm::IntegerType>(type)) {
298 auto ptrWidth = CGT.getTarget().getPointerWidth(LangAS::Default);
299 intCount += (intTy->getBitWidth() + ptrWidth - 1) / ptrWidth;
300 } else {
301 assert(type->isVectorTy() || type->isFloatingPointTy());
302 fpCount++;
303 }
304 }
305
306 return (intCount + fpCount > maxAllRegisters);
307}
308
310 bool AsReturnValue) const {
311 return occupiesMoreThan(ComponentTys, /*total=*/4);
312}
313
314bool SwiftABIInfo::isLegalVectorType(CharUnits VectorSize, llvm::Type *EltTy,
315 unsigned NumElts) const {
316 // The default implementation of this assumes that the target guarantees
317 // 128-bit SIMD support but nothing more.
318 return (VectorSize.getQuantity() > 8 && VectorSize.getQuantity() <= 16);
319}
unsigned IsFirst
Indicates that this is the first token of the file.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:239
QualType getVectorType(QualType VectorType, unsigned NumElts, VectorKind VecKind) const
Return the unique reference to a vector type of the specified element type and size.
const LangOptions & getLangOpts() const
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
Attr - This represents one attribute.
Definition Attr.h:46
A fixed int type of a specified bitwidth.
Definition TypeBase.h:8286
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
CharUnits - This is an opaque type for sizes expressed in character units.
Definition CharUnits.h:38
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Definition CharUnits.h:185
CodeGenOptions - Track various options which control how the code is optimized and passed to the back...
ABIArgInfo - Helper class to encapsulate information about how a specific C type should be passed to ...
static ABIArgInfo getIndirectInReg(CharUnits Alignment, bool ByVal=true, bool Realign=false)
static ABIArgInfo getIndirect(CharUnits Alignment, unsigned AddrSpace, bool ByVal=true, bool Realign=false, llvm::Type *Padding=nullptr)
const llvm::DataLayout & getDataLayout() const
Definition ABIInfo.cpp:26
CodeGen::ABIArgInfo getNaturalAlignIndirect(QualType Ty, unsigned AddrSpace, bool ByVal=true, bool Realign=false, llvm::Type *Padding=nullptr) const
A convenience method to return an indirect ABIArgInfo with an expected alignment equal to the ABI ali...
Definition ABIInfo.cpp:188
const CodeGenOptions & getCodeGenOpts() const
Definition ABIInfo.cpp:32
CodeGen::CodeGenTypes & CGT
Definition ABIInfo.h:51
bool isHomogeneousAggregate(QualType Ty, const Type *&Base, uint64_t &Members) const
isHomogeneousAggregate - Return true if a type is an ELFv2 homogeneous aggregate.
Definition ABIInfo.cpp:66
CodeGen::CGCXXABI & getCXXABI() const
Definition ABIInfo.cpp:18
ASTContext & getContext() const
Definition ABIInfo.cpp:20
virtual bool isHomogeneousAggregateBaseType(QualType Ty) const
Definition ABIInfo.cpp:52
bool isPromotableIntegerTypeForABI(QualType Ty) const
Definition ABIInfo.cpp:177
virtual void createCoercedStore(llvm::Value *Val, Address DstAddr, const ABIArgInfo &AI, bool DestIsVolatile, CodeGenFunction &CGF) const
Definition ABIInfo.cpp:266
virtual void appendAttributeMangling(TargetAttr *Attr, raw_ostream &Out) const
Definition ABIInfo.cpp:201
bool isOHOSFamily() const
Definition ABIInfo.cpp:38
virtual RValue EmitMSVAArg(CodeGen::CodeGenFunction &CGF, CodeGen::Address VAListAddr, QualType Ty, AggValueSlot Slot) const
Emit the target dependent code to load a value of.
Definition ABIInfo.cpp:42
virtual RValue EmitZOSVAArg(CodeGen::CodeGenFunction &CGF, CodeGen::Address VAListAddr, QualType Ty, AggValueSlot Slot) const
Emit the target dependent code to load a value of.
Definition ABIInfo.cpp:47
virtual llvm::Value * createCoercedLoad(Address SrcAddr, const ABIArgInfo &AI, CodeGenFunction &CGF) const
Definition ABIInfo.cpp:261
virtual bool isHomogeneousAggregateSmallEnough(const Type *Base, uint64_t Members) const
Definition ABIInfo.cpp:56
const TargetInfo & getTarget() const
Definition ABIInfo.cpp:30
virtual bool isZeroLengthBitfieldPermittedInHomogeneousAggregate() const
Definition ABIInfo.cpp:61
virtual ABIArgInfo classifyArgForArm64ECVarArg(QualType Ty, bool IsNamedArg) const
Used by Arm64EC calling convention code to call into x86 calling convention code for varargs function...
Definition ABIInfo.cpp:270
CodeGen::ABIArgInfo getNaturalAlignIndirectInReg(QualType Ty, bool Realign=false) const
Definition ABIInfo.cpp:195
bool isAndroid() const
Definition ABIInfo.cpp:36
llvm::LLVMContext & getVMContext() const
Definition ABIInfo.cpp:22
virtual llvm::FixedVectorType * getOptimalVectorMemoryType(llvm::FixedVectorType *T, const LangOptions &Opt) const
Returns the optimal vector memory type based on the given vector type.
Definition ABIInfo.cpp:254
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
Definition Address.h:128
An aggregate value slot.
Definition CGValue.h:551
Implements C++ ABI-specific code generation functions.
Definition CGCXXABI.h:43
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
Definition CGValue.h:42
static RValue getIgnored()
Definition CGValue.h:94
virtual bool isLegalVectorType(CharUnits VectorSize, llvm::Type *EltTy, unsigned NumElts) const
Returns true if the given vector type is legal from Swift's calling convention perspective.
Definition ABIInfo.cpp:314
bool occupiesMoreThan(ArrayRef< llvm::Type * > scalarTypes, unsigned maxAllRegisters) const
Does the given lowering require more than the given number of registers when expanded?
Definition ABIInfo.cpp:291
virtual bool shouldPassIndirectly(ArrayRef< llvm::Type * > ComponentTys, bool AsReturnValue) const
Returns true if an aggregate which expands to the given type sequence should be passed / returned ind...
Definition ABIInfo.cpp:309
Complex values, per C99 6.2.5p11.
Definition TypeBase.h:3355
Represents the canonical version of C arrays with a specified constant size.
Definition TypeBase.h:3851
Represents a concrete matrix type with constant number of rows and columns.
Definition TypeBase.h:4478
unsigned getNumElementsFlattened() const
Returns the number of elements required to embed the matrix into a vector.
Definition TypeBase.h:4500
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
QualType getElementType() const
Returns type of the elements being stored in the matrix.
Definition TypeBase.h:4442
A (possibly-)qualified type.
Definition TypeBase.h:938
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition TypeBase.h:8428
Exposes information about the current target.
Definition TargetInfo.h:226
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
virtual llvm::APInt getFMVPriority(ArrayRef< StringRef > Features) const
virtual ParsedTargetAttr parseTargetAttr(StringRef Str) const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
Definition Type.h:41
bool isConstantMatrixType() const
Definition TypeBase.h:8832
const T * castAs() const
Member-template castAs<specific type>.
Definition TypeBase.h:9331
bool isVectorType() const
Definition TypeBase.h:8804
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9264
Represents a GCC generic vector type.
Definition TypeBase.h:4266
@ Type
The l-value was considered opaque, so the alignment was determined from a type.
Definition CGValue.h:155
bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays, bool AsIfNoUniqueAddr=false)
isEmptyRecord - Return true iff a structure contains only empty fields.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
Top level wrappers for InstallAPI frontend operations.
const FunctionProtoType * T
Contains information gathered from parsing the contents of TargetAttr.
Definition TargetInfo.h:59
std::vector< std::string > Features
Definition TargetInfo.h:60