@@ -68,6 +68,8 @@ class PreprocessMetadata : public ModulePass {
68
68
69
69
bool runOnModule (Module &M) override ;
70
70
void visit (Module *M);
71
+ void preprocessCXXStructorList (SPIRVMDBuilder::NamedMDWrapper &EM,
72
+ GlobalVariable *V, ExecutionMode EMode);
71
73
void preprocessOCLMetadata (Module *M, SPIRVMDBuilder *B, SPIRVMDWalker *W);
72
74
void preprocessVectorComputeMetadata (Module *M, SPIRVMDBuilder *B,
73
75
SPIRVMDWalker *W);
@@ -94,6 +96,24 @@ bool PreprocessMetadata::runOnModule(Module &Module) {
94
96
return true ;
95
97
}
96
98
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
+
97
117
void PreprocessMetadata::visit (Module *M) {
98
118
SPIRVMDBuilder B (*M);
99
119
SPIRVMDWalker W (*M);
@@ -105,6 +125,10 @@ void PreprocessMetadata::visit(Module *M) {
105
125
// of OpExecutionMode instructions
106
126
auto EM = B.addNamedMD (kSPIRVMD ::ExecutionMode); // !spirv.ExecutionMode = {}
107
127
128
+ // Process special variables in LLVM IR module.
129
+ if (auto *GV = M->getGlobalVariable (" llvm.global_ctors" ))
130
+ preprocessCXXStructorList (EM, GV, spv::ExecutionModeInitializer);
131
+
108
132
// Add execution modes for kernels. We take it from metadata attached to
109
133
// the kernel functions.
110
134
for (Function &Kernel : *M) {
0 commit comments