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 return false;
25
26 // A matrix type is modeled as an array but lowers to a single flattened
27 // vector and has scalar evaluation kind in classic CodeGen, so it is not an
28 // aggregate for ABI purposes.
29 if (const auto *AT = dyn_cast<ArrayType>(Ty))
30 if (AT->isMatrixType())
31 return false;
32
33 // Everything else is treated as aggregate.
34 return true;
35}
36
38 // TODO: The threshold should be the target's int size rather than a
39 // hardcoded 32.
40 unsigned BitWidth = IT->getSizeInBits().getFixedValue();
41 return BitWidth < 32;
42}
43
44ArgInfo TargetInfo::getNaturalAlignIndirect(const Type *Ty, unsigned AddrSpace,
45 bool ByVal) const {
46 return ArgInfo::getIndirect(Ty->getAlignment(), ByVal, AddrSpace);
47}
48
50 if (RT && !RT->canPassInRegisters())
51 return RAA_Indirect;
52 return RAA_Default;
53}
54
56 // TODO: When Microsoft ABI is supported, CXX records may need different
57 // handling here (see MicrosoftCXXABI::getRecordArgABI in Clang).
58 const RecordType *RT = dyn_cast<RecordType>(Ty);
59 if (!RT)
60 return RAA_Default;
61 return getRecordArgABI(RT);
62}
63
65 if (const auto *RT = dyn_cast<RecordType>(Ty)) {
66 if (RT->isUnion() && RT->isTransparentUnion()) {
67 auto Fields = RT->getFields();
68 assert(!Fields.empty() && "transparent union cannot be empty");
69 return Fields.front().FieldType;
70 }
71 }
72 return Ty;
73}
74
76 const auto *RT = dyn_cast<RecordType>(Ty);
77 if (!RT)
78 return nullptr;
79
80 if (RT->hasFlexibleArrayMember())
81 return nullptr;
82
83 const Type *Found = nullptr;
84
85 for (const auto &Base : RT->getBaseClasses()) {
86 const Type *BaseTy = Base.FieldType;
87 const auto *BaseRT = dyn_cast<RecordType>(BaseTy);
88
89 if (!BaseRT || BaseRT->isEmpty())
90 continue;
91
92 const Type *Elem = isSingleElementStruct(BaseTy);
93 if (!Elem || Found)
94 return nullptr;
95 Found = Elem;
96 }
97
98 for (const auto &FI : RT->getFields()) {
99 if (FI.isEmpty())
100 continue;
101
102 const Type *FTy = FI.FieldType;
103
104 // Treat single element arrays as the element.
105 while (const auto *AT = dyn_cast<ArrayType>(FTy)) {
106 if (AT->getNumElements() != 1)
107 break;
108 FTy = AT->getElementType();
109 }
110
111 const Type *Elem;
112 if (!isAggregateTypeForABI(FTy))
113 Elem = FTy;
114 else
115 Elem = isSingleElementStruct(FTy);
116 if (!Elem || Found)
117 return nullptr;
118 Found = Elem;
119 }
120
121 if (!Found)
122 return nullptr;
123
124 // We don't consider a struct a single-element struct if it has padding
125 // beyond the element type.
126 if (Found->getSizeInBits() != Ty->getSizeInBits())
127 return nullptr;
128
129 return Found;
130}
131
133 const abi::Type *Ty = FI.getReturnType();
134
135 // TODO: When Microsoft ABI is supported, CXX records may need different
136 // handling here (see MicrosoftCXXABI::classifyReturnType in Clang).
137 if (const auto *RT = llvm::dyn_cast<abi::RecordType>(Ty)) {
138 if (!RT->canPassInRegisters()) {
139 // A record that cannot pass in registers (e.g. a non-trivial copy/dtor)
140 // is returned indirectly with ByVal=false. This is the RAA path and is
141 // distinct from getIndirectReturnResult (plain aggregates), which uses
142 // ByVal=true.
143 FI.getReturnInfo() =
144 ArgInfo::getIndirect(RT->getAlignment(), /*ByVal=*/false);
145 return true;
146 }
147 }
148
149 return false;
150}
151
153 uint64_t &Members) const {
154 bool isMatrixHA = getABICompatInfo().IsMatrixHA;
155 if (const auto *AT = dyn_cast<ArrayType>(Ty)) {
156 if (!isMatrixHA && AT->isMatrixType())
157 return false;
158 uint64_t NElements = AT->getNumElements();
159 if (NElements == 0)
160 return false;
161 if (!isHomogeneousAggregate(AT->getElementType(), Base, Members))
162 return false;
163 Members *= NElements;
164 } else if (const auto *RT = dyn_cast<RecordType>(Ty)) {
165 if (RT->hasFlexibleArrayMember())
166 return false;
167
168 Members = 0;
169
170 // If this is a C++ record, check bases and ABI-specific restrictions.
171 if (RT->isCXXRecord()) {
173 return false;
174
175 for (const FieldInfo &BaseField : RT->getBaseClasses()) {
176 if (BaseField.FieldType->isEmptyRecord())
177 continue;
178
179 uint64_t FldMembers = 0;
180 if (!isHomogeneousAggregate(BaseField.FieldType, Base, FldMembers))
181 return false;
182
183 Members += FldMembers;
184 }
185 }
186
187 for (const FieldInfo &FD : RT->getFields()) {
188 // Ignore (non-zero arrays of) empty records.
189 const Type *FT = FD.FieldType;
190 while (const auto *AT = dyn_cast<ArrayType>(FT)) {
191 // Don't drill down to the element type of a matrix type here.
192 // That should fall through to the element isHomogeneousAggregate check.
193 if (AT->isMatrixType())
194 break;
195 if (AT->getNumElements() == 0)
196 return false;
197 FT = AT->getElementType();
198 }
199 if (FT->isEmptyRecord())
200 continue;
201
203 FD.IsBitField && FD.BitFieldWidth == 0)
204 continue;
205
206 uint64_t FldMembers = 0;
207 if (!isHomogeneousAggregate(FD.FieldType, Base, FldMembers))
208 return false;
209
210 Members =
211 RT->isUnion() ? std::max(Members, FldMembers) : Members + FldMembers;
212 }
213
214 if (!Base)
215 return false;
216
217 // Ensure there is no padding.
218 if (Base->getTypeAllocSize() * Members != Ty->getTypeAllocSize())
219 return false;
220 } else {
221 Members = 1;
222 const Type *ElemTy = Ty;
223 if (const auto *CT = dyn_cast<ComplexType>(Ty)) {
224 Members = 2;
225 ElemTy = CT->getElementType();
226 }
227
228 // Most ABIs only support float, double, and some vector type widths.
230 return false;
231
232 // The base type must be the same for all members. Types that agree in both
233 // total size and mode (float vs. vector) are treated as equivalent here.
234 if (!Base) {
235 Base = ElemTy;
236 // If it's a non-power-of-2 vector, its ABI size is already a power-of-2,
237 // so widen it explicitly to match Clang.
238 if (const auto *VT = dyn_cast<VectorType>(Base)) {
239 assert(VT->isFixedLength() &&
240 "scalable vectors are never homogeneous aggregates");
241 uint64_t EltSize =
242 VT->getElementType()->getSizeInBits().getFixedValue();
243 unsigned NumElements =
244 VT->getTypeAllocSize().getFixedValue() * 8 / EltSize;
245 if (NumElements != VT->getNumElements().getKnownMinValue())
246 Base = TB.getVectorType(VT->getElementType(),
247 ElementCount::getFixed(NumElements),
248 VT->getAlignment());
249 }
250 }
251
252 if (Base->isVector() != ElemTy->isVector() ||
253 Base->getTypeAllocSize() != ElemTy->getTypeAllocSize())
254 return false;
255 }
256 return Members > 0 && isHomogeneousAggregateSmallEnough(Base, Members);
257}
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:400
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:46
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:74
@ 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