Skip to content

Commit eb26a3b

Browse files
committed
[llvm][AsmPrinter] Add direct calls to callgraph section
Extend CallGraphSection to include metadata about direct calls. This simplifies the design of tools that must parse .callgraph section to not require dependency on MC layer.
1 parent e1d45b1 commit eb26a3b

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

llvm/include/llvm/CodeGen/AsmPrinter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ class LLVM_ABI AsmPrinter : public MachineFunctionPass {
214214
/// Map type identifiers to callsite labels. Labels are generated for each
215215
/// indirect callsite in the function.
216216
SmallVector<std::pair<CGTypeId, MCSymbol *>> CallSiteLabels;
217+
SmallVector<std::pair<MCSymbol *, MCSymbol *>> DirectCallSiteLabels;
217218
};
218219

219220
enum CallGraphSectionFormatVersion : uint64_t {

llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@
7878
#include "llvm/IR/GlobalValue.h"
7979
#include "llvm/IR/GlobalVariable.h"
8080
#include "llvm/IR/Instruction.h"
81+
#include "llvm/IR/Instructions.h"
8182
#include "llvm/IR/Mangler.h"
8283
#include "llvm/IR/Metadata.h"
8384
#include "llvm/IR/Module.h"
@@ -1733,6 +1734,14 @@ void AsmPrinter::emitCallGraphSection(const MachineFunction &MF,
17331734
}
17341735
FuncInfo.CallSiteLabels.clear();
17351736

1737+
const auto &DirectCallSiteLabels = FuncInfo.DirectCallSiteLabels;
1738+
OutStreamer->emitInt64(DirectCallSiteLabels.size());
1739+
for (const auto &[CallSiteAddrLabel, CalleeSymbol] : DirectCallSiteLabels) {
1740+
OutStreamer->emitSymbolValue(CallSiteAddrLabel, TM.getProgramPointerSize());
1741+
OutStreamer->emitSymbolValue(CalleeSymbol, TM.getProgramPointerSize());
1742+
}
1743+
FuncInfo.DirectCallSiteLabels.clear();
1744+
17361745
OutStreamer->popSection();
17371746
}
17381747

@@ -1872,9 +1881,28 @@ void AsmPrinter::emitIndirectCalleeLabels(
18721881
const MachineInstr &MI) {
18731882
// Only indirect calls have type identifiers set.
18741883
const auto &CallSiteInfo = CallSitesInfoMap.find(&MI);
1875-
if (CallSiteInfo == CallSitesInfoMap.end())
1884+
1885+
// Handle direct callsite info
1886+
if (CallSiteInfo == CallSitesInfoMap.end()) {
1887+
const MachineOperand &CalleeOperand = MI.getOperand(0);
1888+
MCSymbol *CalleeSymbol = nullptr;
1889+
switch (CalleeOperand.getType()) {
1890+
case llvm::MachineOperand::MO_GlobalAddress:
1891+
CalleeSymbol = getSymbol(CalleeOperand.getGlobal());
1892+
break;
1893+
case llvm::MachineOperand::MO_ExternalSymbol:
1894+
CalleeSymbol = GetExternalSymbolSymbol(CalleeOperand.getSymbolName());
1895+
break;
1896+
default:
1897+
llvm_unreachable("Expect only direct call instructions to be handled.");
1898+
}
1899+
MCSymbol *S = MF->getContext().createTempSymbol();
1900+
OutStreamer->emitLabel(S);
1901+
FuncInfo.DirectCallSiteLabels.emplace_back(S, CalleeSymbol);
18761902
return;
1903+
}
18771904

1905+
// Handle indirect callsite info.
18781906
for (ConstantInt *CalleeTypeId : CallSiteInfo->second.CalleeTypeIds) {
18791907
MCSymbol *S = MF->getContext().createTempSymbol();
18801908
OutStreamer->emitLabel(S);
@@ -2064,8 +2092,13 @@ void AsmPrinter::emitFunctionBody() {
20642092
break;
20652093
}
20662094

2067-
if (TM.Options.EmitCallGraphSection && MI.isCall())
2095+
if (TM.Options.EmitCallGraphSection && MI.isCall()) {
2096+
llvm::outs() << "Dump MI for calls \n";
2097+
MI.dump();
2098+
llvm::outs() << "CallSitesInfoMap.size() " << CallSitesInfoMap.size()
2099+
<< "\n";
20682100
emitIndirectCalleeLabels(FuncInfo, CallSitesInfoMap, MI);
2101+
}
20692102

20702103
// If there is a post-instruction symbol, emit a label for it here.
20712104
if (MCSymbol *S = MI.getPostInstrSymbol())

0 commit comments

Comments
 (0)