clang 22.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
12using namespace clang;
13using namespace clang::CodeGen;
14
15//===----------------------------------------------------------------------===//
16// Lanai ABI Implementation
17//===----------------------------------------------------------------------===//
18
19namespace {
20class LanaiABIInfo : public DefaultABIInfo {
21 struct CCState {
22 unsigned FreeRegs;
23 };
24
25public:
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
51bool 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
68ABIArgInfo 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, getDataLayout().getAllocaAddrSpace(),
76 false);
77 }
78
79 // Compute the byval alignment.
80 const unsigned MinABIStackAlignInBytes = 4;
81 unsigned TypeAlign = getContext().getTypeAlign(Ty) / 8;
84 /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(), /*ByVal=*/true,
85 /*Realign=*/TypeAlign > MinABIStackAlignInBytes);
86}
87
88ABIArgInfo LanaiABIInfo::classifyArgumentType(QualType Ty,
89 CCState &State) const {
90 // Check with the C++ ABI first.
91 const RecordType *RT = Ty->getAsCanonical<RecordType>();
92 if (RT) {
93 CGCXXABI::RecordArgABI RAA = getRecordArgABI(RT, getCXXABI());
94 if (RAA == CGCXXABI::RAA_Indirect) {
95 return getIndirectResult(Ty, /*ByVal=*/false, State);
96 } else if (RAA == CGCXXABI::RAA_DirectInMemory) {
97 return getNaturalAlignIndirect(
98 Ty, /*AddrSpace=*/getDataLayout().getAllocaAddrSpace(),
99 /*ByVal=*/true);
100 }
101 }
102
103 if (isAggregateTypeForABI(Ty)) {
104 // Structures with flexible arrays are always indirect.
105 if (RT &&
106 RT->getOriginalDecl()->getDefinitionOrSelf()->hasFlexibleArrayMember())
107 return getIndirectResult(Ty, /*ByVal=*/true, State);
108
109 // Ignore empty structs/unions.
110 if (isEmptyRecord(getContext(), Ty, true))
111 return ABIArgInfo::getIgnore();
112
113 llvm::LLVMContext &LLVMContext = getVMContext();
114 unsigned SizeInRegs = (getContext().getTypeSize(Ty) + 31) / 32;
115 if (SizeInRegs <= State.FreeRegs) {
116 llvm::IntegerType *Int32 = llvm::Type::getInt32Ty(LLVMContext);
117 SmallVector<llvm::Type *, 3> Elements(SizeInRegs, Int32);
118 llvm::Type *Result = llvm::StructType::get(LLVMContext, Elements);
119 State.FreeRegs -= SizeInRegs;
121 } else {
122 State.FreeRegs = 0;
123 }
124 return getIndirectResult(Ty, true, State);
125 }
126
127 // Treat an enum type as its underlying type.
128 if (const auto *ED = Ty->getAsEnumDecl())
129 Ty = ED->getIntegerType();
130
131 bool InReg = shouldUseInReg(Ty, State);
132
133 // Don't pass >64 bit integers in registers.
134 if (const auto *EIT = Ty->getAs<BitIntType>())
135 if (EIT->getNumBits() > 64)
136 return getIndirectResult(Ty, /*ByVal=*/true, State);
137
138 if (isPromotableIntegerTypeForABI(Ty)) {
139 if (InReg)
141 return ABIArgInfo::getExtend(Ty);
142 }
143 if (InReg)
145 return ABIArgInfo::getDirect();
146}
147
148namespace {
149class LanaiTargetCodeGenInfo : public TargetCodeGenInfo {
150public:
151 LanaiTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT)
152 : TargetCodeGenInfo(std::make_unique<LanaiABIInfo>(CGT)) {}
153};
154}
155
156std::unique_ptr<TargetCodeGenInfo>
158 return std::make_unique<LanaiTargetCodeGenInfo>(CGM.getTypes());
159}
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
Definition CharUnits.h:63
static ABIArgInfo getIgnore()
static ABIArgInfo getDirect(llvm::Type *T=nullptr, unsigned Offset=0, llvm::Type *Padding=nullptr, bool CanBeFlattened=true, unsigned Align=0)
static ABIArgInfo getIndirect(CharUnits Alignment, unsigned AddrSpace, bool ByVal=true, bool Realign=false, llvm::Type *Padding=nullptr)
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
CanQualType getReturnType() const
MutableArrayRef< ArgInfo > arguments()
This class organizes the cross-function state that is used while generating LLVM code.
DefaultABIInfo - The default implementation for ABI specific details.
Definition ABIInfoImpl.h:21
A (possibly-)qualified type.
Definition TypeBase.h:937
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
Definition Type.h:53
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
Definition TypeBase.h:2921
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9098
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:157
The JSON file list parser is used to communicate input to InstallAPI.
@ Result
The result type of a method or function.
Definition TypeBase.h:905