1 //===- ABIInfoImpl.cpp ----------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "ABIInfoImpl.h"
11 using namespace clang
;
12 using namespace clang::CodeGen
;
14 // Pin the vtable to this file.
15 DefaultABIInfo::~DefaultABIInfo() = default;
17 ABIArgInfo
DefaultABIInfo::classifyArgumentType(QualType Ty
) const {
18 Ty
= useFirstFieldIfTransparentUnion(Ty
);
20 if (isAggregateTypeForABI(Ty
)) {
21 // Records with non-trivial destructors/copy-constructors should not be
23 if (CGCXXABI::RecordArgABI RAA
= getRecordArgABI(Ty
, getCXXABI()))
24 return getNaturalAlignIndirect(Ty
, RAA
== CGCXXABI::RAA_DirectInMemory
);
26 return getNaturalAlignIndirect(Ty
);
29 // Treat an enum type as its underlying type.
30 if (const EnumType
*EnumTy
= Ty
->getAs
<EnumType
>())
31 Ty
= EnumTy
->getDecl()->getIntegerType();
33 ASTContext
&Context
= getContext();
34 if (const auto *EIT
= Ty
->getAs
<BitIntType
>())
35 if (EIT
->getNumBits() >
36 Context
.getTypeSize(Context
.getTargetInfo().hasInt128Type()
38 : Context
.LongLongTy
))
39 return getNaturalAlignIndirect(Ty
);
41 return (isPromotableIntegerTypeForABI(Ty
)
42 ? ABIArgInfo::getExtend(Ty
, CGT
.ConvertType(Ty
))
43 : ABIArgInfo::getDirect());
46 ABIArgInfo
DefaultABIInfo::classifyReturnType(QualType RetTy
) const {
47 if (RetTy
->isVoidType())
48 return ABIArgInfo::getIgnore();
50 if (isAggregateTypeForABI(RetTy
))
51 return getNaturalAlignIndirect(RetTy
);
53 // Treat an enum type as its underlying type.
54 if (const EnumType
*EnumTy
= RetTy
->getAs
<EnumType
>())
55 RetTy
= EnumTy
->getDecl()->getIntegerType();
57 if (const auto *EIT
= RetTy
->getAs
<BitIntType
>())
58 if (EIT
->getNumBits() >
59 getContext().getTypeSize(getContext().getTargetInfo().hasInt128Type()
60 ? getContext().Int128Ty
61 : getContext().LongLongTy
))
62 return getNaturalAlignIndirect(RetTy
);
64 return (isPromotableIntegerTypeForABI(RetTy
) ? ABIArgInfo::getExtend(RetTy
)
65 : ABIArgInfo::getDirect());
68 void DefaultABIInfo::computeInfo(CGFunctionInfo
&FI
) const {
69 if (!getCXXABI().classifyReturnType(FI
))
70 FI
.getReturnInfo() = classifyReturnType(FI
.getReturnType());
71 for (auto &I
: FI
.arguments())
72 I
.info
= classifyArgumentType(I
.type
);
75 RValue
DefaultABIInfo::EmitVAArg(CodeGenFunction
&CGF
, Address VAListAddr
,
76 QualType Ty
, AggValueSlot Slot
) const {
77 return CGF
.EmitLoadOfAnyValue(
79 EmitVAArgInstr(CGF
, VAListAddr
, Ty
, classifyArgumentType(Ty
)), Ty
),
83 void CodeGen::AssignToArrayRange(CodeGen::CGBuilderTy
&Builder
,
84 llvm::Value
*Array
, llvm::Value
*Value
,
85 unsigned FirstIndex
, unsigned LastIndex
) {
86 // Alternatively, we could emit this as a loop in the source.
87 for (unsigned I
= FirstIndex
; I
<= LastIndex
; ++I
) {
89 Builder
.CreateConstInBoundsGEP1_32(Builder
.getInt8Ty(), Array
, I
);
90 Builder
.CreateAlignedStore(Value
, Cell
, CharUnits::One());
94 bool CodeGen::isAggregateTypeForABI(QualType T
) {
95 return !CodeGenFunction::hasScalarEvaluationKind(T
) ||
96 T
->isMemberFunctionPointerType();
99 llvm::Type
*CodeGen::getVAListElementType(CodeGenFunction
&CGF
) {
100 return CGF
.ConvertTypeForMem(
101 CGF
.getContext().getBuiltinVaListType()->getPointeeType());
104 CGCXXABI::RecordArgABI
CodeGen::getRecordArgABI(const RecordType
*RT
,
106 const CXXRecordDecl
*RD
= dyn_cast
<CXXRecordDecl
>(RT
->getDecl());
108 if (!RT
->getDecl()->canPassInRegisters())
109 return CGCXXABI::RAA_Indirect
;
110 return CGCXXABI::RAA_Default
;
112 return CXXABI
.getRecordArgABI(RD
);
115 CGCXXABI::RecordArgABI
CodeGen::getRecordArgABI(QualType T
, CGCXXABI
&CXXABI
) {
116 const RecordType
*RT
= T
->getAs
<RecordType
>();
118 return CGCXXABI::RAA_Default
;
119 return getRecordArgABI(RT
, CXXABI
);
122 bool CodeGen::classifyReturnType(const CGCXXABI
&CXXABI
, CGFunctionInfo
&FI
,
123 const ABIInfo
&Info
) {
124 QualType Ty
= FI
.getReturnType();
126 if (const auto *RT
= Ty
->getAs
<RecordType
>())
127 if (!isa
<CXXRecordDecl
>(RT
->getDecl()) &&
128 !RT
->getDecl()->canPassInRegisters()) {
129 FI
.getReturnInfo() = Info
.getNaturalAlignIndirect(Ty
);
133 return CXXABI
.classifyReturnType(FI
);
136 QualType
CodeGen::useFirstFieldIfTransparentUnion(QualType Ty
) {
137 if (const RecordType
*UT
= Ty
->getAsUnionType()) {
138 const RecordDecl
*UD
= UT
->getDecl();
139 if (UD
->hasAttr
<TransparentUnionAttr
>()) {
140 assert(!UD
->field_empty() && "sema created an empty transparent union");
141 return UD
->field_begin()->getType();
147 llvm::Value
*CodeGen::emitRoundPointerUpToAlignment(CodeGenFunction
&CGF
,
150 // OverflowArgArea = (OverflowArgArea + Align - 1) & -Align;
151 llvm::Value
*RoundUp
= CGF
.Builder
.CreateConstInBoundsGEP1_32(
152 CGF
.Builder
.getInt8Ty(), Ptr
, Align
.getQuantity() - 1);
153 return CGF
.Builder
.CreateIntrinsic(
154 llvm::Intrinsic::ptrmask
, {Ptr
->getType(), CGF
.IntPtrTy
},
155 {RoundUp
, llvm::ConstantInt::get(CGF
.IntPtrTy
, -Align
.getQuantity())},
156 nullptr, Ptr
->getName() + ".aligned");
160 CodeGen::emitVoidPtrDirectVAArg(CodeGenFunction
&CGF
, Address VAListAddr
,
161 llvm::Type
*DirectTy
, CharUnits DirectSize
,
162 CharUnits DirectAlign
, CharUnits SlotSize
,
163 bool AllowHigherAlign
, bool ForceRightAdjust
) {
164 // Cast the element type to i8* if necessary. Some platforms define
165 // va_list as a struct containing an i8* instead of just an i8*.
166 if (VAListAddr
.getElementType() != CGF
.Int8PtrTy
)
167 VAListAddr
= VAListAddr
.withElementType(CGF
.Int8PtrTy
);
169 llvm::Value
*Ptr
= CGF
.Builder
.CreateLoad(VAListAddr
, "argp.cur");
171 // If the CC aligns values higher than the slot size, do so if needed.
172 Address Addr
= Address::invalid();
173 if (AllowHigherAlign
&& DirectAlign
> SlotSize
) {
174 Addr
= Address(emitRoundPointerUpToAlignment(CGF
, Ptr
, DirectAlign
),
175 CGF
.Int8Ty
, DirectAlign
);
177 Addr
= Address(Ptr
, CGF
.Int8Ty
, SlotSize
);
180 // Advance the pointer past the argument, then store that back.
181 CharUnits FullDirectSize
= DirectSize
.alignTo(SlotSize
);
183 CGF
.Builder
.CreateConstInBoundsByteGEP(Addr
, FullDirectSize
, "argp.next");
184 CGF
.Builder
.CreateStore(NextPtr
.emitRawPointer(CGF
), VAListAddr
);
186 // If the argument is smaller than a slot, and this is a big-endian
187 // target, the argument will be right-adjusted in its slot.
188 if (DirectSize
< SlotSize
&& CGF
.CGM
.getDataLayout().isBigEndian() &&
189 (!DirectTy
->isStructTy() || ForceRightAdjust
)) {
190 Addr
= CGF
.Builder
.CreateConstInBoundsByteGEP(Addr
, SlotSize
- DirectSize
);
193 return Addr
.withElementType(DirectTy
);
196 RValue
CodeGen::emitVoidPtrVAArg(CodeGenFunction
&CGF
, Address VAListAddr
,
197 QualType ValueTy
, bool IsIndirect
,
198 TypeInfoChars ValueInfo
,
199 CharUnits SlotSizeAndAlign
,
200 bool AllowHigherAlign
, AggValueSlot Slot
,
201 bool ForceRightAdjust
) {
202 // The size and alignment of the value that was passed directly.
203 CharUnits DirectSize
, DirectAlign
;
205 DirectSize
= CGF
.getPointerSize();
206 DirectAlign
= CGF
.getPointerAlign();
208 DirectSize
= ValueInfo
.Width
;
209 DirectAlign
= ValueInfo
.Align
;
212 // Cast the address we've calculated to the right type.
213 llvm::Type
*DirectTy
= CGF
.ConvertTypeForMem(ValueTy
), *ElementTy
= DirectTy
;
215 unsigned AllocaAS
= CGF
.CGM
.getDataLayout().getAllocaAddrSpace();
216 DirectTy
= llvm::PointerType::get(CGF
.getLLVMContext(), AllocaAS
);
219 Address Addr
= emitVoidPtrDirectVAArg(CGF
, VAListAddr
, DirectTy
, DirectSize
,
220 DirectAlign
, SlotSizeAndAlign
,
221 AllowHigherAlign
, ForceRightAdjust
);
224 Addr
= Address(CGF
.Builder
.CreateLoad(Addr
), ElementTy
, ValueInfo
.Align
);
227 return CGF
.EmitLoadOfAnyValue(CGF
.MakeAddrLValue(Addr
, ValueTy
), Slot
);
230 Address
CodeGen::emitMergePHI(CodeGenFunction
&CGF
, Address Addr1
,
231 llvm::BasicBlock
*Block1
, Address Addr2
,
232 llvm::BasicBlock
*Block2
,
233 const llvm::Twine
&Name
) {
234 assert(Addr1
.getType() == Addr2
.getType());
235 llvm::PHINode
*PHI
= CGF
.Builder
.CreatePHI(Addr1
.getType(), 2, Name
);
236 PHI
->addIncoming(Addr1
.emitRawPointer(CGF
), Block1
);
237 PHI
->addIncoming(Addr2
.emitRawPointer(CGF
), Block2
);
238 CharUnits Align
= std::min(Addr1
.getAlignment(), Addr2
.getAlignment());
239 return Address(PHI
, Addr1
.getElementType(), Align
);
242 bool CodeGen::isEmptyField(ASTContext
&Context
, const FieldDecl
*FD
,
243 bool AllowArrays
, bool AsIfNoUniqueAddr
) {
244 if (FD
->isUnnamedBitField())
247 QualType FT
= FD
->getType();
249 // Constant arrays of empty records count as empty, strip them off.
250 // Constant arrays of zero length always count as empty.
251 bool WasArray
= false;
253 while (const ConstantArrayType
*AT
= Context
.getAsConstantArrayType(FT
)) {
254 if (AT
->isZeroSize())
256 FT
= AT
->getElementType();
257 // The [[no_unique_address]] special case below does not apply to
258 // arrays of C++ empty records, so we need to remember this fact.
262 const RecordType
*RT
= FT
->getAs
<RecordType
>();
266 // C++ record fields are never empty, at least in the Itanium ABI.
268 // FIXME: We should use a predicate for whether this behavior is true in the
271 // The exception to the above rule are fields marked with the
272 // [[no_unique_address]] attribute (since C++20). Those do count as empty
273 // according to the Itanium ABI. The exception applies only to records,
274 // not arrays of records, so we must also check whether we stripped off an
276 if (isa
<CXXRecordDecl
>(RT
->getDecl()) &&
277 (WasArray
|| (!AsIfNoUniqueAddr
&& !FD
->hasAttr
<NoUniqueAddressAttr
>())))
280 return isEmptyRecord(Context
, FT
, AllowArrays
, AsIfNoUniqueAddr
);
283 bool CodeGen::isEmptyRecord(ASTContext
&Context
, QualType T
, bool AllowArrays
,
284 bool AsIfNoUniqueAddr
) {
285 const RecordType
*RT
= T
->getAs
<RecordType
>();
288 const RecordDecl
*RD
= RT
->getDecl();
289 if (RD
->hasFlexibleArrayMember())
292 // If this is a C++ record, check the bases first.
293 if (const CXXRecordDecl
*CXXRD
= dyn_cast
<CXXRecordDecl
>(RD
))
294 for (const auto &I
: CXXRD
->bases())
295 if (!isEmptyRecord(Context
, I
.getType(), true, AsIfNoUniqueAddr
))
298 for (const auto *I
: RD
->fields())
299 if (!isEmptyField(Context
, I
, AllowArrays
, AsIfNoUniqueAddr
))
304 bool CodeGen::isEmptyFieldForLayout(const ASTContext
&Context
,
305 const FieldDecl
*FD
) {
306 if (FD
->isZeroLengthBitField(Context
))
309 if (FD
->isUnnamedBitField())
312 return isEmptyRecordForLayout(Context
, FD
->getType());
315 bool CodeGen::isEmptyRecordForLayout(const ASTContext
&Context
, QualType T
) {
316 const RecordType
*RT
= T
->getAs
<RecordType
>();
320 const RecordDecl
*RD
= RT
->getDecl();
322 // If this is a C++ record, check the bases first.
323 if (const CXXRecordDecl
*CXXRD
= dyn_cast
<CXXRecordDecl
>(RD
)) {
324 if (CXXRD
->isDynamicClass())
327 for (const auto &I
: CXXRD
->bases())
328 if (!isEmptyRecordForLayout(Context
, I
.getType()))
332 for (const auto *I
: RD
->fields())
333 if (!isEmptyFieldForLayout(Context
, I
))
339 const Type
*CodeGen::isSingleElementStruct(QualType T
, ASTContext
&Context
) {
340 const RecordType
*RT
= T
->getAs
<RecordType
>();
344 const RecordDecl
*RD
= RT
->getDecl();
345 if (RD
->hasFlexibleArrayMember())
348 const Type
*Found
= nullptr;
350 // If this is a C++ record, check the bases first.
351 if (const CXXRecordDecl
*CXXRD
= dyn_cast
<CXXRecordDecl
>(RD
)) {
352 for (const auto &I
: CXXRD
->bases()) {
353 // Ignore empty records.
354 if (isEmptyRecord(Context
, I
.getType(), true))
357 // If we already found an element then this isn't a single-element struct.
361 // If this is non-empty and not a single element struct, the composite
362 // cannot be a single element struct.
363 Found
= isSingleElementStruct(I
.getType(), Context
);
369 // Check for single element.
370 for (const auto *FD
: RD
->fields()) {
371 QualType FT
= FD
->getType();
373 // Ignore empty fields.
374 if (isEmptyField(Context
, FD
, true))
377 // If we already found an element then this isn't a single-element
382 // Treat single element arrays as the element.
383 while (const ConstantArrayType
*AT
= Context
.getAsConstantArrayType(FT
)) {
384 if (AT
->getZExtSize() != 1)
386 FT
= AT
->getElementType();
389 if (!isAggregateTypeForABI(FT
)) {
390 Found
= FT
.getTypePtr();
392 Found
= isSingleElementStruct(FT
, Context
);
398 // We don't consider a struct a single-element struct if it has
399 // padding beyond the element type.
400 if (Found
&& Context
.getTypeSize(Found
) != Context
.getTypeSize(T
))
406 Address
CodeGen::EmitVAArgInstr(CodeGenFunction
&CGF
, Address VAListAddr
,
407 QualType Ty
, const ABIArgInfo
&AI
) {
408 // This default implementation defers to the llvm backend's va_arg
409 // instruction. It can handle only passing arguments directly
410 // (typically only handled in the backend for primitive types), or
411 // aggregates passed indirectly by pointer (NOTE: if the "byval"
412 // flag has ABI impact in the callee, this implementation cannot
415 // Only a few cases are covered here at the moment -- those needed
416 // by the default abi.
419 if (AI
.isIndirect()) {
420 assert(!AI
.getPaddingType() &&
421 "Unexpected PaddingType seen in arginfo in generic VAArg emitter!");
423 !AI
.getIndirectRealign() &&
424 "Unexpected IndirectRealign seen in arginfo in generic VAArg emitter!");
426 auto TyInfo
= CGF
.getContext().getTypeInfoInChars(Ty
);
427 CharUnits TyAlignForABI
= TyInfo
.Align
;
429 llvm::Type
*ElementTy
= CGF
.ConvertTypeForMem(Ty
);
430 llvm::Type
*BaseTy
= llvm::PointerType::getUnqual(ElementTy
);
432 CGF
.Builder
.CreateVAArg(VAListAddr
.emitRawPointer(CGF
), BaseTy
);
433 return Address(Addr
, ElementTy
, TyAlignForABI
);
435 assert((AI
.isDirect() || AI
.isExtend()) &&
436 "Unexpected ArgInfo Kind in generic VAArg emitter!");
438 assert(!AI
.getInReg() &&
439 "Unexpected InReg seen in arginfo in generic VAArg emitter!");
440 assert(!AI
.getPaddingType() &&
441 "Unexpected PaddingType seen in arginfo in generic VAArg emitter!");
442 assert(!AI
.getDirectOffset() &&
443 "Unexpected DirectOffset seen in arginfo in generic VAArg emitter!");
444 assert(!AI
.getCoerceToType() &&
445 "Unexpected CoerceToType seen in arginfo in generic VAArg emitter!");
447 Address Temp
= CGF
.CreateMemTemp(Ty
, "varet");
448 Val
= CGF
.Builder
.CreateVAArg(VAListAddr
.emitRawPointer(CGF
),
449 CGF
.ConvertTypeForMem(Ty
));
450 CGF
.Builder
.CreateStore(Val
, Temp
);
455 bool CodeGen::isSIMDVectorType(ASTContext
&Context
, QualType Ty
) {
456 return Ty
->getAs
<VectorType
>() && Context
.getTypeSize(Ty
) == 128;
459 bool CodeGen::isRecordWithSIMDVectorType(ASTContext
&Context
, QualType Ty
) {
460 const RecordType
*RT
= Ty
->getAs
<RecordType
>();
463 const RecordDecl
*RD
= RT
->getDecl();
465 // If this is a C++ record, check the bases first.
466 if (const CXXRecordDecl
*CXXRD
= dyn_cast
<CXXRecordDecl
>(RD
))
467 for (const auto &I
: CXXRD
->bases())
468 if (!isRecordWithSIMDVectorType(Context
, I
.getType()))
471 for (const auto *i
: RD
->fields()) {
472 QualType FT
= i
->getType();
474 if (isSIMDVectorType(Context
, FT
))
477 if (isRecordWithSIMDVectorType(Context
, FT
))