clang  19.0.0git
Lanai.cpp
Go to the documentation of this file.
1 //===- Lanai.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 //===----------------------------------------------------------------------===//
16 // Lanai ABI Implementation
17 //===----------------------------------------------------------------------===//
18 
19 namespace {
20 class LanaiABIInfo : public DefaultABIInfo {
21  struct CCState {
22  unsigned FreeRegs;
23  };
24 
25 public:
26  LanaiABIInfo(CodeGen::CodeGenTypes &CGT) : DefaultABIInfo(CGT) {}
27 
28  bool shouldUseInReg(QualType Ty, CCState &State) const;
29 
30  void computeInfo(CGFunctionInfo &FI) const override {
31  CCState State;
32  // Lanai uses 4 registers to pass arguments unless the function has the
33  // regparm attribute set.
34  if (FI.getHasRegParm()) {
35  State.FreeRegs = FI.getRegParm();
36  } else {
37  State.FreeRegs = 4;
38  }
39 
40  if (!getCXXABI().classifyReturnType(FI))
42  for (auto &I : FI.arguments())
43  I.info = classifyArgumentType(I.type, State);
44  }
45 
46  ABIArgInfo getIndirectResult(QualType Ty, bool ByVal, CCState &State) const;
47  ABIArgInfo classifyArgumentType(QualType RetTy, CCState &State) const;
48 };
49 } // end anonymous namespace
50 
51 bool LanaiABIInfo::shouldUseInReg(QualType Ty, CCState &State) const {
52  unsigned Size = getContext().getTypeSize(Ty);
53  unsigned SizeInRegs = llvm::alignTo(Size, 32U) / 32U;
54 
55  if (SizeInRegs == 0)
56  return false;
57 
58  if (SizeInRegs > State.FreeRegs) {
59  State.FreeRegs = 0;
60  return false;
61  }
62 
63  State.FreeRegs -= SizeInRegs;
64 
65  return true;
66 }
67 
68 ABIArgInfo LanaiABIInfo::getIndirectResult(QualType Ty, bool ByVal,
69  CCState &State) const {
70  if (!ByVal) {
71  if (State.FreeRegs) {
72  --State.FreeRegs; // Non-byval indirects just use one pointer.
73  return getNaturalAlignIndirectInReg(Ty);
74  }
75  return getNaturalAlignIndirect(Ty, false);
76  }
77 
78  // Compute the byval alignment.
79  const unsigned MinABIStackAlignInBytes = 4;
80  unsigned TypeAlign = getContext().getTypeAlign(Ty) / 8;
81  return ABIArgInfo::getIndirect(CharUnits::fromQuantity(4), /*ByVal=*/true,
82  /*Realign=*/TypeAlign >
83  MinABIStackAlignInBytes);
84 }
85 
87  CCState &State) const {
88  // Check with the C++ ABI first.
89  const RecordType *RT = Ty->getAs<RecordType>();
90  if (RT) {
91  CGCXXABI::RecordArgABI RAA = getRecordArgABI(RT, getCXXABI());
92  if (RAA == CGCXXABI::RAA_Indirect) {
93  return getIndirectResult(Ty, /*ByVal=*/false, State);
94  } else if (RAA == CGCXXABI::RAA_DirectInMemory) {
95  return getNaturalAlignIndirect(Ty, /*ByVal=*/true);
96  }
97  }
98 
99  if (isAggregateTypeForABI(Ty)) {
100  // Structures with flexible arrays are always indirect.
101  if (RT && RT->getDecl()->hasFlexibleArrayMember())
102  return getIndirectResult(Ty, /*ByVal=*/true, State);
103 
104  // Ignore empty structs/unions.
105  if (isEmptyRecord(getContext(), Ty, true))
106  return ABIArgInfo::getIgnore();
107 
108  llvm::LLVMContext &LLVMContext = getVMContext();
109  unsigned SizeInRegs = (getContext().getTypeSize(Ty) + 31) / 32;
110  if (SizeInRegs <= State.FreeRegs) {
111  llvm::IntegerType *Int32 = llvm::Type::getInt32Ty(LLVMContext);
112  SmallVector<llvm::Type *, 3> Elements(SizeInRegs, Int32);
113  llvm::Type *Result = llvm::StructType::get(LLVMContext, Elements);
114  State.FreeRegs -= SizeInRegs;
115  return ABIArgInfo::getDirectInReg(Result);
116  } else {
117  State.FreeRegs = 0;
118  }
119  return getIndirectResult(Ty, true, State);
120  }
121 
122  // Treat an enum type as its underlying type.
123  if (const auto *EnumTy = Ty->getAs<EnumType>())
124  Ty = EnumTy->getDecl()->getIntegerType();
125 
126  bool InReg = shouldUseInReg(Ty, State);
127 
128  // Don't pass >64 bit integers in registers.
129  if (const auto *EIT = Ty->getAs<BitIntType>())
130  if (EIT->getNumBits() > 64)
131  return getIndirectResult(Ty, /*ByVal=*/true, State);
132 
133  if (isPromotableIntegerTypeForABI(Ty)) {
134  if (InReg)
136  return ABIArgInfo::getExtend(Ty);
137  }
138  if (InReg)
140  return ABIArgInfo::getDirect();
141 }
142 
143 namespace {
144 class LanaiTargetCodeGenInfo : public TargetCodeGenInfo {
145 public:
146  LanaiTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT)
147  : TargetCodeGenInfo(std::make_unique<LanaiABIInfo>(CGT)) {}
148 };
149 }
150 
151 std::unique_ptr<TargetCodeGenInfo>
153  return std::make_unique<LanaiTargetCodeGenInfo>(CGM.getTypes());
154 }
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 getIndirect(CharUnits Alignment, bool ByVal=true, bool Realign=false, llvm::Type *Padding=nullptr)
static ABIArgInfo getDirect(llvm::Type *T=nullptr, unsigned Offset=0, llvm::Type *Padding=nullptr, bool CanBeFlattened=true, unsigned Align=0)
static ABIArgInfo getExtend(QualType Ty, llvm::Type *T=nullptr)
static ABIArgInfo getDirectInReg(llvm::Type *T=nullptr)
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()
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
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
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:8160
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)
bool isAggregateTypeForABI(QualType T)
bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays, bool AsIfNoUniqueAddr=false)
isEmptyRecord - Return true iff a structure contains only empty fields.
std::unique_ptr< TargetCodeGenInfo > createLanaiTargetCodeGenInfo(CodeGenModule &CGM)
Definition: Lanai.cpp:152
The JSON file list parser is used to communicate input to InstallAPI.
Definition: Format.h:5433