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