[clang][modules] Don't prevent translation of FW_Private includes when explicitly...
[llvm-project.git] / clang / lib / CodeGen / Targets / Lanai.cpp
blob2578fc0291e76030c9268c1d604ba4563f023ebd
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 //===----------------------------------------------------------------------===//
9 #include "ABIInfoImpl.h"
10 #include "TargetInfo.h"
12 using namespace clang;
13 using namespace clang::CodeGen;
15 //===----------------------------------------------------------------------===//
16 // Lanai ABI Implementation
17 //===----------------------------------------------------------------------===//
19 namespace {
20 class LanaiABIInfo : public DefaultABIInfo {
21 struct CCState {
22 unsigned FreeRegs;
25 public:
26 LanaiABIInfo(CodeGen::CodeGenTypes &CGT) : DefaultABIInfo(CGT) {}
28 bool shouldUseInReg(QualType Ty, CCState &State) const;
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;
40 if (!getCXXABI().classifyReturnType(FI))
41 FI.getReturnInfo() = classifyReturnType(FI.getReturnType());
42 for (auto &I : FI.arguments())
43 I.info = classifyArgumentType(I.type, State);
46 ABIArgInfo getIndirectResult(QualType Ty, bool ByVal, CCState &State) const;
47 ABIArgInfo classifyArgumentType(QualType RetTy, CCState &State) const;
49 } // end anonymous namespace
51 bool LanaiABIInfo::shouldUseInReg(QualType Ty, CCState &State) const {
52 unsigned Size = getContext().getTypeSize(Ty);
53 unsigned SizeInRegs = llvm::alignTo(Size, 32U) / 32U;
55 if (SizeInRegs == 0)
56 return false;
58 if (SizeInRegs > State.FreeRegs) {
59 State.FreeRegs = 0;
60 return false;
63 State.FreeRegs -= SizeInRegs;
65 return true;
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);
75 return getNaturalAlignIndirect(Ty, false);
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);
86 ABIArgInfo LanaiABIInfo::classifyArgumentType(QualType Ty,
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);
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);
104 // Ignore empty structs/unions.
105 if (isEmptyRecord(getContext(), Ty, true))
106 return ABIArgInfo::getIgnore();
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;
119 return getIndirectResult(Ty, true, State);
122 // Treat an enum type as its underlying type.
123 if (const auto *EnumTy = Ty->getAs<EnumType>())
124 Ty = EnumTy->getDecl()->getIntegerType();
126 bool InReg = shouldUseInReg(Ty, State);
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);
133 if (isPromotableIntegerTypeForABI(Ty)) {
134 if (InReg)
135 return ABIArgInfo::getDirectInReg();
136 return ABIArgInfo::getExtend(Ty);
138 if (InReg)
139 return ABIArgInfo::getDirectInReg();
140 return ABIArgInfo::getDirect();
143 namespace {
144 class LanaiTargetCodeGenInfo : public TargetCodeGenInfo {
145 public:
146 LanaiTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT)
147 : TargetCodeGenInfo(std::make_unique<LanaiABIInfo>(CGT)) {}
151 std::unique_ptr<TargetCodeGenInfo>
152 CodeGen::createLanaiTargetCodeGenInfo(CodeGenModule &CGM) {
153 return std::make_unique<LanaiTargetCodeGenInfo>(CGM.getTypes());