diff --git a/llvm/include/llvm/CodeGen/MIRYamlMapping.h b/llvm/include/llvm/CodeGen/MIRYamlMapping.h --- a/llvm/include/llvm/CodeGen/MIRYamlMapping.h +++ b/llvm/include/llvm/CodeGen/MIRYamlMapping.h @@ -453,6 +453,10 @@ MachineInstrLoc CallLocation; std::vector ArgForwardingRegs; + /// Numeric callee type identifier used for call graph section. + using TypeIdTy = Optional; + TypeIdTy TypeId; + bool operator==(const CallSiteInfo &Other) const { return CallLocation.BlockNum == Other.CallLocation.BlockNum && CallLocation.Offset == Other.CallLocation.Offset; @@ -481,6 +485,7 @@ YamlIO.mapRequired("offset", CSInfo.CallLocation.Offset); YamlIO.mapOptional("fwdArgRegs", CSInfo.ArgForwardingRegs, std::vector()); + YamlIO.mapOptional("typeId", CSInfo.TypeId, None); } static const bool flow = true; diff --git a/llvm/include/llvm/CodeGen/MachineFunction.h b/llvm/include/llvm/CodeGen/MachineFunction.h --- a/llvm/include/llvm/CodeGen/MachineFunction.h +++ b/llvm/include/llvm/CodeGen/MachineFunction.h @@ -418,6 +418,9 @@ struct CallSiteInfo { /// Vector of call argument and its forwarding register. SmallVector ArgRegPairs; + + /// Callee type id. + ConstantInt *TypeId = nullptr; }; private: @@ -425,7 +428,7 @@ GISelChangeObserver *Observer = nullptr; using CallSiteInfoMap = DenseMap; - /// Map a call instruction to call site arguments forwarding info. + /// Map a call instruction to call site arguments forwarding and type id. CallSiteInfoMap CallSitesInfo; /// A helper function that returns call site info for a give call @@ -1174,7 +1177,7 @@ return VariableDbgInfos; } - /// Start tracking the arguments passed to the call \p CallI. + /// Start tracking the arguments passed to the call \p CallI and call type. void addCallSiteInfo(const MachineInstr *CallI, CallSiteInfo &&CallInfo) { assert(CallI->isCandidateForCallSiteEntry()); bool Inserted = diff --git a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp --- a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp +++ b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp @@ -403,12 +403,18 @@ return error(Error, ArgRegPair.Reg.SourceRange); CSInfo.ArgRegPairs.emplace_back(Reg, ArgRegPair.ArgNo); } + if (YamlCSInfo.TypeId.hasValue()) { + IntegerType *Int64Ty = Type::getInt64Ty(Context); + CSInfo.TypeId = ConstantInt::get(Int64Ty, YamlCSInfo.TypeId.getValue(), + /*isSigned=*/false); + } - if (TM.Options.EmitCallSiteInfo) + if (TM.Options.EmitCallSiteInfo || TM.Options.EmitCallGraphSection) MF.addCallSiteInfo(&*CallI, std::move(CSInfo)); } - if (YamlMF.CallSitesInfo.size() && !TM.Options.EmitCallSiteInfo) + if (YamlMF.CallSitesInfo.size() && + !(TM.Options.EmitCallSiteInfo || TM.Options.EmitCallGraphSection)) return error(Twine("Call site info provided but not used")); return false; } diff --git a/llvm/lib/CodeGen/MIRPrinter.cpp b/llvm/lib/CodeGen/MIRPrinter.cpp --- a/llvm/lib/CodeGen/MIRPrinter.cpp +++ b/llvm/lib/CodeGen/MIRPrinter.cpp @@ -525,6 +525,9 @@ printRegMIR(ArgReg.Reg, YmlArgReg.Reg, TRI); YmlCS.ArgForwardingRegs.emplace_back(YmlArgReg); } + // Get type id. + if (CSInfo.second.TypeId) + YmlCS.TypeId = CSInfo.second.TypeId->getZExtValue(); YMF.CallSitesInfo.push_back(YmlCS); } diff --git a/llvm/lib/CodeGen/MachineFunction.cpp b/llvm/lib/CodeGen/MachineFunction.cpp --- a/llvm/lib/CodeGen/MachineFunction.cpp +++ b/llvm/lib/CodeGen/MachineFunction.cpp @@ -897,7 +897,7 @@ assert(MI->isCandidateForCallSiteEntry() && "Call site info refers only to call (MI) candidates"); - if (!Target.Options.EmitCallSiteInfo) + if (!Target.Options.EmitCallSiteInfo && !Target.Options.EmitCallGraphSection) return CallSitesInfo.end(); return CallSitesInfo.find(MI); } diff --git a/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.mir b/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.mir new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/MIR/X86/call-site-info-typeid.mir @@ -0,0 +1,68 @@ +# Test MIR printer and parser for type id field in callSites. It is used +# for propogating call site type identifiers to emit in the call graph section. + +# RUN: llc --call-graph-section %s -run-pass=none -o - | FileCheck %s +# CHECK: name: main +# CHECK: callSites: +# CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], typeId: +# CHECK-NEXT: 123456789 } + +--- | + ; ModuleID = 'test.ll' + source_filename = "test.ll" + target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" + target triple = "x86_64-unknown-linux-gnu" + + define dso_local void @foo(i8 signext %a) { + entry: + ret void + } + + define dso_local i32 @main() { + entry: + %retval = alloca i32, align 4 + %fp = alloca void (i8)*, align 8 + store i32 0, i32* %retval, align 4 + store void (i8)* @foo, void (i8)** %fp, align 8 + %0 = load void (i8)*, void (i8)** %fp, align 8 + call void %0(i8 signext 97) + ret i32 0 + } + +... +--- +name: foo +tracksRegLiveness: true +body: | + bb.0.entry: + RET 0 + +... +--- +name: main +tracksRegLiveness: true +stack: + - { id: 0, name: retval, type: default, offset: 0, size: 4, alignment: 4, + stack-id: default, callee-saved-register: '', callee-saved-restored: true, + debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } + - { id: 1, name: fp, type: default, offset: 0, size: 8, alignment: 8, + stack-id: default, callee-saved-register: '', callee-saved-restored: true, + debug-info-variable: '', debug-info-expression: '', debug-info-location: '' } +callSites: + - { bb: 0, offset: 6, fwdArgRegs: [], typeId: + 123456789 } +body: | + bb.0.entry: + MOV32mi %stack.0.retval, 1, $noreg, 0, $noreg, 0 :: (store (s32) into %ir.retval) + MOV64mi32 %stack.1.fp, 1, $noreg, 0, $noreg, @foo :: (store (s64) into %ir.fp) + %0:gr64 = MOV32ri64 @foo + ADJCALLSTACKDOWN64 0, 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp + %1:gr32 = MOV32ri 97 + $edi = COPY %1 + CALL64r killed %0, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit-def $rsp, implicit-def $ssp + ADJCALLSTACKUP64 0, 0, implicit-def dead $rsp, implicit-def dead $eflags, implicit-def dead $ssp, implicit $rsp, implicit $ssp + %2:gr32 = MOV32r0 implicit-def dead $eflags + $eax = COPY %2 + RET 0, $eax + +...