Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/clang/lib/CodeGen/ABIInfo.cpp
35233 views
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
20
ASTContext &ABIInfo::getContext() const { return CGT.getContext(); }
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
32
const CodeGenOptions &ABIInfo::getCodeGenOpts() const {
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
42
RValue ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr,
43
QualType Ty, AggValueSlot Slot) const {
44
return RValue::getIgnored();
45
}
46
47
bool ABIInfo::isHomogeneousAggregateBaseType(QualType Ty) const {
48
return false;
49
}
50
51
bool ABIInfo::isHomogeneousAggregateSmallEnough(const Type *Base,
52
uint64_t Members) const {
53
return false;
54
}
55
56
bool ABIInfo::isZeroLengthBitfieldPermittedInHomogeneousAggregate() const {
57
// For compatibility with GCC, ignore empty bitfields in C++ mode.
58
return getContext().getLangOpts().CPlusPlus;
59
}
60
61
bool ABIInfo::isHomogeneousAggregate(QualType Ty, const Type *&Base,
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
108
if (isZeroLengthBitfieldPermittedInHomogeneousAggregate() &&
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.
135
if (!isHomogeneousAggregateBaseType(Ty))
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
163
bool ABIInfo::isPromotableIntegerTypeForABI(QualType Ty) const {
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
174
ABIArgInfo ABIInfo::getNaturalAlignIndirect(QualType Ty, bool ByVal,
175
bool Realign,
176
llvm::Type *Padding) const {
177
return ABIArgInfo::getIndirect(getContext().getTypeAlignInChars(Ty), ByVal,
178
Realign, Padding);
179
}
180
181
ABIArgInfo ABIInfo::getNaturalAlignIndirectInReg(QualType Ty,
182
bool Realign) const {
183
return ABIArgInfo::getIndirectInReg(getContext().getTypeAlignInChars(Ty),
184
/*ByVal*/ false, Realign);
185
}
186
187
void ABIInfo::appendAttributeMangling(TargetAttr *Attr,
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.
255
bool SwiftABIInfo::occupiesMoreThan(ArrayRef<llvm::Type *> scalarTypes,
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
273
bool SwiftABIInfo::shouldPassIndirectly(ArrayRef<llvm::Type *> ComponentTys,
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
}
284
285