diff --git a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp index c0795146e9b923..1b85b72bc690ed 100644 --- a/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVAsmPrinter.cpp @@ -150,7 +150,9 @@ void SPIRVAsmPrinter::outputOpFunctionEnd() { // Emit OpFunctionEnd at the end of MF and clear BBNumToRegMap. void SPIRVAsmPrinter::emitFunctionBodyEnd() { // Do not emit anything if it's an internal service function. - if (MF->getFunction().getFnAttribute(SPIRV_BACKEND_SERVICE_FUN_NAME).isValid()) + if (MF->getFunction() + .getFnAttribute(SPIRV_BACKEND_SERVICE_FUN_NAME) + .isValid()) return; outputOpFunctionEnd(); diff --git a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp index 43e70ae2032dfe..e9dfdde24ff3ba 100644 --- a/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVEmitIntrinsics.cpp @@ -1673,6 +1673,52 @@ void SPIRVEmitIntrinsics::processParamTypes(Function *F, IRBuilder<> &B) { } } +bool SPIRVEmitIntrinsics::processFunctionPointers(Module &M) { + bool IsExt = false; + SmallVector Worklist; + for (auto &F : M) { + if (!IsExt) { + if (!TM->getSubtarget(F).canUseExtension( + SPIRV::Extension::SPV_INTEL_function_pointers)) + return false; + IsExt = true; + } + if (!F.isDeclaration() || F.isIntrinsic()) + continue; + for (User *U : F.users()) { + CallInst *CI = dyn_cast(U); + if (!CI || CI->getCalledFunction() != &F) { + Worklist.push_back(&F); + break; + } + } + } + if (Worklist.empty()) + return false; + + std::string ServiceFunName = SPIRV_BACKEND_SERVICE_FUN_NAME; + if (!getVacantFunctionName(M, ServiceFunName)) + report_fatal_error( + "cannot allocate a name for the internal service function"); + LLVMContext &Ctx = M.getContext(); + Function *SF = + Function::Create(FunctionType::get(Type::getVoidTy(Ctx), {}, false), + GlobalValue::PrivateLinkage, ServiceFunName, M); + SF->addFnAttr(SPIRV_BACKEND_SERVICE_FUN_NAME, ""); + BasicBlock *BB = BasicBlock::Create(Ctx, "entry", SF); + IRBuilder<> IRB(BB); + + for (Function *F : Worklist) { + SmallVector Args; + for (const auto &Arg : F->args()) + Args.push_back(PoisonValue::get(Arg.getType())); + IRB.CreateCall(F, Args); + } + IRB.CreateRetVoid(); + + return true; +} + bool SPIRVEmitIntrinsics::runOnFunction(Function &Func) { if (Func.isDeclaration()) return false; @@ -1832,52 +1878,6 @@ bool SPIRVEmitIntrinsics::runOnModule(Module &M) { return Changed; } -bool SPIRVEmitIntrinsics::processFunctionPointers(Module &M) { - bool IsExt = false; - SmallVector Worklist; - for (auto &F : M) { - if (!IsExt) { - if (!TM->getSubtarget(F).canUseExtension( - SPIRV::Extension::SPV_INTEL_function_pointers)) - return false; - IsExt = true; - } - if (!F.isDeclaration() || F.isIntrinsic()) - continue; - for (User *U : F.users()) { - CallInst *CI = dyn_cast(U); - if (!CI || CI->getCalledFunction() != &F) { - Worklist.push_back(&F); - break; - } - } - } - if (Worklist.empty()) - return false; - - std::string ServiceFunName = SPIRV_BACKEND_SERVICE_FUN_NAME; - if (!getVacantFunctionName(M, ServiceFunName)) - report_fatal_error( - "cannot allocate a name for the internal service function"); - LLVMContext &Ctx = M.getContext(); - Function *SF = - Function::Create(FunctionType::get(Type::getVoidTy(Ctx), {}, false), - GlobalValue::PrivateLinkage, ServiceFunName, M); - SF->addFnAttr(SPIRV_BACKEND_SERVICE_FUN_NAME, ""); - BasicBlock *BB = BasicBlock::Create(Ctx, "entry", SF); - IRBuilder<> IRB(BB); - - for (Function *F : Worklist) { - SmallVector Args; - for (const auto &Arg : F->args()) - Args.push_back(PoisonValue::get(Arg.getType())); - IRB.CreateCall(F, Args); - } - IRB.CreateRetVoid(); - - return true; -} - ModulePass *llvm::createSPIRVEmitIntrinsicsPass(SPIRVTargetMachine *TM) { return new SPIRVEmitIntrinsics(TM); }