clang 20.0.0git
NVPTX.cpp
Go to the documentation of this file.
1//===- NVPTX.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#include "llvm/ADT/STLExtras.h"
12#include "llvm/IR/IntrinsicsNVPTX.h"
13
14using namespace clang;
15using namespace clang::CodeGen;
16
17//===----------------------------------------------------------------------===//
18// NVPTX ABI Implementation
19//===----------------------------------------------------------------------===//
20
21namespace {
22
23class NVPTXTargetCodeGenInfo;
24
25class NVPTXABIInfo : public ABIInfo {
26 NVPTXTargetCodeGenInfo &CGInfo;
27
28public:
29 NVPTXABIInfo(CodeGenTypes &CGT, NVPTXTargetCodeGenInfo &Info)
30 : ABIInfo(CGT), CGInfo(Info) {}
31
34
35 void computeInfo(CGFunctionInfo &FI) const override;
36 RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
37 AggValueSlot Slot) const override;
38 bool isUnsupportedType(QualType T) const;
39 ABIArgInfo coerceToIntArrayWithLimit(QualType Ty, unsigned MaxSize) const;
40};
41
42class NVPTXTargetCodeGenInfo : public TargetCodeGenInfo {
43public:
44 NVPTXTargetCodeGenInfo(CodeGenTypes &CGT)
45 : TargetCodeGenInfo(std::make_unique<NVPTXABIInfo>(CGT, *this)) {}
46
47 void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
48 CodeGen::CodeGenModule &M) const override;
49 bool shouldEmitStaticExternCAliases() const override;
50
51 llvm::Constant *getNullPointer(const CodeGen::CodeGenModule &CGM,
52 llvm::PointerType *T,
53 QualType QT) const override;
54
55 llvm::Type *getCUDADeviceBuiltinSurfaceDeviceType() const override {
56 // On the device side, surface reference is represented as an object handle
57 // in 64-bit integer.
58 return llvm::Type::getInt64Ty(getABIInfo().getVMContext());
59 }
60
61 llvm::Type *getCUDADeviceBuiltinTextureDeviceType() const override {
62 // On the device side, texture reference is represented as an object handle
63 // in 64-bit integer.
64 return llvm::Type::getInt64Ty(getABIInfo().getVMContext());
65 }
66
68 LValue Src) const override {
69 emitBuiltinSurfTexDeviceCopy(CGF, Dst, Src);
70 return true;
71 }
72
74 LValue Src) const override {
75 emitBuiltinSurfTexDeviceCopy(CGF, Dst, Src);
76 return true;
77 }
78
79 // Adds a NamedMDNode with GV, Name, and Operand as operands, and adds the
80 // resulting MDNode to the nvvm.annotations MDNode.
81 static void addNVVMMetadata(llvm::GlobalValue *GV, StringRef Name,
82 int Operand,
83 const SmallVectorImpl<int> &GridConstantArgs);
84
85 static void addNVVMMetadata(llvm::GlobalValue *GV, StringRef Name,
86 int Operand) {
87 addNVVMMetadata(GV, Name, Operand, SmallVector<int, 1>(0));
88 }
89
90private:
91 static void emitBuiltinSurfTexDeviceCopy(CodeGenFunction &CGF, LValue Dst,
92 LValue Src) {
93 llvm::Value *Handle = nullptr;
94 llvm::Constant *C =
95 llvm::dyn_cast<llvm::Constant>(Src.getAddress().emitRawPointer(CGF));
96 // Lookup `addrspacecast` through the constant pointer if any.
97 if (auto *ASC = llvm::dyn_cast_or_null<llvm::AddrSpaceCastOperator>(C))
98 C = llvm::cast<llvm::Constant>(ASC->getPointerOperand());
99 if (auto *GV = llvm::dyn_cast_or_null<llvm::GlobalVariable>(C)) {
100 // Load the handle from the specific global variable using
101 // `nvvm.texsurf.handle.internal` intrinsic.
102 Handle = CGF.EmitRuntimeCall(
103 CGF.CGM.getIntrinsic(llvm::Intrinsic::nvvm_texsurf_handle_internal,
104 {GV->getType()}),
105 {GV}, "texsurf_handle");
106 } else
107 Handle = CGF.EmitLoadOfScalar(Src, SourceLocation());
108 CGF.EmitStoreOfScalar(Handle, Dst);
109 }
110};
111
112/// Checks if the type is unsupported directly by the current target.
113bool NVPTXABIInfo::isUnsupportedType(QualType T) const {
114 ASTContext &Context = getContext();
115 if (!Context.getTargetInfo().hasFloat16Type() && T->isFloat16Type())
116 return true;
117 if (!Context.getTargetInfo().hasFloat128Type() &&
118 (T->isFloat128Type() ||
119 (T->isRealFloatingType() && Context.getTypeSize(T) == 128)))
120 return true;
121 if (const auto *EIT = T->getAs<BitIntType>())
122 return EIT->getNumBits() >
123 (Context.getTargetInfo().hasInt128Type() ? 128U : 64U);
124 if (!Context.getTargetInfo().hasInt128Type() && T->isIntegerType() &&
125 Context.getTypeSize(T) > 64U)
126 return true;
127 if (const auto *AT = T->getAsArrayTypeUnsafe())
128 return isUnsupportedType(AT->getElementType());
129 const auto *RT = T->getAs<RecordType>();
130 if (!RT)
131 return false;
132 const RecordDecl *RD = RT->getDecl();
133
134 // If this is a C++ record, check the bases first.
135 if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
136 for (const CXXBaseSpecifier &I : CXXRD->bases())
137 if (isUnsupportedType(I.getType()))
138 return true;
139
140 for (const FieldDecl *I : RD->fields())
141 if (isUnsupportedType(I->getType()))
142 return true;
143 return false;
144}
145
146/// Coerce the given type into an array with maximum allowed size of elements.
147ABIArgInfo NVPTXABIInfo::coerceToIntArrayWithLimit(QualType Ty,
148 unsigned MaxSize) const {
149 // Alignment and Size are measured in bits.
150 const uint64_t Size = getContext().getTypeSize(Ty);
151 const uint64_t Alignment = getContext().getTypeAlign(Ty);
152 const unsigned Div = std::min<unsigned>(MaxSize, Alignment);
153 llvm::Type *IntType = llvm::Type::getIntNTy(getVMContext(), Div);
154 const uint64_t NumElements = (Size + Div - 1) / Div;
155 return ABIArgInfo::getDirect(llvm::ArrayType::get(IntType, NumElements));
156}
157
158ABIArgInfo NVPTXABIInfo::classifyReturnType(QualType RetTy) const {
159 if (RetTy->isVoidType())
160 return ABIArgInfo::getIgnore();
161
162 if (getContext().getLangOpts().OpenMP &&
163 getContext().getLangOpts().OpenMPIsTargetDevice &&
164 isUnsupportedType(RetTy))
165 return coerceToIntArrayWithLimit(RetTy, 64);
166
167 // note: this is different from default ABI
168 if (!RetTy->isScalarType())
169 return ABIArgInfo::getDirect();
170
171 // Treat an enum type as its underlying type.
172 if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
173 RetTy = EnumTy->getDecl()->getIntegerType();
174
175 return (isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy)
177}
178
179ABIArgInfo NVPTXABIInfo::classifyArgumentType(QualType Ty) const {
180 // Treat an enum type as its underlying type.
181 if (const EnumType *EnumTy = Ty->getAs<EnumType>())
182 Ty = EnumTy->getDecl()->getIntegerType();
183
184 // Return aggregates type as indirect by value
185 if (isAggregateTypeForABI(Ty)) {
186 // Under CUDA device compilation, tex/surf builtin types are replaced with
187 // object types and passed directly.
188 if (getContext().getLangOpts().CUDAIsDevice) {
191 CGInfo.getCUDADeviceBuiltinSurfaceDeviceType());
194 CGInfo.getCUDADeviceBuiltinTextureDeviceType());
195 }
196 return getNaturalAlignIndirect(Ty, /* byval */ true);
197 }
198
199 if (const auto *EIT = Ty->getAs<BitIntType>()) {
200 if ((EIT->getNumBits() > 128) ||
201 (!getContext().getTargetInfo().hasInt128Type() &&
202 EIT->getNumBits() > 64))
203 return getNaturalAlignIndirect(Ty, /* byval */ true);
204 }
205
206 return (isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty)
208}
209
210void NVPTXABIInfo::computeInfo(CGFunctionInfo &FI) const {
211 if (!getCXXABI().classifyReturnType(FI))
213
214 for (auto &&[ArgumentsCount, I] : llvm::enumerate(FI.arguments()))
215 I.info = ArgumentsCount < FI.getNumRequiredArgs()
216 ? classifyArgumentType(I.type)
217 : ABIArgInfo::getDirect();
218
219 // Always honor user-specified calling convention.
220 if (FI.getCallingConvention() != llvm::CallingConv::C)
221 return;
222
223 FI.setEffectiveCallingConvention(getRuntimeCC());
224}
225
226RValue NVPTXABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
227 QualType Ty, AggValueSlot Slot) const {
228 return emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*IsIndirect=*/false,
229 getContext().getTypeInfoInChars(Ty),
231 /*AllowHigherAlign=*/true, Slot);
232}
233
234void NVPTXTargetCodeGenInfo::setTargetAttributes(
235 const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const {
236 if (GV->isDeclaration())
237 return;
238 const VarDecl *VD = dyn_cast_or_null<VarDecl>(D);
239 if (VD) {
240 if (M.getLangOpts().CUDA) {
242 addNVVMMetadata(GV, "surface", 1);
243 else if (VD->getType()->isCUDADeviceBuiltinTextureType())
244 addNVVMMetadata(GV, "texture", 1);
245 return;
246 }
247 }
248
249 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
250 if (!FD)
251 return;
252
253 llvm::Function *F = cast<llvm::Function>(GV);
254
255 // Perform special handling in OpenCL mode
256 if (M.getLangOpts().OpenCL) {
257 // Use OpenCL function attributes to check for kernel functions
258 // By default, all functions are device functions
259 if (FD->hasAttr<OpenCLKernelAttr>()) {
260 // OpenCL __kernel functions get kernel metadata
261 // Create !{<func-ref>, metadata !"kernel", i32 1} node
262 addNVVMMetadata(F, "kernel", 1);
263 // And kernel functions are not subject to inlining
264 F->addFnAttr(llvm::Attribute::NoInline);
265 }
266 }
267
268 // Perform special handling in CUDA mode.
269 if (M.getLangOpts().CUDA) {
270 // CUDA __global__ functions get a kernel metadata entry. Since
271 // __global__ functions cannot be called from the device, we do not
272 // need to set the noinline attribute.
273 if (FD->hasAttr<CUDAGlobalAttr>()) {
275 for (auto IV : llvm::enumerate(FD->parameters()))
276 if (IV.value()->hasAttr<CUDAGridConstantAttr>())
277 // For some reason arg indices are 1-based in NVVM
278 GCI.push_back(IV.index() + 1);
279 // Create !{<func-ref>, metadata !"kernel", i32 1} node
280 addNVVMMetadata(F, "kernel", 1, GCI);
281 }
282 if (CUDALaunchBoundsAttr *Attr = FD->getAttr<CUDALaunchBoundsAttr>())
284 }
285
286 // Attach kernel metadata directly if compiling for NVPTX.
287 if (FD->hasAttr<NVPTXKernelAttr>()) {
288 addNVVMMetadata(F, "kernel", 1);
289 }
290}
291
292void NVPTXTargetCodeGenInfo::addNVVMMetadata(
293 llvm::GlobalValue *GV, StringRef Name, int Operand,
294 const SmallVectorImpl<int> &GridConstantArgs) {
295 llvm::Module *M = GV->getParent();
296 llvm::LLVMContext &Ctx = M->getContext();
297
298 // Get "nvvm.annotations" metadata node
299 llvm::NamedMDNode *MD = M->getOrInsertNamedMetadata("nvvm.annotations");
300
302 llvm::ConstantAsMetadata::get(GV), llvm::MDString::get(Ctx, Name),
303 llvm::ConstantAsMetadata::get(
304 llvm::ConstantInt::get(llvm::Type::getInt32Ty(Ctx), Operand))};
305 if (!GridConstantArgs.empty()) {
307 for (int I : GridConstantArgs)
308 GCM.push_back(llvm::ConstantAsMetadata::get(
309 llvm::ConstantInt::get(llvm::Type::getInt32Ty(Ctx), I)));
310 MDVals.append({llvm::MDString::get(Ctx, "grid_constant"),
311 llvm::MDNode::get(Ctx, GCM)});
312 }
313 // Append metadata to nvvm.annotations
314 MD->addOperand(llvm::MDNode::get(Ctx, MDVals));
315}
316
317bool NVPTXTargetCodeGenInfo::shouldEmitStaticExternCAliases() const {
318 return false;
319}
320
321llvm::Constant *
322NVPTXTargetCodeGenInfo::getNullPointer(const CodeGen::CodeGenModule &CGM,
323 llvm::PointerType *PT,
324 QualType QT) const {
325 auto &Ctx = CGM.getContext();
326 if (PT->getAddressSpace() != Ctx.getTargetAddressSpace(LangAS::opencl_local))
327 return llvm::ConstantPointerNull::get(PT);
328
329 auto NPT = llvm::PointerType::get(
330 PT->getContext(), Ctx.getTargetAddressSpace(LangAS::opencl_generic));
331 return llvm::ConstantExpr::getAddrSpaceCast(
332 llvm::ConstantPointerNull::get(NPT), PT);
333}
334} // namespace
335
337 const CUDALaunchBoundsAttr *Attr,
338 int32_t *MaxThreadsVal,
339 int32_t *MinBlocksVal,
340 int32_t *MaxClusterRankVal) {
341 // Create !{<func-ref>, metadata !"maxntidx", i32 <val>} node
342 llvm::APSInt MaxThreads(32);
343 MaxThreads = Attr->getMaxThreads()->EvaluateKnownConstInt(getContext());
344 if (MaxThreads > 0) {
345 if (MaxThreadsVal)
346 *MaxThreadsVal = MaxThreads.getExtValue();
347 if (F) {
348 // Create !{<func-ref>, metadata !"maxntidx", i32 <val>} node
349 NVPTXTargetCodeGenInfo::addNVVMMetadata(F, "maxntidx",
350 MaxThreads.getExtValue());
351 }
352 }
353
354 // min and max blocks is an optional argument for CUDALaunchBoundsAttr. If it
355 // was not specified in __launch_bounds__ or if the user specified a 0 value,
356 // we don't have to add a PTX directive.
357 if (Attr->getMinBlocks()) {
358 llvm::APSInt MinBlocks(32);
359 MinBlocks = Attr->getMinBlocks()->EvaluateKnownConstInt(getContext());
360 if (MinBlocks > 0) {
361 if (MinBlocksVal)
362 *MinBlocksVal = MinBlocks.getExtValue();
363 if (F) {
364 // Create !{<func-ref>, metadata !"minctasm", i32 <val>} node
365 NVPTXTargetCodeGenInfo::addNVVMMetadata(F, "minctasm",
366 MinBlocks.getExtValue());
367 }
368 }
369 }
370 if (Attr->getMaxBlocks()) {
371 llvm::APSInt MaxBlocks(32);
372 MaxBlocks = Attr->getMaxBlocks()->EvaluateKnownConstInt(getContext());
373 if (MaxBlocks > 0) {
374 if (MaxClusterRankVal)
375 *MaxClusterRankVal = MaxBlocks.getExtValue();
376 if (F) {
377 // Create !{<func-ref>, metadata !"maxclusterrank", i32 <val>} node
378 NVPTXTargetCodeGenInfo::addNVVMMetadata(F, "maxclusterrank",
379 MaxBlocks.getExtValue());
380 }
381 }
382 }
383}
384
385std::unique_ptr<TargetCodeGenInfo>
387 return std::make_unique<NVPTXTargetCodeGenInfo>(CGM.getTypes());
388}
const Decl * D
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:188
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
Definition: ASTContext.h:2482
const TargetInfo & getTargetInfo() const
Definition: ASTContext.h:799
Attr - This represents one attribute.
Definition: Attr.h:43
A fixed int type of a specified bitwidth.
Definition: Type.h:7814
Represents a base class of a C++ class.
Definition: DeclCXX.h:146
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
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)
ABIInfo - Target specific hooks for defining how a type should be passed or returned from functions.
Definition: ABIInfo.h:47
virtual RValue EmitVAArg(CodeGen::CodeGenFunction &CGF, CodeGen::Address VAListAddr, QualType Ty, AggValueSlot Slot) const =0
EmitVAArg - Emit the target dependent code to load a value of.
virtual void computeInfo(CodeGen::CGFunctionInfo &FI) const =0
Like RawAddress, an abstract representation of an aligned address, but the pointer contained in this ...
Definition: Address.h:128
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
Definition: Address.h:251
An aggregate value slot.
Definition: CGValue.h:504
CGFunctionInfo - Class to encapsulate the information about a function definition.
unsigned getCallingConvention() const
getCallingConvention - Return the user specified calling convention, which has been translated into a...
CanQualType getReturnType() const
MutableArrayRef< ArgInfo > arguments()
void setEffectiveCallingConvention(unsigned Value)
unsigned getNumRequiredArgs() const
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
llvm::Value * EmitLoadOfScalar(Address Addr, bool Volatile, QualType Ty, SourceLocation Loc, AlignmentSource Source=AlignmentSource::Type, bool isNontemporal=false)
EmitLoadOfScalar - Load a scalar value from an address, taking care to appropriately convert from the...
llvm::CallInst * EmitRuntimeCall(llvm::FunctionCallee callee, const Twine &name="")
void EmitStoreOfScalar(llvm::Value *Value, Address Addr, bool Volatile, QualType Ty, AlignmentSource Source=AlignmentSource::Type, bool isInit=false, bool isNontemporal=false)
EmitStoreOfScalar - Store a scalar value to an address, taking care to appropriately convert from the...
This class organizes the cross-function state that is used while generating LLVM code.
void handleCUDALaunchBoundsAttr(llvm::Function *F, const CUDALaunchBoundsAttr *A, int32_t *MaxThreadsVal=nullptr, int32_t *MinBlocksVal=nullptr, int32_t *MaxClusterRankVal=nullptr)
Emit the IR encoding to attach the CUDA launch bounds attribute to F.
Definition: NVPTX.cpp:336
const LangOptions & getLangOpts() const
ASTContext & getContext() const
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})
This class organizes the cross-module state that is used while lowering AST types to LLVM types.
Definition: CodeGenTypes.h:54
LValue - This represents an lvalue references.
Definition: CGValue.h:182
Address getAddress() const
Definition: CGValue.h:361
RValue - This trivial value class is used to represent the result of an expression that is evaluated.
Definition: CGValue.h:42
TargetCodeGenInfo - This class organizes various target-specific codegeneration issues,...
Definition: TargetInfo.h:47
virtual bool emitCUDADeviceBuiltinSurfaceDeviceCopy(CodeGenFunction &CGF, LValue Dst, LValue Src) const
Emit the device-side copy of the builtin surface type.
Definition: TargetInfo.h:422
virtual bool emitCUDADeviceBuiltinTextureDeviceCopy(CodeGenFunction &CGF, LValue Dst, LValue Src) const
Emit the device-side copy of the builtin texture type.
Definition: TargetInfo.h:429
virtual llvm::Type * getCUDADeviceBuiltinSurfaceDeviceType() const
Return the device-side type for the CUDA device builtin surface type.
Definition: TargetInfo.h:405
const T & getABIInfo() const
Definition: TargetInfo.h:57
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:76
virtual llvm::Type * getCUDADeviceBuiltinTextureDeviceType() const
Return the device-side type for the CUDA device builtin texture type.
Definition: TargetInfo.h:410
virtual llvm::Constant * getNullPointer(const CodeGen::CodeGenModule &CGM, llvm::PointerType *T, QualType QT) const
Get target specific null pointer.
Definition: TargetInfo.cpp:120
virtual bool shouldEmitStaticExternCAliases() const
Definition: TargetInfo.h:395
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
T * getAttr() const
Definition: DeclBase.h:576
bool hasAttr() const
Definition: DeclBase.h:580
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
Definition: Type.h:6098
Represents a member of a struct/union/class.
Definition: Decl.h:3033
Represents a function declaration or definition.
Definition: Decl.h:1935
ArrayRef< ParmVarDecl * > parameters() const
Definition: Decl.h:2649
A (possibly-)qualified type.
Definition: Type.h:929
Represents a struct/union/class.
Definition: Decl.h:4148
field_range fields() const
Definition: Decl.h:4354
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
Definition: Type.h:6072
Encodes a location in the source.
virtual bool hasInt128Type() const
Determine whether the __int128 type is supported on this target.
Definition: TargetInfo.h:658
virtual bool hasFloat16Type() const
Determine whether the _Float16 type is supported on this target.
Definition: TargetInfo.h:699
virtual bool hasFloat128Type() const
Determine whether the __float128 type is supported on this target.
Definition: TargetInfo.h:696
bool isVoidType() const
Definition: Type.h:8510
bool isFloat16Type() const
Definition: Type.h:8519
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
Definition: Type.h:8550
bool isScalarType() const
Definition: Type.h:8609
bool isFloat128Type() const
Definition: Type.h:8535
bool isCUDADeviceBuiltinSurfaceType() const
Check if the type is the CUDA device builtin surface type.
Definition: Type.cpp:5072
bool isCUDADeviceBuiltinTextureType() const
Check if the type is the CUDA device builtin texture type.
Definition: Type.cpp:5079
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
Definition: Type.h:8786
bool isRealFloatingType() const
Floating point categories.
Definition: Type.cpp:2300
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:8731
QualType getType() const
Definition: Decl.h:682
Represents a variable declaration or definition.
Definition: Decl.h:882
ABIArgInfo classifyArgumentType(CodeGenModule &CGM, CanQualType type)
Classify the rules for how to pass a particular type.
bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, const ABIInfo &Info)
std::unique_ptr< TargetCodeGenInfo > createNVPTXTargetCodeGenInfo(CodeGenModule &CGM)
Definition: NVPTX.cpp:386
RValue emitVoidPtrVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType ValueTy, bool IsIndirect, TypeInfoChars ValueInfo, CharUnits SlotSizeAndAlign, bool AllowHigherAlign, AggValueSlot Slot, bool ForceRightAdjust=false)
Emit va_arg for a platform using the common void* representation, where arguments are simply emitted ...
bool isAggregateTypeForABI(QualType T)
Definition: ABIInfoImpl.cpp:94
bool Div(InterpState &S, CodePtr OpPC)
1) Pops the RHS from the stack.
Definition: Interp.h:674
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
unsigned long uint64_t