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();
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();
auto Lnk = MI.getOperand(MI.getNumOperands() - 1).getImm();
if (Lnk == static_cast<unsigned>(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) {
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;
}
}
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);
}
DenseMap<unsigned, Register> ExtInstSetMap;
// Contains the list of all global OpVariables in the module.
SmallVector<MachineInstr *, 4> GlobalVarList;
- // Maps function names to coresponding function ID registers.
- StringMap<Register> FuncNameMap;
+ // Maps functions to corresponding function ID registers.
+ DenseMap<const Function *, Register> FuncMap;
// The set contains machine instructions which are necessary
// for correct MIR but will not be emitted in function bodies.
DenseSet<MachineInstr *> InstrsToDelete;
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]; }
std::function<bool(const SPIRV::DTSortableEntry *)> 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);
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
// 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
+++ /dev/null
-; 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
-}
--- /dev/null
+; 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
+}