10#include "TargetInfo.h"
11#include "llvm/ADT/STLExtras.h"
12#include "llvm/ADT/StringExtras.h"
13#include "llvm/IR/CallingConv.h"
14#include "llvm/IR/IntrinsicsNVPTX.h"
25class NVPTXTargetCodeGenInfo;
27class NVPTXABIInfo :
public ABIInfo {
28 NVPTXTargetCodeGenInfo &CGInfo;
31 NVPTXABIInfo(CodeGenTypes &CGT, NVPTXTargetCodeGenInfo &Info)
32 : ABIInfo(CGT), CGInfo(Info) {}
37 void computeInfo(CGFunctionInfo &FI)
const override;
38 RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
39 AggValueSlot Slot)
const override;
40 bool isUnsupportedType(QualType
T)
const;
41 ABIArgInfo coerceToIntArrayWithLimit(QualType Ty,
unsigned MaxSize)
const;
46 NVPTXTargetCodeGenInfo(CodeGenTypes &CGT)
47 : TargetCodeGenInfo(std::make_unique<NVPTXABIInfo>(CGT, *this)) {}
49 void setTargetAttributes(
const Decl *D, llvm::GlobalValue *GV,
50 CodeGen::CodeGenModule &M)
const override;
51 bool shouldEmitStaticExternCAliases()
const override;
53 llvm::Constant *getNullPointer(
const CodeGen::CodeGenModule &CGM,
55 QualType QT)
const override;
57 llvm::Type *getCUDADeviceBuiltinSurfaceDeviceType()
const override {
60 return llvm::Type::getInt64Ty(getABIInfo().getVMContext());
63 llvm::Type *getCUDADeviceBuiltinTextureDeviceType()
const override {
66 return llvm::Type::getInt64Ty(getABIInfo().getVMContext());
69 bool emitCUDADeviceBuiltinSurfaceDeviceCopy(CodeGenFunction &CGF, LValue Dst,
70 LValue Src)
const override {
71 emitBuiltinSurfTexDeviceCopy(CGF, Dst, Src);
75 bool emitCUDADeviceBuiltinTextureDeviceCopy(CodeGenFunction &CGF, LValue Dst,
76 LValue Src)
const override {
77 emitBuiltinSurfTexDeviceCopy(CGF, Dst, Src);
81 unsigned getDeviceKernelCallingConv()
const override {
82 return llvm::CallingConv::PTX_Kernel;
87 static void addNVVMMetadata(llvm::GlobalValue *GV, StringRef Name,
91 static void emitBuiltinSurfTexDeviceCopy(CodeGenFunction &CGF, LValue Dst,
93 llvm::Value *Handle =
nullptr;
95 llvm::dyn_cast<llvm::Constant>(Src.getAddress().emitRawPointer(CGF));
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)) {
105 {GV},
"texsurf_handle");
113bool NVPTXABIInfo::isUnsupportedType(
QualType T)
const {
114 ASTContext &Context = getContext();
121 if (
const auto *EIT =
T->
getAs<BitIntType>())
122 return EIT->getNumBits() >
128 return isUnsupportedType(AT->getElementType());
134 if (
const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
135 for (
const CXXBaseSpecifier &I : CXXRD->bases())
136 if (isUnsupportedType(I.getType()))
139 for (
const FieldDecl *I : RD->fields())
140 if (isUnsupportedType(I->getType()))
146ABIArgInfo NVPTXABIInfo::coerceToIntArrayWithLimit(QualType Ty,
147 unsigned MaxSize)
const {
150 const uint64_t Alignment = getContext().getTypeAlign(Ty);
151 const unsigned Div = std::min<unsigned>(MaxSize, Alignment);
152 llvm::Type *IntType = llvm::Type::getIntNTy(getVMContext(), Div);
157ABIArgInfo NVPTXABIInfo::classifyReturnType(QualType RetTy)
const {
161 if (getContext().getLangOpts().OpenMP &&
162 getContext().getLangOpts().OpenMPIsTargetDevice &&
163 isUnsupportedType(RetTy))
164 return coerceToIntArrayWithLimit(RetTy, 64);
172 RetTy = ED->getIntegerType();
178ABIArgInfo NVPTXABIInfo::classifyArgumentType(QualType Ty)
const {
181 Ty = ED->getIntegerType();
187 if (getContext().getLangOpts().CUDAIsDevice) {
190 CGInfo.getCUDADeviceBuiltinSurfaceDeviceType());
193 CGInfo.getCUDADeviceBuiltinTextureDeviceType());
195 return getNaturalAlignIndirect(
196 Ty, getDataLayout().getAllocaAddrSpace(),
200 if (
const auto *EIT = Ty->
getAs<BitIntType>()) {
201 if ((EIT->getNumBits() > 128) ||
202 (!getContext().getTargetInfo().hasInt128Type() &&
203 EIT->getNumBits() > 64))
204 return getNaturalAlignIndirect(
205 Ty, getDataLayout().getAllocaAddrSpace(),
213void NVPTXABIInfo::computeInfo(CGFunctionInfo &FI)
const {
217 for (
auto &&[ArgumentsCount, I] : llvm::enumerate(FI.
arguments()))
220 : ABIArgInfo::getDirect();
229RValue NVPTXABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
230 QualType Ty, AggValueSlot Slot)
const {
232 getContext().getTypeInfoInChars(Ty),
237void NVPTXTargetCodeGenInfo::setTargetAttributes(
238 const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M)
const {
239 if (GV->isDeclaration())
241 const VarDecl *VD = dyn_cast_or_null<VarDecl>(D);
245 addNVVMMetadata(GV,
"surface", 1);
247 addNVVMMetadata(GV,
"texture", 1);
252 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
262 if (FD->
hasAttr<DeviceKernelAttr>() || FD->
hasAttr<CUDAGlobalAttr>()) {
265 F->addFnAttr(llvm::Attribute::NoInline);
266 if (FD->
hasAttr<CUDAGlobalAttr>()) {
267 F->setCallingConv(llvm::CallingConv::PTX_Kernel);
269 for (
auto IV : llvm::enumerate(FD->
parameters()))
270 if (IV.value()->hasAttr<CUDAGridConstantAttr>())
273 llvm::Attribute::get(F->getContext(),
"nvvm.grid_constant"));
275 if (CUDALaunchBoundsAttr *Attr = FD->
getAttr<CUDALaunchBoundsAttr>())
280 if (FD->
hasAttr<DeviceKernelAttr>())
281 F->setCallingConv(llvm::CallingConv::PTX_Kernel);
284void NVPTXTargetCodeGenInfo::addNVVMMetadata(llvm::GlobalValue *GV,
285 StringRef Name,
int Operand) {
286 llvm::Module *M = GV->getParent();
290 llvm::NamedMDNode *MD = M->getOrInsertNamedMetadata(
"nvvm.annotations");
292 SmallVector<llvm::Metadata *, 5> MDVals = {
293 llvm::ConstantAsMetadata::get(GV), llvm::MDString::get(Ctx, Name),
294 llvm::ConstantAsMetadata::get(
295 llvm::ConstantInt::get(llvm::Type::getInt32Ty(Ctx), Operand))};
298 MD->addOperand(llvm::MDNode::get(Ctx, MDVals));
301bool NVPTXTargetCodeGenInfo::shouldEmitStaticExternCAliases()
const {
306NVPTXTargetCodeGenInfo::getNullPointer(
const CodeGen::CodeGenModule &CGM,
307 llvm::PointerType *PT,
310 if (PT->getAddressSpace() != Ctx.getTargetAddressSpace(LangAS::opencl_local))
311 return llvm::ConstantPointerNull::get(PT);
313 auto NPT = llvm::PointerType::get(
314 PT->getContext(), Ctx.getTargetAddressSpace(LangAS::opencl_generic));
315 return llvm::ConstantExpr::getAddrSpaceCast(
316 llvm::ConstantPointerNull::get(NPT), PT);
321 const CUDALaunchBoundsAttr *
Attr,
322 int32_t *MaxThreadsVal,
323 int32_t *MinBlocksVal,
324 int32_t *MaxClusterRankVal) {
325 llvm::APSInt MaxThreads(32);
326 MaxThreads =
Attr->getMaxThreads()->EvaluateKnownConstInt(
getContext());
327 if (MaxThreads > 0) {
329 *MaxThreadsVal = MaxThreads.getExtValue();
331 F->addFnAttr(
"nvvm.maxntid", llvm::utostr(MaxThreads.getExtValue()));
337 if (
Attr->getMinBlocks()) {
338 llvm::APSInt MinBlocks(32);
339 MinBlocks =
Attr->getMinBlocks()->EvaluateKnownConstInt(
getContext());
342 *MinBlocksVal = MinBlocks.getExtValue();
344 F->addFnAttr(
"nvvm.minctasm", llvm::utostr(MinBlocks.getExtValue()));
347 if (
Attr->getMaxBlocks()) {
348 llvm::APSInt MaxBlocks(32);
349 MaxBlocks =
Attr->getMaxBlocks()->EvaluateKnownConstInt(
getContext());
351 if (MaxClusterRankVal)
352 *MaxClusterRankVal = MaxBlocks.getExtValue();
354 F->addFnAttr(
"nvvm.maxclusterrank",
355 llvm::utostr(MaxBlocks.getExtValue()));
360std::unique_ptr<TargetCodeGenInfo>
362 return std::make_unique<NVPTXTargetCodeGenInfo>(CGM.
getTypes());
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
const TargetInfo & getTargetInfo() const
Attr - This represents one attribute.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
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.
ABIArgInfo & getReturnInfo()
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
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.
const LangOptions & getLangOpts() const
CodeGenTypes & getTypes()
ASTContext & getContext() const
llvm::Function * getIntrinsic(unsigned IID, ArrayRef< llvm::Type * > Tys={})
TargetCodeGenInfo - This class organizes various target-specific codegeneration issues,...
ArrayRef< ParmVarDecl * > parameters() const
A (possibly-)qualified type.
virtual bool hasInt128Type() const
Determine whether the __int128 type is supported on this target.
virtual bool hasFloat16Type() const
Determine whether the _Float16 type is supported on this target.
virtual bool hasFloat128Type() const
Determine whether the __float128 type is supported on this target.
bool isFloat16Type() const
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
bool isScalarType() const
bool isFloat128Type() const
bool isCUDADeviceBuiltinSurfaceType() const
Check if the type is the CUDA device builtin surface type.
bool isCUDADeviceBuiltinTextureType() const
Check if the type is the CUDA device builtin texture type.
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
bool isRealFloatingType() const
Floating point categories.
const T * getAs() const
Member-template getAs<specific type>'.
ABIArgInfo classifyArgumentType(CodeGenModule &CGM, CanQualType type)
Classify the rules for how to pass a particular type.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, const ABIInfo &Info)
std::unique_ptr< TargetCodeGenInfo > createNVPTXTargetCodeGenInfo(CodeGenModule &CGM)
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)
bool Div(InterpState &S, CodePtr OpPC)
1) Pops the RHS from the stack.
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
U cast(CodeGen::Address addr)