xref: /llvm-project/clang/lib/CodeGen/ABIInfoImpl.cpp (revision cfe26358e3051755961fb1f3b46328dc2c326895)
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 
17 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)
42               ? ABIArgInfo::getExtend(Ty, CGT.ConvertType(Ty))
43               : ABIArgInfo::getDirect());
44 }
45 
46 ABIArgInfo DefaultABIInfo::classifyReturnType(QualType RetTy) const {
47   if (RetTy->isVoidType())
48     return ABIArgInfo::getIgnore();
49 
50   if (isAggregateTypeForABI(RetTy))
51     return getNaturalAlignIndirect(RetTy);
52 
53   // Treat an enum type as its underlying type.
54   if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
55     RetTy = EnumTy->getDecl()->getIntegerType();
56 
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);
63 
64   return (isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy)
65                                                : ABIArgInfo::getDirect());
66 }
67 
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);
73 }
74 
75 RValue DefaultABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
76                                  QualType Ty, AggValueSlot Slot) const {
77   return CGF.EmitLoadOfAnyValue(
78       CGF.MakeAddrLValue(
79           EmitVAArgInstr(CGF, VAListAddr, Ty, classifyArgumentType(Ty)), Ty),
80       Slot);
81 }
82 
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) {
88     llvm::Value *Cell =
89         Builder.CreateConstInBoundsGEP1_32(Builder.getInt8Ty(), Array, I);
90     Builder.CreateAlignedStore(Value, Cell, CharUnits::One());
91   }
92 }
93 
94 bool CodeGen::isAggregateTypeForABI(QualType T) {
95   return !CodeGenFunction::hasScalarEvaluationKind(T) ||
96          T->isMemberFunctionPointerType();
97 }
98 
99 llvm::Type *CodeGen::getVAListElementType(CodeGenFunction &CGF) {
100   return CGF.ConvertTypeForMem(
101       CGF.getContext().getBuiltinVaListType()->getPointeeType());
102 }
103 
104 CGCXXABI::RecordArgABI CodeGen::getRecordArgABI(const RecordType *RT,
105                                                 CGCXXABI &CXXABI) {
106   const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
107   if (!RD) {
108     if (!RT->getDecl()->canPassInRegisters())
109       return CGCXXABI::RAA_Indirect;
110     return CGCXXABI::RAA_Default;
111   }
112   return CXXABI.getRecordArgABI(RD);
113 }
114 
115 CGCXXABI::RecordArgABI CodeGen::getRecordArgABI(QualType T, CGCXXABI &CXXABI) {
116   const RecordType *RT = T->getAs<RecordType>();
117   if (!RT)
118     return CGCXXABI::RAA_Default;
119   return getRecordArgABI(RT, CXXABI);
120 }
121 
122 bool CodeGen::classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI,
123                                  const ABIInfo &Info) {
124   QualType Ty = FI.getReturnType();
125 
126   if (const auto *RT = Ty->getAs<RecordType>())
127     if (!isa<CXXRecordDecl>(RT->getDecl()) &&
128         !RT->getDecl()->canPassInRegisters()) {
129       FI.getReturnInfo() = Info.getNaturalAlignIndirect(Ty);
130       return true;
131     }
132 
133   return CXXABI.classifyReturnType(FI);
134 }
135 
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();
142     }
143   }
144   return Ty;
145 }
146 
147 llvm::Value *CodeGen::emitRoundPointerUpToAlignment(CodeGenFunction &CGF,
148                                                     llvm::Value *Ptr,
149                                                     CharUnits Align) {
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");
157 }
158 
159 Address
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);
168 
169   llvm::Value *Ptr = CGF.Builder.CreateLoad(VAListAddr, "argp.cur");
170 
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);
176   } else {
177     Addr = Address(Ptr, CGF.Int8Ty, SlotSize);
178   }
179 
180   // Advance the pointer past the argument, then store that back.
181   CharUnits FullDirectSize = DirectSize.alignTo(SlotSize);
182   Address NextPtr =
183       CGF.Builder.CreateConstInBoundsByteGEP(Addr, FullDirectSize, "argp.next");
184   CGF.Builder.CreateStore(NextPtr.emitRawPointer(CGF), VAListAddr);
185 
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);
191   }
192 
193   return Addr.withElementType(DirectTy);
194 }
195 
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;
204   if (IsIndirect) {
205     DirectSize = CGF.getPointerSize();
206     DirectAlign = CGF.getPointerAlign();
207   } else {
208     DirectSize = ValueInfo.Width;
209     DirectAlign = ValueInfo.Align;
210   }
211 
212   // Cast the address we've calculated to the right type.
213   llvm::Type *DirectTy = CGF.ConvertTypeForMem(ValueTy), *ElementTy = DirectTy;
214   if (IsIndirect) {
215     unsigned AllocaAS = CGF.CGM.getDataLayout().getAllocaAddrSpace();
216     DirectTy = llvm::PointerType::get(CGF.getLLVMContext(), AllocaAS);
217   }
218 
219   Address Addr = emitVoidPtrDirectVAArg(CGF, VAListAddr, DirectTy, DirectSize,
220                                         DirectAlign, SlotSizeAndAlign,
221                                         AllowHigherAlign, ForceRightAdjust);
222 
223   if (IsIndirect) {
224     Addr = Address(CGF.Builder.CreateLoad(Addr), ElementTy, ValueInfo.Align);
225   }
226 
227   return CGF.EmitLoadOfAnyValue(CGF.MakeAddrLValue(Addr, ValueTy), Slot);
228 }
229 
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);
240 }
241 
242 bool CodeGen::isEmptyField(ASTContext &Context, const FieldDecl *FD,
243                            bool AllowArrays, bool AsIfNoUniqueAddr) {
244   if (FD->isUnnamedBitField())
245     return true;
246 
247   QualType FT = FD->getType();
248 
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;
252   if (AllowArrays)
253     while (const ConstantArrayType *AT = Context.getAsConstantArrayType(FT)) {
254       if (AT->isZeroSize())
255         return true;
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.
259       WasArray = true;
260     }
261 
262   const RecordType *RT = FT->getAs<RecordType>();
263   if (!RT)
264     return false;
265 
266   // C++ record fields are never empty, at least in the Itanium ABI.
267   //
268   // FIXME: We should use a predicate for whether this behavior is true in the
269   // current ABI.
270   //
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
275   // array type above.
276   if (isa<CXXRecordDecl>(RT->getDecl()) &&
277       (WasArray || (!AsIfNoUniqueAddr && !FD->hasAttr<NoUniqueAddressAttr>())))
278     return false;
279 
280   return isEmptyRecord(Context, FT, AllowArrays, AsIfNoUniqueAddr);
281 }
282 
283 bool CodeGen::isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays,
284                             bool AsIfNoUniqueAddr) {
285   const RecordType *RT = T->getAs<RecordType>();
286   if (!RT)
287     return false;
288   const RecordDecl *RD = RT->getDecl();
289   if (RD->hasFlexibleArrayMember())
290     return false;
291 
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))
296         return false;
297 
298   for (const auto *I : RD->fields())
299     if (!isEmptyField(Context, I, AllowArrays, AsIfNoUniqueAddr))
300       return false;
301   return true;
302 }
303 
304 bool CodeGen::isEmptyFieldForLayout(const ASTContext &Context,
305                                     const FieldDecl *FD) {
306   if (FD->isZeroLengthBitField())
307     return true;
308 
309   if (FD->isUnnamedBitField())
310     return false;
311 
312   return isEmptyRecordForLayout(Context, FD->getType());
313 }
314 
315 bool CodeGen::isEmptyRecordForLayout(const ASTContext &Context, QualType T) {
316   const RecordType *RT = T->getAs<RecordType>();
317   if (!RT)
318     return false;
319 
320   const RecordDecl *RD = RT->getDecl();
321 
322   // If this is a C++ record, check the bases first.
323   if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
324     if (CXXRD->isDynamicClass())
325       return false;
326 
327     for (const auto &I : CXXRD->bases())
328       if (!isEmptyRecordForLayout(Context, I.getType()))
329         return false;
330   }
331 
332   for (const auto *I : RD->fields())
333     if (!isEmptyFieldForLayout(Context, I))
334       return false;
335 
336   return true;
337 }
338 
339 const Type *CodeGen::isSingleElementStruct(QualType T, ASTContext &Context) {
340   const RecordType *RT = T->getAs<RecordType>();
341   if (!RT)
342     return nullptr;
343 
344   const RecordDecl *RD = RT->getDecl();
345   if (RD->hasFlexibleArrayMember())
346     return nullptr;
347 
348   const Type *Found = nullptr;
349 
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))
355         continue;
356 
357       // If we already found an element then this isn't a single-element struct.
358       if (Found)
359         return nullptr;
360 
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);
364       if (!Found)
365         return nullptr;
366     }
367   }
368 
369   // Check for single element.
370   for (const auto *FD : RD->fields()) {
371     QualType FT = FD->getType();
372 
373     // Ignore empty fields.
374     if (isEmptyField(Context, FD, true))
375       continue;
376 
377     // If we already found an element then this isn't a single-element
378     // struct.
379     if (Found)
380       return nullptr;
381 
382     // Treat single element arrays as the element.
383     while (const ConstantArrayType *AT = Context.getAsConstantArrayType(FT)) {
384       if (AT->getZExtSize() != 1)
385         break;
386       FT = AT->getElementType();
387     }
388 
389     if (!isAggregateTypeForABI(FT)) {
390       Found = FT.getTypePtr();
391     } else {
392       Found = isSingleElementStruct(FT, Context);
393       if (!Found)
394         return nullptr;
395     }
396   }
397 
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))
401     return nullptr;
402 
403   return Found;
404 }
405 
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
413   // work.)
414 
415   // Only a few cases are covered here at the moment -- those needed
416   // by the default abi.
417   llvm::Value *Val;
418 
419   if (AI.isIndirect()) {
420     assert(!AI.getPaddingType() &&
421            "Unexpected PaddingType seen in arginfo in generic VAArg emitter!");
422     assert(
423         !AI.getIndirectRealign() &&
424         "Unexpected IndirectRealign seen in arginfo in generic VAArg emitter!");
425 
426     auto TyInfo = CGF.getContext().getTypeInfoInChars(Ty);
427     CharUnits TyAlignForABI = TyInfo.Align;
428 
429     llvm::Type *ElementTy = CGF.ConvertTypeForMem(Ty);
430     llvm::Type *BaseTy = llvm::PointerType::getUnqual(ElementTy);
431     llvm::Value *Addr =
432         CGF.Builder.CreateVAArg(VAListAddr.emitRawPointer(CGF), BaseTy);
433     return Address(Addr, ElementTy, TyAlignForABI);
434   } else {
435     assert((AI.isDirect() || AI.isExtend()) &&
436            "Unexpected ArgInfo Kind in generic VAArg emitter!");
437 
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!");
446 
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);
451     return Temp;
452   }
453 }
454 
455 bool CodeGen::isSIMDVectorType(ASTContext &Context, QualType Ty) {
456   return Ty->getAs<VectorType>() && Context.getTypeSize(Ty) == 128;
457 }
458 
459 bool CodeGen::isRecordWithSIMDVectorType(ASTContext &Context, QualType Ty) {
460   const RecordType *RT = Ty->getAs<RecordType>();
461   if (!RT)
462     return false;
463   const RecordDecl *RD = RT->getDecl();
464 
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()))
469         return false;
470 
471   for (const auto *i : RD->fields()) {
472     QualType FT = i->getType();
473 
474     if (isSIMDVectorType(Context, FT))
475       return true;
476 
477     if (isRecordWithSIMDVectorType(Context, FT))
478       return true;
479   }
480 
481   return false;
482 }
483