Skip to content

Commit e8e4495

Browse files
svenvhvmaksimo
authored andcommitted
Set Initializer ExecutionMode for global ctors
SPIR-V 1.1 adds the Initializer Execution Mode for entry points. Set this execution mode for entry points listed in the llvm.global_ctors variable.
1 parent 32999cb commit e8e4495

File tree

2 files changed

+45
-0
lines changed

2 files changed

+45
-0
lines changed

llvm-spirv/lib/SPIRV/PreprocessMetadata.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,8 @@ class PreprocessMetadata : public ModulePass {
6868

6969
bool runOnModule(Module &M) override;
7070
void visit(Module *M);
71+
void preprocessCXXStructorList(SPIRVMDBuilder::NamedMDWrapper &EM,
72+
GlobalVariable *V, ExecutionMode EMode);
7173
void preprocessOCLMetadata(Module *M, SPIRVMDBuilder *B, SPIRVMDWalker *W);
7274
void preprocessVectorComputeMetadata(Module *M, SPIRVMDBuilder *B,
7375
SPIRVMDWalker *W);
@@ -94,6 +96,24 @@ bool PreprocessMetadata::runOnModule(Module &Module) {
9496
return true;
9597
}
9698

99+
void PreprocessMetadata::preprocessCXXStructorList(
100+
SPIRVMDBuilder::NamedMDWrapper &EM, GlobalVariable *V,
101+
ExecutionMode EMode) {
102+
auto *List = dyn_cast_or_null<ConstantArray>(V->getInitializer());
103+
if (!List)
104+
return;
105+
106+
for (Value *V : List->operands()) {
107+
auto *Structor = cast<ConstantStruct>(V);
108+
109+
// Each entry in the list is a struct containing 3 members:
110+
// (priority, function, data), with function being the entry point.
111+
auto *Kernel = cast<Function>(Structor->getOperand(1));
112+
113+
EM.addOp().add(Kernel).add(EMode).done();
114+
}
115+
}
116+
97117
void PreprocessMetadata::visit(Module *M) {
98118
SPIRVMDBuilder B(*M);
99119
SPIRVMDWalker W(*M);
@@ -105,6 +125,10 @@ void PreprocessMetadata::visit(Module *M) {
105125
// of OpExecutionMode instructions
106126
auto EM = B.addNamedMD(kSPIRVMD::ExecutionMode); // !spirv.ExecutionMode = {}
107127

128+
// Process special variables in LLVM IR module.
129+
if (auto *GV = M->getGlobalVariable("llvm.global_ctors"))
130+
preprocessCXXStructorList(EM, GV, spv::ExecutionModeInitializer);
131+
108132
// Add execution modes for kernels. We take it from metadata attached to
109133
// the kernel functions.
110134
for (Function &Kernel : *M) {

llvm-spirv/test/CXX/global-ctor.cl

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// RUN: %clang_cc1 -cl-std=clc++ -emit-llvm-bc -triple spir -O0 %s -o %t.bc
2+
// RUN: llvm-spirv %t.bc -o %t.spv
3+
// RUN: spirv-val %t.spv
4+
// RUN: llvm-spirv %t.spv -to-text -o - | FileCheck %s --check-prefix=CHECK-SPIRV
5+
6+
class Something {
7+
public:
8+
Something(int a) : v(a) {}
9+
int v;
10+
};
11+
12+
Something g(33);
13+
14+
void kernel work(global int *out) {
15+
*out = g.v;
16+
}
17+
18+
// CHECK-SPIRV: EntryPoint 6 [[work:[0-9]+]] "work"
19+
// CHECK-SPIRV-NOT: ExecutionMode [[work]] 33
20+
// CHECK-SPIRV: EntryPoint 6 [[ctor:[0-9]+]] "_GLOBAL__sub_I_global_ctor.cl"
21+
// CHECK-SPIRV: ExecutionMode [[ctor]] 33

0 commit comments

Comments
 (0)