-
Notifications
You must be signed in to change notification settings - Fork 809
SYCL: Implement some dependencies for SYCL 2020 Spec constant design #3499
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
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -111,6 +111,10 @@ class Util { | |
| /// specialization constant class. | ||
| static bool isSyclSpecConstantType(const QualType &Ty); | ||
|
|
||
| /// Checks whether given clang type is a full specialization of the SYCL | ||
| /// specialization id class. | ||
| static bool isSyclSpecIdType(const QualType &Ty); | ||
erichkeane marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
|
|
||
| /// Checks whether given clang type is a full specialization of the SYCL | ||
| /// kernel_handler class. | ||
| static bool isSyclKernelHandlerType(const QualType &Ty); | ||
|
|
@@ -4245,6 +4249,22 @@ SYCLIntegrationHeader::SYCLIntegrationHeader(bool _UnnamedLambdaSupport, | |
| Sema &_S) | ||
| : UnnamedLambdaSupport(_UnnamedLambdaSupport), S(_S) {} | ||
|
|
||
| void SYCLIntegrationFooter::addVarDecl(VarDecl *VD) { | ||
| // Step 1: ensure that this is of the correct type(spec-constant template | ||
erichkeane marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| // specialization). | ||
| if (!Util::isSyclSpecIdType(VD->getType())) | ||
| return; | ||
| // Step 2: ensure that this is a static member, or a namespace-scope. | ||
| // Note that the isLocalVarDeclorParm excludes thread-local and static-local | ||
erichkeane marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| // intentionally, as there is no way to 'spell' one of those in the | ||
| // specialization. We just don't generate the specialization for those, and | ||
| // let an error happen during host compilation. | ||
| if (!VD->hasGlobalStorage() || VD->isLocalVarDeclOrParm()) | ||
| return; | ||
| // Step 3: Add to SpecConstants collection. | ||
| SpecConstants.push_back(VD); | ||
| } | ||
|
|
||
| // Post-compile integration header support. | ||
| bool SYCLIntegrationFooter::emit(StringRef IntHeaderName) { | ||
| if (IntHeaderName.empty()) | ||
|
|
@@ -4261,8 +4281,40 @@ bool SYCLIntegrationFooter::emit(StringRef IntHeaderName) { | |
| return emit(Out); | ||
| } | ||
|
|
||
| void SYCLIntegrationFooter::emitSpecIDName(raw_ostream &O, const VarDecl *VD) { | ||
| // FIXME: Figure out the spec-constant unique name here. | ||
| // Note that this changes based on the linkage of the variable. | ||
| // We typically want to use the __builtin_unique_stable_name for the variable | ||
| // (or the newer-equivilent for values, see the JIRA), but we also have to | ||
| // figure out if this has internal or external linkage. In external-case this | ||
| // should be the same as the the unique-name. However, this isn't the case | ||
| // with local-linkage, where we want to put the driver-provided random-value | ||
| // ahead of it, so that we make sure it is unique across translation units. | ||
| // This name should come from the yet implemented__builtin_unique_stable_name | ||
| // feature that accepts variables and gives the mangling for that. | ||
| O << ""; | ||
| } | ||
|
|
||
| bool SYCLIntegrationFooter::emit(raw_ostream &O) { | ||
| O << "// Integration Footer contents to go here.\n"; | ||
| PrintingPolicy Policy{S.getLangOpts()}; | ||
| Policy.adjustForCPlusPlusFwdDecl(); | ||
| Policy.SuppressTypedefs = true; | ||
| Policy.SuppressUnwrittenScope = true; | ||
|
|
||
| for (const VarDecl *D : SpecConstants) { | ||
| O << "template<>\n"; | ||
| O << "inline const char *get_spec_constant_symbolic_ID<"; | ||
| // Emit the FQN for this, but we probably need to do some funny-business for | ||
| // anonymous namespaces. | ||
| D->printQualifiedName(O, Policy); | ||
| O << ">() {\n"; | ||
| O << " return \""; | ||
| emitSpecIDName(O, D); | ||
| O << "\";\n"; | ||
| O << "}\n"; | ||
| } | ||
|
|
||
| O << "#include <CL/sycl/detail/spec_const_integration.hpp>\n"; | ||
| return true; | ||
| } | ||
|
|
||
|
|
@@ -4304,6 +4356,15 @@ bool Util::isSyclSpecConstantType(const QualType &Ty) { | |
| return matchQualifiedTypeName(Ty, Scopes); | ||
| } | ||
|
|
||
| bool Util::isSyclSpecIdType(const QualType &Ty) { | ||
| llvm::StringLiteral Name = "specialization_id"; | ||
| std::array<DeclContextDesc, 3> Scopes = { | ||
| Util::DeclContextDesc{clang::Decl::Kind::Namespace, "cl"}, | ||
| Util::DeclContextDesc{clang::Decl::Kind::Namespace, "sycl"}, | ||
| Util::DeclContextDesc{Decl::Kind::ClassTemplateSpecialization, Name}}; | ||
|
||
| return matchQualifiedTypeName(Ty, Scopes); | ||
| } | ||
|
|
||
| bool Util::isSyclKernelHandlerType(const QualType &Ty) { | ||
| const StringRef &Name = "kernel_handler"; | ||
| std::array<DeclContextDesc, 3> Scopes = { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,10 +1,92 @@ | ||
| // RUN: %clang_cc1 -fsycl-is-device -triple spir64-unknown-unknown-sycldevice -fsycl-int-footer=%t.h %s -emit-llvm -o %t.ll | ||
| // RUN: FileCheck -input-file=%t.h %s | ||
|
|
||
| // CHECK: // Integration Footer contents to go here. | ||
|
|
||
| #include "Inputs/sycl.hpp" | ||
|
|
||
| int main() { | ||
| cl::sycl::kernel_single_task<class first_kernel>([]() {}); | ||
| } | ||
|
|
||
| using namespace cl::sycl; | ||
|
|
||
| cl::sycl::specialization_id<int> GlobalSpecID; | ||
| // CHECK: template<> | ||
| // CHECK-NEXT: inline const char *get_spec_constant_symbolic_ID<GlobalSpecID>() { | ||
| // CHECK-NEXT: return ""; | ||
| // CHECK-NEXT: } | ||
|
|
||
| struct Wrapper { | ||
| static specialization_id<int> WrapperSpecID; | ||
| // CHECK: template<> | ||
| // CHECK-NEXT: inline const char *get_spec_constant_symbolic_ID<Wrapper::WrapperSpecID>() { | ||
| // CHECK-NEXT: return ""; | ||
| // CHECK-NEXT: } | ||
| }; | ||
|
|
||
| template <typename T> | ||
| struct WrapperTemplate { | ||
| static specialization_id<T> WrapperSpecID; | ||
| }; | ||
| template class WrapperTemplate<int>; | ||
| // CHECK: template<> | ||
| // CHECK-NEXT: inline const char *get_spec_constant_symbolic_ID<WrapperTemplate<int>::WrapperSpecID>() { | ||
| // CHECK-NEXT: return ""; | ||
| // CHECK-NEXT: } | ||
| template class WrapperTemplate<double>; | ||
| // CHECK: template<> | ||
| // CHECK-NEXT: inline const char *get_spec_constant_symbolic_ID<WrapperTemplate<double>::WrapperSpecID>() { | ||
| // CHECK-NEXT: return ""; | ||
| // CHECK-NEXT: } | ||
|
|
||
| namespace Foo { | ||
| specialization_id<int> NSSpecID; | ||
| // CHECK: template<> | ||
| // CHECK-NEXT: inline const char *get_spec_constant_symbolic_ID<Foo::NSSpecID>() { | ||
| // CHECK-NEXT: return ""; | ||
| // CHECK-NEXT: } | ||
| inline namespace Bar { | ||
| specialization_id<int> InlineNSSpecID; | ||
| // CHECK: template<> | ||
| // CHECK-NEXT: inline const char *get_spec_constant_symbolic_ID<Foo::InlineNSSpecID>() { | ||
| // CHECK-NEXT: return ""; | ||
| // CHECK-NEXT: } | ||
| specialization_id<int> NSSpecID; | ||
| // CHECK: template<> | ||
| // CHECK-NEXT: inline const char *get_spec_constant_symbolic_ID<Foo::Bar::NSSpecID>() { | ||
| // CHECK-NEXT: return ""; | ||
| // CHECK-NEXT: } | ||
|
|
||
| struct Wrapper { | ||
| static specialization_id<int> WrapperSpecID; | ||
| // CHECK: template<> | ||
| // CHECK-NEXT: inline const char *get_spec_constant_symbolic_ID<Foo::Wrapper::WrapperSpecID>() { | ||
| // CHECK-NEXT: return ""; | ||
| // CHECK-NEXT: } | ||
| }; | ||
|
|
||
| template <typename T> | ||
| struct WrapperTemplate { | ||
| static specialization_id<T> WrapperSpecID; | ||
| }; | ||
| template class WrapperTemplate<int>; | ||
| // CHECK: template<> | ||
| // CHECK-NEXT: inline const char *get_spec_constant_symbolic_ID<Foo::WrapperTemplate<int>::WrapperSpecID>() { | ||
| // CHECK-NEXT: return ""; | ||
| // CHECK-NEXT: } | ||
| template class WrapperTemplate<double>; | ||
| // CHECK: template<> | ||
| // CHECK-NEXT: inline const char *get_spec_constant_symbolic_ID<Foo::WrapperTemplate<double>::WrapperSpecID>() { | ||
| // CHECK-NEXT: return ""; | ||
| // CHECK-NEXT: } | ||
| } // namespace Bar | ||
| namespace { | ||
| specialization_id<int> AnonNSSpecID; | ||
| // CHECK: template<> | ||
| // CHECK-NEXT: inline const char *get_spec_constant_symbolic_ID<Foo::AnonNSSpecID>() { | ||
| // CHECK-NEXT: return ""; | ||
| // CHECK-NEXT: } | ||
| } // namespace | ||
|
|
||
| } // namespace Foo | ||
|
|
||
| // CHECK: #include <CL/sycl/detail/spec_const_integration.hpp> |
Uh oh!
There was an error while loading. Please reload this page.