Skip to content

Commit eeac017

Browse files
AlexeySachkovianayl
authored andcommitted
[SYCL] Force-emit more member functions into device code (intel#13985)
By some reason, we used to only emit unused member functions if they are explicitly annotated with `sycl_device` attribute (through `SYCL_EXTERNAL` macro). This logic was introduced in 3baec18 and there is no clear indication as to why exactly we have a check that the attribute is explicit. SYCL extension for virtual functions introduces an alternative markup for specifying which function and that markup is SYCL compile-time properties that we turn into attributes implicitly under the hood. Essentially, we now have a situation where an implicit `sycl_device` attribute on a member function should be treated as an explicit one, because it could be a result of SYCL compile-time property being applied to that method. Considering our current codebase, it seems like we intend to have member function to be emitted in all cases where `sycl_device` is being implicitly added and therefore this patch removes the requirement for the attribute to be explicit.
1 parent 874846e commit eeac017

File tree

2 files changed

+51
-4
lines changed

2 files changed

+51
-4
lines changed

clang/lib/AST/ASTContext.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12035,10 +12035,10 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
1203512035
// or `indirectly_callable' attribute must be emitted regardless of number
1203612036
// of actual uses
1203712037
if (LangOpts.SYCLIsDevice && isa<CXXMethodDecl>(D)) {
12038-
if (auto *A = D->getAttr<SYCLDeviceIndirectlyCallableAttr>())
12039-
return !A->isImplicit();
12040-
if (auto *A = D->getAttr<SYCLDeviceAttr>())
12041-
return !A->isImplicit();
12038+
if (D->hasAttr<SYCLDeviceIndirectlyCallableAttr>())
12039+
return true;
12040+
if (D->hasAttr<SYCLDeviceAttr>())
12041+
return true;
1204212042
}
1204312043

1204412044
GVALinkage Linkage = GetGVALinkageForFunction(FD);
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// RUN: %clang_cc1 -internal-isystem %S/Inputs -triple spir64-unknown-unknown -fsycl-is-device \
2+
// RUN: -fsycl-allow-virtual-functions -emit-llvm %s -o %t.ll
3+
// RUN: FileCheck %s --input-file=%t.ll --implicit-check-not _ZN7Derived3baz \
4+
// RUN: --implicit-check-not _ZN4Base4baz --implicit-check-not _ZN4Base3foo
5+
//
6+
// Some SYCL properties may be turned into 'sycl_device' attribute implicitly
7+
// and we would like to ensure that functions like this (at the moment those
8+
// would be virtual member functions only) are forcefully emitted into device
9+
// code.
10+
11+
class Base {
12+
virtual void foo() {}
13+
14+
virtual void baz();
15+
16+
[[__sycl_detail__::add_ir_attributes_function("indirectly-callable", "a")]]
17+
virtual void bar();
18+
};
19+
20+
void Base::bar() {}
21+
22+
void Base::baz() {}
23+
24+
class Derived : public Base {
25+
public:
26+
[[__sycl_detail__::add_ir_attributes_function("indirectly-callable", "b")]]
27+
void foo() override;
28+
29+
[[__sycl_detail__::add_ir_attributes_function("indirectly-callable", "c")]]
30+
void bar() override final;
31+
32+
[[__sycl_detail__::add_ir_attributes_function("not-indirectly-callable", "c")]]
33+
void baz() override final;
34+
};
35+
36+
void Derived::foo() {}
37+
38+
void Derived::bar() {}
39+
40+
void Derived::baz() {}
41+
42+
// CHECK: define {{.*}}spir_func void @_ZN4Base3bar{{.*}} #[[#AttrA:]]
43+
// CHECK: define {{.*}}spir_func void @_ZN7Derived3foo{{.*}} #[[#AttrB:]]
44+
// CHECK: define {{.*}}spir_func void @_ZN7Derived3bar{{.*}} #[[#AttrC:]]
45+
// CHECK: attributes #[[#AttrA]] = {{.*}} "indirectly-callable"="a"
46+
// CHECK: attributes #[[#AttrB]] = {{.*}} "indirectly-callable"="b"
47+
// CHECK: attributes #[[#AttrC]] = {{.*}} "indirectly-callable"="c"

0 commit comments

Comments
 (0)