Skip to content

Commit 96ef141

Browse files
committed
[SYCL] Do not emit unneeded static initializations in sycl device code
Signed-off-by: Premanand M Rao <[email protected]>
1 parent 0473316 commit 96ef141

File tree

3 files changed

+57
-5
lines changed

3 files changed

+57
-5
lines changed

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1276,7 +1276,12 @@ void CodeGenModule::EmitCtorList(CtorList &Fns, const char *GlobalName) {
12761276
ctor.addInt(Int32Ty, I.Priority);
12771277
ctor.add(llvm::ConstantExpr::getBitCast(I.Initializer, CtorPFTy));
12781278
if (I.AssociatedData)
1279-
ctor.add(llvm::ConstantExpr::getBitCast(I.AssociatedData, VoidPtrTy));
1279+
if (I.AssociatedData->getType()->getPointerAddressSpace() !=
1280+
VoidPtrTy->getAddressSpace())
1281+
ctor.add(
1282+
llvm::ConstantExpr::getAddrSpaceCast(I.AssociatedData, VoidPtrTy));
1283+
else
1284+
ctor.add(llvm::ConstantExpr::getBitCast(I.AssociatedData, VoidPtrTy));
12801285
else
12811286
ctor.addNullPointer(VoidPtrTy);
12821287
ctor.finishAndAddTo(ctors);

clang/lib/Sema/SemaTemplateInstantiateDecl.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5264,16 +5264,21 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation,
52645264

52655265
// Make sure to pass the instantiated variable to the consumer at the end.
52665266
struct PassToConsumerRAII {
5267+
Sema &SemaRef;
52675268
ASTConsumer &Consumer;
52685269
VarDecl *Var;
52695270

5270-
PassToConsumerRAII(ASTConsumer &Consumer, VarDecl *Var)
5271-
: Consumer(Consumer), Var(Var) { }
5271+
PassToConsumerRAII(Sema &SemaRef, ASTConsumer &Consumer, VarDecl *Var)
5272+
: SemaRef(SemaRef), Consumer(Consumer), Var(Var) {}
52725273

52735274
~PassToConsumerRAII() {
5274-
Consumer.HandleCXXStaticMemberVarInstantiation(Var);
5275+
// Do not explicitly emit non-const static data member definitions
5276+
// on SYCL device.
5277+
if (!SemaRef.getLangOpts().SYCLIsDevice || !Var->isStaticDataMember() ||
5278+
Var->isConstexpr() || Var->getType().isConstQualified())
5279+
Consumer.HandleCXXStaticMemberVarInstantiation(Var);
52755280
}
5276-
} PassToConsumerRAII(Consumer, Var);
5281+
} PassToConsumerRAII(*this, Consumer, Var);
52775282

52785283
// If we already have a definition, we're done.
52795284
if (VarDecl *Def = Var->getDefinition()) {
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
// RUN: %clang_cc1 -fsycl -fsycl-is-device -triple spir64-unknown-unknown-sycldevice -disable-llvm-passes %s -emit-llvm -o - | FileCheck %s
2+
// Test that static initializers do not force the emission of globals on sycl device
3+
4+
// CHECK: %struct._ZTS16RegisterBaseInit.RegisterBaseInit = type { i8 }
5+
// CHECK-NOT: $_ZN8BaseInitI12TestBaseTypeE15s_regbase_ncsdmE = comdat any
6+
// CHECK: $_ZN8BaseInitI12TestBaseTypeE3varE = comdat any
7+
// CHECK: @_ZN8BaseInitI12TestBaseTypeE9s_regbaseE = {{.*}} global %struct._ZTS16RegisterBaseInit.RegisterBaseInit
8+
// CHECK-NOT: @_ZN8BaseInitI12TestBaseTypeE15s_regbase_ncsdmE = weak_odr addrspace(1) global %struct._ZTS16RegisterBaseInit.RegisterBaseInit zeroinitializer, comdat, align 1
9+
// CHECK: @_ZN8BaseInitI12TestBaseTypeE3varE = weak_odr addrspace(1) constant i32 9, comdat, align 4
10+
// CHECK-NOT: @_ZGVN8BaseInitI12TestBaseTypeE15s_regbase_ncsdmE = weak_odr global i64 0, comdat($_ZN8BaseInitI12TestBaseTypeE9s_regbaseE), align 8
11+
// CHECK: define spir_kernel void @_ZTSZ4mainE11fake_kernel()
12+
// CHECK: call spir_func void @"_ZZ4mainENK3$_0clE16RegisterBaseInit
13+
// CHECK: declare spir_func void @_ZN16RegisterBaseInit3fooEv
14+
15+
struct TestBaseType {};
16+
struct RegisterBaseInit {
17+
__attribute__((sycl_device)) void foo();
18+
RegisterBaseInit();
19+
};
20+
template <class T>
21+
struct BaseInit {
22+
static const RegisterBaseInit s_regbase;
23+
static RegisterBaseInit s_regbase_ncsdm;
24+
static const int var;
25+
};
26+
template <class T>
27+
const RegisterBaseInit BaseInit<T>::s_regbase;
28+
template <class T>
29+
RegisterBaseInit BaseInit<T>::s_regbase_ncsdm;
30+
template <class T>
31+
const int BaseInit<T>::var = 9;
32+
template struct BaseInit<TestBaseType>;
33+
template <typename name, typename Func>
34+
__attribute__((sycl_kernel)) void kernel_single_task(Func kernelFunc) {
35+
kernelFunc(BaseInit<TestBaseType>::s_regbase);
36+
}
37+
int main() {
38+
kernel_single_task<class fake_kernel>([=](RegisterBaseInit s) {
39+
s.foo();
40+
});
41+
return 0;
42+
}

0 commit comments

Comments
 (0)