clang 19.0.0git
Hexagon.cpp
Go to the documentation of this file.
1//===- Hexagon.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// Hexagon ABI Implementation
17//===----------------------------------------------------------------------===//
18
19namespace {
20
21class HexagonABIInfo : public DefaultABIInfo {
22public:
23 HexagonABIInfo(CodeGenTypes &CGT) : DefaultABIInfo(CGT) {}
24
25private:
28 ABIArgInfo classifyArgumentType(QualType RetTy, unsigned *RegsLeft) const;
29
30 void computeInfo(CGFunctionInfo &FI) const override;
31
33 QualType Ty) const override;
34 Address EmitVAArgFromMemory(CodeGenFunction &CFG, Address VAListAddr,
35 QualType Ty) const;
36 Address EmitVAArgForHexagon(CodeGenFunction &CFG, Address VAListAddr,
37 QualType Ty) const;
38 Address EmitVAArgForHexagonLinux(CodeGenFunction &CFG, Address VAListAddr,
39 QualType Ty) const;
40};
41
42class HexagonTargetCodeGenInfo : public TargetCodeGenInfo {
43public:
44 HexagonTargetCodeGenInfo(CodeGenTypes &CGT)
45 : TargetCodeGenInfo(std::make_unique<HexagonABIInfo>(CGT)) {}
46
47 int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const override {
48 return 29;
49 }
50
51 void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
52 CodeGen::CodeGenModule &GCM) const override {
53 if (GV->isDeclaration())
54 return;
55 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
56 if (!FD)
57 return;
58 }
59};
60
61} // namespace
62
63void HexagonABIInfo::computeInfo(CGFunctionInfo &FI) const {
64 unsigned RegsLeft = 6;
65 if (!getCXXABI().classifyReturnType(FI))
67 for (auto &I : FI.arguments())
68 I.info = classifyArgumentType(I.type, &RegsLeft);
69}
70
71static bool HexagonAdjustRegsLeft(uint64_t Size, unsigned *RegsLeft) {
72 assert(Size <= 64 && "Not expecting to pass arguments larger than 64 bits"
73 " through registers");
74
75 if (*RegsLeft == 0)
76 return false;
77
78 if (Size <= 32) {
79 (*RegsLeft)--;
80 return true;
81 }
82
83 if (2 <= (*RegsLeft & (~1U))) {
84 *RegsLeft = (*RegsLeft & (~1U)) - 2;
85 return true;
86 }
87
88 // Next available register was r5 but candidate was greater than 32-bits so it
89 // has to go on the stack. However we still consume r5
90 if (*RegsLeft == 1)
91 *RegsLeft = 0;
92
93 return false;
94}
95
96ABIArgInfo HexagonABIInfo::classifyArgumentType(QualType Ty,
97 unsigned *RegsLeft) const {
98 if (!isAggregateTypeForABI(Ty)) {
99 // Treat an enum type as its underlying type.
100 if (const EnumType *EnumTy = Ty->getAs<EnumType>())
101 Ty = EnumTy->getDecl()->getIntegerType();
102
103 uint64_t Size = getContext().getTypeSize(Ty);
104 if (Size <= 64)
105 HexagonAdjustRegsLeft(Size, RegsLeft);
106
107 if (Size > 64 && Ty->isBitIntType())
108 return getNaturalAlignIndirect(Ty, /*ByVal=*/true);
109
110 return isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty)
111 : ABIArgInfo::getDirect();
112 }
113
114 if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))
115 return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory);
116
117 // Ignore empty records.
118 if (isEmptyRecord(getContext(), Ty, true))
119 return ABIArgInfo::getIgnore();
120
121 uint64_t Size = getContext().getTypeSize(Ty);
122 unsigned Align = getContext().getTypeAlign(Ty);
123
124 if (Size > 64)
125 return getNaturalAlignIndirect(Ty, /*ByVal=*/true);
126
127 if (HexagonAdjustRegsLeft(Size, RegsLeft))
128 Align = Size <= 32 ? 32 : 64;
129 if (Size <= Align) {
130 // Pass in the smallest viable integer type.
131 Size = llvm::bit_ceil(Size);
132 return ABIArgInfo::getDirect(llvm::Type::getIntNTy(getVMContext(), Size));
133 }
135}
136
137ABIArgInfo HexagonABIInfo::classifyReturnType(QualType RetTy) const {
138 if (RetTy->isVoidType())
139 return ABIArgInfo::getIgnore();
140
141 const TargetInfo &T = CGT.getTarget();
142 uint64_t Size = getContext().getTypeSize(RetTy);
143
144 if (RetTy->getAs<VectorType>()) {
145 // HVX vectors are returned in vector registers or register pairs.
146 if (T.hasFeature("hvx")) {
147 assert(T.hasFeature("hvx-length64b") || T.hasFeature("hvx-length128b"));
148 uint64_t VecSize = T.hasFeature("hvx-length64b") ? 64*8 : 128*8;
149 if (Size == VecSize || Size == 2*VecSize)
151 }
152 // Large vector types should be returned via memory.
153 if (Size > 64)
154 return getNaturalAlignIndirect(RetTy);
155 }
156
157 if (!isAggregateTypeForABI(RetTy)) {
158 // Treat an enum type as its underlying type.
159 if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
160 RetTy = EnumTy->getDecl()->getIntegerType();
161
162 if (Size > 64 && RetTy->isBitIntType())
163 return getNaturalAlignIndirect(RetTy, /*ByVal=*/false);
164
165 return isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy)
166 : ABIArgInfo::getDirect();
167 }
168
169 if (isEmptyRecord(getContext(), RetTy, true))
170 return ABIArgInfo::getIgnore();
171
172 // Aggregates <= 8 bytes are returned in registers, other aggregates
173 // are returned indirectly.
174 if (Size <= 64) {
175 // Return in the smallest viable integer type.
176 Size = llvm::bit_ceil(Size);
177 return ABIArgInfo::getDirect(llvm::Type::getIntNTy(getVMContext(), Size));
178 }
179 return getNaturalAlignIndirect(RetTy, /*ByVal=*/true);
180}
181
182Address HexagonABIInfo::EmitVAArgFromMemory(CodeGenFunction &CGF,
183 Address VAListAddr,
184 QualType Ty) const {
185 // Load the overflow area pointer.
186 Address __overflow_area_pointer_p =
187 CGF.Builder.CreateStructGEP(VAListAddr, 2, "__overflow_area_pointer_p");
188 llvm::Value *__overflow_area_pointer = CGF.Builder.CreateLoad(
189 __overflow_area_pointer_p, "__overflow_area_pointer");
190
191 uint64_t Align = CGF.getContext().getTypeAlign(Ty) / 8;
192 if (Align > 4) {
193 // Alignment should be a power of 2.
194 assert((Align & (Align - 1)) == 0 && "Alignment is not power of 2!");
195
196 // overflow_arg_area = (overflow_arg_area + align - 1) & -align;
197 llvm::Value *Offset = llvm::ConstantInt::get(CGF.Int64Ty, Align - 1);
198
199 // Add offset to the current pointer to access the argument.
200 __overflow_area_pointer =
201 CGF.Builder.CreateGEP(CGF.Int8Ty, __overflow_area_pointer, Offset);
202 llvm::Value *AsInt =
203 CGF.Builder.CreatePtrToInt(__overflow_area_pointer, CGF.Int32Ty);
204
205 // Create a mask which should be "AND"ed
206 // with (overflow_arg_area + align - 1)
207 llvm::Value *Mask = llvm::ConstantInt::get(CGF.Int32Ty, -(int)Align);
208 __overflow_area_pointer = CGF.Builder.CreateIntToPtr(
209 CGF.Builder.CreateAnd(AsInt, Mask), __overflow_area_pointer->getType(),
210 "__overflow_area_pointer.align");
211 }
212
213 // Get the type of the argument from memory and bitcast
214 // overflow area pointer to the argument type.
215 llvm::Type *PTy = CGF.ConvertTypeForMem(Ty);
216 Address AddrTyped =
217 Address(__overflow_area_pointer, PTy, CharUnits::fromQuantity(Align));
218
219 // Round up to the minimum stack alignment for varargs which is 4 bytes.
220 uint64_t Offset = llvm::alignTo(CGF.getContext().getTypeSize(Ty) / 8, 4);
221
222 __overflow_area_pointer = CGF.Builder.CreateGEP(
223 CGF.Int8Ty, __overflow_area_pointer,
224 llvm::ConstantInt::get(CGF.Int32Ty, Offset),
225 "__overflow_area_pointer.next");
226 CGF.Builder.CreateStore(__overflow_area_pointer, __overflow_area_pointer_p);
227
228 return AddrTyped;
229}
230
231Address HexagonABIInfo::EmitVAArgForHexagon(CodeGenFunction &CGF,
232 Address VAListAddr,
233 QualType Ty) const {
234 // FIXME: Need to handle alignment
235 llvm::Type *BP = CGF.Int8PtrTy;
236 CGBuilderTy &Builder = CGF.Builder;
237 Address VAListAddrAsBPP = VAListAddr.withElementType(BP);
238 llvm::Value *Addr = Builder.CreateLoad(VAListAddrAsBPP, "ap.cur");
239 // Handle address alignment for type alignment > 32 bits
240 uint64_t TyAlign = CGF.getContext().getTypeAlign(Ty) / 8;
241 if (TyAlign > 4) {
242 assert((TyAlign & (TyAlign - 1)) == 0 && "Alignment is not power of 2!");
243 llvm::Value *AddrAsInt = Builder.CreatePtrToInt(Addr, CGF.Int32Ty);
244 AddrAsInt = Builder.CreateAdd(AddrAsInt, Builder.getInt32(TyAlign - 1));
245 AddrAsInt = Builder.CreateAnd(AddrAsInt, Builder.getInt32(~(TyAlign - 1)));
246 Addr = Builder.CreateIntToPtr(AddrAsInt, BP);
247 }
248 Address AddrTyped =
249 Address(Addr, CGF.ConvertType(Ty), CharUnits::fromQuantity(TyAlign));
250
251 uint64_t Offset = llvm::alignTo(CGF.getContext().getTypeSize(Ty) / 8, 4);
252 llvm::Value *NextAddr = Builder.CreateGEP(
253 CGF.Int8Ty, Addr, llvm::ConstantInt::get(CGF.Int32Ty, Offset), "ap.next");
254 Builder.CreateStore(NextAddr, VAListAddrAsBPP);
255
256 return AddrTyped;
257}
258
259Address HexagonABIInfo::EmitVAArgForHexagonLinux(CodeGenFunction &CGF,
260 Address VAListAddr,
261 QualType Ty) const {
262 int ArgSize = CGF.getContext().getTypeSize(Ty) / 8;
263
264 if (ArgSize > 8)
265 return EmitVAArgFromMemory(CGF, VAListAddr, Ty);
266
267 // Here we have check if the argument is in register area or
268 // in overflow area.
269 // If the saved register area pointer + argsize rounded up to alignment >
270 // saved register area end pointer, argument is in overflow area.
271 unsigned RegsLeft = 6;
272 Ty = CGF.getContext().getCanonicalType(Ty);
273 (void)classifyArgumentType(Ty, &RegsLeft);
274
275 llvm::BasicBlock *MaybeRegBlock = CGF.createBasicBlock("vaarg.maybe_reg");
276 llvm::BasicBlock *InRegBlock = CGF.createBasicBlock("vaarg.in_reg");
277 llvm::BasicBlock *OnStackBlock = CGF.createBasicBlock("vaarg.on_stack");
278 llvm::BasicBlock *ContBlock = CGF.createBasicBlock("vaarg.end");
279
280 // Get rounded size of the argument.GCC does not allow vararg of
281 // size < 4 bytes. We follow the same logic here.
282 ArgSize = (CGF.getContext().getTypeSize(Ty) <= 32) ? 4 : 8;
283 int ArgAlign = (CGF.getContext().getTypeSize(Ty) <= 32) ? 4 : 8;
284
285 // Argument may be in saved register area
286 CGF.EmitBlock(MaybeRegBlock);
287
288 // Load the current saved register area pointer.
289 Address __current_saved_reg_area_pointer_p = CGF.Builder.CreateStructGEP(
290 VAListAddr, 0, "__current_saved_reg_area_pointer_p");
291 llvm::Value *__current_saved_reg_area_pointer = CGF.Builder.CreateLoad(
292 __current_saved_reg_area_pointer_p, "__current_saved_reg_area_pointer");
293
294 // Load the saved register area end pointer.
295 Address __saved_reg_area_end_pointer_p = CGF.Builder.CreateStructGEP(
296 VAListAddr, 1, "__saved_reg_area_end_pointer_p");
297 llvm::Value *__saved_reg_area_end_pointer = CGF.Builder.CreateLoad(
298 __saved_reg_area_end_pointer_p, "__saved_reg_area_end_pointer");
299
300 // If the size of argument is > 4 bytes, check if the stack
301 // location is aligned to 8 bytes
302 if (ArgAlign > 4) {
303
304 llvm::Value *__current_saved_reg_area_pointer_int =
305 CGF.Builder.CreatePtrToInt(__current_saved_reg_area_pointer,
306 CGF.Int32Ty);
307
308 __current_saved_reg_area_pointer_int = CGF.Builder.CreateAdd(
309 __current_saved_reg_area_pointer_int,
310 llvm::ConstantInt::get(CGF.Int32Ty, (ArgAlign - 1)),
311 "align_current_saved_reg_area_pointer");
312
313 __current_saved_reg_area_pointer_int =
314 CGF.Builder.CreateAnd(__current_saved_reg_area_pointer_int,
315 llvm::ConstantInt::get(CGF.Int32Ty, -ArgAlign),
316 "align_current_saved_reg_area_pointer");
317
318 __current_saved_reg_area_pointer =
319 CGF.Builder.CreateIntToPtr(__current_saved_reg_area_pointer_int,
320 __current_saved_reg_area_pointer->getType(),
321 "align_current_saved_reg_area_pointer");
322 }
323
324 llvm::Value *__new_saved_reg_area_pointer =
325 CGF.Builder.CreateGEP(CGF.Int8Ty, __current_saved_reg_area_pointer,
326 llvm::ConstantInt::get(CGF.Int32Ty, ArgSize),
327 "__new_saved_reg_area_pointer");
328
329 llvm::Value *UsingStack = nullptr;
330 UsingStack = CGF.Builder.CreateICmpSGT(__new_saved_reg_area_pointer,
331 __saved_reg_area_end_pointer);
332
333 CGF.Builder.CreateCondBr(UsingStack, OnStackBlock, InRegBlock);
334
335 // Argument in saved register area
336 // Implement the block where argument is in register saved area
337 CGF.EmitBlock(InRegBlock);
338
339 llvm::Type *PTy = CGF.ConvertType(Ty);
340 llvm::Value *__saved_reg_area_p = CGF.Builder.CreateBitCast(
341 __current_saved_reg_area_pointer, llvm::PointerType::getUnqual(PTy));
342
343 CGF.Builder.CreateStore(__new_saved_reg_area_pointer,
344 __current_saved_reg_area_pointer_p);
345
346 CGF.EmitBranch(ContBlock);
347
348 // Argument in overflow area
349 // Implement the block where the argument is in overflow area.
350 CGF.EmitBlock(OnStackBlock);
351
352 // Load the overflow area pointer
353 Address __overflow_area_pointer_p =
354 CGF.Builder.CreateStructGEP(VAListAddr, 2, "__overflow_area_pointer_p");
355 llvm::Value *__overflow_area_pointer = CGF.Builder.CreateLoad(
356 __overflow_area_pointer_p, "__overflow_area_pointer");
357
358 // Align the overflow area pointer according to the alignment of the argument
359 if (ArgAlign > 4) {
360 llvm::Value *__overflow_area_pointer_int =
361 CGF.Builder.CreatePtrToInt(__overflow_area_pointer, CGF.Int32Ty);
362
363 __overflow_area_pointer_int =
364 CGF.Builder.CreateAdd(__overflow_area_pointer_int,
365 llvm::ConstantInt::get(CGF.Int32Ty, ArgAlign - 1),
366 "align_overflow_area_pointer");
367
368 __overflow_area_pointer_int =
369 CGF.Builder.CreateAnd(__overflow_area_pointer_int,
370 llvm::ConstantInt::get(CGF.Int32Ty, -ArgAlign),
371 "align_overflow_area_pointer");
372
373 __overflow_area_pointer = CGF.Builder.CreateIntToPtr(
374 __overflow_area_pointer_int, __overflow_area_pointer->getType(),
375 "align_overflow_area_pointer");
376 }
377
378 // Get the pointer for next argument in overflow area and store it
379 // to overflow area pointer.
380 llvm::Value *__new_overflow_area_pointer = CGF.Builder.CreateGEP(
381 CGF.Int8Ty, __overflow_area_pointer,
382 llvm::ConstantInt::get(CGF.Int32Ty, ArgSize),
383 "__overflow_area_pointer.next");
384
385 CGF.Builder.CreateStore(__new_overflow_area_pointer,
386 __overflow_area_pointer_p);
387
388 CGF.Builder.CreateStore(__new_overflow_area_pointer,
389 __current_saved_reg_area_pointer_p);
390
391 // Bitcast the overflow area pointer to the type of argument.
392 llvm::Type *OverflowPTy = CGF.ConvertTypeForMem(Ty);
393 llvm::Value *__overflow_area_p = CGF.Builder.CreateBitCast(
394 __overflow_area_pointer, llvm::PointerType::getUnqual(OverflowPTy));
395
396 CGF.EmitBranch(ContBlock);
397
398 // Get the correct pointer to load the variable argument
399 // Implement the ContBlock
400 CGF.EmitBlock(ContBlock);
401
402 llvm::Type *MemTy = CGF.ConvertTypeForMem(Ty);
403 llvm::Type *MemPTy = llvm::PointerType::getUnqual(MemTy);
404 llvm::PHINode *ArgAddr = CGF.Builder.CreatePHI(MemPTy, 2, "vaarg.addr");
405 ArgAddr->addIncoming(__saved_reg_area_p, InRegBlock);
406 ArgAddr->addIncoming(__overflow_area_p, OnStackBlock);
407
408 return Address(ArgAddr, MemTy, CharUnits::fromQuantity(ArgAlign));
409}
410
411Address HexagonABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
412 QualType Ty) const {
413
414 if (getTarget().getTriple().isMusl())
415 return EmitVAArgForHexagonLinux(CGF, VAListAddr, Ty);
416
417 return EmitVAArgForHexagon(CGF, VAListAddr, Ty);
418}
419
420std::unique_ptr<TargetCodeGenInfo>
422 return std::make_unique<HexagonTargetCodeGenInfo>(CGM.getTypes());
423}
static bool HexagonAdjustRegsLeft(uint64_t Size, unsigned *RegsLeft)
Definition: Hexagon.cpp:71
CanQualType getCanonicalType(QualType T) const
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
Definition: ASTContext.h:2574
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
Definition: ASTContext.h:2340
unsigned getTypeAlign(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in bits.
Definition: ASTContext.h:2371
Represents a source-level, intra-procedural CFG that represents the control-flow of a Stmt.
Definition: CFG.h:1214
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 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)
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
Definition: Address.h:111
Address withElementType(llvm::Type *ElemTy) const
Return address with different element type, but same pointer and alignment.
Definition: Address.h:241
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
Definition: CGBuilder.h:136
Address CreateGEP(CodeGenFunction &CGF, Address Addr, llvm::Value *Index, const llvm::Twine &Name="")
Definition: CGBuilder.h:292
Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")
Definition: CGBuilder.h:219
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
Definition: CGBuilder.h:108
RecordArgABI
Specify how one should pass an argument of a record type.
Definition: CGCXXABI.h:150
@ 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...
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
llvm::Type * ConvertTypeForMem(QualType T)
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
llvm::Type * ConvertType(QualType T)
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
ABIArgInfo classifyArgumentType(QualType RetTy) const
Definition: ABIInfoImpl.cpp:17
ABIArgInfo classifyReturnType(QualType RetTy) const
Definition: ABIInfoImpl.cpp:45
void computeInfo(CGFunctionInfo &FI) const override
Definition: ABIInfoImpl.cpp:67
Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty) const override
EmitVAArg - Emit the target dependent code to load a value of.
Definition: ABIInfoImpl.cpp:74
TargetCodeGenInfo - This class organizes various target-specific codegeneration issues,...
Definition: TargetInfo.h:46
virtual void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const
setTargetAttributes - Provides a convenient hook to handle extra target-specific attributes for the g...
Definition: TargetInfo.h:75
virtual int getDwarfEHStackPointer(CodeGen::CodeGenModule &M) const
Determines the DWARF register number for the stack pointer, for exception-handling purposes.
Definition: TargetInfo.h:122
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
Definition: Type.h:5575
Represents a function declaration or definition.
Definition: Decl.h:1971
A (possibly-)qualified type.
Definition: Type.h:940
Exposes information about the current target.
Definition: TargetInfo.h:214
bool isVoidType() const
Definition: Type.h:7905
bool isBitIntType() const
Definition: Type.h:7840
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:8123
Represents a GCC generic vector type.
Definition: Type.h:3969
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)
std::unique_ptr< TargetCodeGenInfo > createHexagonTargetCodeGenInfo(CodeGenModule &CGM)
Definition: Hexagon.cpp:421
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.
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
unsigned long uint64_t
Definition: Format.h:5394
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64