Skip to content

Commit 88d2031

Browse files
authored
[SYCL] Do not emit unneeded static initializations in sycl device code (#1774)
Signed-off-by: Premanand M Rao <premanand.m.rao@intel.com>
1 parent 9072d49 commit 88d2031

File tree

3 files changed

+54
-5
lines changed

3 files changed

+54
-5
lines changed

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1279,7 +1279,8 @@ void CodeGenModule::EmitCtorList(CtorList &Fns, const char *GlobalName) {
12791279
ctor.addInt(Int32Ty, I.Priority);
12801280
ctor.add(llvm::ConstantExpr::getBitCast(I.Initializer, CtorPFTy));
12811281
if (I.AssociatedData)
1282-
ctor.add(llvm::ConstantExpr::getBitCast(I.AssociatedData, VoidPtrTy));
1282+
ctor.add(llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(
1283+
I.AssociatedData, VoidPtrTy));
12831284
else
12841285
ctor.addNullPointer(VoidPtrTy);
12851286
ctor.finishAndAddTo(ctors);

clang/lib/Sema/SemaTemplateInstantiateDecl.cpp

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

52815281
// Make sure to pass the instantiated variable to the consumer at the end.
52825282
struct PassToConsumerRAII {
5283+
Sema &SemaRef;
52835284
ASTConsumer &Consumer;
52845285
VarDecl *Var;
52855286

5286-
PassToConsumerRAII(ASTConsumer &Consumer, VarDecl *Var)
5287-
: Consumer(Consumer), Var(Var) { }
5287+
PassToConsumerRAII(Sema &SemaRef, ASTConsumer &Consumer, VarDecl *Var)
5288+
: SemaRef(SemaRef), Consumer(Consumer), Var(Var) {}
52885289

52895290
~PassToConsumerRAII() {
5290-
Consumer.HandleCXXStaticMemberVarInstantiation(Var);
5291+
// Do not explicitly emit non-const static data member definitions
5292+
// on SYCL device.
5293+
if (!SemaRef.getLangOpts().SYCLIsDevice || !Var->isStaticDataMember() ||
5294+
Var->isConstexpr() || Var->getType().isConstQualified())
5295+
Consumer.HandleCXXStaticMemberVarInstantiation(Var);
52915296
}
5292-
} PassToConsumerRAII(Consumer, Var);
5297+
} PassToConsumerRAII(*this, Consumer, Var);
52935298

52945299
// If we already have a definition, we're done.
52955300
if (VarDecl *Def = Var->getDefinition()) {
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
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: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @__cxx_global_var_init, i8* addrspacecast (i8 addrspace(1)* getelementptr inbounds (%struct._ZTS16RegisterBaseInit.RegisterBaseInit, %struct._ZTS16RegisterBaseInit.RegisterBaseInit addrspace(1)* @_ZN8BaseInitI12TestBaseTypeE9s_regbaseE, i32 0, i32 0) to i8*) }]
11+
// CHECK-NOT: @_ZGVN8BaseInitI12TestBaseTypeE15s_regbase_ncsdmE = weak_odr global i64 0, comdat($_ZN8BaseInitI12TestBaseTypeE9s_regbaseE), align 8
12+
// CHECK: define spir_kernel void @_ZTSZ4mainE11fake_kernel()
13+
// CHECK: call spir_func void @"_ZZ4mainENK3$_0clE16RegisterBaseInit
14+
// CHECK: declare spir_func void @_ZN16RegisterBaseInit3fooEv
15+
16+
struct TestBaseType {};
17+
struct RegisterBaseInit {
18+
__attribute__((sycl_device)) void foo();
19+
RegisterBaseInit();
20+
};
21+
template <class T>
22+
struct BaseInit {
23+
static const RegisterBaseInit s_regbase;
24+
static RegisterBaseInit s_regbase_ncsdm;
25+
static const int var;
26+
};
27+
template <class T>
28+
const RegisterBaseInit BaseInit<T>::s_regbase;
29+
template <class T>
30+
RegisterBaseInit BaseInit<T>::s_regbase_ncsdm;
31+
template <class T>
32+
const int BaseInit<T>::var = 9;
33+
template struct BaseInit<TestBaseType>;
34+
template <typename name, typename Func>
35+
__attribute__((sycl_kernel)) void kernel_single_task(Func kernelFunc) {
36+
kernelFunc(BaseInit<TestBaseType>::s_regbase);
37+
}
38+
int main() {
39+
kernel_single_task<class fake_kernel>([=](RegisterBaseInit s) {
40+
s.foo();
41+
});
42+
return 0;
43+
}

0 commit comments

Comments
 (0)