Skip to content

Commit 3b9ebe9

Browse files
authored
[clang] Simplify device kernel attributes (llvm#137882)
We have multiple different attributes in clang representing device kernels for specific targets/languages. Refactor them into one attribute with different spellings to make it more easily scalable for new languages/targets. --------- Signed-off-by: Sarnie, Nick <[email protected]>
1 parent b2379bd commit 3b9ebe9

38 files changed

+255
-172
lines changed

clang-tools-extra/clang-tidy/altera/SingleWorkItemBarrierCheck.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,14 @@ namespace clang::tidy::altera {
1616

1717
void SingleWorkItemBarrierCheck::registerMatchers(MatchFinder *Finder) {
1818
// Find any function that calls barrier but does not call an ID function.
19-
// hasAttr(attr::Kind::OpenCLKernel) restricts it to only kernel functions.
19+
// hasAttr(attr::Kind::DeviceKernel) restricts it to only kernel functions.
2020
// FIXME: Have it accept all functions but check for a parameter that gets an
2121
// ID from one of the four ID functions.
2222
Finder->addMatcher(
2323
// Find function declarations...
2424
functionDecl(
25-
// That are OpenCL kernels...
26-
hasAttr(attr::Kind::OpenCLKernel),
25+
// That are device kernels...
26+
hasAttr(attr::Kind::DeviceKernel),
2727
// And call a barrier function (either 1.x or 2.x version)...
2828
forEachDescendant(callExpr(callee(functionDecl(hasAnyName(
2929
"barrier", "work_group_barrier"))))

clang/include/clang/AST/GlobalDecl.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ class GlobalDecl {
164164
}
165165

166166
static KernelReferenceKind getDefaultKernelReference(const FunctionDecl *D) {
167-
return (D->hasAttr<OpenCLKernelAttr>() || D->getLangOpts().CUDAIsDevice)
167+
return (D->hasAttr<DeviceKernelAttr>() || D->getLangOpts().CUDAIsDevice)
168168
? KernelReferenceKind::Kernel
169169
: KernelReferenceKind::Stub;
170170
}

clang/include/clang/Basic/Attr.td

Lines changed: 50 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,10 @@ def FunctionPointer : SubsetSubject<DeclBase,
196196
"functions pointers">;
197197

198198
def OpenCLKernelFunction
199-
: SubsetSubject<Function, [{S->hasAttr<OpenCLKernelAttr>()}],
200-
"kernel functions">;
199+
: SubsetSubject<Function, [{S->getASTContext().getLangOpts().OpenCL &&
200+
DeviceKernelAttr::isOpenCLSpelling(
201+
S->getAttr<DeviceKernelAttr>()}],
202+
"kernel functions">;
201203

202204
// HasFunctionProto is a more strict version of FunctionLike, so it should
203205
// never be specified in a Subjects list along with FunctionLike (due to the
@@ -1515,12 +1517,6 @@ def CUDAGridConstant : InheritableAttr {
15151517
let Documentation = [CUDAGridConstantAttrDocs];
15161518
}
15171519

1518-
def NVPTXKernel : InheritableAttr, TargetSpecificAttr<TargetNVPTX> {
1519-
let Spellings = [Clang<"nvptx_kernel">];
1520-
let Subjects = SubjectList<[Function]>;
1521-
let Documentation = [Undocumented];
1522-
}
1523-
15241520
def HIPManaged : InheritableAttr {
15251521
let Spellings = [GNU<"managed">, Declspec<"__managed__">];
15261522
let Subjects = SubjectList<[Var]>;
@@ -1555,11 +1551,52 @@ def CUDAShared : InheritableAttr {
15551551
}
15561552
def : MutualExclusions<[CUDAConstant, CUDAShared, HIPManaged]>;
15571553

1558-
def SYCLKernel : InheritableAttr {
1559-
let Spellings = [Clang<"sycl_kernel">];
1560-
let Subjects = SubjectList<[FunctionTmpl]>;
1561-
let LangOpts = [SYCLDevice];
1562-
let Documentation = [SYCLKernelDocs];
1554+
def DeviceKernel : DeclOrTypeAttr {
1555+
let Spellings = [Clang<"device_kernel">, Clang<"sycl_kernel">,
1556+
Clang<"nvptx_kernel">, Clang<"amdgpu_kernel">,
1557+
CustomKeyword<"__kernel">, CustomKeyword<"kernel">];
1558+
let Documentation = [DeviceKernelDocs];
1559+
let AdditionalMembers =
1560+
[{
1561+
static inline bool isAMDGPUSpelling(const AttributeCommonInfo& A) {
1562+
return A.getAttributeSpellingListIndex() == GNU_amdgpu_kernel ||
1563+
A.getAttributeSpellingListIndex() == CXX11_clang_amdgpu_kernel ||
1564+
A.getAttributeSpellingListIndex() == C23_clang_amdgpu_kernel;
1565+
}
1566+
static inline bool isAMDGPUSpelling(const AttributeCommonInfo* A) {
1567+
if(!A) return false;
1568+
return isAMDGPUSpelling(*A);
1569+
}
1570+
static inline bool isNVPTXSpelling(const AttributeCommonInfo& A) {
1571+
return A.getAttributeSpellingListIndex() == GNU_nvptx_kernel ||
1572+
A.getAttributeSpellingListIndex() == CXX11_clang_nvptx_kernel ||
1573+
A.getAttributeSpellingListIndex() == C23_clang_nvptx_kernel;
1574+
}
1575+
static inline bool isNVPTXSpelling(const AttributeCommonInfo* A) {
1576+
if(!A) return false;
1577+
return isNVPTXSpelling(*A);
1578+
}
1579+
static inline bool isSYCLSpelling(const AttributeCommonInfo& A) {
1580+
return A.getAttributeSpellingListIndex() == GNU_sycl_kernel ||
1581+
A.getAttributeSpellingListIndex() == CXX11_clang_sycl_kernel ||
1582+
A.getAttributeSpellingListIndex() == C23_clang_sycl_kernel;
1583+
}
1584+
static inline bool isSYCLSpelling(const AttributeCommonInfo* A) {
1585+
if(!A) return false;
1586+
return isSYCLSpelling(*A);
1587+
}
1588+
static inline bool isOpenCLSpelling(const AttributeCommonInfo& A) {
1589+
// Tablegen trips underscores from spellings to build the spelling
1590+
// list, but here we have the same spelling with unscores and without,
1591+
// so handle that case manually.
1592+
return A.getAttributeSpellingListIndex() == Keyword_kernel ||
1593+
A.getAttrName()->getName() == "kernel";
1594+
}
1595+
static inline bool isOpenCLSpelling(const AttributeCommonInfo* A) {
1596+
if (!A) return false;
1597+
return isOpenCLSpelling(*A);
1598+
}
1599+
}];
15631600
}
15641601

15651602
def SYCLKernelEntryPoint : InheritableAttr {
@@ -1625,15 +1662,6 @@ def Allocating : TypeAttr {
16251662
let Documentation = [AllocatingDocs];
16261663
}
16271664

1628-
// Similar to CUDA, OpenCL attributes do not receive a [[]] spelling because
1629-
// the specification does not expose them with one currently.
1630-
def OpenCLKernel : InheritableAttr {
1631-
let Spellings = [CustomKeyword<"__kernel">, CustomKeyword<"kernel">];
1632-
let Subjects = SubjectList<[Function], ErrorDiag>;
1633-
let Documentation = [Undocumented];
1634-
let SimpleHandler = 1;
1635-
}
1636-
16371665
def OpenCLUnrollHint : StmtAttr {
16381666
let Spellings = [GNU<"opencl_unroll_hint">];
16391667
let Subjects = SubjectList<[ForStmt, CXXForRangeStmt, WhileStmt, DoStmt],
@@ -2370,11 +2398,6 @@ def AMDGPUMaxNumWorkGroups : InheritableAttr {
23702398
let Subjects = SubjectList<[Function], ErrorDiag, "kernel functions">;
23712399
}
23722400

2373-
def AMDGPUKernelCall : DeclOrTypeAttr {
2374-
let Spellings = [Clang<"amdgpu_kernel">];
2375-
let Documentation = [Undocumented];
2376-
}
2377-
23782401
def BPFPreserveAccessIndex : InheritableAttr,
23792402
TargetSpecificAttr<TargetBPF> {
23802403
let Spellings = [Clang<"preserve_access_index">];

clang/include/clang/Basic/AttrDocs.td

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -396,9 +396,13 @@ any option of a multiversioned function is undefined.
396396
}];
397397
}
398398

399-
def SYCLKernelDocs : Documentation {
399+
def DeviceKernelDocs : Documentation {
400400
let Category = DocCatFunction;
401+
let Heading = "device_kernel, sycl_kernel, nvptx_kernel, amdgpu_kernel, "
402+
"kernel, __kernel";
401403
let Content = [{
404+
These attributes specify that the function represents a kernel for device offloading.
405+
The specific semantics depend on the offloading language, target, and attribute spelling.
402406
The ``sycl_kernel`` attribute specifies that a function template will be used
403407
to outline device code and to generate an OpenCL kernel.
404408
Here is a code example of the SYCL program, which demonstrates the compiler's

clang/include/clang/Basic/Specifiers.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -289,14 +289,13 @@ namespace clang {
289289
CC_AAPCS_VFP, // __attribute__((pcs("aapcs-vfp")))
290290
CC_IntelOclBicc, // __attribute__((intel_ocl_bicc))
291291
CC_SpirFunction, // default for OpenCL functions on SPIR target
292-
CC_OpenCLKernel, // inferred for OpenCL kernels
292+
CC_DeviceKernel, // __attribute__((device_kernel))
293293
CC_Swift, // __attribute__((swiftcall))
294294
CC_SwiftAsync, // __attribute__((swiftasynccall))
295295
CC_PreserveMost, // __attribute__((preserve_most))
296296
CC_PreserveAll, // __attribute__((preserve_all))
297297
CC_AArch64VectorCall, // __attribute__((aarch64_vector_pcs))
298298
CC_AArch64SVEPCS, // __attribute__((aarch64_sve_pcs))
299-
CC_AMDGPUKernelCall, // __attribute__((amdgpu_kernel))
300299
CC_M68kRTD, // __attribute__((m68k_rtd))
301300
CC_PreserveNone, // __attribute__((preserve_none))
302301
CC_RISCVVectorCall, // __attribute__((riscv_vector_cc))
@@ -326,7 +325,7 @@ namespace clang {
326325
case CC_X86Pascal:
327326
case CC_X86VectorCall:
328327
case CC_SpirFunction:
329-
case CC_OpenCLKernel:
328+
case CC_DeviceKernel:
330329
case CC_Swift:
331330
case CC_SwiftAsync:
332331
case CC_M68kRTD:

clang/lib/AST/Decl.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3541,7 +3541,7 @@ bool FunctionDecl::isExternC() const {
35413541
}
35423542

35433543
bool FunctionDecl::isInExternCContext() const {
3544-
if (hasAttr<OpenCLKernelAttr>())
3544+
if (DeviceKernelAttr::isOpenCLSpelling(getAttr<DeviceKernelAttr>()))
35453545
return true;
35463546
return getLexicalDeclContext()->isExternCContext();
35473547
}
@@ -5510,7 +5510,8 @@ FunctionDecl *FunctionDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
55105510
}
55115511

55125512
bool FunctionDecl::isReferenceableKernel() const {
5513-
return hasAttr<CUDAGlobalAttr>() || hasAttr<OpenCLKernelAttr>();
5513+
return hasAttr<CUDAGlobalAttr>() ||
5514+
DeviceKernelAttr::isOpenCLSpelling(getAttr<DeviceKernelAttr>());
55145515
}
55155516

55165517
BlockDecl *BlockDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) {

clang/lib/AST/ItaniumMangle.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1557,7 +1557,8 @@ void CXXNameMangler::mangleUnqualifiedName(
15571557
FD && FD->hasAttr<CUDAGlobalAttr>() &&
15581558
GD.getKernelReferenceKind() == KernelReferenceKind::Stub;
15591559
bool IsOCLDeviceStub =
1560-
FD && FD->hasAttr<OpenCLKernelAttr>() &&
1560+
FD &&
1561+
DeviceKernelAttr::isOpenCLSpelling(FD->getAttr<DeviceKernelAttr>()) &&
15611562
GD.getKernelReferenceKind() == KernelReferenceKind::Stub;
15621563
if (IsDeviceStub)
15631564
mangleDeviceStubName(II);
@@ -3532,10 +3533,9 @@ StringRef CXXNameMangler::getCallingConvQualifierName(CallingConv CC) {
35323533
case CC_AAPCS_VFP:
35333534
case CC_AArch64VectorCall:
35343535
case CC_AArch64SVEPCS:
3535-
case CC_AMDGPUKernelCall:
35363536
case CC_IntelOclBicc:
35373537
case CC_SpirFunction:
3538-
case CC_OpenCLKernel:
3538+
case CC_DeviceKernel:
35393539
case CC_PreserveMost:
35403540
case CC_PreserveAll:
35413541
case CC_M68kRTD:

clang/lib/AST/MicrosoftMangle.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1164,7 +1164,9 @@ void MicrosoftCXXNameMangler::mangleUnqualifiedName(GlobalDecl GD,
11641164
->hasAttr<CUDAGlobalAttr>())) &&
11651165
GD.getKernelReferenceKind() == KernelReferenceKind::Stub;
11661166
bool IsOCLDeviceStub =
1167-
ND && isa<FunctionDecl>(ND) && ND->hasAttr<OpenCLKernelAttr>() &&
1167+
ND && isa<FunctionDecl>(ND) &&
1168+
DeviceKernelAttr::isOpenCLSpelling(
1169+
ND->getAttr<DeviceKernelAttr>()) &&
11681170
GD.getKernelReferenceKind() == KernelReferenceKind::Stub;
11691171
if (IsDeviceStub)
11701172
mangleSourceName(

clang/lib/AST/Type.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3606,14 +3606,12 @@ StringRef FunctionType::getNameForCallConv(CallingConv CC) {
36063606
return "aarch64_vector_pcs";
36073607
case CC_AArch64SVEPCS:
36083608
return "aarch64_sve_pcs";
3609-
case CC_AMDGPUKernelCall:
3610-
return "amdgpu_kernel";
36113609
case CC_IntelOclBicc:
36123610
return "intel_ocl_bicc";
36133611
case CC_SpirFunction:
36143612
return "spir_function";
3615-
case CC_OpenCLKernel:
3616-
return "opencl_kernel";
3613+
case CC_DeviceKernel:
3614+
return "device_kernel";
36173615
case CC_Swift:
36183616
return "swiftcall";
36193617
case CC_SwiftAsync:
@@ -4328,7 +4326,7 @@ bool AttributedType::isCallingConv() const {
43284326
case attr::VectorCall:
43294327
case attr::AArch64VectorPcs:
43304328
case attr::AArch64SVEPcs:
4331-
case attr::AMDGPUKernelCall:
4329+
case attr::DeviceKernel:
43324330
case attr::Pascal:
43334331
case attr::MSABI:
43344332
case attr::SysVABI:

clang/lib/AST/TypePrinter.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1100,8 +1100,8 @@ void TypePrinter::printFunctionAfter(const FunctionType::ExtInfo &Info,
11001100
case CC_AArch64SVEPCS:
11011101
OS << "__attribute__((aarch64_sve_pcs))";
11021102
break;
1103-
case CC_AMDGPUKernelCall:
1104-
OS << "__attribute__((amdgpu_kernel))";
1103+
case CC_DeviceKernel:
1104+
OS << "__attribute__((device_kernel))";
11051105
break;
11061106
case CC_IntelOclBicc:
11071107
OS << " __attribute__((intel_ocl_bicc))";
@@ -1116,7 +1116,6 @@ void TypePrinter::printFunctionAfter(const FunctionType::ExtInfo &Info,
11161116
OS << " __attribute__((regcall))";
11171117
break;
11181118
case CC_SpirFunction:
1119-
case CC_OpenCLKernel:
11201119
// Do nothing. These CCs are not available as attributes.
11211120
break;
11221121
case CC_Swift:
@@ -2069,7 +2068,9 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
20692068
}
20702069
case attr::AArch64VectorPcs: OS << "aarch64_vector_pcs"; break;
20712070
case attr::AArch64SVEPcs: OS << "aarch64_sve_pcs"; break;
2072-
case attr::AMDGPUKernelCall: OS << "amdgpu_kernel"; break;
2071+
case attr::DeviceKernel:
2072+
OS << T->getAttr()->getSpelling();
2073+
break;
20732074
case attr::IntelOclBicc: OS << "inteloclbicc"; break;
20742075
case attr::PreserveMost:
20752076
OS << "preserve_most";

clang/lib/Basic/Targets/AArch64.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1400,7 +1400,7 @@ AArch64TargetInfo::checkCallingConvention(CallingConv CC) const {
14001400
case CC_PreserveMost:
14011401
case CC_PreserveAll:
14021402
case CC_PreserveNone:
1403-
case CC_OpenCLKernel:
1403+
case CC_DeviceKernel:
14041404
case CC_AArch64VectorCall:
14051405
case CC_AArch64SVEPCS:
14061406
case CC_Win64:
@@ -1758,7 +1758,7 @@ WindowsARM64TargetInfo::checkCallingConvention(CallingConv CC) const {
17581758
case CC_X86FastCall:
17591759
return CCCR_Ignore;
17601760
case CC_C:
1761-
case CC_OpenCLKernel:
1761+
case CC_DeviceKernel:
17621762
case CC_PreserveMost:
17631763
case CC_PreserveAll:
17641764
case CC_PreserveNone:

clang/lib/Basic/Targets/AMDGPU.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -415,8 +415,7 @@ class LLVM_LIBRARY_VISIBILITY AMDGPUTargetInfo final : public TargetInfo {
415415
default:
416416
return CCCR_Warning;
417417
case CC_C:
418-
case CC_OpenCLKernel:
419-
case CC_AMDGPUKernelCall:
418+
case CC_DeviceKernel:
420419
return CCCR_OK;
421420
}
422421
}

clang/lib/Basic/Targets/ARM.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1404,7 +1404,7 @@ ARMTargetInfo::checkCallingConvention(CallingConv CC) const {
14041404
case CC_AAPCS_VFP:
14051405
case CC_Swift:
14061406
case CC_SwiftAsync:
1407-
case CC_OpenCLKernel:
1407+
case CC_DeviceKernel:
14081408
return CCCR_OK;
14091409
default:
14101410
return CCCR_Warning;
@@ -1479,7 +1479,7 @@ WindowsARMTargetInfo::checkCallingConvention(CallingConv CC) const {
14791479
case CC_X86VectorCall:
14801480
return CCCR_Ignore;
14811481
case CC_C:
1482-
case CC_OpenCLKernel:
1482+
case CC_DeviceKernel:
14831483
case CC_PreserveMost:
14841484
case CC_PreserveAll:
14851485
case CC_Swift:

clang/lib/Basic/Targets/BPF.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ class LLVM_LIBRARY_VISIBILITY BPFTargetInfo : public TargetInfo {
9494
default:
9595
return CCCR_Warning;
9696
case CC_C:
97-
case CC_OpenCLKernel:
97+
case CC_DeviceKernel:
9898
return CCCR_OK;
9999
}
100100
}

clang/lib/Basic/Targets/Mips.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ WindowsMipsTargetInfo::checkCallingConvention(CallingConv CC) const {
336336
case CC_X86VectorCall:
337337
return CCCR_Ignore;
338338
case CC_C:
339-
case CC_OpenCLKernel:
339+
case CC_DeviceKernel:
340340
case CC_PreserveMost:
341341
case CC_PreserveAll:
342342
case CC_Swift:

clang/lib/Basic/Targets/SPIR.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo : public TargetInfo {
193193
}
194194

195195
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
196-
return (CC == CC_SpirFunction || CC == CC_OpenCLKernel) ? CCCR_OK
196+
return (CC == CC_SpirFunction || CC == CC_DeviceKernel) ? CCCR_OK
197197
: CCCR_Warning;
198198
}
199199

clang/lib/Basic/Targets/SystemZ.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ class LLVM_LIBRARY_VISIBILITY SystemZTargetInfo : public TargetInfo {
245245
switch (CC) {
246246
case CC_C:
247247
case CC_Swift:
248-
case CC_OpenCLKernel:
248+
case CC_DeviceKernel:
249249
return CCCR_OK;
250250
case CC_SwiftAsync:
251251
return CCCR_Error;

0 commit comments

Comments
 (0)