clang 18.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
19
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) const {
44 return Address::invalid();
45}
46
48 return false;
49}
50
52 uint64_t Members) const {
53 return false;
54}
55
57 // For compatibility with GCC, ignore empty bitfields in C++ mode.
58 return getContext().getLangOpts().CPlusPlus;
59}
60
62 uint64_t &Members) const {
63 if (const ConstantArrayType *AT = getContext().getAsConstantArrayType(Ty)) {
64 uint64_t NElements = AT->getSize().getZExtValue();
65 if (NElements == 0)
66 return false;
67 if (!isHomogeneousAggregate(AT->getElementType(), Base, Members))
68 return false;
69 Members *= NElements;
70 } else if (const RecordType *RT = Ty->getAs<RecordType>()) {
71 const RecordDecl *RD = RT->getDecl();
72 if (RD->hasFlexibleArrayMember())
73 return false;
74
75 Members = 0;
76
77 // If this is a C++ record, check the properties of the record such as
78 // bases and ABI specific restrictions
79 if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
80 if (!getCXXABI().isPermittedToBeHomogeneousAggregate(CXXRD))
81 return false;
82
83 for (const auto &I : CXXRD->bases()) {
84 // Ignore empty records.
85 if (isEmptyRecord(getContext(), I.getType(), true))
86 continue;
87
88 uint64_t FldMembers;
89 if (!isHomogeneousAggregate(I.getType(), Base, FldMembers))
90 return false;
91
92 Members += FldMembers;
93 }
94 }
95
96 for (const auto *FD : RD->fields()) {
97 // Ignore (non-zero arrays of) empty records.
98 QualType FT = FD->getType();
99 while (const ConstantArrayType *AT =
100 getContext().getAsConstantArrayType(FT)) {
101 if (AT->getSize().getZExtValue() == 0)
102 return false;
103 FT = AT->getElementType();
104 }
105 if (isEmptyRecord(getContext(), FT, true))
106 continue;
107
109 FD->isZeroLengthBitField(getContext()))
110 continue;
111
112 uint64_t FldMembers;
113 if (!isHomogeneousAggregate(FD->getType(), Base, FldMembers))
114 return false;
115
116 Members = (RD->isUnion() ?
117 std::max(Members, FldMembers) : Members + FldMembers);
118 }
119
120 if (!Base)
121 return false;
122
123 // Ensure there is no padding.
124 if (getContext().getTypeSize(Base) * Members !=
126 return false;
127 } else {
128 Members = 1;
129 if (const ComplexType *CT = Ty->getAs<ComplexType>()) {
130 Members = 2;
131 Ty = CT->getElementType();
132 }
133
134 // Most ABIs only support float, double, and some vector type widths.
136 return false;
137
138 // The base type must be the same for all members. Types that
139 // agree in both total size and mode (float vs. vector) are
140 // treated as being equivalent here.
141 const Type *TyPtr = Ty.getTypePtr();
142 if (!Base) {
143 Base = TyPtr;
144 // If it's a non-power-of-2 vector, its size is already a power-of-2,
145 // so make sure to widen it explicitly.
146 if (const VectorType *VT = Base->getAs<VectorType>()) {
147 QualType EltTy = VT->getElementType();
148 unsigned NumElements =
150 Base = getContext()
151 .getVectorType(EltTy, NumElements, VT->getVectorKind())
152 .getTypePtr();
153 }
154 }
155
156 if (Base->isVectorType() != TyPtr->isVectorType() ||
157 getContext().getTypeSize(Base) != getContext().getTypeSize(TyPtr))
158 return false;
159 }
160 return Members > 0 && isHomogeneousAggregateSmallEnough(Base, Members);
161}
162
164 if (getContext().isPromotableIntegerType(Ty))
165 return true;
166
167 if (const auto *EIT = Ty->getAs<BitIntType>())
168 if (EIT->getNumBits() < getContext().getTypeSize(getContext().IntTy))
169 return true;
170
171 return false;
172}
173
175 bool Realign,
176 llvm::Type *Padding) const {
177 return ABIArgInfo::getIndirect(getContext().getTypeAlignInChars(Ty), ByVal,
178 Realign, Padding);
179}
180
182 bool Realign) const {
183 return ABIArgInfo::getIndirectInReg(getContext().getTypeAlignInChars(Ty),
184 /*ByVal*/ false, Realign);
185}
186
187// Pin the vtable to this file.
189
190/// Does the given lowering require more than the given number of
191/// registers when expanded?
192///
193/// This is intended to be the basis of a reasonable basic implementation
194/// of should{Pass,Return}Indirectly.
195///
196/// For most targets, a limit of four total registers is reasonable; this
197/// limits the amount of code required in order to move around the value
198/// in case it wasn't produced immediately prior to the call by the caller
199/// (or wasn't produced in exactly the right registers) or isn't used
200/// immediately within the callee. But some targets may need to further
201/// limit the register count due to an inability to support that many
202/// return registers.
204 unsigned maxAllRegisters) const {
205 unsigned intCount = 0, fpCount = 0;
206 for (llvm::Type *type : scalarTypes) {
207 if (type->isPointerTy()) {
208 intCount++;
209 } else if (auto intTy = dyn_cast<llvm::IntegerType>(type)) {
210 auto ptrWidth = CGT.getTarget().getPointerWidth(LangAS::Default);
211 intCount += (intTy->getBitWidth() + ptrWidth - 1) / ptrWidth;
212 } else {
213 assert(type->isVectorTy() || type->isFloatingPointTy());
214 fpCount++;
215 }
216 }
217
218 return (intCount + fpCount > maxAllRegisters);
219}
220
222 bool AsReturnValue) const {
223 return occupiesMoreThan(ComponentTys, /*total=*/4);
224}
225
226bool SwiftABIInfo::isLegalVectorType(CharUnits VectorSize, llvm::Type *EltTy,
227 unsigned NumElts) const {
228 // The default implementation of this assumes that the target guarantees
229 // 128-bit SIMD support but nothing more.
230 return (VectorSize.getQuantity() > 8 && VectorSize.getQuantity() <= 16);
231}
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
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
Definition: ASTContext.h:767
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
Definition: ASTContext.h:2307
A fixed int type of a specified bitwidth.
Definition: Type.h:6664
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, bool ByVal=true, bool Realign=false, llvm::Type *Padding=nullptr)
const llvm::DataLayout & getDataLayout() const
Definition: ABIInfo.cpp:26
const CodeGenOptions & getCodeGenOpts() const
Definition: ABIInfo.cpp:32
CodeGen::CodeGenTypes & CGT
Definition: ABIInfo.h:46
virtual CodeGen::Address EmitMSVAArg(CodeGen::CodeGenFunction &CGF, CodeGen::Address VAListAddr, QualType Ty) const
Emit the target dependent code to load a value of.
Definition: ABIInfo.cpp:42
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:61
CodeGen::CGCXXABI & getCXXABI() const
Definition: ABIInfo.cpp:18
ASTContext & getContext() const
Definition: ABIInfo.cpp:20
virtual bool isHomogeneousAggregateBaseType(QualType Ty) const
Definition: ABIInfo.cpp:47
bool isPromotableIntegerTypeForABI(QualType Ty) const
Definition: ABIInfo.cpp:163
bool isOHOSFamily() const
Definition: ABIInfo.cpp:38
CodeGen::ABIArgInfo getNaturalAlignIndirect(QualType Ty, 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:174
virtual bool isHomogeneousAggregateSmallEnough(const Type *Base, uint64_t Members) const
Definition: ABIInfo.cpp:51
const TargetInfo & getTarget() const
Definition: ABIInfo.cpp:30
virtual bool isZeroLengthBitfieldPermittedInHomogeneousAggregate() const
Definition: ABIInfo.cpp:56
CodeGen::ABIArgInfo getNaturalAlignIndirectInReg(QualType Ty, bool Realign=false) const
Definition: ABIInfo.cpp:181
bool isAndroid() const
Definition: ABIInfo.cpp:36
llvm::LLVMContext & getVMContext() const
Definition: ABIInfo.cpp:22
An aligned address.
Definition: Address.h:29
static Address invalid()
Definition: Address.h:46
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...
const CodeGenOptions & getCodeGenOpts() const
ASTContext & getContext() const
Definition: CodeGenTypes.h:108
const TargetInfo & getTarget() const
Definition: CodeGenTypes.h:110
llvm::LLVMContext & getLLVMContext()
Definition: CodeGenTypes.h:112
const llvm::DataLayout & getDataLayout() const
Definition: CodeGenTypes.h:104
CGCXXABI & getCXXABI() const
Definition: CodeGenTypes.h:111
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:226
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:203
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:221
Complex values, per C99 6.2.5p11.
Definition: Type.h:2843
Represents the canonical version of C arrays with a specified constant size.
Definition: Type.h:3184
A (possibly-)qualified type.
Definition: Type.h:736
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:6781
Represents a struct/union/class.
Definition: Decl.h:4117
bool hasFlexibleArrayMember() const
Definition: Decl.h:4150
field_range fields() const
Definition: Decl.h:4323
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:4971
bool isUnion() const
Definition: Decl.h:3739
Exposes information about the current target.
Definition: TargetInfo.h:212
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Definition: TargetInfo.h:1218
uint64_t getPointerWidth(LangAS AddrSpace) const
Return the width of pointers on this target, for the specified address space.
Definition: TargetInfo.h:464
The base class of the type hierarchy.
Definition: Type.h:1602
bool isVectorType() const
Definition: Type.h:7135
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:7558
Represents a GCC generic vector type.
Definition: Type.h:3507
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.