Skip to content

Commit b035640

Browse files
svenvhvmaksimo
authored andcommitted
Translate Initializer to llvm.global_ctors
Reconstruct a llvm.global_ctors variable for entry points with the Initializer Execution Mode.
1 parent e8e4495 commit b035640

File tree

3 files changed

+51
-0
lines changed

3 files changed

+51
-0
lines changed

llvm-spirv/lib/SPIRV/SPIRVReader.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3691,6 +3691,45 @@ void SPIRVToLLVM::transGlobalCtorDtors(SPIRVVariable *BV) {
36913691
cast<GlobalValue>(V)->setLinkage(GlobalValue::AppendingLinkage);
36923692
}
36933693

3694+
void SPIRVToLLVM::createCXXStructor(const char *ListName,
3695+
SmallVectorImpl<Function *> &Funcs) {
3696+
if (Funcs.empty())
3697+
return;
3698+
3699+
// If the SPIR-V input contained a variable for the structor list and it
3700+
// has already been translated, then don't interfere.
3701+
if (M->getGlobalVariable(ListName))
3702+
return;
3703+
3704+
// Type of a structor entry: { i32, void ()*, i8* }
3705+
Type *PriorityTy = Type::getInt32Ty(*Context);
3706+
PointerType *CtorTy = PointerType::getUnqual(
3707+
FunctionType::get(Type::getVoidTy(*Context), false));
3708+
PointerType *ComdatTy = Type::getInt8PtrTy(*Context);
3709+
StructType *StructorTy = StructType::get(PriorityTy, CtorTy, ComdatTy);
3710+
3711+
ArrayType *ArrTy = ArrayType::get(StructorTy, Funcs.size());
3712+
3713+
GlobalVariable *GV =
3714+
cast<GlobalVariable>(M->getOrInsertGlobal(ListName, ArrTy));
3715+
GV->setLinkage(GlobalValue::AppendingLinkage);
3716+
3717+
// Build the initializer.
3718+
SmallVector<Constant *, 2> ArrayElts;
3719+
for (auto *F : Funcs) {
3720+
SmallVector<Constant *, 3> Elts;
3721+
// SPIR-V does not specify an order between Initializers, so set default
3722+
// priority.
3723+
Elts.push_back(ConstantInt::get(PriorityTy, 65535));
3724+
Elts.push_back(ConstantExpr::getBitCast(F, CtorTy));
3725+
Elts.push_back(ConstantPointerNull::get(ComdatTy));
3726+
ArrayElts.push_back(ConstantStruct::get(StructorTy, Elts));
3727+
}
3728+
3729+
Constant *NewArray = ConstantArray::get(ArrTy, ArrayElts);
3730+
GV->setInitializer(NewArray);
3731+
}
3732+
36943733
bool SPIRVToLLVM::transFPContractMetadata() {
36953734
bool ContractOff = false;
36963735
for (unsigned I = 0, E = BM->getNumFunctions(); I != E; ++I) {
@@ -3767,6 +3806,7 @@ static bool transKernelArgTypeMedataFromString(LLVMContext *Ctx,
37673806
}
37683807

37693808
bool SPIRVToLLVM::transMetadata() {
3809+
SmallVector<Function *, 2> CtorKernels;
37703810
for (unsigned I = 0, E = BM->getNumFunctions(); I != E; ++I) {
37713811
SPIRVFunction *BF = BM->getFunction(I);
37723812
Function *F = static_cast<Function *>(getTranslatedValue(BF));
@@ -3798,6 +3838,10 @@ bool SPIRVToLLVM::transMetadata() {
37983838
ConstantInt::get(Type::getInt32Ty(*Context), 1)));
37993839
F->setMetadata(kSPIR2MD::VecTyHint, MDNode::get(*Context, MetadataVec));
38003840
}
3841+
// Generate metadata for Initializer.
3842+
if (BF->getExecutionMode(ExecutionModeInitializer)) {
3843+
CtorKernels.push_back(F);
3844+
}
38013845
// Generate metadata for intel_reqd_sub_group_size
38023846
if (auto *EM = BF->getExecutionMode(ExecutionModeSubgroupSize)) {
38033847
auto SizeMD = ConstantAsMetadata::get(getUInt32(M, EM->getLiterals()[0]));
@@ -3828,6 +3872,7 @@ bool SPIRVToLLVM::transMetadata() {
38283872
MemoryModelMD->addOperand(
38293873
getMDTwoInt(Context, static_cast<unsigned>(BM->getAddressingModel()),
38303874
static_cast<unsigned>(BM->getMemoryModel())));
3875+
createCXXStructor("llvm.global_ctors", CtorKernels);
38313876
return true;
38323877
}
38333878

llvm-spirv/lib/SPIRV/SPIRVReader.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,8 @@ class SPIRVToLLVM {
271271
void transUserSemantic(SPIRV::SPIRVFunction *Fun);
272272
void transGlobalAnnotations();
273273
void transGlobalCtorDtors(SPIRVVariable *BV);
274+
void createCXXStructor(const char *ListName,
275+
SmallVectorImpl<Function *> &Funcs);
274276
void transIntelFPGADecorations(SPIRVValue *BV, Value *V);
275277
}; // class SPIRVToLLVM
276278

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
// RUN: llvm-spirv %t.bc -o %t.spv
33
// RUN: spirv-val %t.spv
44
// RUN: llvm-spirv %t.spv -to-text -o - | FileCheck %s --check-prefix=CHECK-SPIRV
5+
// RUN: llvm-spirv -r %t.spv -o - | llvm-dis -o - | FileCheck %s --check-prefix=CHECK-LLVM
56

67
class Something {
78
public:
@@ -19,3 +20,6 @@ void kernel work(global int *out) {
1920
// CHECK-SPIRV-NOT: ExecutionMode [[work]] 33
2021
// CHECK-SPIRV: EntryPoint 6 [[ctor:[0-9]+]] "_GLOBAL__sub_I_global_ctor.cl"
2122
// CHECK-SPIRV: ExecutionMode [[ctor]] 33
23+
24+
// CHECK-LLVM: llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @[[CTORNAME:_GLOBAL__sub_I[^ ]+]], i8* null }
25+
// CHECK-LLVM: define spir_kernel void @[[CTORNAME]]

0 commit comments

Comments
 (0)