xref: /freebsd/contrib/llvm-project/clang/lib/CodeGen/ABIInfoImpl.cpp (revision e64bea71c21eb42e97aa615188ba91f6cce0d36d)
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, 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 
47 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 
70 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 
77 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 
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 
96 bool CodeGen::isAggregateTypeForABI(QualType T) {
97   return !CodeGenFunction::hasScalarEvaluationKind(T) ||
98          T->isMemberFunctionPointerType();
99 }
100 
101 llvm::Type *CodeGen::getVAListElementType(CodeGenFunction &CGF) {
102   return CGF.ConvertTypeForMem(
103       CGF.getContext().getBuiltinVaListType()->getPointeeType());
104 }
105 
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 
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 
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 
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 
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
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 
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 
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 
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 
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 
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 
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 
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 
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 
458 bool CodeGen::isSIMDVectorType(ASTContext &Context, QualType Ty) {
459   return Ty->getAs<VectorType>() && Context.getTypeSize(Ty) == 128;
460 }
461 
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