diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp index d7f620516df6b..af48d51a056f9 100644 --- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.cpp @@ -92,7 +92,7 @@ void SPIRVModuleAnalysis::setBaseInfo(const Module &M) { MAI.MS[i].clear(); MAI.RegisterAliasTable.clear(); MAI.InstrsToDelete.clear(); - MAI.FuncNameMap.clear(); + MAI.FuncMap.clear(); MAI.GlobalVarList.clear(); MAI.ExtInstSetMap.clear(); MAI.Reqs.clear(); @@ -279,12 +279,12 @@ static bool findSameInstrInMS(const MachineInstr &A, return false; } -// Look for IDs declared with Import linkage, and map the imported name string +// Look for IDs declared with Import linkage, and map the corresponding function // to the register defining that variable (which will usually be the result of // an OpFunction). This lets us call externally imported functions using // the correct ID registers. void SPIRVModuleAnalysis::collectFuncNames(MachineInstr &MI, - const Function &F) { + const Function *F) { if (MI.getOpcode() == SPIRV::OpDecorate) { // If it's got Import linkage. auto Dec = MI.getOperand(1).getImm(); @@ -292,10 +292,10 @@ void SPIRVModuleAnalysis::collectFuncNames(MachineInstr &MI, auto Lnk = MI.getOperand(MI.getNumOperands() - 1).getImm(); if (Lnk == static_cast(SPIRV::LinkageType::Import)) { // Map imported function name to function ID register. - std::string Name = getStringImm(MI, 2); + const Function *ImportedFunc = + F->getParent()->getFunction(getStringImm(MI, 2)); Register Target = MI.getOperand(0).getReg(); - // TODO: check defs from different MFs. - MAI.FuncNameMap[Name] = MAI.getRegisterAlias(MI.getMF(), Target); + MAI.FuncMap[ImportedFunc] = MAI.getRegisterAlias(MI.getMF(), Target); } } } else if (MI.getOpcode() == SPIRV::OpFunction) { @@ -303,8 +303,7 @@ void SPIRVModuleAnalysis::collectFuncNames(MachineInstr &MI, Register Reg = MI.defs().begin()->getReg(); Register GlobalReg = MAI.getRegisterAlias(MI.getMF(), Reg); assert(GlobalReg.isValid()); - // TODO: check that it does not conflict with existing entries. - MAI.FuncNameMap[getFunctionGlobalIdentifier(&F)] = GlobalReg; + MAI.FuncMap[F] = GlobalReg; } } @@ -343,13 +342,13 @@ void SPIRVModuleAnalysis::processOtherInstrs(const Module &M) { collectOtherInstr(MI, MAI, SPIRV::MB_EntryPoints); } else if (TII->isDecorationInstr(MI)) { collectOtherInstr(MI, MAI, SPIRV::MB_Annotations); - collectFuncNames(MI, *F); + collectFuncNames(MI, &*F); } else if (TII->isConstantInstr(MI)) { // Now OpSpecConstant*s are not in DT, // but they need to be collected anyway. collectOtherInstr(MI, MAI, SPIRV::MB_TypeConstVars); } else if (OpCode == SPIRV::OpFunction) { - collectFuncNames(MI, *F); + collectFuncNames(MI, &*F); } else if (OpCode == SPIRV::OpTypeForwardPointer) { collectOtherInstr(MI, MAI, SPIRV::MB_TypeConstVars, false); } diff --git a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h index c99fdeb5ae364..a8b659ce3957f 100644 --- a/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h +++ b/llvm/lib/Target/SPIRV/SPIRVModuleAnalysis.h @@ -131,8 +131,8 @@ struct ModuleAnalysisInfo { DenseMap ExtInstSetMap; // Contains the list of all global OpVariables in the module. SmallVector GlobalVarList; - // Maps function names to coresponding function ID registers. - StringMap FuncNameMap; + // Maps functions to corresponding function ID registers. + DenseMap FuncMap; // The set contains machine instructions which are necessary // for correct MIR but will not be emitted in function bodies. DenseSet InstrsToDelete; @@ -152,9 +152,9 @@ struct ModuleAnalysisInfo { Register getFuncReg(const Function *F) { assert(F && "Function is null"); - auto FuncReg = FuncNameMap.find(getFunctionGlobalIdentifier(F)); - assert(FuncReg != FuncNameMap.end() && "Cannot find function Id"); - return FuncReg->second; + auto FuncPtrRegPair = FuncMap.find(F); + assert(FuncPtrRegPair != FuncMap.end() && "Cannot find function ID"); + return FuncPtrRegPair->second; } Register getExtInstSetReg(unsigned SetNum) { return ExtInstSetMap[SetNum]; } InstrList &getMSInstrs(unsigned MSType) { return MS[MSType]; } @@ -211,7 +211,7 @@ struct SPIRVModuleAnalysis : public ModulePass { std::function Pred, bool UsePreOrder); void processDefInstrs(const Module &M); - void collectFuncNames(MachineInstr &MI, const Function &F); + void collectFuncNames(MachineInstr &MI, const Function *F); void processOtherInstrs(const Module &M); void numberRegistersGlobally(const Module &M); diff --git a/llvm/lib/Target/SPIRV/SPIRVUtils.cpp b/llvm/lib/Target/SPIRV/SPIRVUtils.cpp index 0f024efdc329d..9dcddf5f5e34e 100644 --- a/llvm/lib/Target/SPIRV/SPIRVUtils.cpp +++ b/llvm/lib/Target/SPIRV/SPIRVUtils.cpp @@ -354,11 +354,4 @@ bool isSpecialOpaqueType(const Type *Ty) { return isOpenCLBuiltinType(SType) || isSPIRVBuiltinType(SType); return false; } - -std::string getFunctionGlobalIdentifier(const Function *F) { - StringRef Name = F->hasName() ? F->getName() : ".anonymous"; - GlobalValue::LinkageTypes Linkage = F->getLinkage(); - StringRef ModuleFileName = F->getParent()->getSourceFileName(); - return GlobalValue::getGlobalIdentifier(Name, Linkage, ModuleFileName); -} } // namespace llvm diff --git a/llvm/lib/Target/SPIRV/SPIRVUtils.h b/llvm/lib/Target/SPIRV/SPIRVUtils.h index 09e14a0f84a3a..7c193611a8574 100644 --- a/llvm/lib/Target/SPIRV/SPIRVUtils.h +++ b/llvm/lib/Target/SPIRV/SPIRVUtils.h @@ -94,7 +94,5 @@ const Type *getTypedPtrEltType(const Type *Type); // Check if given LLVM type is a special opaque builtin type. bool isSpecialOpaqueType(const Type *Ty); - -std::string getFunctionGlobalIdentifier(const Function *F); } // namespace llvm #endif // LLVM_LIB_TARGET_SPIRV_SPIRVUTILS_H diff --git a/llvm/test/CodeGen/SPIRV/function/internal-anonymous-function.ll b/llvm/test/CodeGen/SPIRV/function/internal-anonymous-function.ll deleted file mode 100644 index 761091924d56b..0000000000000 --- a/llvm/test/CodeGen/SPIRV/function/internal-anonymous-function.ll +++ /dev/null @@ -1,20 +0,0 @@ -; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s - -;; Types: -; CHECK-DAG: %[[#F32:]] = OpTypeFloat 32 -; CHECK-DAG: %[[#FNF32:]] = OpTypeFunction %[[#F32]] %[[#F32]] -;; Function decl: -; CHECK: %[[#ANON:]] = OpFunction %[[#F32]] None %[[#FNF32]] -; CHECK-NEXT: OpFunctionParameter %[[#F32]] -; CHECK-NEXT: OpLabel -; CHECK-NEXT: OpReturnValue -; CHECK-NEXT: OpFunctionEnd -define internal spir_func float @0(float %a) { - ret float %a -} - -; CHECK: OpFunctionCall %[[#F32]] %[[#ANON]] -define spir_kernel void @foo(float %a) { - %1 = call spir_func float @0(float %a) - ret void -} diff --git a/llvm/test/CodeGen/SPIRV/function/multiple-anonymous-functions.ll b/llvm/test/CodeGen/SPIRV/function/multiple-anonymous-functions.ll new file mode 100644 index 0000000000000..93bdbe3c1c211 --- /dev/null +++ b/llvm/test/CodeGen/SPIRV/function/multiple-anonymous-functions.ll @@ -0,0 +1,36 @@ +; RUN: llc -O0 -mtriple=spirv64-unknown-unknown %s -o - | FileCheck %s + +;; Types: +; CHECK-DAG: %[[#I32:]] = OpTypeInt 32 +; CHECK-DAG: %[[#F32:]] = OpTypeFloat 32 +; CHECK-DAG: %[[#FNI32:]] = OpTypeFunction %[[#I32]] %[[#I32]] +; CHECK-DAG: %[[#FNF32:]] = OpTypeFunction %[[#F32]] %[[#F32]] + +;; Function declarations: +; CHECK: %[[#ANON0:]] = OpFunction %[[#I32]] None %[[#FNI32]] +; CHECK-NEXT: OpFunctionParameter %[[#I32]] +; CHECK-NEXT: OpLabel +; CHECK-NEXT: OpReturnValue +; CHECK-NEXT: OpFunctionEnd +define internal spir_func i32 @0(i32 %a) { + ret i32 %a +} + +; CHECK: %[[#ANON1:]] = OpFunction %[[#F32]] None %[[#FNF32]] +; CHECK-NEXT: OpFunctionParameter %[[#F32]] +; CHECK-NEXT: OpLabel +; CHECK-NEXT: OpReturnValue +; CHECK-NEXT: OpFunctionEnd +define internal spir_func float @1(float %a) { + ret float %a +} + +;; Calls: +; CHECK: OpFunctionCall %[[#I32]] %[[#ANON0]] +; CHECK: OpFunctionCall %[[#F32]] %[[#ANON1]] +define spir_kernel void @foo(i32 %a) { + %call1 = call spir_func i32 @0(i32 %a) + %b = sitofp i32 %a to float + %call2 = call spir_func float @1(float %b) + ret void +}