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