-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[clang] Simplify device kernel attributes #137882
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
711a62e
to
20498a3
Compare
✅ With the latest revision this PR passed the C/C++ code formatter. |
@llvm/pr-subscribers-clang-tidy @llvm/pr-subscribers-clang Author: Nick Sarnie (sarnex) ChangesSPIR kernels have a specific calling convention, so add an attribute to explicitly specify this calling convention when targetting pure SPIR/SPIRV. Full diff: https://github.com/llvm/llvm-project/pull/137882.diff 14 Files Affected:
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index a734eb6658c3d..c3a3db095bb81 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -472,7 +472,9 @@ def TargetRISCV : TargetArch<["riscv32", "riscv64"]>;
def TargetX86 : TargetArch<["x86"]>;
def TargetX86_64 : TargetArch<["x86_64"]>;
def TargetAnyX86 : TargetArch<["x86", "x86_64"]>;
+def TargetSPIR : TargetArch<["spir", "spir64"]>;
def TargetSPIRV : TargetArch<["spirv", "spirv32", "spirv64"]>;
+def TargetAnySPIR : TargetArch<!listconcat(TargetSPIR.Arches, TargetSPIRV.Arches)>;
def TargetWebAssembly : TargetArch<["wasm32", "wasm64"]>;
def TargetNVPTX : TargetArch<["nvptx", "nvptx64"]>;
def TargetWindows : TargetSpec {
@@ -1504,6 +1506,12 @@ def NVPTXKernel : InheritableAttr, TargetSpecificAttr<TargetNVPTX> {
let Documentation = [Undocumented];
}
+def SPIRKernel : InheritableAttr, TargetSpecificAttr<TargetAnySPIR> {
+ let Spellings = [Clang<"spir_kernel">];
+ let Subjects = SubjectList<[Function]>;
+ let Documentation = [Undocumented];
+}
+
def HIPManaged : InheritableAttr {
let Spellings = [GNU<"managed">, Declspec<"__managed__">];
let Subjects = SubjectList<[Var]>;
diff --git a/clang/include/clang/Basic/Specifiers.h b/clang/include/clang/Basic/Specifiers.h
index 491badcc804e7..f9a72f378490e 100644
--- a/clang/include/clang/Basic/Specifiers.h
+++ b/clang/include/clang/Basic/Specifiers.h
@@ -289,6 +289,7 @@ namespace clang {
CC_AAPCS_VFP, // __attribute__((pcs("aapcs-vfp")))
CC_IntelOclBicc, // __attribute__((intel_ocl_bicc))
CC_SpirFunction, // default for OpenCL functions on SPIR target
+ CC_SpirKernel, // __attribute__((spir_kernel))
CC_OpenCLKernel, // inferred for OpenCL kernels
CC_Swift, // __attribute__((swiftcall))
CC_SwiftAsync, // __attribute__((swiftasynccall))
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 33a8728728574..c16005ccaf51f 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -3532,6 +3532,7 @@ StringRef CXXNameMangler::getCallingConvQualifierName(CallingConv CC) {
case CC_AMDGPUKernelCall:
case CC_IntelOclBicc:
case CC_SpirFunction:
+ case CC_SpirKernel:
case CC_OpenCLKernel:
case CC_PreserveMost:
case CC_PreserveAll:
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index 59369fba2e772..da9ba8e3e971a 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -3623,6 +3623,8 @@ StringRef FunctionType::getNameForCallConv(CallingConv CC) {
return "intel_ocl_bicc";
case CC_SpirFunction:
return "spir_function";
+ case CC_SpirKernel:
+ return "spir_kernel";
case CC_OpenCLKernel:
return "opencl_kernel";
case CC_Swift:
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index cba1a2d98d660..5aa37ca9ec17f 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -1115,6 +1115,9 @@ void TypePrinter::printFunctionAfter(const FunctionType::ExtInfo &Info,
case CC_OpenCLKernel:
// Do nothing. These CCs are not available as attributes.
break;
+ case CC_SpirKernel:
+ OS << " __attribute__((spir_kernel))";
+ break;
case CC_Swift:
OS << " __attribute__((swiftcall))";
break;
diff --git a/clang/lib/Basic/Targets/SPIR.h b/clang/lib/Basic/Targets/SPIR.h
index bf249e271a870..43c71a1aeb5d5 100644
--- a/clang/lib/Basic/Targets/SPIR.h
+++ b/clang/lib/Basic/Targets/SPIR.h
@@ -191,8 +191,10 @@ class LLVM_LIBRARY_VISIBILITY BaseSPIRTargetInfo : public TargetInfo {
}
CallingConvCheckResult checkCallingConvention(CallingConv CC) const override {
- return (CC == CC_SpirFunction || CC == CC_OpenCLKernel) ? CCCR_OK
- : CCCR_Warning;
+ return (CC == CC_SpirKernel || CC == CC_SpirFunction ||
+ CC == CC_OpenCLKernel)
+ ? CCCR_OK
+ : CCCR_Warning;
}
CallingConv getDefaultCallingConv() const override {
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index 83b0e8e965770..a7bbff116b584 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -84,6 +84,8 @@ unsigned CodeGenTypes::ClangCallConvToLLVMCallConv(CallingConv CC) {
return llvm::CallingConv::AMDGPU_KERNEL;
case CC_SpirFunction:
return llvm::CallingConv::SPIR_FUNC;
+ case CC_SpirKernel:
+ return llvm::CallingConv::SPIR_KERNEL;
case CC_OpenCLKernel:
return CGM.getTargetCodeGenInfo().getOpenCLKernelCallingConv();
case CC_PreserveMost:
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index f3ec498d4064b..10fba7b772486 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -1589,6 +1589,8 @@ static unsigned getDwarfCC(CallingConv CC) {
return llvm::dwarf::DW_CC_LLVM_IntelOclBicc;
case CC_SpirFunction:
return llvm::dwarf::DW_CC_LLVM_SpirFunction;
+ case CC_SpirKernel:
+ return llvm::dwarf::DW_CC_LLVM_SpirKernel;
case CC_OpenCLKernel:
case CC_AMDGPUKernelCall:
return llvm::dwarf::DW_CC_LLVM_OpenCLKernel;
diff --git a/clang/lib/CodeGen/Targets/SPIR.cpp b/clang/lib/CodeGen/Targets/SPIR.cpp
index f35c124f50aa0..29a258e457317 100644
--- a/clang/lib/CodeGen/Targets/SPIR.cpp
+++ b/clang/lib/CodeGen/Targets/SPIR.cpp
@@ -60,6 +60,8 @@ class CommonSPIRTargetCodeGenInfo : public TargetCodeGenInfo {
llvm::Type *ElementType, llvm::LLVMContext &Ctx) const;
void
setOCLKernelStubCallingConvention(const FunctionType *&FT) const override;
+ void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
+ CodeGen::CodeGenModule &M) const override;
};
class SPIRVTargetCodeGenInfo : public CommonSPIRTargetCodeGenInfo {
public:
@@ -238,6 +240,20 @@ void CommonSPIRTargetCodeGenInfo::setOCLKernelStubCallingConvention(
FT, FT->getExtInfo().withCallingConv(CC_SpirFunction));
}
+void CommonSPIRTargetCodeGenInfo::setTargetAttributes(
+ const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const {
+ const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
+ if (!FD)
+ return;
+
+ llvm::Function *F = cast<llvm::Function>(GV);
+
+ // Attach kernel metadata directly if compiling for SPIR.
+ if (FD->hasAttr<SPIRKernelAttr>()) {
+ F->setCallingConv(llvm::CallingConv::SPIR_KERNEL);
+ }
+}
+
LangAS
SPIRVTargetCodeGenInfo::getGlobalVarAddressSpace(CodeGenModule &CGM,
const VarDecl *D) const {
@@ -262,6 +278,7 @@ SPIRVTargetCodeGenInfo::getGlobalVarAddressSpace(CodeGenModule &CGM,
void SPIRVTargetCodeGenInfo::setTargetAttributes(
const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const {
+ CommonSPIRTargetCodeGenInfo::setTargetAttributes(D, GV, M);
if (!M.getLangOpts().HIP ||
M.getTarget().getTriple().getVendor() != llvm::Triple::AMD)
return;
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index ab66ae860f86b..56aea1e878f23 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -5503,6 +5503,9 @@ bool Sema::CheckCallingConvAttr(const ParsedAttr &Attrs, CallingConv &CC,
llvm::Log2_64(ABIVLen) - 5);
break;
}
+ case ParsedAttr::AT_SPIRKernel:
+ CC = CC_SpirKernel;
+ break;
default: llvm_unreachable("unexpected attribute kind");
}
@@ -7152,6 +7155,9 @@ ProcessDeclAttribute(Sema &S, Scope *scope, Decl *D, const ParsedAttr &AL,
case ParsedAttr::AT_CUDALaunchBounds:
handleLaunchBoundsAttr(S, D, AL);
break;
+ case ParsedAttr::AT_SPIRKernel:
+ handleSimpleAttribute<SPIRKernelAttr>(S, D, AL);
+ break;
case ParsedAttr::AT_Restrict:
handleRestrictAttr(S, D, AL);
break;
diff --git a/clang/test/Misc/pragma-attribute-supported-attributes-list.test b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
index 7affacb1a109a..53a7ea4c8033b 100644
--- a/clang/test/Misc/pragma-attribute-supported-attributes-list.test
+++ b/clang/test/Misc/pragma-attribute-supported-attributes-list.test
@@ -181,6 +181,7 @@
// CHECK-NEXT: ReturnTypestate (SubjectMatchRule_function, SubjectMatchRule_variable_is_parameter)
// CHECK-NEXT: ReturnsNonNull (SubjectMatchRule_objc_method, SubjectMatchRule_function)
// CHECK-NEXT: ReturnsTwice (SubjectMatchRule_function)
+// CHECK-NEXT: SPIRKernel (SubjectMatchRule_function)
// CHECK-NEXT: SYCLKernelEntryPoint (SubjectMatchRule_function)
// CHECK-NEXT: SYCLSpecialClass (SubjectMatchRule_record)
// CHECK-NEXT: ScopedLockable (SubjectMatchRule_record)
diff --git a/clang/test/Misc/spir-kernel-attr.c b/clang/test/Misc/spir-kernel-attr.c
new file mode 100644
index 0000000000000..40de980716ff2
--- /dev/null
+++ b/clang/test/Misc/spir-kernel-attr.c
@@ -0,0 +1,10 @@
+// RUN: %clang_cc1 -triple spir -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple spir64 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple spirv-unknown-vulkan-compute -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple spirv32 -emit-llvm %s -o - | FileCheck %s
+// RUN: %clang_cc1 -triple spirv64 -emit-llvm %s -o - | FileCheck %s
+__attribute__((spir_kernel)) void foo(void) {}
+
+[[clang::spir_kernel]] void bar(void) {}
+
+// CHECK-COUNT-2: spir_kernel
diff --git a/llvm/include/llvm/BinaryFormat/Dwarf.def b/llvm/include/llvm/BinaryFormat/Dwarf.def
index e52324a8ebc12..575ab05f4e3c4 100644
--- a/llvm/include/llvm/BinaryFormat/Dwarf.def
+++ b/llvm/include/llvm/BinaryFormat/Dwarf.def
@@ -1127,6 +1127,7 @@ HANDLE_DW_CC(0xcd, LLVM_PreserveNone)
HANDLE_DW_CC(0xce, LLVM_RISCVVectorCall)
HANDLE_DW_CC(0xcf, LLVM_SwiftTail)
HANDLE_DW_CC(0xd0, LLVM_RISCVVLSCall)
+HANDLE_DW_CC(0xd1, LLVM_SpirKernel)
// From GCC source code (include/dwarf2.h): This DW_CC_ value is not currently
// generated by any toolchain. It is used internally to GDB to indicate OpenCL
// C functions that have been compiled with the IBM XL C for OpenCL compiler and
diff --git a/llvm/include/llvm/DebugInfo/DWARF/DWARFTypePrinter.h b/llvm/include/llvm/DebugInfo/DWARF/DWARFTypePrinter.h
index bd25f6c30ebf1..82337774f2396 100644
--- a/llvm/include/llvm/DebugInfo/DWARF/DWARFTypePrinter.h
+++ b/llvm/include/llvm/DebugInfo/DWARF/DWARFTypePrinter.h
@@ -741,6 +741,9 @@ void DWARFTypePrinter<DieType>::appendSubroutineNameAfter(
// instantiated with function types with these calling conventions won't
// have distinct names - so we'd need to fix that too)
break;
+ case dwarf::CallingConvention::DW_CC_LLVM_SpirKernel:
+ OS << " __attribute((spir_kernel))";
+ break;
case dwarf::CallingConvention::DW_CC_LLVM_Swift:
// SwiftAsync missing
OS << " __attribute__((swiftcall))";
|
clang/lib/Sema/SemaDeclAttr.cpp
Outdated
@@ -5503,6 +5503,9 @@ bool Sema::CheckCallingConvAttr(const ParsedAttr &Attrs, CallingConv &CC, | |||
llvm::Log2_64(ABIVLen) - 5); | |||
break; | |||
} | |||
case ParsedAttr::AT_SPIRKernel: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps a silly request, but please sort this as 'not last'. It is too easy to miss when after a big block.
clang/include/clang/Basic/Attr.td
Outdated
def SPIRKernel : InheritableAttr, TargetSpecificAttr<TargetAnySPIR> { | ||
let Spellings = [Clang<"spir_kernel">]; | ||
let Subjects = SubjectList<[Function]>; | ||
let Documentation = [Undocumented]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this non-documented? WE very much don't approve/accept new undocumented attributes without good reason.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I wasn't sure how strict we were with that, will add documentation.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need yet another calling convention or is there a way we can start to combine some of these for all the offloading languages? It seems we keep re-implementing the same concepts multiple times for each language and it would be nice to share as much of the frontend logic as possible rather than keep doing this dance of adding another case to every switch in the compiler. :-D
Do you have an idea? Maybe we could have a |
I was thinking that orthogonal calling conventions could be combined so that we need fewer of them. e.g., if spir_kernel cannot be mixed with nvptx_kernel in the same TU, then there's no need for two distinct internal representations for the attributes, just two distinct spellings that are based on the target. |
Ah, I see. Okay, I'll try, but it might take me a while. Thanks for the feedback. Marking this as a draft for now. |
Signed-off-by: Sarnie, Nick <[email protected]>
@AaronBallman I just pushed a first attempt to combine the attrs, however I'm not sure if it's much cleaner given the attrs have different subjects/allowed cases/expected warnings/etc. Do you mind taking a first look and seeing if you think the general direction is a good idea? Thanks |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CC @erichkeane and @jdoerfert for other opinions on the direction this is heading, but my initial thoughts are that this is not unreasonable. But I'd love to hear from others!
clang/include/clang/Basic/Attr.td
Outdated
inline bool isAMDGPUSpelling() const { | ||
return isAMDGPUSpelling(*this); | ||
} | ||
template<typename T> | ||
static inline bool isAMDGPUSpelling(const T& Attr) { | ||
return Attr.getAttrName()->getName() == "amdgpu_kernel"; | ||
} | ||
inline bool isNVPTXSpelling() const { | ||
return isNVPTXSpelling(*this); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's an easier way to do this, I think. We have:
let Accessors = [Accessor<"isAMDGPU", [Clang<"amdgpu_kernel">]>,
Accessor<"isNVPTX", [Clang<"nvptx_kernel">]>];
which generates an accessor method for you which returns true/false based on the spelling.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah cool, thanks! Will do! I think I still need some of the methods to deal with the fact ParsedAttr
isn't a subclass of Attr
but also has a getAttrName()
function, but maybe we can get rid of half of them
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried this, but we actually need to check the spelling mostly for ParsedAttr
, so the accessors here won't help. I implemented Erich's idea to use the enum instead of the string. Let me know if you have some tablegen magic that we can use!
clang/include/clang/Basic/Attr.td
Outdated
let Spellings = [Clang<"device_kernel">, Clang<"sycl_kernel">, | ||
Clang<"nvptx_kernel">, Clang<"amdgpu_kernel">, | ||
CustomKeyword<"__kernel">, CustomKeyword<"kernel">]; | ||
let LangOpts = []; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can drop this entirely.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I honestly really like the approach. Those attributes really only differ by spelling and are almost semantically identical, so it makes a lot of sense to do it this way. So I'm happy.
The accessors could be cleaned up, otherwise this is a LGTM.
clang/include/clang/Basic/Attr.td
Outdated
} | ||
template<typename T> | ||
static inline bool isOpenCLSpelling(const T& Attr) { | ||
return Attr.getAttrName()->getName() == "kernel" || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even without the Accessors
thing that Aaron suggests, you can check the spelling-id vs the generated enums which is better than string compares.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will try if it I hit an issue with Aaron's suggestion, thanks!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I ended up doing it this way using the enums.
Thanks a lot guys, I didn't expect this to be a good direction :) |
Signed-off-by: Sarnie, Nick <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In general, I think this is heading in the right direction.
let Category = DocCatFunction; | ||
let Heading = "device_kernel"; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should probably list the other spellings of the attribute to the heading, that helps folks searching for those docs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done in latest commit, thanks!
Signed-off-by: Sarnie, Nick <[email protected]>
Precommit CI found relevant failures; it looks like clang-tools-extra needs some updates as well |
Whoops, thanks! |
Signed-off-by: Sarnie, Nick <[email protected]>
Any final comments on this @AaronBallman @erichkeane @arsenm @AlexVlx @yxsamliu, would appreciate a review, thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks reasonable to me, but please wait for @erichkeane to sign off before landing
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1 set of questions, something I'm concerned about: How do we make sure we don't try to have two kernel languages defined at the same time (I realize that might be messy, but it is something that could happen), then just are checking language version?
clang/lib/AST/Decl.cpp
Outdated
@@ -3541,7 +3541,7 @@ bool FunctionDecl::isExternC() const { | |||
} | |||
|
|||
bool FunctionDecl::isInExternCContext() const { | |||
if (hasAttr<OpenCLKernelAttr>()) | |||
if (hasAttr<DeviceKernelAttr>() && getASTContext().getLangOpts().OpenCL) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this really the same thing? Do we prevent enabling multiple kernel-defining languages at the same time? Should this instead check spelling?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the review. In an ideal world we would just be able to use the fact it's been specified as a device kernel and do to the checks but right now it's not that simple, one case is the multiple languages with kernels like you mentioned. I tried OpenCL + SYCL and that worked, so there is some ambiguity there.
Let me update these checks to use the spelling just to simplify this change. Thanks again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the delay, I just pushed a commit updating all the sites I previously had checking the language to now check for the OpenCL spelling. Should be less risky. Please take a look when you have a sec, thanks.
clang/lib/AST/ItaniumMangle.cpp
Outdated
@@ -1556,7 +1556,8 @@ void CXXNameMangler::mangleUnqualifiedName( | |||
FD && FD->hasAttr<CUDAGlobalAttr>() && | |||
GD.getKernelReferenceKind() == KernelReferenceKind::Stub; | |||
bool IsOCLDeviceStub = | |||
FD && FD->hasAttr<OpenCLKernelAttr>() && | |||
getASTContext().getLangOpts().OpenCL && FD && | |||
FD->hasAttr<DeviceKernelAttr>() && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same question here.
clang/lib/AST/MicrosoftMangle.cpp
Outdated
@@ -1164,7 +1164,8 @@ void MicrosoftCXXNameMangler::mangleUnqualifiedName(GlobalDecl GD, | |||
->hasAttr<CUDAGlobalAttr>())) && | |||
GD.getKernelReferenceKind() == KernelReferenceKind::Stub; | |||
bool IsOCLDeviceStub = | |||
ND && isa<FunctionDecl>(ND) && ND->hasAttr<OpenCLKernelAttr>() && | |||
getASTContext().getLangOpts().OpenCL && ND && |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And here :)
Signed-off-by: Sarnie, Nick <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this looks reasonable, LGTM.
Signed-off-by: Sarnie, Nick <[email protected]>
Thanks Erich! @AaronBallman Do you mind giving the final version another quick pass to make sure all concerns are addressed before I merge? Thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
Thanks all for the reviews/feedback, going to merge this. Hopefully there isn't any fallout :) |
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]>
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]>
case CC_DeviceKernel: { | ||
if (CGM.getLangOpts().OpenCL) | ||
return CGM.getTargetCodeGenInfo().getOpenCLKernelCallingConv(); | ||
if (CGM.getTriple().isSPIROrSPIRV()) | ||
return llvm::CallingConv::SPIR_KERNEL; | ||
if (CGM.getTriple().isAMDGPU()) | ||
return llvm::CallingConv::AMDGPU_KERNEL; | ||
if (CGM.getTriple().isNVPTX()) | ||
return llvm::CallingConv::PTX_Kernel; | ||
llvm_unreachable("Unknown kernel calling convention"); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sarnex,
IMHO, the implementation of CC_DeviceKernel
case should look like:
case CC_DeviceKernel:
return CGM.getTargetCodeGenInfo().getDeviceKernelCallingConv();
SPIR/SPIR-V/NVPTX/AMDGPU targets should define target specific calling convention.
i.e. getOpenCLKernelCallingConv -> getDeviceKernelCallingConv.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sure, let me take a look
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
…144728) We should abstract this logic away to `TargetInfo`. See #137882 for more information. --------- Signed-off-by: Sarnie, Nick <[email protected]>
…convention (#144728) We should abstract this logic away to `TargetInfo`. See llvm/llvm-project#137882 for more information. --------- Signed-off-by: Sarnie, Nick <[email protected]>
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.