clang  19.0.0git
ARC.cpp
Go to the documentation of this file.
1 //===- ARC.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 #include "TargetInfo.h"
11 
12 using namespace clang;
13 using namespace clang::CodeGen;
14 
15 // ARC ABI implementation.
16 namespace {
17 
18 class ARCABIInfo : public DefaultABIInfo {
19  struct CCState {
20  unsigned FreeRegs;
21  };
22 
23 public:
25 
26 private:
27  Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
28  QualType Ty) const override;
29 
30  void updateState(const ABIArgInfo &Info, QualType Ty, CCState &State) const {
31  if (!State.FreeRegs)
32  return;
33  if (Info.isIndirect() && Info.getInReg())
34  State.FreeRegs--;
35  else if (Info.isDirect() && Info.getInReg()) {
36  unsigned sz = (getContext().getTypeSize(Ty) + 31) / 32;
37  if (sz < State.FreeRegs)
38  State.FreeRegs -= sz;
39  else
40  State.FreeRegs = 0;
41  }
42  }
43 
44  void computeInfo(CGFunctionInfo &FI) const override {
45  CCState State;
46  // ARC uses 8 registers to pass arguments.
47  State.FreeRegs = 8;
48 
49  if (!getCXXABI().classifyReturnType(FI))
51  updateState(FI.getReturnInfo(), FI.getReturnType(), State);
52  for (auto &I : FI.arguments()) {
53  I.info = classifyArgumentType(I.type, State.FreeRegs);
54  updateState(I.info, I.type, State);
55  }
56  }
57 
58  ABIArgInfo getIndirectByRef(QualType Ty, bool HasFreeRegs) const;
59  ABIArgInfo getIndirectByValue(QualType Ty) const;
60  ABIArgInfo classifyArgumentType(QualType Ty, uint8_t FreeRegs) const;
62 };
63 
64 class ARCTargetCodeGenInfo : public TargetCodeGenInfo {
65 public:
66  ARCTargetCodeGenInfo(CodeGenTypes &CGT)
67  : TargetCodeGenInfo(std::make_unique<ARCABIInfo>(CGT)) {}
68 };
69 
70 
71 ABIArgInfo ARCABIInfo::getIndirectByRef(QualType Ty, bool HasFreeRegs) const {
72  return HasFreeRegs ? getNaturalAlignIndirectInReg(Ty) :
73  getNaturalAlignIndirect(Ty, false);
74 }
75 
76 ABIArgInfo ARCABIInfo::getIndirectByValue(QualType Ty) const {
77  // Compute the byval alignment.
78  const unsigned MinABIStackAlignInBytes = 4;
79  unsigned TypeAlign = getContext().getTypeAlign(Ty) / 8;
80  return ABIArgInfo::getIndirect(CharUnits::fromQuantity(4), /*ByVal=*/true,
81  TypeAlign > MinABIStackAlignInBytes);
82 }
83 
84 Address ARCABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
85  QualType Ty) const {
86  return emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*indirect*/ false,
87  getContext().getTypeInfoInChars(Ty),
88  CharUnits::fromQuantity(4), true);
89 }
90 
92  uint8_t FreeRegs) const {
93  // Handle the generic C++ ABI.
94  const RecordType *RT = Ty->getAs<RecordType>();
95  if (RT) {
96  CGCXXABI::RecordArgABI RAA = getRecordArgABI(RT, getCXXABI());
97  if (RAA == CGCXXABI::RAA_Indirect)
98  return getIndirectByRef(Ty, FreeRegs > 0);
99 
100  if (RAA == CGCXXABI::RAA_DirectInMemory)
101  return getIndirectByValue(Ty);
102  }
103 
104  // Treat an enum type as its underlying type.
105  if (const EnumType *EnumTy = Ty->getAs<EnumType>())
106  Ty = EnumTy->getDecl()->getIntegerType();
107 
108  auto SizeInRegs = llvm::alignTo(getContext().getTypeSize(Ty), 32) / 32;
109 
110  if (isAggregateTypeForABI(Ty)) {
111  // Structures with flexible arrays are always indirect.
112  if (RT && RT->getDecl()->hasFlexibleArrayMember())
113  return getIndirectByValue(Ty);
114 
115  // Ignore empty structs/unions.
116  if (isEmptyRecord(getContext(), Ty, true))
117  return ABIArgInfo::getIgnore();
118 
119  llvm::LLVMContext &LLVMContext = getVMContext();
120 
121  llvm::IntegerType *Int32 = llvm::Type::getInt32Ty(LLVMContext);
122  SmallVector<llvm::Type *, 3> Elements(SizeInRegs, Int32);
123  llvm::Type *Result = llvm::StructType::get(LLVMContext, Elements);
124 
125  return FreeRegs >= SizeInRegs ?
127  ABIArgInfo::getDirect(Result, 0, nullptr, false);
128  }
129 
130  if (const auto *EIT = Ty->getAs<BitIntType>())
131  if (EIT->getNumBits() > 64)
132  return getIndirectByValue(Ty);
133 
134  return isPromotableIntegerTypeForABI(Ty)
135  ? (FreeRegs >= SizeInRegs ? ABIArgInfo::getExtendInReg(Ty)
136  : ABIArgInfo::getExtend(Ty))
137  : (FreeRegs >= SizeInRegs ? ABIArgInfo::getDirectInReg()
138  : ABIArgInfo::getDirect());
139 }
140 
142  if (RetTy->isAnyComplexType())
144 
145  // Arguments of size > 4 registers are indirect.
146  auto RetSize = llvm::alignTo(getContext().getTypeSize(RetTy), 32) / 32;
147  if (RetSize > 4)
148  return getIndirectByRef(RetTy, /*HasFreeRegs*/ true);
149 
151 }
152 
153 } // End anonymous namespace.
154 
155 std::unique_ptr<TargetCodeGenInfo>
157  return std::make_unique<ARCTargetCodeGenInfo>(CGM.getTypes());
158 }
LineState State
A fixed int type of a specified bitwidth.
Definition: Type.h:7254
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
Definition: CharUnits.h:63
ABIArgInfo - Helper class to encapsulate information about how a specific C type should be passed to ...
static ABIArgInfo getIgnore()
static ABIArgInfo getExtendInReg(QualType Ty, llvm::Type *T=nullptr)
static ABIArgInfo getIndirect(CharUnits Alignment, bool ByVal=true, bool Realign=false, llvm::Type *Padding=nullptr)
static ABIArgInfo getDirectInReg(llvm::Type *T=nullptr)
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
Definition: Address.h:111
RecordArgABI
Specify how one should pass an argument of a record type.
Definition: CGCXXABI.h:150
@ RAA_Indirect
Pass it as a pointer to temporary memory.
Definition: CGCXXABI.h:161
@ RAA_DirectInMemory
Pass it on the stack using its defined layout.
Definition: CGCXXABI.h:158
CGFunctionInfo - Class to encapsulate the information about a function definition.
CanQualType getReturnType() const
MutableArrayRef< ArgInfo > arguments()
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
This class organizes the cross-function state that is used while generating LLVM code.
This class organizes the cross-module state that is used while lowering AST types to LLVM types.
Definition: CodeGenTypes.h:54
DefaultABIInfo - The default implementation for ABI specific details.
Definition: ABIInfoImpl.h:21
DefaultABIInfo(CodeGen::CodeGenTypes &CGT)
Definition: ABIInfoImpl.h:23
ABIArgInfo classifyReturnType(QualType RetTy) const
Definition: ABIInfoImpl.cpp:45
TargetCodeGenInfo - This class organizes various target-specific codegeneration issues,...
Definition: TargetInfo.h:46
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
Definition: Type.h:5587
A (possibly-)qualified type.
Definition: Type.h:940
bool hasFlexibleArrayMember() const
Definition: Decl.h:4204
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:5561
RecordDecl * getDecl() const
Definition: Type.h:5571
bool isAnyComplexType() const
Definition: Type.h:7726
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:8160
ABIArgInfo classifyReturnType(CodeGenModule &CGM, CanQualType type)
Classify the rules for how to return a particular type.
ABIArgInfo classifyArgumentType(CodeGenModule &CGM, CanQualType type)
Classify the rules for how to pass a particular type.
CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI)
bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, const ABIInfo &Info)
Address emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType ValueTy, bool IsIndirect, TypeInfoChars ValueInfo, CharUnits SlotSizeAndAlign, bool AllowHigherAlign, bool ForceRightAdjust=false)
Emit va_arg for a platform using the common void* representation, where arguments are simply emitted ...
bool isAggregateTypeForABI(QualType T)
std::unique_ptr< TargetCodeGenInfo > createARCTargetCodeGenInfo(CodeGenModule &CGM)
Definition: ARC.cpp:156
bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays, bool AsIfNoUniqueAddr=false)
isEmptyRecord - Return true iff a structure contains only empty fields.
The JSON file list parser is used to communicate input to InstallAPI.
Definition: Format.h:5433
#define false
Definition: stdbool.h:26