1 //===- ABIInfoImpl.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 "ABIInfoImpl.h"
10
11 using namespace clang;
12 using namespace clang::CodeGen;
13
14 // Pin the vtable to this file.
15 DefaultABIInfo::~DefaultABIInfo() = default;
16
classifyArgumentType(QualType Ty) const17 ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty) const {
18 Ty = useFirstFieldIfTransparentUnion(Ty);
19
20 if (isAggregateTypeForABI(Ty)) {
21 // Records with non-trivial destructors/copy-constructors should not be
22 // passed by value.
23 if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))
24 return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory);
25
26 return getNaturalAlignIndirect(Ty);
27 }
28
29 // Treat an enum type as its underlying type.
30 if (const EnumType *EnumTy = Ty->getAs<EnumType>())
31 Ty = EnumTy->getDecl()->getIntegerType();
32
33 ASTContext &Context = getContext();
34 if (const auto *EIT = Ty->getAs<BitIntType>())
35 if (EIT->getNumBits() >
36 Context.getTypeSize(Context.getTargetInfo().hasInt128Type()
37 ? Context.Int128Ty
38 : Context.LongLongTy))
39 return getNaturalAlignIndirect(Ty);
40
41 return (isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty)
42 : ABIArgInfo::getDirect());
43 }
44
classifyReturnType(QualType RetTy) const45 ABIArgInfo DefaultABIInfo::classifyReturnType(QualType RetTy) const {
46 if (RetTy->isVoidType())
47 return ABIArgInfo::getIgnore();
48
49 if (isAggregateTypeForABI(RetTy))
50 return getNaturalAlignIndirect(RetTy);
51
52 // Treat an enum type as its underlying type.
53 if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
54 RetTy = EnumTy->getDecl()->getIntegerType();
55
56 if (const auto *EIT = RetTy->getAs<BitIntType>())
57 if (EIT->getNumBits() >
58 getContext().getTypeSize(getContext().getTargetInfo().hasInt128Type()
59 ? getContext().Int128Ty
60 : getContext().LongLongTy))
61 return getNaturalAlignIndirect(RetTy);
62
63 return (isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy)
64 : ABIArgInfo::getDirect());
65 }
66
computeInfo(CGFunctionInfo & FI) const67 void DefaultABIInfo::computeInfo(CGFunctionInfo &FI) const {
68 if (!getCXXABI().classifyReturnType(FI))
69 FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
70 for (auto &I : FI.arguments())
71 I.info = classifyArgumentType(I.type);
72 }
73
EmitVAArg(CodeGenFunction & CGF,Address VAListAddr,QualType Ty,AggValueSlot Slot) const74 RValue DefaultABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
75 QualType Ty, AggValueSlot Slot) const {
76 return CGF.EmitLoadOfAnyValue(
77 CGF.MakeAddrLValue(
78 EmitVAArgInstr(CGF, VAListAddr, Ty, classifyArgumentType(Ty)), Ty),
79 Slot);
80 }
81
coerceToIntArray(QualType Ty,ASTContext & Context,llvm::LLVMContext & LLVMContext)82 ABIArgInfo CodeGen::coerceToIntArray(QualType Ty, ASTContext &Context,
83 llvm::LLVMContext &LLVMContext) {
84 // Alignment and Size are measured in bits.
85 const uint64_t Size = Context.getTypeSize(Ty);
86 const uint64_t Alignment = Context.getTypeAlign(Ty);
87 llvm::Type *IntType = llvm::Type::getIntNTy(LLVMContext, Alignment);
88 const uint64_t NumElements = (Size + Alignment - 1) / Alignment;
89 return ABIArgInfo::getDirect(llvm::ArrayType::get(IntType, NumElements));
90 }
91
AssignToArrayRange(CodeGen::CGBuilderTy & Builder,llvm::Value * Array,llvm::Value * Value,unsigned FirstIndex,unsigned LastIndex)92 void CodeGen::AssignToArrayRange(CodeGen::CGBuilderTy &Builder,
93 llvm::Value *Array, llvm::Value *Value,
94 unsigned FirstIndex, unsigned LastIndex) {
95 // Alternatively, we could emit this as a loop in the source.
96 for (unsigned I = FirstIndex; I <= LastIndex; ++I) {
97 llvm::Value *Cell =
98 Builder.CreateConstInBoundsGEP1_32(Builder.getInt8Ty(), Array, I);
99 Builder.CreateAlignedStore(Value, Cell, CharUnits::One());
100 }
101 }
102
isAggregateTypeForABI(QualType T)103 bool CodeGen::isAggregateTypeForABI(QualType T) {
104 return !CodeGenFunction::hasScalarEvaluationKind(T) ||
105 T->isMemberFunctionPointerType();
106 }
107
getVAListElementType(CodeGenFunction & CGF)108 llvm::Type *CodeGen::getVAListElementType(CodeGenFunction &CGF) {
109 return CGF.ConvertTypeForMem(
110 CGF.getContext().getBuiltinVaListType()->getPointeeType());
111 }
112
getRecordArgABI(const RecordType * RT,CGCXXABI & CXXABI)113 CGCXXABI::RecordArgABI CodeGen::getRecordArgABI(const RecordType *RT,
114 CGCXXABI &CXXABI) {
115 const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
116 if (!RD) {
117 if (!RT->getDecl()->canPassInRegisters())
118 return CGCXXABI::RAA_Indirect;
119 return CGCXXABI::RAA_Default;
120 }
121 return CXXABI.getRecordArgABI(RD);
122 }
123
getRecordArgABI(QualType T,CGCXXABI & CXXABI)124 CGCXXABI::RecordArgABI CodeGen::getRecordArgABI(QualType T, CGCXXABI &CXXABI) {
125 const RecordType *RT = T->getAs<RecordType>();
126 if (!RT)
127 return CGCXXABI::RAA_Default;
128 return getRecordArgABI(RT, CXXABI);
129 }
130
classifyReturnType(const CGCXXABI & CXXABI,CGFunctionInfo & FI,const ABIInfo & Info)131 bool CodeGen::classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI,
132 const ABIInfo &Info) {
133 QualType Ty = FI.getReturnType();
134
135 if (const auto *RT = Ty->getAs<RecordType>())
136 if (!isa<CXXRecordDecl>(RT->getDecl()) &&
137 !RT->getDecl()->canPassInRegisters()) {
138 FI.getReturnInfo() = Info.getNaturalAlignIndirect(Ty);
139 return true;
140 }
141
142 return CXXABI.classifyReturnType(FI);
143 }
144
useFirstFieldIfTransparentUnion(QualType Ty)145 QualType CodeGen::useFirstFieldIfTransparentUnion(QualType Ty) {
146 if (const RecordType *UT = Ty->getAsUnionType()) {
147 const RecordDecl *UD = UT->getDecl();
148 if (UD->hasAttr<TransparentUnionAttr>()) {
149 assert(!UD->field_empty() && "sema created an empty transparent union");
150 return UD->field_begin()->getType();
151 }
152 }
153 return Ty;
154 }
155
emitRoundPointerUpToAlignment(CodeGenFunction & CGF,llvm::Value * Ptr,CharUnits Align)156 llvm::Value *CodeGen::emitRoundPointerUpToAlignment(CodeGenFunction &CGF,
157 llvm::Value *Ptr,
158 CharUnits Align) {
159 // OverflowArgArea = (OverflowArgArea + Align - 1) & -Align;
160 llvm::Value *RoundUp = CGF.Builder.CreateConstInBoundsGEP1_32(
161 CGF.Builder.getInt8Ty(), Ptr, Align.getQuantity() - 1);
162 return CGF.Builder.CreateIntrinsic(
163 llvm::Intrinsic::ptrmask, {Ptr->getType(), CGF.IntPtrTy},
164 {RoundUp, llvm::ConstantInt::get(CGF.IntPtrTy, -Align.getQuantity())},
165 nullptr, Ptr->getName() + ".aligned");
166 }
167
168 Address
emitVoidPtrDirectVAArg(CodeGenFunction & CGF,Address VAListAddr,llvm::Type * DirectTy,CharUnits DirectSize,CharUnits DirectAlign,CharUnits SlotSize,bool AllowHigherAlign,bool ForceRightAdjust)169 CodeGen::emitVoidPtrDirectVAArg(CodeGenFunction &CGF, Address VAListAddr,
170 llvm::Type *DirectTy, CharUnits DirectSize,
171 CharUnits DirectAlign, CharUnits SlotSize,
172 bool AllowHigherAlign, bool ForceRightAdjust) {
173 // Cast the element type to i8* if necessary. Some platforms define
174 // va_list as a struct containing an i8* instead of just an i8*.
175 if (VAListAddr.getElementType() != CGF.Int8PtrTy)
176 VAListAddr = VAListAddr.withElementType(CGF.Int8PtrTy);
177
178 llvm::Value *Ptr = CGF.Builder.CreateLoad(VAListAddr, "argp.cur");
179
180 // If the CC aligns values higher than the slot size, do so if needed.
181 Address Addr = Address::invalid();
182 if (AllowHigherAlign && DirectAlign > SlotSize) {
183 Addr = Address(emitRoundPointerUpToAlignment(CGF, Ptr, DirectAlign),
184 CGF.Int8Ty, DirectAlign);
185 } else {
186 Addr = Address(Ptr, CGF.Int8Ty, SlotSize);
187 }
188
189 // Advance the pointer past the argument, then store that back.
190 CharUnits FullDirectSize = DirectSize.alignTo(SlotSize);
191 Address NextPtr =
192 CGF.Builder.CreateConstInBoundsByteGEP(Addr, FullDirectSize, "argp.next");
193 CGF.Builder.CreateStore(NextPtr.emitRawPointer(CGF), VAListAddr);
194
195 // If the argument is smaller than a slot, and this is a big-endian
196 // target, the argument will be right-adjusted in its slot.
197 if (DirectSize < SlotSize && CGF.CGM.getDataLayout().isBigEndian() &&
198 (!DirectTy->isStructTy() || ForceRightAdjust)) {
199 Addr = CGF.Builder.CreateConstInBoundsByteGEP(Addr, SlotSize - DirectSize);
200 }
201
202 return Addr.withElementType(DirectTy);
203 }
204
emitVoidPtrVAArg(CodeGenFunction & CGF,Address VAListAddr,QualType ValueTy,bool IsIndirect,TypeInfoChars ValueInfo,CharUnits SlotSizeAndAlign,bool AllowHigherAlign,AggValueSlot Slot,bool ForceRightAdjust)205 RValue CodeGen::emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr,
206 QualType ValueTy, bool IsIndirect,
207 TypeInfoChars ValueInfo,
208 CharUnits SlotSizeAndAlign,
209 bool AllowHigherAlign, AggValueSlot Slot,
210 bool ForceRightAdjust) {
211 // The size and alignment of the value that was passed directly.
212 CharUnits DirectSize, DirectAlign;
213 if (IsIndirect) {
214 DirectSize = CGF.getPointerSize();
215 DirectAlign = CGF.getPointerAlign();
216 } else {
217 DirectSize = ValueInfo.Width;
218 DirectAlign = ValueInfo.Align;
219 }
220
221 // Cast the address we've calculated to the right type.
222 llvm::Type *DirectTy = CGF.ConvertTypeForMem(ValueTy), *ElementTy = DirectTy;
223 if (IsIndirect) {
224 unsigned AllocaAS = CGF.CGM.getDataLayout().getAllocaAddrSpace();
225 DirectTy = llvm::PointerType::get(CGF.getLLVMContext(), AllocaAS);
226 }
227
228 Address Addr = emitVoidPtrDirectVAArg(CGF, VAListAddr, DirectTy, DirectSize,
229 DirectAlign, SlotSizeAndAlign,
230 AllowHigherAlign, ForceRightAdjust);
231
232 if (IsIndirect) {
233 Addr = Address(CGF.Builder.CreateLoad(Addr), ElementTy, ValueInfo.Align);
234 }
235
236 return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(Addr, ValueTy), Slot);
237 }
238
emitMergePHI(CodeGenFunction & CGF,Address Addr1,llvm::BasicBlock * Block1,Address Addr2,llvm::BasicBlock * Block2,const llvm::Twine & Name)239 Address CodeGen::emitMergePHI(CodeGenFunction &CGF, Address Addr1,
240 llvm::BasicBlock *Block1, Address Addr2,
241 llvm::BasicBlock *Block2,
242 const llvm::Twine &Name) {
243 assert(Addr1.getType() == Addr2.getType());
244 llvm::PHINode *PHI = CGF.Builder.CreatePHI(Addr1.getType(), 2, Name);
245 PHI->addIncoming(Addr1.emitRawPointer(CGF), Block1);
246 PHI->addIncoming(Addr2.emitRawPointer(CGF), Block2);
247 CharUnits Align = std::min(Addr1.getAlignment(), Addr2.getAlignment());
248 return Address(PHI, Addr1.getElementType(), Align);
249 }
250
isEmptyField(ASTContext & Context,const FieldDecl * FD,bool AllowArrays,bool AsIfNoUniqueAddr)251 bool CodeGen::isEmptyField(ASTContext &Context, const FieldDecl *FD,
252 bool AllowArrays, bool AsIfNoUniqueAddr) {
253 if (FD->isUnnamedBitField())
254 return true;
255
256 QualType FT = FD->getType();
257
258 // Constant arrays of empty records count as empty, strip them off.
259 // Constant arrays of zero length always count as empty.
260 bool WasArray = false;
261 if (AllowArrays)
262 while (const ConstantArrayType *AT = Context.getAsConstantArrayType(FT)) {
263 if (AT->isZeroSize())
264 return true;
265 FT = AT->getElementType();
266 // The [[no_unique_address]] special case below does not apply to
267 // arrays of C++ empty records, so we need to remember this fact.
268 WasArray = true;
269 }
270
271 const RecordType *RT = FT->getAs<RecordType>();
272 if (!RT)
273 return false;
274
275 // C++ record fields are never empty, at least in the Itanium ABI.
276 //
277 // FIXME: We should use a predicate for whether this behavior is true in the
278 // current ABI.
279 //
280 // The exception to the above rule are fields marked with the
281 // [[no_unique_address]] attribute (since C++20). Those do count as empty
282 // according to the Itanium ABI. The exception applies only to records,
283 // not arrays of records, so we must also check whether we stripped off an
284 // array type above.
285 if (isa<CXXRecordDecl>(RT->getDecl()) &&
286 (WasArray || (!AsIfNoUniqueAddr && !FD->hasAttr<NoUniqueAddressAttr>())))
287 return false;
288
289 return isEmptyRecord(Context, FT, AllowArrays, AsIfNoUniqueAddr);
290 }
291
isEmptyRecord(ASTContext & Context,QualType T,bool AllowArrays,bool AsIfNoUniqueAddr)292 bool CodeGen::isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays,
293 bool AsIfNoUniqueAddr) {
294 const RecordType *RT = T->getAs<RecordType>();
295 if (!RT)
296 return false;
297 const RecordDecl *RD = RT->getDecl();
298 if (RD->hasFlexibleArrayMember())
299 return false;
300
301 // If this is a C++ record, check the bases first.
302 if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
303 for (const auto &I : CXXRD->bases())
304 if (!isEmptyRecord(Context, I.getType(), true, AsIfNoUniqueAddr))
305 return false;
306
307 for (const auto *I : RD->fields())
308 if (!isEmptyField(Context, I, AllowArrays, AsIfNoUniqueAddr))
309 return false;
310 return true;
311 }
312
isEmptyFieldForLayout(const ASTContext & Context,const FieldDecl * FD)313 bool CodeGen::isEmptyFieldForLayout(const ASTContext &Context,
314 const FieldDecl *FD) {
315 if (FD->isZeroLengthBitField(Context))
316 return true;
317
318 if (FD->isUnnamedBitField())
319 return false;
320
321 return isEmptyRecordForLayout(Context, FD->getType());
322 }
323
isEmptyRecordForLayout(const ASTContext & Context,QualType T)324 bool CodeGen::isEmptyRecordForLayout(const ASTContext &Context, QualType T) {
325 const RecordType *RT = T->getAs<RecordType>();
326 if (!RT)
327 return false;
328
329 const RecordDecl *RD = RT->getDecl();
330
331 // If this is a C++ record, check the bases first.
332 if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
333 if (CXXRD->isDynamicClass())
334 return false;
335
336 for (const auto &I : CXXRD->bases())
337 if (!isEmptyRecordForLayout(Context, I.getType()))
338 return false;
339 }
340
341 for (const auto *I : RD->fields())
342 if (!isEmptyFieldForLayout(Context, I))
343 return false;
344
345 return true;
346 }
347
isSingleElementStruct(QualType T,ASTContext & Context)348 const Type *CodeGen::isSingleElementStruct(QualType T, ASTContext &Context) {
349 const RecordType *RT = T->getAs<RecordType>();
350 if (!RT)
351 return nullptr;
352
353 const RecordDecl *RD = RT->getDecl();
354 if (RD->hasFlexibleArrayMember())
355 return nullptr;
356
357 const Type *Found = nullptr;
358
359 // If this is a C++ record, check the bases first.
360 if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
361 for (const auto &I : CXXRD->bases()) {
362 // Ignore empty records.
363 if (isEmptyRecord(Context, I.getType(), true))
364 continue;
365
366 // If we already found an element then this isn't a single-element struct.
367 if (Found)
368 return nullptr;
369
370 // If this is non-empty and not a single element struct, the composite
371 // cannot be a single element struct.
372 Found = isSingleElementStruct(I.getType(), Context);
373 if (!Found)
374 return nullptr;
375 }
376 }
377
378 // Check for single element.
379 for (const auto *FD : RD->fields()) {
380 QualType FT = FD->getType();
381
382 // Ignore empty fields.
383 if (isEmptyField(Context, FD, true))
384 continue;
385
386 // If we already found an element then this isn't a single-element
387 // struct.
388 if (Found)
389 return nullptr;
390
391 // Treat single element arrays as the element.
392 while (const ConstantArrayType *AT = Context.getAsConstantArrayType(FT)) {
393 if (AT->getZExtSize() != 1)
394 break;
395 FT = AT->getElementType();
396 }
397
398 if (!isAggregateTypeForABI(FT)) {
399 Found = FT.getTypePtr();
400 } else {
401 Found = isSingleElementStruct(FT, Context);
402 if (!Found)
403 return nullptr;
404 }
405 }
406
407 // We don't consider a struct a single-element struct if it has
408 // padding beyond the element type.
409 if (Found && Context.getTypeSize(Found) != Context.getTypeSize(T))
410 return nullptr;
411
412 return Found;
413 }
414
EmitVAArgInstr(CodeGenFunction & CGF,Address VAListAddr,QualType Ty,const ABIArgInfo & AI)415 Address CodeGen::EmitVAArgInstr(CodeGenFunction &CGF, Address VAListAddr,
416 QualType Ty, const ABIArgInfo &AI) {
417 // This default implementation defers to the llvm backend's va_arg
418 // instruction. It can handle only passing arguments directly
419 // (typically only handled in the backend for primitive types), or
420 // aggregates passed indirectly by pointer (NOTE: if the "byval"
421 // flag has ABI impact in the callee, this implementation cannot
422 // work.)
423
424 // Only a few cases are covered here at the moment -- those needed
425 // by the default abi.
426 llvm::Value *Val;
427
428 if (AI.isIndirect()) {
429 assert(!AI.getPaddingType() &&
430 "Unexpected PaddingType seen in arginfo in generic VAArg emitter!");
431 assert(
432 !AI.getIndirectRealign() &&
433 "Unexpected IndirectRealign seen in arginfo in generic VAArg emitter!");
434
435 auto TyInfo = CGF.getContext().getTypeInfoInChars(Ty);
436 CharUnits TyAlignForABI = TyInfo.Align;
437
438 llvm::Type *ElementTy = CGF.ConvertTypeForMem(Ty);
439 llvm::Type *BaseTy = llvm::PointerType::getUnqual(ElementTy);
440 llvm::Value *Addr =
441 CGF.Builder.CreateVAArg(VAListAddr.emitRawPointer(CGF), BaseTy);
442 return Address(Addr, ElementTy, TyAlignForABI);
443 } else {
444 assert((AI.isDirect() || AI.isExtend()) &&
445 "Unexpected ArgInfo Kind in generic VAArg emitter!");
446
447 assert(!AI.getInReg() &&
448 "Unexpected InReg seen in arginfo in generic VAArg emitter!");
449 assert(!AI.getPaddingType() &&
450 "Unexpected PaddingType seen in arginfo in generic VAArg emitter!");
451 assert(!AI.getDirectOffset() &&
452 "Unexpected DirectOffset seen in arginfo in generic VAArg emitter!");
453 assert(!AI.getCoerceToType() &&
454 "Unexpected CoerceToType seen in arginfo in generic VAArg emitter!");
455
456 Address Temp = CGF.CreateMemTemp(Ty, "varet");
457 Val = CGF.Builder.CreateVAArg(VAListAddr.emitRawPointer(CGF),
458 CGF.ConvertTypeForMem(Ty));
459 CGF.Builder.CreateStore(Val, Temp);
460 return Temp;
461 }
462 }
463
isSIMDVectorType(ASTContext & Context,QualType Ty)464 bool CodeGen::isSIMDVectorType(ASTContext &Context, QualType Ty) {
465 return Ty->getAs<VectorType>() && Context.getTypeSize(Ty) == 128;
466 }
467
isRecordWithSIMDVectorType(ASTContext & Context,QualType Ty)468 bool CodeGen::isRecordWithSIMDVectorType(ASTContext &Context, QualType Ty) {
469 const RecordType *RT = Ty->getAs<RecordType>();
470 if (!RT)
471 return false;
472 const RecordDecl *RD = RT->getDecl();
473
474 // If this is a C++ record, check the bases first.
475 if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
476 for (const auto &I : CXXRD->bases())
477 if (!isRecordWithSIMDVectorType(Context, I.getType()))
478 return false;
479
480 for (const auto *i : RD->fields()) {
481 QualType FT = i->getType();
482
483 if (isSIMDVectorType(Context, FT))
484 return true;
485
486 if (isRecordWithSIMDVectorType(Context, FT))
487 return true;
488 }
489
490 return false;
491 }
492