Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions llvm/include/llvm/CodeGen/CommandFlags.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ LLVM_ABI bool getEnableStackSizeSection();

LLVM_ABI bool getEnableAddrsig();

LLVM_ABI bool getEnableCallGraphSection();

LLVM_ABI bool getEmitCallSiteInfo();

LLVM_ABI bool getEnableMachineFunctionSplitter();
Expand Down
3 changes: 3 additions & 0 deletions llvm/include/llvm/CodeGen/MIRYamlMapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -482,6 +482,8 @@ struct CallSiteInfo {

MachineInstrLoc CallLocation;
std::vector<ArgRegPair> ArgForwardingRegs;
/// Numeric callee type identifiers for the callgraph section.
std::vector<uint64_t> CalleeTypeIds;

bool operator==(const CallSiteInfo &Other) const {
return CallLocation.BlockNum == Other.CallLocation.BlockNum &&
Expand Down Expand Up @@ -511,6 +513,7 @@ template <> struct MappingTraits<CallSiteInfo> {
YamlIO.mapRequired("offset", CSInfo.CallLocation.Offset);
YamlIO.mapOptional("fwdArgRegs", CSInfo.ArgForwardingRegs,
std::vector<CallSiteInfo::ArgRegPair>());
YamlIO.mapOptional("calleeTypeIds", CSInfo.CalleeTypeIds);
}

static const bool flow = true;
Expand Down
2 changes: 2 additions & 0 deletions llvm/include/llvm/CodeGen/MachineFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,8 @@ class LLVM_ABI MachineFunction {
struct CallSiteInfo {
/// Vector of call argument and its forwarding register.
SmallVector<ArgRegPair, 1> ArgRegPairs;
/// Callee type ids.
SmallVector<ConstantInt *, 4> CalleeTypeIds;
};

struct CalledGlobalInfo {
Expand Down
12 changes: 8 additions & 4 deletions llvm/include/llvm/Target/TargetOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,11 @@ class TargetOptions {
EmitStackSizeSection(false), EnableMachineOutliner(false),
EnableMachineFunctionSplitter(false),
EnableStaticDataPartitioning(false), SupportsDefaultOutlining(false),
EmitAddrsig(false), BBAddrMap(false), EmitCallSiteInfo(false),
SupportsDebugEntryValues(false), EnableDebugEntryValues(false),
ValueTrackingVariableLocations(false), ForceDwarfFrameSection(false),
XRayFunctionIndex(true), DebugStrictDwarf(false), Hotpatch(false),
EmitAddrsig(false), BBAddrMap(false), EmitCallGraphSection(false),
EmitCallSiteInfo(false), SupportsDebugEntryValues(false),
EnableDebugEntryValues(false), ValueTrackingVariableLocations(false),
ForceDwarfFrameSection(false), XRayFunctionIndex(true),
DebugStrictDwarf(false), Hotpatch(false),
PPCGenScalarMASSEntries(false), JMCInstrument(false),
EnableCFIFixup(false), MisExpect(false), XCOFFReadOnlyPointers(false),
VerifyArgABICompliance(true),
Expand Down Expand Up @@ -319,6 +320,9 @@ class TargetOptions {
/// to selectively generate basic block sections.
std::shared_ptr<MemoryBuffer> BBSectionsFuncListBuf;

/// Emit section containing call graph metadata.
unsigned EmitCallGraphSection : 1;

/// The flag enables call site info production. It is used only for debug
/// info, and it is restricted only to optimized code. This can be used for
/// something else, so that should be controlled in the frontend.
Expand Down
7 changes: 7 additions & 0 deletions llvm/lib/CodeGen/CommandFlags.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ CGOPT(EABI, EABIVersion)
CGOPT(DebuggerKind, DebuggerTuningOpt)
CGOPT(bool, EnableStackSizeSection)
CGOPT(bool, EnableAddrsig)
CGOPT(bool, EnableCallGraphSection)
CGOPT(bool, EmitCallSiteInfo)
CGOPT(bool, EnableMachineFunctionSplitter)
CGOPT(bool, EnableStaticDataPartitioning)
Expand Down Expand Up @@ -461,6 +462,11 @@ codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() {
cl::init(false));
CGBINDOPT(EnableAddrsig);

static cl::opt<bool> EnableCallGraphSection(
"call-graph-section", cl::desc("Emit a call graph section"),
cl::init(false));
CGBINDOPT(EnableCallGraphSection);

static cl::opt<bool> EmitCallSiteInfo(
"emit-call-site-info",
cl::desc(
Expand Down Expand Up @@ -595,6 +601,7 @@ codegen::InitTargetOptionsFromCodeGenFlags(const Triple &TheTriple) {
Options.EnableMachineFunctionSplitter = getEnableMachineFunctionSplitter();
Options.EnableStaticDataPartitioning = getEnableStaticDataPartitioning();
Options.EmitAddrsig = getEnableAddrsig();
Options.EmitCallGraphSection = getEnableCallGraphSection();
Options.EmitCallSiteInfo = getEmitCallSiteInfo();
Options.EnableDebugEntryValues = getEnableDebugEntryValues();
Options.ForceDwarfFrameSection = getForceDwarfFrameSection();
Expand Down
14 changes: 11 additions & 3 deletions llvm/lib/CodeGen/MIRParser/MIRParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -504,13 +504,21 @@ bool MIRParserImpl::initializeCallSiteInfo(
return error(Error, ArgRegPair.Reg.SourceRange);
CSInfo.ArgRegPairs.emplace_back(Reg, ArgRegPair.ArgNo);
}
if (!YamlCSInfo.CalleeTypeIds.empty()) {
for (auto CalleeTypeId : YamlCSInfo.CalleeTypeIds) {
IntegerType *Int64Ty = Type::getInt64Ty(Context);
CSInfo.CalleeTypeIds.push_back(ConstantInt::get(Int64Ty, CalleeTypeId,
/*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)
return error(Twine("Call site info provided but not used"));
if (!YamlMF.CallSitesInfo.empty() &&
!(TM.Options.EmitCallSiteInfo || TM.Options.EmitCallGraphSection))
return error("call site info provided but not used");
return false;
}

Expand Down
12 changes: 9 additions & 3 deletions llvm/lib/CodeGen/MIRPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -525,24 +525,30 @@ static void convertCallSiteObjects(yaml::MachineFunction &YMF,
const MachineFunction &MF,
ModuleSlotTracker &MST) {
const auto *TRI = MF.getSubtarget().getRegisterInfo();
for (auto CSInfo : MF.getCallSitesInfo()) {
for (auto [MI, CallSiteInfo] : MF.getCallSitesInfo()) {
yaml::CallSiteInfo YmlCS;
yaml::MachineInstrLoc CallLocation;

// Prepare instruction position.
MachineBasicBlock::const_instr_iterator CallI = CSInfo.first->getIterator();
MachineBasicBlock::const_instr_iterator CallI = MI->getIterator();
CallLocation.BlockNum = CallI->getParent()->getNumber();
// Get call instruction offset from the beginning of block.
CallLocation.Offset =
std::distance(CallI->getParent()->instr_begin(), CallI);
YmlCS.CallLocation = CallLocation;

auto [ArgRegPairs, CalleeTypeIds] = CallSiteInfo;
// Construct call arguments and theirs forwarding register info.
for (auto ArgReg : CSInfo.second.ArgRegPairs) {
for (auto ArgReg : ArgRegPairs) {
yaml::CallSiteInfo::ArgRegPair YmlArgReg;
YmlArgReg.ArgNo = ArgReg.ArgNo;
printRegMIR(ArgReg.Reg, YmlArgReg.Reg, TRI);
YmlCS.ArgForwardingRegs.emplace_back(YmlArgReg);
}
// Get type ids.
for (auto *CalleeTypeId : CalleeTypeIds) {
YmlCS.CalleeTypeIds.push_back(CalleeTypeId->getZExtValue());
}
YMF.CallSitesInfo.push_back(std::move(YmlCS));
}

Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/MachineFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -919,7 +919,7 @@ MachineFunction::getCallSiteInfo(const MachineInstr *MI) {
assert(MI->isCandidateForAdditionalCallInfo() &&
"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);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Test MIR printer and parser to check if a call instruction with multiple
# callee types are handled correctly.

# RUN: llc -mtriple=x86_64 --call-graph-section %s -run-pass=none -o - | FileCheck --match-full-lines %s
# CHECK: name: ambiguous_caller
# CHECK: callSites:
# CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: {{.*}}, calleeTypeIds:
# CHECK-NEXT: [ 1234, 5678 ] }

--- |
define ptr @ambiguous_caller() {
entry:
%fn = alloca ptr, align 8
%call1 = call ptr %fn(i64 4), !callee_type !0
ret ptr %call1
}

!0 = !{!1, !2}
!1 = !{i64 0, !"callee_type0.generalized"}
!2 = !{i64 0, !"callee_type2.generalized"}
...
---
name: ambiguous_caller
callSites:
- { bb: 0, offset: 1, fwdArgRegs: [], calleeTypeIds: [ 1234, 5678 ] }
body: |
bb.0.entry:
%0:gr64 = MOV32ri64 4
CALL64r killed %0, csr_64, implicit $rsp, implicit $ssp, implicit $rdi, implicit-def $rsp, implicit-def $ssp, implicit-def $rax
RET 0, $rax
...
54 changes: 54 additions & 0 deletions llvm/test/CodeGen/MIR/X86/call-site-info-direct-calls-typeid.mir
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Test MIR printer and parser to NOT have `CalleeTypeIds` field in callSites.
# `CalleeTypeId` is used for propagating call site type identifiers for
# indirect targets only. This test does not contain any indirect targets.

# RUN: llc -mtriple=x86_64 --call-graph-section %s -run-pass=none -o - | FileCheck --match-full-lines %s
# CHECK-NOT: calleeTypeIds
# CHECK: name: bar
# CHECK: callSites:
# CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [] }
# CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [] }
# CHECK: name: foo
# CHECK: callSites:
# CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [] }

--- |
declare i32 @fizz(i32, i32)

declare i32 @buzz(i32, i32)

define i32 @bar(i32 %x, i32 %y) !type !0 {
entry:
%call = call i32 @buzz(i32 %x, i32 %x)
%call1 = call i32 @fizz(i32 %x, i32 %x)
ret i32 0
}

define i32 @foo(i32 %x, i32 %y) !type !0 {
entry:
%call1 = call i32 @bar(i32 %x, i32 %x)
ret i32 0
}

!0 = !{i64 0, !"_ZTSFiiiE.generalized"}
...
---
name: bar
callSites:
- { bb: 0, offset: 0, fwdArgRegs: [] }
- { bb: 0, offset: 1, fwdArgRegs: [] }
body: |
bb.0.entry:
CALL64pcrel32 target-flags(x86-plt) @buzz, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit $esi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax
CALL64pcrel32 target-flags(x86-plt) @fizz, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit $esi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax

...
---
name: foo
callSites:
- { bb: 0, offset: 0, fwdArgRegs: [] }
body: |
bb.0.entry:
CALL64pcrel32 target-flags(x86-plt) @bar, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit $esi, implicit-def $rsp, implicit-def $ssp, implicit-def $eax

...
28 changes: 28 additions & 0 deletions llvm/test/CodeGen/MIR/X86/call-site-info-typeid.mir
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# Test MIR printer and parser for type id field in callSites. It is used
# for propagating call site type identifiers to emit in the call graph section.

# RUN: llc -mtriple=x86_64 --call-graph-section %s -run-pass=none -o - | FileCheck --match-full-lines %s
# CHECK: name: call_foo
# CHECK: callSites:
# CHECK-NEXT: - { bb: {{.*}}, offset: {{.*}}, fwdArgRegs: [], calleeTypeIds:
# CHECK-NEXT: [ 123456789 ] }

--- |
define i32 @call_foo() {
entry:
%0 = load ptr, ptr null, align 8
call void %0(i8 0), !callee_type !0
ret i32 0
}

!0 = !{!1}
!1 = !{i64 0, !"_ZTSFvcE.generalized"}
...
---
name: call_foo
callSites:
- { bb: 0, offset: 0, fwdArgRegs: [], calleeTypeIds: [ 123456789 ] }
body: |
bb.0.entry:
CALL64m $noreg, 1, $noreg, 0, $noreg, csr_64, implicit $rsp, implicit $ssp, implicit $edi, implicit-def $rsp, implicit-def $ssp :: (load (s64) from `ptr null`)
...