20#include "llvm/ADT/StringExtras.h"
21#include "llvm/Support/raw_ostream.h"
30handleAMDGPUFlatWorkGroupSizeAttr(
const FunctionDecl *fd, cir::FuncOp func,
32 bool isOpenCLKernel,
bool isHIPKernel) {
33 const auto *flatWGS = fd->
getAttr<AMDGPUFlatWorkGroupSizeAttr>();
37 if (flatWGS || reqdWGS) {
40 min = flatWGS->getMin()
43 max = flatWGS->getMax()
47 if (reqdWGS &&
min == 0 &&
max == 0) {
48 min =
max = reqdWGS->getXDim()
59 assert(
min <=
max &&
"Min must be less than or equal Max");
60 std::string attrVal = llvm::utostr(
min) +
"," + llvm::utostr(
max);
61 func->setAttr(
"cir.amdgpu-flat-work-group-size",
62 builder.getStringAttr(attrVal));
64 assert(
max == 0 &&
"Max must be zero");
66 }
else if (isOpenCLKernel || isHIPKernel) {
69 const unsigned openCLDefaultMaxWorkGroupSize = 256;
70 const unsigned defaultMaxWorkGroupSize =
71 isOpenCLKernel ? openCLDefaultMaxWorkGroupSize
74 std::string(
"1,") + llvm::utostr(defaultMaxWorkGroupSize);
75 func->setAttr(
"cir.amdgpu-flat-work-group-size",
76 builder.getStringAttr(attrVal));
81static void handleAMDGPUWavesPerEUAttr(
const FunctionDecl *fd, cir::FuncOp func,
84 const auto *
attr = fd->
getAttr<AMDGPUWavesPerEUAttr>();
96 assert((
max == 0 ||
min <=
max) &&
"Min must be less than or equal Max");
97 std::string attrVal = llvm::utostr(
min);
99 attrVal = attrVal +
"," + llvm::utostr(
max);
100 func->setAttr(
"cir.amdgpu-waves-per-eu", builder.getStringAttr(attrVal));
102 assert(
max == 0 &&
"Max must be zero");
107static void handleAMDGPUNumSGPRAttr(
const FunctionDecl *fd, cir::FuncOp func,
110 const auto *
attr = fd->
getAttr<AMDGPUNumSGPRAttr>();
116 func->setAttr(
"cir.amdgpu-num-sgpr",
117 builder.getStringAttr(llvm::utostr(numSGPR)));
122static void handleAMDGPUNumVGPRAttr(
const FunctionDecl *fd, cir::FuncOp func,
125 const auto *
attr = fd->
getAttr<AMDGPUNumVGPRAttr>();
131 func->setAttr(
"cir.amdgpu-num-vgpr",
132 builder.getStringAttr(llvm::utostr(numVGPR)));
137static void handleAMDGPUMaxNumWorkGroupsAttr(
const FunctionDecl *fd,
141 const auto *
attr = fd->
getAttr<AMDGPUMaxNumWorkGroupsAttr>();
148 ?
attr->getMaxNumWorkGroupsY()
153 ?
attr->getMaxNumWorkGroupsZ()
159 llvm::raw_svector_ostream os(attrVal);
160 os << x <<
',' << y <<
',' << z;
161 func->setAttr(
"cir.amdgpu-max-num-workgroups",
162 builder.getStringAttr(attrVal.str()));
166static void handleAMDGPUClusterDimsAttr(
const FunctionDecl *fd,
169 bool isOpenCLKernel) {
171 if (
const auto *
attr = fd->
getAttr<CUDAClusterDimsAttr>()) {
172 auto getExprVal = [&](
const Expr *e) {
173 return e ? e->EvaluateKnownConstInt(cgm.
getASTContext()).getExtValue()
176 unsigned x = getExprVal(
attr->getX());
177 unsigned y = getExprVal(
attr->getY());
178 unsigned z = getExprVal(
attr->getZ());
181 llvm::raw_svector_ostream os(attrVal);
182 os << x <<
',' << y <<
',' << z;
183 func->setAttr(
"cir.amdgpu-cluster-dims",
184 builder.getStringAttr(attrVal.str()));
188 if ((isOpenCLKernel &&
191 fd->
hasAttr<CUDANoClusterAttr>()) {
192 func->setAttr(
"cir.amdgpu-cluster-dims", builder.getStringAttr(
"0,0,0"));
197static void handleAMDGPUIEEEAttr(cir::FuncOp func,
CIRGenModule &cgm,
200 func->setAttr(
"cir.amdgpu-ieee", builder.getStringAttr(
"false"));
204static void handleAMDGPUExpandWaitcntProfilingAttr(cir::FuncOp func,
208 func->setAttr(
"cir.amdgpu-expand-waitcnt-profiling",
209 builder.getStringAttr(
""));
217 if (func.isDeclaration())
222 const auto *fd = dyn_cast_or_null<FunctionDecl>(
decl);
224 const bool isOpenCLKernel =
226 const bool isHIPKernel =
229 handleAMDGPUFlatWorkGroupSizeAttr(fd, func, cgm, builder, isOpenCLKernel,
231 handleAMDGPUWavesPerEUAttr(fd, func, cgm, builder);
232 handleAMDGPUNumSGPRAttr(fd, func, cgm, builder);
233 handleAMDGPUNumVGPRAttr(fd, func, cgm, builder);
234 handleAMDGPUMaxNumWorkGroupsAttr(fd, func, cgm, builder);
235 handleAMDGPUClusterDimsAttr(fd, func, cgm, builder, isOpenCLKernel);
237 handleAMDGPUIEEEAttr(func, cgm, builder);
238 handleAMDGPUExpandWaitcntProfilingAttr(func, cgm, builder);
__DEVICE__ int min(int __a, int __b)
__DEVICE__ int max(int __a, int __b)
const TargetInfo & getTargetInfo() const
This class organizes the cross-function state that is used while generating CIR code.
clang::ASTContext & getASTContext() const
CIRGenBuilderTy & getBuilder()
const clang::CodeGenOptions & getCodeGenOpts() const
const clang::LangOptions & getLangOpts() const
This represents one expression.
Represents a function declaration or definition.
Exposes information about the current target.
TargetOptions & getTargetOpts() const
Retrieve the target options.
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.
Defines the clang::TargetInfo interface.
void setAMDGPUTargetFunctionAttributes(const clang::Decl *decl, cir::FuncOp func, CIRGenModule &cgm)
Set AMDGPU-specific function attributes for HIP kernels.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
Top level wrappers for InstallAPI frontend operations.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...