LLVM 24.0.0git
TargetInfo.cpp
Go to the documentation of this file.
1//===- TargetInfo.cpp - Target ABI information ----------------------------===//
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
11#include <algorithm>
12#include <cstdint>
13
14using namespace llvm::abi;
15using llvm::dyn_cast;
16
18 // Atomic values use the evaluation kind of their underlying value type.
19 if (const auto *AT = dyn_cast<AtomicType>(Ty))
20 return isAggregateTypeForABI(AT->getValueType());
21
22 // Check for fundamental scalar types.
23 if (Ty->isInteger() || Ty->isFloat() || Ty->isPointer() || Ty->isVector() ||
24 Ty->isTuple())
25 return false;
26
27 // A matrix type is modeled as an array but lowers to a single flattened
28 // vector and has scalar evaluation kind in classic CodeGen, so it is not an
29 // aggregate for ABI purposes.
30 if (const auto *AT = dyn_cast<ArrayType>(Ty))
31 if (AT->isMatrixType())
32 return false;
33
34 // Everything else is treated as aggregate.
35 return true;
36}
37
39 // TODO: The threshold should be the target's int size rather than a
40 // hardcoded 32.
41 unsigned BitWidth = IT->getSizeInBits().getFixedValue();
42 return BitWidth < 32;
43}
44
45ArgInfo TargetInfo::getNaturalAlignIndirect(const Type *Ty, unsigned AddrSpace,
46 bool ByVal) const {
47 return ArgInfo::getIndirect(Ty->getAlignment(), ByVal, AddrSpace);
48}
49
51 if (RT && !RT->canPassInRegisters())
52 return RAA_Indirect;
53 return RAA_Default;
54}
55
57 // TODO: When Microsoft ABI is supported, CXX records may need different
58 // handling here (see MicrosoftCXXABI::getRecordArgABI in Clang).
59 const RecordType *RT = dyn_cast<RecordType>(Ty);
60 if (!RT)
61 return RAA_Default;
62 return getRecordArgABI(RT);
63}
64
66 if (const auto *RT = dyn_cast<RecordType>(Ty)) {
67 if (RT->isUnion() && RT->isTransparentUnion()) {
68 auto Fields = RT->getFields();
69 assert(!Fields.empty() && "transparent union cannot be empty");
70 return Fields.front().FieldType;
71 }
72 }
73 return Ty;
74}
75
77 const auto *RT = dyn_cast<RecordType>(Ty);
78 if (!RT)
79 return nullptr;
80
81 if (RT->hasFlexibleArrayMember())
82 return nullptr;
83
84 const Type *Found = nullptr;
85
86 for (const auto &Base : RT->getBaseClasses()) {
87 const Type *BaseTy = Base.FieldType;
88 const auto *BaseRT = dyn_cast<RecordType>(BaseTy);
89
90 if (!BaseRT || BaseRT->isEmpty())
91 continue;
92
93 const Type *Elem = isSingleElementStruct(BaseTy);
94 if (!Elem || Found)
95 return nullptr;
96 Found = Elem;
97 }
98
99 for (const auto &FI : RT->getFields()) {
100 if (FI.isEmpty())
101 continue;
102
103 const Type *FTy = FI.FieldType;
104
105 // Treat single element arrays as the element.
106 while (const auto *AT = dyn_cast<ArrayType>(FTy)) {
107 if (AT->getNumElements() != 1)
108 break;
109 FTy = AT->getElementType();
110 }
111
112 const Type *Elem;
113 if (!isAggregateTypeForABI(FTy))
114 Elem = FTy;
115 else
116 Elem = isSingleElementStruct(FTy);
117 if (!Elem || Found)
118 return nullptr;
119 Found = Elem;
120 }
121
122 if (!Found)
123 return nullptr;
124
125 // We don't consider a struct a single-element struct if it has padding
126 // beyond the element type.
127 if (Found->getSizeInBits() != Ty->getSizeInBits())
128 return nullptr;
129
130 return Found;
131}
132
134 const abi::Type *Ty = FI.getReturnType();
135
136 // TODO: When Microsoft ABI is supported, CXX records may need different
137 // handling here (see MicrosoftCXXABI::classifyReturnType in Clang).
138 if (const auto *RT = llvm::dyn_cast<abi::RecordType>(Ty)) {
139 if (!RT->canPassInRegisters()) {
140 // A record that cannot pass in registers (e.g. a non-trivial copy/dtor)
141 // is returned indirectly with ByVal=false. This is the RAA path and is
142 // distinct from getIndirectReturnResult (plain aggregates), which uses
143 // ByVal=true.
144 FI.getReturnInfo() =
145 ArgInfo::getIndirect(RT->getAlignment(), /*ByVal=*/false);
146 return true;
147 }
148 }
149
150 return false;
151}
152
154 uint64_t &Members) const {
155 bool isMatrixHA = getABICompatInfo().IsMatrixHA;
156 if (const auto *AT = dyn_cast<ArrayType>(Ty)) {
157 if (!isMatrixHA && AT->isMatrixType())
158 return false;
159 uint64_t NElements = AT->getNumElements();
160 if (NElements == 0)
161 return false;
162 if (!isHomogeneousAggregate(AT->getElementType(), Base, Members))
163 return false;
164 Members *= NElements;
165 } else if (const auto *RT = dyn_cast<RecordType>(Ty)) {
166 if (RT->hasFlexibleArrayMember())
167 return false;
168
169 Members = 0;
170
171 // If this is a C++ record, check bases and ABI-specific restrictions.
172 if (RT->isCXXRecord()) {
174 return false;
175
176 for (const FieldInfo &BaseField : RT->getBaseClasses()) {
177 if (BaseField.FieldType->isEmptyRecord())
178 continue;
179
180 uint64_t FldMembers = 0;
181 if (!isHomogeneousAggregate(BaseField.FieldType, Base, FldMembers))
182 return false;
183
184 Members += FldMembers;
185 }
186 }
187
188 for (const FieldInfo &FD : RT->getFields()) {
189 // Ignore (non-zero arrays of) empty records.
190 const Type *FT = FD.FieldType;
191 while (const auto *AT = dyn_cast<ArrayType>(FT)) {
192 // Don't drill down to the element type of a matrix type here.
193 // That should fall through to the element isHomogeneousAggregate check.
194 if (AT->isMatrixType())
195 break;
196 if (AT->getNumElements() == 0)
197 return false;
198 FT = AT->getElementType();
199 }
200 if (FT->isEmptyRecord())
201 continue;
202
204 FD.IsBitField && FD.BitFieldWidth == 0)
205 continue;
206
207 uint64_t FldMembers = 0;
208 if (!isHomogeneousAggregate(FD.FieldType, Base, FldMembers))
209 return false;
210
211 Members =
212 RT->isUnion() ? std::max(Members, FldMembers) : Members + FldMembers;
213 }
214
215 if (!Base)
216 return false;
217
218 // Ensure there is no padding.
219 if (Base->getTypeAllocSize() * Members != Ty->getTypeAllocSize())
220 return false;
221 } else {
222 Members = 1;
223 const Type *ElemTy = Ty;
224 if (const auto *CT = dyn_cast<ComplexType>(Ty)) {
225 Members = 2;
226 ElemTy = CT->getElementType();
227 }
228
229 // Most ABIs only support float, double, and some vector type widths.
231 return false;
232
233 // The base type must be the same for all members. Types that agree in both
234 // total size and mode (float vs. vector) are treated as equivalent here.
235 if (!Base) {
236 Base = ElemTy;
237 // If it's a non-power-of-2 vector, its ABI size is already a power-of-2,
238 // so widen it explicitly to match Clang.
239 if (const auto *VT = dyn_cast<VectorType>(Base)) {
240 assert(VT->isFixedLength() &&
241 "scalable vectors are never homogeneous aggregates");
242 uint64_t EltSize =
243 VT->getElementType()->getSizeInBits().getFixedValue();
244 unsigned NumElements =
245 VT->getTypeAllocSize().getFixedValue() * 8 / EltSize;
246 if (NumElements != VT->getNumElements().getKnownMinValue())
247 Base = TB.getVectorType(VT->getElementType(),
248 ElementCount::getFixed(NumElements),
249 VT->getAlignment());
250 }
251 }
252
253 if (Base->isVector() != ElemTy->isVector() ||
254 Base->getTypeAllocSize() != ElemTy->getTypeAllocSize())
255 return false;
256 }
257 return Members > 0 && isHomogeneousAggregateSmallEnough(Base, Members);
258}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static cl::opt< ITMode > IT(cl::desc("IT block support"), cl::Hidden, cl::init(DefaultIT), cl::values(clEnumValN(DefaultIT, "arm-default-it", "Generate any type of IT block"), clEnumValN(RestrictedIT, "arm-restrict-it", "Disallow complex IT blocks")))
Target-specific ABI information and factory functions.
static constexpr ElementCount getFixed(ScalarTy MinVal)
Definition TypeSize.h:305
Helper class to encapsulate information about how a specific type should be passed to or returned fro...
static ArgInfo getIndirect(Align Align, bool ByVal, unsigned AddrSpace=0, bool Realign=false)
Realign: the caller couldn't guarantee sufficient alignment - the callee must copy the argument to a ...
const Type * getReturnType() const
bool canPassInRegisters() const
Definition Types.h:431
LLVM_ABI const Type * isSingleElementStruct(const Type *Ty) const
Returns the scalar a single-element struct reduces to, else null.
virtual bool isPermittedToBeHomogeneousAggregate(const RecordType *RT) const
Return true if the C++ ABI permits RT to be a homogeneous aggregate.
Definition TargetInfo.h:135
virtual const ABICompatInfo & getABICompatInfo() const =0
Return this target's ABI compatibility flags.
virtual bool isHomogeneousAggregateSmallEnough(const Type *Base, uint64_t Members) const
Return true if a homogeneous aggregate with Members copies of Base is small enough to be passed in re...
Definition TargetInfo.h:123
LLVM_ABI bool isHomogeneousAggregate(const Type *Ty, const Type *&Base, uint64_t &Members) const
Return true if Ty is an ELFv2-style homogeneous aggregate.
LLVM_ABI bool isPromotableInteger(const IntegerType *IT) const
virtual bool isZeroLengthBitfieldPermittedInHomogeneousAggregate() const
Return true if zero-length bitfields should be ignored when deciding whether an aggregate is homogene...
Definition TargetInfo.h:130
virtual bool isHomogeneousAggregateBaseType(const Type *Ty) const
Return true if Ty is a valid base type for a homogeneous aggregate.
Definition TargetInfo.h:117
LLVM_ABI bool maybeCommonClassifyReturnType(FunctionInfo &FI) const
Apply rules for classifying return types that are common to all targets.
LLVM_ABI bool isAggregateTypeForABI(const Type *Ty) const
TypeBuilder & TB
Definition TargetInfo.h:67
LLVM_ABI const Type * useFirstFieldIfTransparentUnion(const Type *Ty) const
If Ty is a transparent union, return its first field type; otherwise return Ty unchanged.
LLVM_ABI ArgInfo getNaturalAlignIndirect(const Type *Ty, unsigned AddrSpace, bool ByVal=true) const
LLVM_ABI RecordArgABI getRecordArgABI(const RecordType *RT) const
Represents the ABI-specific view of a type in LLVM.
Definition Types.h:48
LLVM_ABI bool isEmptyRecord() const
True if this type is a record that is empty for ABI purposes.
Definition Types.cpp:28
TypeSize getSizeInBits() const
Definition Types.h:76
@ RAA_Indirect
Pass it as a pointer to temporary memory.
Definition TargetInfo.h:37
@ RAA_Default
Pass it using the normal C aggregate rules for the ABI, potentially introducing extra copies and pass...
Definition TargetInfo.h:29
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
constexpr unsigned BitWidth
bool IsMatrixHA
Whether a matrix type may be the base type of a homogeneous aggregate.
Definition TargetInfo.h:45