-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[SPIRV] Add shadow function when only global variable declared in the module #164829
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[SPIRV] Add shadow function when only global variable declared in the module #164829
Conversation
|
@llvm/pr-subscribers-backend-spir-v Author: None (YixingZhang007) ChangesFull diff: https://github.com/llvm/llvm-project/pull/164829.diff 1 Files Affected:
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
index 9f2e07508a36a..64e076338816f 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
@@ -3013,6 +3013,36 @@ bool SPIRVEmitIntrinsics::runOnModule(Module &M) {
parseFunDeclarations(M);
insertConstantsForFPFastMathDefault(M);
+ // If there are no functions but there is at least one global variable,
+ // create a shadow function to "anchor" global handling in codegen.
+ bool HasAnyFunction = false;
+ for (auto &F : M)
+ if (!F.isDeclaration() && !F.isIntrinsic())
+ HasAnyFunction = true;
+
+ Function *ShadowFunc = nullptr;
+ if (!HasAnyFunction) {
+ for (auto GI = M.global_begin(), GE = M.global_end(); GI != GE; ) {
+ GlobalVariable *GV = &*GI++;
+ if (GV->hasInternalLinkage()) {
+ GV->eraseFromParent();
+ Changed = true;
+ } else if (ShadowFunc == nullptr) {
+ LLVMContext &Ctx = M.getContext();
+ auto *FTy = FunctionType::get(Type::getVoidTy(Ctx), /*isVarArg=*/false);
+ ShadowFunc = Function::Create(
+ FTy, GlobalValue::InternalLinkage, "__spirv_globals_entry", &M);
+
+ // Create a basic block and insert a ret void
+ BasicBlock *BB = BasicBlock::Create(Ctx, "entry", ShadowFunc);
+ IRBuilder<> B(BB);
+ B.CreateRetVoid();
+
+ Changed = true;
+ }
+ }
+ }
+
TodoType.clear();
for (auto &F : M)
Changed |= runOnFunction(F);
|
You can test this locally with the following command:git-clang-format --diff origin/main HEAD --extensions cpp -- llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp --diff_from_common_commit
View the diff from clang-format here.diff --git a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
index cc6d122c0..ae48f4dd8 100644
--- a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp
@@ -304,9 +304,10 @@ void SPIRVAsmPrinter::emitInstruction(const MachineInstr *MI) {
void SPIRVAsmPrinter::outputModuleSection(SPIRV::ModuleSectionType MSType) {
const Function &F = MF->getFunction();
for (const MachineInstr *MI : MAI->getMSInstrs(MSType)) {
- if (F.getName() != "__spirv_globals_entry" || ((MI->getOpcode() != SPIRV::OpName)
- && (MI->getOpcode() != SPIRV::OpTypeVoid)
- && (MI->getOpcode() != SPIRV::OpTypeFunction))) {
+ if (F.getName() != "__spirv_globals_entry" ||
+ ((MI->getOpcode() != SPIRV::OpName) &&
+ (MI->getOpcode() != SPIRV::OpTypeVoid) &&
+ (MI->getOpcode() != SPIRV::OpTypeFunction))) {
outputInstruction(MI);
}
}
diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
index 7a67cb35d..3b8bfd2eb 100644
--- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
+++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp
@@ -3029,25 +3029,25 @@ bool SPIRVEmitIntrinsics::runOnModule(Module &M) {
Function *ShadowFunc = nullptr;
if (!HasAnyFunction) {
- for (auto GI = M.global_begin(), GE = M.global_end(); GI != GE; ) {
- GlobalVariable *GV = &*GI++;
- if (GV->hasInternalLinkage()) {
- GV->eraseFromParent();
- Changed = true;
- } else if (ShadowFunc == nullptr) {
- LLVMContext &Ctx = M.getContext();
- auto *FTy = FunctionType::get(Type::getVoidTy(Ctx), /*isVarArg=*/false);
- ShadowFunc = Function::Create(
- FTy, GlobalValue::InternalLinkage, "__spirv_globals_entry", &M);
-
- // Create a basic block and insert a ret void
- BasicBlock *BB = BasicBlock::Create(Ctx, "entry", ShadowFunc);
- IRBuilder<> B(BB);
- B.CreateRetVoid();
-
- Changed = true;
- }
+ for (auto GI = M.global_begin(), GE = M.global_end(); GI != GE;) {
+ GlobalVariable *GV = &*GI++;
+ if (GV->hasInternalLinkage()) {
+ GV->eraseFromParent();
+ Changed = true;
+ } else if (ShadowFunc == nullptr) {
+ LLVMContext &Ctx = M.getContext();
+ auto *FTy = FunctionType::get(Type::getVoidTy(Ctx), /*isVarArg=*/false);
+ ShadowFunc = Function::Create(FTy, GlobalValue::InternalLinkage,
+ "__spirv_globals_entry", &M);
+
+ // Create a basic block and insert a ret void
+ BasicBlock *BB = BasicBlock::Create(Ctx, "entry", ShadowFunc);
+ IRBuilder<> B(BB);
+ B.CreateRetVoid();
+
+ Changed = true;
}
+ }
}
TodoType.clear();
|
ea674a6 to
63ae5de
Compare
…there is global variable but no function
63ae5de to
388e124
Compare
This PR is still working in progress. Thank you for your understanding!