10 #include "TargetInfo.h"
12 using namespace clang;
43 return getNaturalAlignIndirect(Ty);
51 bool IsRegCall = CC == llvm::CallingConv::X86_RegCall;
60 if (CC == llvm::CallingConv::SPIR_KERNEL) {
61 Arg.info = classifyKernelArgumentType(Arg.type);
63 Arg.info = IsRegCall ? classifyRegcallArgumentType(Arg.type)
104 llvm::Type *I32Ty = llvm::Type::getInt32Ty(getVMContext());
151 llvm::Type *I32Ty = llvm::Type::getInt32Ty(getVMContext());
162 class SPIRVABIInfo :
public CommonSPIRABIInfo {
164 SPIRVABIInfo(
CodeGenTypes &CGT) : CommonSPIRABIInfo(CGT) {}
176 CommonSPIRTargetCodeGenInfo(std::unique_ptr<ABIInfo>
ABIInfo)
179 LangAS getASTAllocaAddressSpace()
const override {
181 getABIInfo().getDataLayout().getAllocaAddrSpace());
184 unsigned getOpenCLKernelCallingConv()
const override;
187 bool shouldEmitStaticExternCAliases()
const override;
189 class SPIRVTargetCodeGenInfo :
public CommonSPIRTargetCodeGenInfo {
192 : CommonSPIRTargetCodeGenInfo(
std::make_unique<SPIRVABIInfo>(CGT)) {}
197 void CommonSPIRABIInfo::setCCs() {
199 RuntimeCC = llvm::CallingConv::SPIR_FUNC;
203 if (getContext().getLangOpts().CUDAIsDevice) {
207 llvm::Type *LTy = CGT.ConvertType(Ty);
210 auto *PtrTy = llvm::dyn_cast<llvm::PointerType>(LTy);
211 if (PtrTy && PtrTy->getAddressSpace() == DefaultAS) {
212 LTy = llvm::PointerType::get(PtrTy->getContext(), GlobalAS);
223 return getNaturalAlignIndirect(Ty,
true);
237 if (CC == llvm::CallingConv::SPIR_KERNEL) {
238 I.info = classifyKernelArgumentType(I.type);
249 SPIRVABIInfo(CGM.
getTypes()).computeInfo(FI);
251 CommonSPIRABIInfo(CGM.
getTypes()).computeInfo(FI);
256 unsigned CommonSPIRTargetCodeGenInfo::getOpenCLKernelCallingConv()
const {
257 return llvm::CallingConv::SPIR_KERNEL;
260 bool CommonSPIRTargetCodeGenInfo::shouldEmitStaticExternCAliases()
const {
267 if (getABIInfo().getContext().getLangOpts().HIP) {
268 FT = getABIInfo().getContext().adjustFunctionType(
276 StringRef OpenCLName,
277 unsigned AccessQualifier) {
288 if (OpenCLName.starts_with(
"image2d"))
290 else if (OpenCLName.starts_with(
"image3d"))
292 else if (OpenCLName ==
"image1d_buffer")
295 assert(OpenCLName.starts_with(
"image1d") &&
"Unknown image type");
300 if (OpenCLName.contains(
"_depth"))
302 if (OpenCLName.contains(
"_array"))
304 if (OpenCLName.contains(
"_msaa"))
308 IntParams.push_back(AccessQualifier);
310 return llvm::TargetExtType::get(Ctx, BaseType, {llvm::Type::getVoidTy(Ctx)},
314 llvm::Type *CommonSPIRTargetCodeGenInfo::getOpenCLType(
CodeGenModule &CGM,
315 const Type *Ty)
const {
317 if (Ctx.supportsTypedPointers())
319 if (
auto *PipeTy = dyn_cast<PipeType>(Ty))
320 return llvm::TargetExtType::get(Ctx,
"spirv.Pipe", {},
321 {!PipeTy->isReadOnly()});
322 if (
auto *BuiltinTy = dyn_cast<BuiltinType>(Ty)) {
323 enum AccessQualifier :
unsigned { AQ_ro = 0, AQ_wo = 1, AQ_rw = 2 };
324 switch (BuiltinTy->getKind()) {
326 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
327 case BuiltinType::Id: \
328 return getSPIRVImageType(Ctx, "spirv.Image", #ImgType, AQ_##Suffix);
329 #include "clang/Basic/OpenCLImageTypes.def"
330 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
331 case BuiltinType::Sampled##Id: \
332 return getSPIRVImageType(Ctx, "spirv.SampledImage", #ImgType, AQ_##Suffix);
334 #define IMAGE_WRITE_TYPE(Type, Id, Ext)
335 #define IMAGE_READ_WRITE_TYPE(Type, Id, Ext)
336 #include "clang/Basic/OpenCLImageTypes.def"
337 case BuiltinType::OCLSampler:
338 return llvm::TargetExtType::get(Ctx,
"spirv.Sampler");
339 case BuiltinType::OCLEvent:
340 return llvm::TargetExtType::get(Ctx,
"spirv.Event");
341 case BuiltinType::OCLClkEvent:
342 return llvm::TargetExtType::get(Ctx,
"spirv.DeviceEvent");
343 case BuiltinType::OCLQueue:
344 return llvm::TargetExtType::get(Ctx,
"spirv.Queue");
345 case BuiltinType::OCLReserveID:
346 return llvm::TargetExtType::get(Ctx,
"spirv.ReserveId");
347 #define INTEL_SUBGROUP_AVC_TYPE(Name, Id) \
348 case BuiltinType::OCLIntelSubgroupAVC##Id: \
349 return llvm::TargetExtType::get(Ctx, "spirv.Avc" #Id "INTEL");
350 #include "clang/Basic/OpenCLExtensionTypes.def"
359 std::unique_ptr<TargetCodeGenInfo>
361 return std::make_unique<CommonSPIRTargetCodeGenInfo>(CGM.
getTypes());
364 std::unique_ptr<TargetCodeGenInfo>
366 return std::make_unique<SPIRVTargetCodeGenInfo>(CGM.
getTypes());
static void setCUDAKernelCallingConvention(CanQualType &FTy, CodeGenModule &CGM, const FunctionDecl *FD)
Set calling convention for CUDA/HIP kernel.
static llvm::Type * getSPIRVImageType(llvm::LLVMContext &Ctx, StringRef BaseType, StringRef OpenCLName, unsigned AccessQualifier)
Construct a SPIR-V target extension type for the given OpenCL image type.
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)
ABIInfo - Target specific hooks for defining how a type should be passed or returned from functions.
@ RAA_DirectInMemory
Pass it on the stack using its defined layout.
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()
ABIArgInfo & getReturnInfo()
This class organizes the cross-function state that is used while generating LLVM code.
const TargetInfo & getTarget() const
CodeGenTypes & getTypes()
llvm::LLVMContext & getLLVMContext()
This class organizes the cross-module state that is used while lowering AST types to LLVM types.
DefaultABIInfo - The default implementation for ABI specific details.
ABIArgInfo classifyArgumentType(QualType RetTy) const
TargetCodeGenInfo - This class organizes various target-specific codegeneration issues,...
ExtInfo withCallingConv(CallingConv cc) const
FunctionType - C99 6.7.5.3 - Function Declarators.
ExtInfo getExtInfo() const
A (possibly-)qualified type.
Represents a struct/union/class.
bool hasFlexibleArrayMember() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
The base class of the type hierarchy.
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.
CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI)
bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, const ABIInfo &Info)
void computeSPIRKernelABIInfo(CodeGenModule &CGM, CGFunctionInfo &FI)
bool isAggregateTypeForABI(QualType T)
const Type * isSingleElementStruct(QualType T, ASTContext &Context)
isSingleElementStruct - Determine if a structure is a "single element struct", i.e.
std::unique_ptr< TargetCodeGenInfo > createSPIRVTargetCodeGenInfo(CodeGenModule &CGM)
QualType useFirstFieldIfTransparentUnion(QualType Ty)
Pass transparent unions as if they were the type of the first element.
std::unique_ptr< TargetCodeGenInfo > createCommonSPIRTargetCodeGenInfo(CodeGenModule &CGM)
bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays, bool AsIfNoUniqueAddr=false)
isEmptyRecord - Return true iff a structure contains only empty fields.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
The JSON file list parser is used to communicate input to InstallAPI.
LangAS
Defines the address space values used by the address space qualifier of QualType.
const FunctionProtoType * T
LangAS getLangASFromTargetAS(unsigned TargetAS)