10#include "TargetInfo.h"
13#include "llvm/ADT/StringExtras.h"
14#include "llvm/IR/LLVMContext.h"
15#include "llvm/IR/MemoryModelRelaxationAnnotations.h"
16#include "llvm/Support/AMDGPUAddrSpace.h"
29 static const unsigned MaxNumRegsForArgsRet = 16;
31 uint64_t numRegsForType(QualType Ty)
const;
33 bool isHomogeneousAggregateBaseType(QualType Ty)
const override;
34 bool isHomogeneousAggregateSmallEnough(
const Type *Base,
35 uint64_t Members)
const override;
38 llvm::Type *coerceKernelArgumentType(llvm::Type *Ty,
unsigned FromAS,
39 unsigned ToAS)
const {
41 auto *PtrTy = llvm::dyn_cast<llvm::PointerType>(Ty);
42 if (PtrTy && PtrTy->getAddressSpace() == FromAS)
43 return llvm::PointerType::get(Ty->getContext(), ToAS);
48 explicit AMDGPUABIInfo(CodeGen::CodeGenTypes &CGT) :
49 DefaultABIInfo(CGT) {}
52 ABIArgInfo classifyKernelArgumentType(QualType Ty)
const;
54 unsigned &NumRegsLeft)
const;
56 void computeInfo(CGFunctionInfo &FI)
const override;
57 RValue EmitVAArg(CodeGenFunction &CGF, Address VAListAddr, QualType Ty,
58 AggValueSlot Slot)
const override;
60 llvm::FixedVectorType *
61 getOptimalVectorMemoryType(llvm::FixedVectorType *
T,
62 const LangOptions &Opt)
const override {
66 if (
T->getNumElements() == 3 && getDataLayout().getTypeSizeInBits(
T) == 96)
68 return DefaultABIInfo::getOptimalVectorMemoryType(
T, Opt);
72bool AMDGPUABIInfo::isHomogeneousAggregateBaseType(
QualType Ty)
const {
76bool AMDGPUABIInfo::isHomogeneousAggregateSmallEnough(
77 const Type *Base, uint64_t Members)
const {
78 uint32_t NumRegs = (getContext().getTypeSize(Base) + 31) / 32;
81 return Members * NumRegs <= MaxNumRegsForArgsRet;
85uint64_t AMDGPUABIInfo::numRegsForType(QualType Ty)
const {
88 if (
const VectorType *VT = Ty->
getAs<VectorType>()) {
91 QualType EltTy = VT->getElementType();
92 uint64_t EltSize = getContext().getTypeSize(EltTy);
96 return (VT->getNumElements() + 1) / 2;
98 uint64_t EltNumRegs = (EltSize + 31) / 32;
99 return EltNumRegs * VT->getNumElements();
103 assert(!RD->hasFlexibleArrayMember());
105 for (
const FieldDecl *Field : RD->fields()) {
106 QualType FieldTy =
Field->getType();
107 NumRegs += numRegsForType(FieldTy);
113 return (getContext().getTypeSize(Ty) + 31) / 32;
116void AMDGPUABIInfo::computeInfo(CGFunctionInfo &FI)
const {
122 unsigned ArgumentIndex = 0;
125 unsigned NumRegsLeft = MaxNumRegsForArgsRet;
127 if (CC == llvm::CallingConv::AMDGPU_KERNEL) {
128 Arg.info = classifyKernelArgumentType(Arg.type);
130 bool FixedArgument = ArgumentIndex++ < numFixedArguments;
136RValue AMDGPUABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
137 QualType Ty, AggValueSlot Slot)
const {
138 const bool IsIndirect =
false;
139 const bool AllowHigherAlign =
false;
141 getContext().getTypeInfoInChars(Ty),
145ABIArgInfo AMDGPUABIInfo::classifyReturnType(QualType RetTy)
const {
171 llvm::Type *I32Ty = llvm::Type::getInt32Ty(getVMContext());
175 if (numRegsForType(RetTy) <= MaxNumRegsForArgsRet)
186ABIArgInfo AMDGPUABIInfo::classifyKernelArgumentType(QualType Ty)
const {
192 Ty = QualType(SeltTy, 0);
194 llvm::Type *OrigLTy = CGT.ConvertType(Ty);
195 llvm::Type *LTy = OrigLTy;
196 if (getContext().getLangOpts().
HIP) {
197 LTy = coerceKernelArgumentType(
198 OrigLTy, getContext().getTargetAddressSpace(LangAS::Default),
199 getContext().getTargetAddressSpace(LangAS::cuda_device));
207 getContext().getTypeAlignInChars(Ty),
208 getContext().getTargetAddressSpace(LangAS::opencl_constant),
218ABIArgInfo AMDGPUABIInfo::classifyArgumentType(QualType Ty,
bool Variadic,
219 unsigned &NumRegsLeft)
const {
220 assert(NumRegsLeft <= MaxNumRegsForArgsRet &&
"register estimate underflow");
236 return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
256 unsigned NumRegs = (
Size + 31) / 32;
257 NumRegsLeft -= std::min(NumRegsLeft, NumRegs);
266 llvm::Type *I32Ty = llvm::Type::getInt32Ty(getVMContext());
270 if (NumRegsLeft > 0) {
271 uint64_t NumRegs = numRegsForType(Ty);
272 if (NumRegsLeft >= NumRegs) {
273 NumRegsLeft -= NumRegs;
281 getContext().getTypeAlignInChars(Ty),
282 getContext().getTargetAddressSpace(LangAS::opencl_private));
288 uint64_t NumRegs = numRegsForType(Ty);
289 NumRegsLeft -= std::min(NumRegs, uint64_t{NumRegsLeft});
295class AMDGPUTargetCodeGenInfo :
public TargetCodeGenInfo {
297 AMDGPUTargetCodeGenInfo(CodeGenTypes &CGT)
298 : TargetCodeGenInfo(std::make_unique<AMDGPUABIInfo>(CGT)) {}
300 bool supportsLibCall()
const override {
return false; }
301 void setFunctionDeclAttributes(
const FunctionDecl *FD, llvm::Function *F,
302 CodeGenModule &CGM)
const;
304 void setTargetAttributes(
const Decl *D, llvm::GlobalValue *GV,
305 CodeGen::CodeGenModule &M)
const override;
306 unsigned getDeviceKernelCallingConv()
const override;
308 llvm::Constant *getNullPointer(
const CodeGen::CodeGenModule &CGM,
309 llvm::PointerType *
T, QualType QT)
const override;
311 LangAS getSRetAddrSpace(
const CXXRecordDecl *RD)
const override;
313 LangAS getGlobalVarAddressSpace(CodeGenModule &CGM,
314 const VarDecl *D)
const override;
315 StringRef getLLVMSyncScopeStr(
const LangOptions &LangOpts,
SyncScope Scope,
316 llvm::AtomicOrdering Ordering)
const override;
317 void setTargetAtomicMetadata(CodeGenFunction &CGF,
318 llvm::Instruction &AtomicInst,
319 const AtomicExpr *Expr =
nullptr)
const override;
320 llvm::Value *createEnqueuedBlockKernel(CodeGenFunction &CGF,
321 llvm::Function *BlockInvokeFunc,
322 llvm::Type *BlockTy)
const override;
323 bool shouldEmitStaticExternCAliases()
const override;
324 bool shouldEmitDWARFBitFieldSeparators()
const override;
329void AMDGPUTargetCodeGenInfo::setFunctionDeclAttributes(
330 const FunctionDecl *FD, llvm::Function *F, CodeGenModule &M)
const {
331 const auto *ReqdWGS =
333 const bool IsOpenCLKernel =
337 const auto *FlatWGS = FD->
getAttr<AMDGPUFlatWorkGroupSizeAttr>();
343 const auto *LaunchBounds =
345 unsigned LBMaxThreads = 0;
346 unsigned LBMinWaves = 0;
348 LBMaxThreads = LaunchBounds->getMaxThreads()
351 if (
const Expr *MinBlocks = LaunchBounds->getMinBlocks()) {
353 MinBlocks->EvaluateKnownConstInt(M.
getContext()).getExtValue();
357 if (ReqdWGS || FlatWGS) {
359 }
else if (LBMaxThreads > 0) {
360 F->addFnAttr(
"amdgpu-flat-work-group-size",
361 "1," + llvm::utostr(LBMaxThreads));
362 }
else if (IsOpenCLKernel || IsHIPKernel) {
365 const unsigned OpenCLDefaultMaxWorkGroupSize = 256;
366 const unsigned DefaultMaxWorkGroupSize =
367 IsOpenCLKernel ? OpenCLDefaultMaxWorkGroupSize
369 std::string AttrVal =
370 std::string(
"1,") + llvm::utostr(DefaultMaxWorkGroupSize);
371 F->addFnAttr(
"amdgpu-flat-work-group-size", AttrVal);
374 if (
const auto *Attr = FD->
getAttr<AMDGPUWavesPerEUAttr>()) {
376 }
else if (LBMinWaves > 0) {
381 F->addFnAttr(
"amdgpu-waves-per-eu", llvm::utostr(LBMinWaves));
384 if (
const auto *Attr = FD->
getAttr<AMDGPUNumSGPRAttr>()) {
385 unsigned NumSGPR = Attr->getNumSGPR();
388 F->addFnAttr(
"amdgpu-num-sgpr", llvm::utostr(NumSGPR));
391 if (
const auto *Attr = FD->
getAttr<AMDGPUNumVGPRAttr>()) {
392 uint32_t NumVGPR = Attr->getNumVGPR();
395 F->addFnAttr(
"amdgpu-num-vgpr", llvm::utostr(NumVGPR));
398 if (
const auto *Attr = FD->
getAttr<AMDGPUMaxNumWorkGroupsAttr>()) {
399 uint32_t X = Attr->getMaxNumWorkGroupsX()
403 uint32_t Y = Attr->getMaxNumWorkGroupsY()
404 ? Attr->getMaxNumWorkGroupsY()
408 uint32_t Z = Attr->getMaxNumWorkGroupsZ()
409 ? Attr->getMaxNumWorkGroupsZ()
414 llvm::SmallString<32> AttrVal;
415 llvm::raw_svector_ostream
OS(AttrVal);
416 OS <<
X <<
',' << Y <<
',' << Z;
418 F->addFnAttr(
"amdgpu-max-num-workgroups", AttrVal.str());
421 if (
auto *Attr = FD->
getAttr<CUDAClusterDimsAttr>()) {
422 auto GetExprVal = [&](
const auto &E) {
423 return E ? E->EvaluateKnownConstInt(M.
getContext()).getExtValue() : 1;
425 unsigned X = GetExprVal(Attr->getX());
426 unsigned Y = GetExprVal(Attr->getY());
427 unsigned Z = GetExprVal(Attr->getZ());
428 llvm::SmallString<32> AttrVal;
429 llvm::raw_svector_ostream
OS(AttrVal);
430 OS <<
X <<
',' << Y <<
',' << Z;
431 F->addFnAttr(
"amdgpu-cluster-dims", AttrVal.str());
436 if ((IsOpenCLKernel &&
438 FD->
hasAttr<CUDANoClusterAttr>())
439 F->addFnAttr(
"amdgpu-cluster-dims",
"0,0,0");
442void AMDGPUTargetCodeGenInfo::setTargetAttributes(
443 const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M)
const {
445 D, GV->getVisibility() == llvm::GlobalValue::HiddenVisibility)) {
446 GV->setVisibility(llvm::GlobalValue::ProtectedVisibility);
447 GV->setDSOLocal(
true);
450 if (GV->isDeclaration())
453 llvm::Function *F = dyn_cast<llvm::Function>(GV);
457 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
459 setFunctionDeclAttributes(FD, F, M);
460 if (!getABIInfo().getCodeGenOpts().EmitIEEENaNCompliantInsts)
461 F->addFnAttr(
"amdgpu-ieee",
"false");
462 if (getABIInfo().getCodeGenOpts().AMDGPUExpandWaitcntProfiling)
463 F->addFnAttr(
"amdgpu-expand-waitcnt-profiling");
466unsigned AMDGPUTargetCodeGenInfo::getDeviceKernelCallingConv()
const {
467 return llvm::CallingConv::AMDGPU_KERNEL;
475llvm::Constant *AMDGPUTargetCodeGenInfo::getNullPointer(
476 const CodeGen::CodeGenModule &CGM, llvm::PointerType *PT,
479 return llvm::ConstantPointerNull::get(PT);
482 auto NPT = llvm::PointerType::get(
483 PT->getContext(), Ctx.getTargetAddressSpace(LangAS::opencl_generic));
484 return llvm::ConstantExpr::getAddrSpaceCast(
485 llvm::ConstantPointerNull::get(NPT), PT);
489AMDGPUTargetCodeGenInfo::getSRetAddrSpace(
const CXXRecordDecl *RD)
const {
493 return LangAS::Default;
495 getABIInfo().getDataLayout().getAllocaAddrSpace());
499AMDGPUTargetCodeGenInfo::getGlobalVarAddressSpace(CodeGenModule &CGM,
500 const VarDecl *D)
const {
503 "Address space agnostic languages only");
507 return DefaultGlobalAS;
510 if (AddrSpace != LangAS::Default)
519 return DefaultGlobalAS;
522StringRef AMDGPUTargetCodeGenInfo::getLLVMSyncScopeStr(
523 const LangOptions &LangOpts,
SyncScope Scope,
524 llvm::AtomicOrdering Ordering)
const {
528 bool IsOneAs = (Scope >= SyncScope::OpenCLWorkGroup &&
529 Scope <= SyncScope::OpenCLSubGroup &&
530 Ordering != llvm::AtomicOrdering::SequentiallyConsistent);
533 assert((AS != llvm::AtomicScope::Cluster || !IsOneAs) &&
534 "OpenCL does not have cluster scope");
535 return *llvm::getAtomicScopeIRString(getABIInfo().getTarget().
getTriple(), AS,
539void AMDGPUTargetCodeGenInfo::setTargetAtomicMetadata(
540 CodeGenFunction &CGF, llvm::Instruction &AtomicInst,
541 const AtomicExpr *AE)
const {
542 auto *RMW = dyn_cast<llvm::AtomicRMWInst>(&AtomicInst);
543 auto *CmpX = dyn_cast<llvm::AtomicCmpXchgInst>(&AtomicInst);
550 if (((RMW && RMW->getPointerAddressSpace() == llvm::AMDGPUAS::FLAT_ADDRESS) ||
552 CmpX->getPointerAddressSpace() == llvm::AMDGPUAS::FLAT_ADDRESS)) &&
555 llvm::MDNode *ASRange = MDHelper.createRange(
556 llvm::APInt(32, llvm::AMDGPUAS::PRIVATE_ADDRESS),
557 llvm::APInt(32, llvm::AMDGPUAS::PRIVATE_ADDRESS + 1));
558 AtomicInst.setMetadata(llvm::LLVMContext::MD_noalias_addrspace, ASRange);
569 RMW->setMetadata(
"amdgpu.no.fine.grained.memory",
Empty);
571 RMW->setMetadata(
"amdgpu.no.remote.memory",
Empty);
576bool AMDGPUTargetCodeGenInfo::shouldEmitStaticExternCAliases()
const {
580bool AMDGPUTargetCodeGenInfo::shouldEmitDWARFBitFieldSeparators()
const {
584void AMDGPUTargetCodeGenInfo::setCUDAKernelCallingConvention(
585 const FunctionType *&FT)
const {
586 FT = getABIInfo().getContext().adjustFunctionType(
596static llvm::StructType *
598 llvm::Type *KernelDescriptorPtrTy) {
599 llvm::Type *Int32 = llvm::Type::getInt32Ty(
C);
600 return llvm::StructType::create(
C, {KernelDescriptorPtrTy, Int32, Int32},
601 "block.runtime.handle.t");
612llvm::Value *AMDGPUTargetCodeGenInfo::createEnqueuedBlockKernel(
613 CodeGenFunction &CGF, llvm::Function *Invoke, llvm::Type *BlockTy)
const {
617 auto *InvokeFT = Invoke->getFunctionType();
618 llvm::SmallVector<llvm::Type *, 2> ArgTys;
619 llvm::SmallVector<llvm::Metadata *, 8> AddressQuals;
620 llvm::SmallVector<llvm::Metadata *, 8> AccessQuals;
621 llvm::SmallVector<llvm::Metadata *, 8> ArgTypeNames;
622 llvm::SmallVector<llvm::Metadata *, 8> ArgBaseTypeNames;
623 llvm::SmallVector<llvm::Metadata *, 8> ArgTypeQuals;
624 llvm::SmallVector<llvm::Metadata *, 8> ArgNames;
626 ArgTys.push_back(BlockTy);
627 ArgTypeNames.push_back(llvm::MDString::get(
C,
"__block_literal"));
628 AddressQuals.push_back(llvm::ConstantAsMetadata::get(Builder.getInt32(0)));
629 ArgBaseTypeNames.push_back(llvm::MDString::get(
C,
"__block_literal"));
630 ArgTypeQuals.push_back(llvm::MDString::get(
C,
""));
631 AccessQuals.push_back(llvm::MDString::get(
C,
"none"));
632 ArgNames.push_back(llvm::MDString::get(
C,
"block_literal"));
633 for (
unsigned I = 1, E = InvokeFT->getNumParams(); I < E; ++I) {
634 ArgTys.push_back(InvokeFT->getParamType(I));
635 ArgTypeNames.push_back(llvm::MDString::get(
C,
"void*"));
636 AddressQuals.push_back(llvm::ConstantAsMetadata::get(Builder.getInt32(3)));
637 AccessQuals.push_back(llvm::MDString::get(
C,
"none"));
638 ArgBaseTypeNames.push_back(llvm::MDString::get(
C,
"void*"));
639 ArgTypeQuals.push_back(llvm::MDString::get(
C,
""));
641 llvm::MDString::get(
C, (Twine(
"local_arg") + Twine(I)).str()));
645 const llvm::DataLayout &DL = Mod.getDataLayout();
647 llvm::Twine Name = Invoke->getName() +
"_kernel";
648 auto *FT = llvm::FunctionType::get(llvm::Type::getVoidTy(
C), ArgTys,
false);
652 auto *F = llvm::Function::Create(FT, llvm::GlobalValue::InternalLinkage, Name,
654 F->setCallingConv(getDeviceKernelCallingConv());
656 llvm::AttrBuilder KernelAttrs(
C);
660 F->addFnAttrs(KernelAttrs);
662 auto IP = CGF.
Builder.saveIP();
663 auto *BB = llvm::BasicBlock::Create(
C,
"entry", F);
664 Builder.SetInsertPoint(BB);
665 const auto BlockAlign = DL.getPrefTypeAlign(BlockTy);
666 auto *BlockPtr = Builder.CreateAlloca(BlockTy,
nullptr);
667 BlockPtr->setAlignment(BlockAlign);
668 Builder.CreateAlignedStore(F->arg_begin(), BlockPtr, BlockAlign);
669 auto *
Cast = Builder.CreatePointerCast(BlockPtr, InvokeFT->getParamType(0));
670 llvm::SmallVector<llvm::Value *, 2> Args;
671 Args.push_back(Cast);
672 for (llvm::Argument &A : llvm::drop_begin(F->args()))
674 llvm::CallInst *call = Builder.CreateCall(Invoke, Args);
675 call->setCallingConv(Invoke->getCallingConv());
676 Builder.CreateRetVoid();
677 Builder.restoreIP(IP);
679 F->setMetadata(
"kernel_arg_addr_space", llvm::MDNode::get(
C, AddressQuals));
680 F->setMetadata(
"kernel_arg_access_qual", llvm::MDNode::get(
C, AccessQuals));
681 F->setMetadata(
"kernel_arg_type", llvm::MDNode::get(
C, ArgTypeNames));
682 F->setMetadata(
"kernel_arg_base_type",
683 llvm::MDNode::get(
C, ArgBaseTypeNames));
684 F->setMetadata(
"kernel_arg_type_qual", llvm::MDNode::get(
C, ArgTypeQuals));
686 F->setMetadata(
"kernel_arg_name", llvm::MDNode::get(
C, ArgNames));
689 C, llvm::PointerType::get(
C, DL.getDefaultGlobalsAddressSpace()));
690 llvm::Constant *RuntimeHandleInitializer =
691 llvm::ConstantAggregateZero::get(HandleTy);
693 llvm::Twine RuntimeHandleName = F->getName() +
".runtime.handle";
704 auto *RuntimeHandle =
new llvm::GlobalVariable(
706 true, llvm::GlobalValue::InternalLinkage,
707 RuntimeHandleInitializer, RuntimeHandleName,
708 nullptr, llvm::GlobalValue::NotThreadLocal,
709 DL.getDefaultGlobalsAddressSpace(),
712 llvm::MDNode *HandleAsMD =
713 llvm::MDNode::get(
C, llvm::ValueAsMetadata::get(RuntimeHandle));
714 F->setMetadata(llvm::LLVMContext::MD_associated, HandleAsMD);
716 RuntimeHandle->setSection(
".amdgpu.kernel.runtime.handle");
720 return RuntimeHandle;
724 llvm::Function *F,
const AMDGPUFlatWorkGroupSizeAttr *FlatWGS,
725 const ReqdWorkGroupSizeAttr *ReqdWGS, int32_t *MinThreadsVal,
726 int32_t *MaxThreadsVal) {
729 auto Eval = [&](
Expr *E) {
730 return E->EvaluateKnownConstInt(
getContext()).getExtValue();
733 Min =
Max = Eval(ReqdWGS->getXDim()) * Eval(ReqdWGS->getYDim()) *
734 Eval(ReqdWGS->getZDim());
735 }
else if (FlatWGS) {
736 Min = Eval(FlatWGS->getMin());
737 Max = Eval(FlatWGS->getMax());
740 if (
Min != 0 || ReqdWGS) {
741 assert(
Min <=
Max &&
"Min must be less than or equal Max");
744 *MinThreadsVal =
Min;
746 *MaxThreadsVal =
Max;
747 std::string AttrVal = llvm::utostr(
Min) +
"," + llvm::utostr(
Max);
749 F->addFnAttr(
"amdgpu-flat-work-group-size", AttrVal);
751 assert(
Max == 0 &&
"Max must be zero");
755 llvm::Function *F,
const AMDGPUWavesPerEUAttr *
Attr) {
757 Attr->getMin()->EvaluateKnownConstInt(
getContext()).getExtValue();
760 ?
Attr->getMax()->EvaluateKnownConstInt(
getContext()).getExtValue()
764 assert((
Max == 0 ||
Min <=
Max) &&
"Min must be less than or equal Max");
766 std::string AttrVal = llvm::utostr(
Min);
768 AttrVal = AttrVal +
"," + llvm::utostr(
Max);
769 F->addFnAttr(
"amdgpu-waves-per-eu", AttrVal);
771 assert(
Max == 0 &&
"Max must be zero");
774std::unique_ptr<TargetCodeGenInfo>
776 return std::make_unique<AMDGPUTargetCodeGenInfo>(CGM.
getTypes());
static void setCUDAKernelCallingConvention(CanQualType &funcTy, CIRGenModule &cgm, const FunctionDecl *fd)
Set calling convention for CUDA/HIP kernel.
static llvm::StructType * getAMDGPURuntimeHandleType(llvm::LLVMContext &C, llvm::Type *KernelDescriptorPtrTy)
Return IR struct type for rtinfo struct in rocm-device-libs used for device enqueue.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
static StringRef getTriple(const Command &Job)
uint64_t getTargetNullPointerValue(QualType QT) const
Get target-dependent integer value for null pointer which is used for constant folding.
const TargetInfo & getTargetInfo() const
unsigned getTargetAddressSpace(LangAS AS) const
bool threadPrivateMemoryAtomicsAreUndefined() const
Return true if atomics operations targeting allocations in private memory are undefined.
Attr - This represents one attribute.
static CharUnits fromQuantity(QuantityType Quantity)
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 getIndirectAliased(CharUnits Alignment, unsigned AddrSpace, bool Realign=false, llvm::Type *Padding=nullptr)
Pass this in memory using the IR byref attribute.
@ RAA_DirectInMemory
Pass it on the stack using its defined layout.
ABIArgInfo & getReturnInfo()
unsigned getCallingConvention() const
getCallingConvention - Return the user specified calling convention, which has been translated into a...
CanQualType getReturnType() const
MutableArrayRef< ArgInfo > arguments()
unsigned getNumRequiredArgs() const
void AddAMDGPUAvailableVisibleMMRA(llvm::Instruction *Inst)
Attach the AMDGPU availability/visibility MMRA to Inst when the amdgpu_av attribute is active on the ...
llvm::LLVMContext & getLLVMContext()
This class organizes the cross-function state that is used while generating LLVM code.
llvm::Module & getModule() const
void handleAMDGPUWavesPerEUAttr(llvm::Function *F, const AMDGPUWavesPerEUAttr *A)
Emit the IR encoding to attach the AMD GPU waves-per-eu attribute to F.
const LangOptions & getLangOpts() const
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
void addUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.used metadata.
void handleAMDGPUFlatWorkGroupSizeAttr(llvm::Function *F, const AMDGPUFlatWorkGroupSizeAttr *A, const ReqdWorkGroupSizeAttr *ReqdWGS=nullptr, int32_t *MinThreadsVal=nullptr, int32_t *MaxThreadsVal=nullptr)
Emit the IR encoding to attach the AMD GPU flat-work-group-size attribute to F.
AtomicOptions getAtomicOpts()
Get the current Atomic options.
ASTContext & getContext() const
const CodeGenOptions & getCodeGenOpts() const
void addDefaultFunctionDefinitionAttributes(llvm::AttrBuilder &attrs)
Like the overload taking a Function &, but intended specifically for frontends that want to build on ...
DefaultABIInfo - The default implementation for ABI specific details.
ABIArgInfo classifyArgumentType(QualType RetTy) const
ABIArgInfo classifyReturnType(QualType RetTy) const
This represents one expression.
ExtInfo withCallingConv(CallingConv cc) const
ExtInfo getExtInfo() const
A (possibly-)qualified type.
LangAS getAddressSpace() const
Return the address space of this type.
bool isConstantStorage(const ASTContext &Ctx, bool ExcludeCtor, bool ExcludeDtor)
bool canPassInRegisters() const
Determine whether this class can be passed in registers.
bool hasFlexibleArrayMember() const
TargetOptions & getTargetOpts() const
Retrieve the target options.
virtual std::optional< LangAS > getConstantAddressSpace() const
Return an AST address space which can be used opportunistically for constant global memory.
virtual bool hasFeatureEnabled(const llvm::StringMap< bool > &Features, StringRef Name) const
Check if target has a given feature enabled.
llvm::StringMap< bool > FeatureMap
The map of which features have been enabled disabled based on the command line.
RecordDecl * getAsRecordDecl() const
Retrieves the RecordDecl this type refers to.
const T * getAs() const
Member-template getAs<specific type>'.
bool hasConstantInitialization() const
Determine whether this variable has constant initialization.
bool requiresAMDGPUProtectedVisibility(const Decl *D, bool HasHiddenVisibility)
Returns whether D must be given protected visibility on AMDGPU.
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 ...
CGCXXABI::RecordArgABI getRecordArgABI(const RecordType *RT, CGCXXABI &CXXABI)
bool classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI, const ABIInfo &Info)
std::unique_ptr< TargetCodeGenInfo > createAMDGPUTargetCodeGenInfo(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 ...
const Type * isSingleElementRecord(QualType T, ASTContext &Context)
isSingleElementRecord - Determine if a record is a "singleelement record", i.e.
void addAtomicIgnoreDenormalModeMetadata(CodeGenFunction &CGF, llvm::Instruction &AtomicInst, bool AllowHalf=false)
Attach !atomic.ignore.denormal.mode to AtomicInst, if it is an atomicrmw the metadata is meaningful f...
bool isAggregateTypeForABI(QualType T)
QualType useFirstFieldIfTransparentUnion(QualType Ty)
Pass transparent unions as if they were the type of the first element.
bool isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays, bool AsIfNoUniqueAddr=false)
isEmptyRecord - Return true iff a structure contains only empty fields.
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
bool Cast(InterpState &S, CodePtr OpPC)
Top level wrappers for InstallAPI frontend operations.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
const FunctionProtoType * T
LangAS
Defines the address space values used by the address space qualifier of QualType.
llvm::AtomicScope getAtomicScope(SyncScope S)
Collapses a clang sync scope onto the target-neutral llvm::AtomicScope.
SyncScope
Defines sync scope values used internally by clang.
LangAS getLangASFromTargetAS(unsigned TargetAS)
bool getOption(AtomicOptionKind Kind) const