clang  20.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 
12 using namespace clang;
13 using namespace clang::CodeGen;
14 
15 // Pin the vtable to this file.
16 ABIInfo::~ABIInfo() = default;
17 
18 CGCXXABI &ABIInfo::getCXXABI() const { return CGT.getCXXABI(); }
19 
21 
22 llvm::LLVMContext &ABIInfo::getVMContext() const {
23  return CGT.getLLVMContext();
24 }
25 
26 const llvm::DataLayout &ABIInfo::getDataLayout() const {
27  return CGT.getDataLayout();
28 }
29 
30 const TargetInfo &ABIInfo::getTarget() const { return CGT.getTarget(); }
31 
33  return CGT.getCodeGenOpts();
34 }
35 
36 bool ABIInfo::isAndroid() const { return getTarget().getTriple().isAndroid(); }
37 
38 bool ABIInfo::isOHOSFamily() const {
39  return getTarget().getTriple().isOHOSFamily();
40 }
41 
43  QualType Ty, AggValueSlot Slot) const {
44  return RValue::getIgnored();
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->getZExtSize();
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->isZeroSize())
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 !=
125  getContext().getTypeSize(Ty))
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 =
149  getContext().getTypeSize(VT) / getContext().getTypeSize(EltTy);
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 
188  raw_ostream &Out) const {
189  if (Attr->isDefaultVersion())
190  return;
191  appendAttributeMangling(Attr->getFeaturesStr(), Out);
192 }
193 
194 void ABIInfo::appendAttributeMangling(TargetVersionAttr *Attr,
195  raw_ostream &Out) const {
196  appendAttributeMangling(Attr->getNamesStr(), Out);
197 }
198 
199 void ABIInfo::appendAttributeMangling(TargetClonesAttr *Attr, unsigned Index,
200  raw_ostream &Out) const {
201  appendAttributeMangling(Attr->getFeatureStr(Index), Out);
202  Out << '.' << Attr->getMangledIndex(Index);
203 }
204 
205 void ABIInfo::appendAttributeMangling(StringRef AttrStr,
206  raw_ostream &Out) const {
207  if (AttrStr == "default") {
208  Out << ".default";
209  return;
210  }
211 
212  Out << '.';
213  const TargetInfo &TI = CGT.getTarget();
214  ParsedTargetAttr Info = TI.parseTargetAttr(AttrStr);
215 
216  llvm::sort(Info.Features, [&TI](StringRef LHS, StringRef RHS) {
217  // Multiversioning doesn't allow "no-${feature}", so we can
218  // only have "+" prefixes here.
219  assert(LHS.starts_with("+") && RHS.starts_with("+") &&
220  "Features should always have a prefix.");
221  return TI.multiVersionSortPriority(LHS.substr(1)) >
222  TI.multiVersionSortPriority(RHS.substr(1));
223  });
224 
225  bool IsFirst = true;
226  if (!Info.CPU.empty()) {
227  IsFirst = false;
228  Out << "arch_" << Info.CPU;
229  }
230 
231  for (StringRef Feat : Info.Features) {
232  if (!IsFirst)
233  Out << '_';
234  IsFirst = false;
235  Out << Feat.substr(1);
236  }
237 }
238 
239 // Pin the vtable to this file.
240 SwiftABIInfo::~SwiftABIInfo() = default;
241 
242 /// Does the given lowering require more than the given number of
243 /// registers when expanded?
244 ///
245 /// This is intended to be the basis of a reasonable basic implementation
246 /// of should{Pass,Return}Indirectly.
247 ///
248 /// For most targets, a limit of four total registers is reasonable; this
249 /// limits the amount of code required in order to move around the value
250 /// in case it wasn't produced immediately prior to the call by the caller
251 /// (or wasn't produced in exactly the right registers) or isn't used
252 /// immediately within the callee. But some targets may need to further
253 /// limit the register count due to an inability to support that many
254 /// return registers.
256  unsigned maxAllRegisters) const {
257  unsigned intCount = 0, fpCount = 0;
258  for (llvm::Type *type : scalarTypes) {
259  if (type->isPointerTy()) {
260  intCount++;
261  } else if (auto intTy = dyn_cast<llvm::IntegerType>(type)) {
262  auto ptrWidth = CGT.getTarget().getPointerWidth(LangAS::Default);
263  intCount += (intTy->getBitWidth() + ptrWidth - 1) / ptrWidth;
264  } else {
265  assert(type->isVectorTy() || type->isFloatingPointTy());
266  fpCount++;
267  }
268  }
269 
270  return (intCount + fpCount > maxAllRegisters);
271 }
272 
274  bool AsReturnValue) const {
275  return occupiesMoreThan(ComponentTys, /*total=*/4);
276 }
277 
278 bool SwiftABIInfo::isLegalVectorType(CharUnits VectorSize, llvm::Type *EltTy,
279  unsigned NumElts) const {
280  // The default implementation of this assumes that the target guarantees
281  // 128-bit SIMD support but nothing more.
282  return (VectorSize.getQuantity() > 8 && VectorSize.getQuantity() <= 16);
283 }
__DEVICE__ int max(int __a, int __b)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:187
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:797
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
Definition: ASTContext.h:2399
Attr - This represents one attribute.
Definition: Attr.h:46
A fixed int type of a specified bitwidth.
Definition: Type.h:7643
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:49
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
virtual void appendAttributeMangling(TargetAttr *Attr, raw_ostream &Out) const
Definition: ABIInfo.cpp:187
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
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
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:504
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
const llvm::DataLayout & getDataLayout() const
Definition: CodeGenTypes.h:104
const TargetInfo & getTarget() const
Definition: CodeGenTypes.h:110
ASTContext & getContext() const
Definition: CodeGenTypes.h:108
CGCXXABI & getCXXABI() const
Definition: CodeGenTypes.h:111
llvm::LLVMContext & getLLVMContext()
Definition: CodeGenTypes.h:112
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:93
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:278
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:255
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:273
Complex values, per C99 6.2.5p11.
Definition: Type.h:3144
Represents the canonical version of C arrays with a specified constant size.
Definition: Type.h:3614
A (possibly-)qualified type.
Definition: Type.h:941
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
Definition: Type.h:7760
Represents a struct/union/class.
Definition: Decl.h:4146
bool hasFlexibleArrayMember() const
Definition: Decl.h:4179
field_range fields() const
Definition: Decl.h:4352
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:5975
bool isUnion() const
Definition: Decl.h:3768
Exposes information about the current target.
Definition: TargetInfo.h:218
uint64_t getPointerWidth(LangAS AddrSpace) const
Return the width of pointers on this target, for the specified address space.
Definition: TargetInfo.h:472
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
Definition: TargetInfo.h:1256
virtual ParsedTargetAttr parseTargetAttr(StringRef Str) const
Definition: TargetInfo.cpp:582
The base class of the type hierarchy.
Definition: Type.h:1829
bool isVectorType() const
Definition: Type.h:8125
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:8568
Represents a GCC generic vector type.
Definition: Type.h:4031
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.
The JSON file list parser is used to communicate input to InstallAPI.
unsigned long uint64_t
Contains information gathered from parsing the contents of TargetAttr.
Definition: TargetInfo.h:57
std::vector< std::string > Features
Definition: TargetInfo.h:58