-
Notifications
You must be signed in to change notification settings - Fork 787
[sycl] [clang] Add sycl global var attribute #3746
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 9 commits
682277f
2c6f8fa
4184aa4
3f7887f
63c4f17
8b721d9
08d0c67
5c0f8af
a1ac1c5
a046f39
6bb98b9
47ce16a
a349032
79d4ed7
e9b7b2a
7219bff
3373830
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 |
---|---|---|
|
@@ -1197,6 +1197,14 @@ def SYCLDevice : InheritableAttr { | |
let Documentation = [SYCLDeviceDocs]; | ||
} | ||
|
||
def SYCLGlobalVar : InheritableAttr { | ||
let Spellings = [GNU<"sycl_global_var">]; | ||
let Subjects = SubjectList<[GlobalVar]>; | ||
let LangOpts = [SYCLIsDevice]; | ||
AaronBallman marked this conversation as resolved.
Show resolved
Hide resolved
AaronBallman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
let Documentation = [SYCLGlobalVarDocs]; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Now that this is only usable in system headers, this can go back to being undocumented with a comment about it only being used internally by the SYCL implementation (and the docs can be removed from AttrDocs.td). |
||
let SimpleHandler = 1; | ||
AaronBallman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
def SYCLKernel : InheritableAttr { | ||
let Spellings = [Clang<"sycl_kernel">]; | ||
let Subjects = SubjectList<[FunctionTmpl]>; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
// RUN: %clang_cc1 -fsycl-is-device -verify -fsyntax-only %s | ||
|
||
#include "Inputs/sycl.hpp" | ||
|
||
__attribute__((sycl_global_var)) int GlobalWithAttribute; | ||
|
||
__attribute__((sycl_global_var)) extern int ExternGlobalWithAttribute; | ||
|
||
namespace NS { | ||
__attribute__((sycl_global_var)) int NSGlobalWithAttribute; | ||
} | ||
|
||
union U { | ||
int InstanceMember; | ||
}; | ||
|
||
__attribute__((sycl_global_var)) U GlobalUnion; | ||
AaronBallman marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
struct S { | ||
__attribute__((sycl_global_var)) static int StaticMember; | ||
|
||
// expected-warning@+1 {{attribute only applies to global variables}} | ||
__attribute__((sycl_global_var)) int InstanceMember; | ||
}; | ||
int S::StaticMember = 0; | ||
|
||
__attribute__((sycl_global_var)) S GlobalStruct; | ||
|
||
__attribute__((sycl_global_var)) static S StaticGlobal; | ||
|
||
// expected-error@+1 {{attribute takes no arguments}} | ||
__attribute__((sycl_global_var(42))) int GlobalWithAttributeArg; | ||
|
||
int GlobalNoAttribute; | ||
|
||
// expected-warning@+1 {{attribute only applies to global variables}} | ||
__attribute__((sycl_global_var)) void F() { | ||
__attribute__((sycl_global_var)) static int StaticLocalVar; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would have expected a diagnostic here as a local variable is not a global variable. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This is an interesting question. SYCL spec applies the "global variable" restriction (that it must be const) to variables of static storage duration. Given this, I wonder if the attribute could be applied to the file-scope static variables to override the restriction. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I updated the tests and added the anonymous static union. The anonymous union is not considered a global (doesn't accept the attribute) and isn't allowed in a kernel. The static local var, surprisingly, is considered a global and accepts the attribute, though still not allowed in a kernel (because I didn't use the attribute's presence to allow that specific case). These are interesting results. In my changes, I relied on the pre-defined "GlobalVar" subject list. "GlobalVar" is defined earlier as a Var where the code check I'm stepping through code so I can answer why some of these results "have global storage" and some don't. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ultimately, though, this isn't a feature we're expecting external users to use. This is meant to be used by us to enable the assert feature. Perhaps there's a different subject list I can use that applies to fewer things? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
That's why you get the behavior you're getting (and the name
It doesn't much matter what we expect -- once we expose the attribute, users will use the attribute. This is basically giving users a blessed way to opt-in to using global variables whenever they'd like (I'm not convinced this is a good idea, btw) because we found a use case where we want to do it ourselves. We can give this attribute whatever semantics we'd like, so there may be a more restrictive predicate we can use, but without a design document for the feature as such, I don't really know what the right answer is as a reviewer (I can't go off the SYCL 2020 spec because this attribute is intended specifically to do things the SYCL spec doesn't allow). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Sounds good. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Latest commit expands the test to distinguish between user code and system-include code. Currently, the attribute is still allowed to appear in user code, but it won't have any effect. The attribute will only have an effect if it's used from a system header. To disallow the attribute from even appearing in user code, I'll need to figure out how to do a source location check from within a tablegen subject list. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On the second thought, here is another example: // sycl.hpp, system header
template <typename T>
struct Struct {
__attribute__((sycl_global_var)) static T Variable;
};
// main.cpp, user's application
struct UserTy {
int X;
int Y;
};
Struct<UserTy> Global; Is this use-case allowed? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would imagine that use case should be allowed -- the declaration of the variable is appropriately marked, the fact that the type comes from a user instantiation shouldn't matter to the attribute's semantics. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Latest commit updated with non-simple handler. Also included templates in tests. |
||
|
||
// expected-warning@+1 {{attribute only applies to global variables}} | ||
__attribute__((sycl_global_var)) int Local; | ||
|
||
cl::sycl::kernel_single_task<class kernel_name>([=] () { | ||
(void)GlobalWithAttribute; | ||
(void)ExternGlobalWithAttribute; | ||
(void)NS::NSGlobalWithAttribute; | ||
(void)GlobalUnion.InstanceMember; | ||
(void)S::StaticMember; | ||
(void)GlobalStruct.InstanceMember; | ||
(void)StaticGlobal.InstanceMember; // expected-error {{SYCL kernel cannot use a non-const static data variable}} | ||
(void)StaticLocalVar; // expected-error {{SYCL kernel cannot use a non-const static data variable}} | ||
(void)GlobalNoAttribute; // expected-error {{SYCL kernel cannot use a non-const global variable}} expected-note@Inputs/sycl.hpp:* {{called by}} | ||
}); | ||
} |
Uh oh!
There was an error while loading. Please reload this page.