-
Notifications
You must be signed in to change notification settings - Fork 796
[SYCL] Turn indirectly-callable
property into sycl_device
attribute
#13819
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
[SYCL] Turn indirectly-callable
property into sycl_device
attribute
#13819
Conversation
This PR is a part of virtual functions feature being designed in intel#10540. One aspects of the proposed language specification is to be able to mark functions as device functions using SYCL compile-time properties mechanism. Compile-time properties are lowered into `[[__sycl_detail__::add_ir_attribute_function()]]` attribute and this patch introduces extra processing for the attribute: property names passed to the attribute are analyzed so we can generate other attributes based on those strings. The only example of such property/attribute pair is `indirectly-callable` string that indicates that a function with such property should be treated as if it had `sycl_device` attribute attached to it and we do exactly that implicitly now. Note that there were changes required to the attribute parsing logic: because we now access its argument way earlier than we used to, that logic had to be improved to be more robust and pass existing `SemaSYCL/attr-add-ir-attributes.cpp` test.
@@ -1816,7 +1841,7 @@ def SYCLAddIRAttrCommonMembers : SYCLAddIRAttrMemberCodeHolder<[{ | |||
ValueQType->getArrayElementTypeNoTypeQual() | |||
->isIntegralOrEnumerationType())) { | |||
SmallString<10> StrBuffer; | |||
for (unsigned I = 0; I < Value.getArraySize(); ++I) { | |||
for (unsigned I = 0; I < Value.getArrayInitializedElts(); ++I) { |
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.
Note for reviewers: this particular change was done to avoid assertion failure within APInt
on the following test case:
[[__sycl_detail__::add_ir_attributes_function("Attr1", CEStr)]] void FunctionCEVal2() {} |
@@ -1782,7 +1806,8 @@ def SYCLAddIRAttrCommonMembers : SYCLAddIRAttrMemberCodeHolder<[{ | |||
NameLValue = NameCE->getAPValueResult(); | |||
|
|||
if (!NameLValue.isLValue()) | |||
return std::nullopt; | |||
return getValidAttributeNameAsString(NameLValue, Context, |
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.
Note for reviewers: this particular change was done to avoid assertion failure due to invalid attribute name (nullopt
being returned) on the following test case:
[[__sycl_detail__::add_ir_attributes_function(CEAttrName1, nullptr)]] void FunctionCEName1() {} |
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'm a little confused. Why did your change cause this and the test mentioned below to break? I understand getFilteredAttributeNameValuePairs
is now called earlier but I don't understand why that causes these specific issues.
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'm a little confused. Why did your change cause this and the test mentioned below to break?
I honestly don't understand that myself. I can do a bit more of a debugging here to see why we see this particular AST and not another. My current guess is that it can be related to evaluation of constexpr
variables, i.e. by the time we parse this attribute, we haven't done some processing of CEAttrName1
(due to lazy nature of that processing), but it is always done before we reach CodeGen and therefore we haven't seen this problem before
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.
Ok, I seem to have figured it out. The issue is reproducible even without my changes, it is just hidden by the test without my changes. If you try to compile the following file with plain intel/llvm
:
$ cat p.cpp
constexpr const char CEAttrName1[] = "CEAttr1";
__attribute__((sycl_device)) [[__sycl_detail__::add_ir_attributes_function(CEAttrName1, nullptr)]] void FunctionCEName1() {}
$ clang++ -cc1 -fsycl-is-device -fsyntax-only p.cpp
clang++: github.com/intel/llvm/build/tools/clang/include/clang/AST/Attrs.inc:11988: llvm::SmallVector<std::pair<std::__cxx11::basic_strin
g<char>, std::__cxx11::basic_string<char> >, 4> clang::SYCLAddIRAttributesFunctionAttr::getFilteredAttributeNameValuePairs(const std::optional<llvm::SmallSet<
llvm::StringRef, 4> >&, const clang::ASTContext&) const: Assertion `NameStr && "Attribute name is not a valid string."' failed.
PLEASE submit a bug report to https://github.com/intel/llvm/issues and include the crash backtrace, preprocessed source, and associated run script.
Stack dump:
0. Program arguments: ./bin/clang++ -cc1 -fsycl-is-device -fsyntax-only p.cpp
1. <eof> parser at end of file
2. p.cpp:3:123: parsing function body 'FunctionCEName1'
Because the test also contains lines that cause compilation errors, we exit early from parsing/handling some of the things and therefore we don't see this assert. With the attribute arguments analysis performed earlier, we always go through that path and any "early exits" due to errors in the code do not help us avoid this issue.
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
…icit-attrs-based-on-properties
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. Thank you for applying the comment.
Pre-commit on CUDA seem to have failed due to infrastructure reason. Previous run had passed and the only change added since then is a non-functional commit to use |
@rdeodhar, FYI: you can probably re-use this infrastructure in free kernel functions extension to avoid the need of using |
I noticed that some joint matrix tests used add_ir_attributes_function with non-constexpr values for the value part. Then, using getFilteredAttributeNameValuePairs as the primary means of detecting free functions choked over those joint matrix functions. Using SYCL_EXTERNAL as a first filter eliminated those joint matrix functions from being run through getFilteredAttributeNameValuePairs. That is why free functins currently use SYCL_EXTERNAL as the first criterion. |
Curious. My understanding is that the attribute is intended to generate LLVM IR, we can't pass anything that can't be evaluated in compile-time to it. Perhaps those tests were hitting cases that I've fixed in this PR with the attribute arguments parsing |
Yes, those values should be constexprs. I plan to try again with your fix in place to see if that issue no longer affects free function detection. Otherwise, I will work with the owners of those joint matrix tests to make everything constexpr. |
This PR is a part of virtual functions feature being designed in #10540. One aspects of the proposed language specification is to be able to mark functions as device functions using SYCL compile-time properties mechanism.
Compile-time properties are lowered into
[[__sycl_detail__::add_ir_attribute_function()]]
attribute and this patch introduces extra processing for the attribute: property names passed to the attribute are analyzed so we can generate other attributes based on those strings.The only example of such property/attribute pair is
indirectly-callable
string that indicates that a function with such property should be treated as if it hadsycl_device
attribute attached to it and we do exactly that implicitly now.Note that there were changes required to the attribute parsing logic: because we now access its argument way earlier than we used to, that logic had to be improved to be more robust and pass existing
SemaSYCL/attr-add-ir-attributes.cpp
test.