[llvm] [llvm][AsmPrinter] Add direct calls to callgraph section (PR #155706)

Prabhu Rajasekaran via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 27 15:14:31 PDT 2025


https://github.com/Prabhuk created https://github.com/llvm/llvm-project/pull/155706

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.


>From eb26a3bdf9bfba33531d9c48f6080946b148f03a Mon Sep 17 00:00:00 2001
From: prabhukr <prabhukr at google.com>
Date: Wed, 27 Aug 2025 22:11:28 +0000
Subject: [PATCH] [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.
---
 llvm/include/llvm/CodeGen/AsmPrinter.h     |  1 +
 llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp | 37 ++++++++++++++++++++--
 2 files changed, 36 insertions(+), 2 deletions(-)

diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h
index 91c014236f6cb..e139eb7010dc5 100644
--- a/llvm/include/llvm/CodeGen/AsmPrinter.h
+++ b/llvm/include/llvm/CodeGen/AsmPrinter.h
@@ -214,6 +214,7 @@ class LLVM_ABI AsmPrinter : public MachineFunctionPass {
     /// Map type identifiers to callsite labels. Labels are generated for each
     /// indirect callsite in the function.
     SmallVector<std::pair<CGTypeId, MCSymbol *>> CallSiteLabels;
+    SmallVector<std::pair<MCSymbol *, MCSymbol *>> DirectCallSiteLabels;
   };
 
   enum CallGraphSectionFormatVersion : uint64_t {
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 1641c3eb535a9..4fe082481cbb0 100644
--- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
@@ -78,6 +78,7 @@
 #include "llvm/IR/GlobalValue.h"
 #include "llvm/IR/GlobalVariable.h"
 #include "llvm/IR/Instruction.h"
+#include "llvm/IR/Instructions.h"
 #include "llvm/IR/Mangler.h"
 #include "llvm/IR/Metadata.h"
 #include "llvm/IR/Module.h"
@@ -1733,6 +1734,14 @@ void AsmPrinter::emitCallGraphSection(const MachineFunction &MF,
   }
   FuncInfo.CallSiteLabels.clear();
 
+  const auto &DirectCallSiteLabels = FuncInfo.DirectCallSiteLabels;
+  OutStreamer->emitInt64(DirectCallSiteLabels.size());
+  for (const auto &[CallSiteAddrLabel, CalleeSymbol] : DirectCallSiteLabels) {
+    OutStreamer->emitSymbolValue(CallSiteAddrLabel, TM.getProgramPointerSize());
+    OutStreamer->emitSymbolValue(CalleeSymbol, TM.getProgramPointerSize());
+  }
+  FuncInfo.DirectCallSiteLabels.clear();
+
   OutStreamer->popSection();
 }
 
@@ -1872,9 +1881,28 @@ void AsmPrinter::emitIndirectCalleeLabels(
     const MachineInstr &MI) {
   // Only indirect calls have type identifiers set.
   const auto &CallSiteInfo = CallSitesInfoMap.find(&MI);
-  if (CallSiteInfo == CallSitesInfoMap.end())
+
+  // Handle direct callsite info
+  if (CallSiteInfo == CallSitesInfoMap.end()) {
+    const MachineOperand &CalleeOperand = MI.getOperand(0);
+    MCSymbol *CalleeSymbol = nullptr;
+    switch (CalleeOperand.getType()) {
+    case llvm::MachineOperand::MO_GlobalAddress:
+      CalleeSymbol = getSymbol(CalleeOperand.getGlobal());
+      break;
+    case llvm::MachineOperand::MO_ExternalSymbol:
+      CalleeSymbol = GetExternalSymbolSymbol(CalleeOperand.getSymbolName());
+      break;
+    default:
+      llvm_unreachable("Expect only direct call instructions to be handled.");
+    }
+    MCSymbol *S = MF->getContext().createTempSymbol();
+    OutStreamer->emitLabel(S);
+    FuncInfo.DirectCallSiteLabels.emplace_back(S, CalleeSymbol);
     return;
+  }
 
+  // Handle indirect callsite info.
   for (ConstantInt *CalleeTypeId : CallSiteInfo->second.CalleeTypeIds) {
     MCSymbol *S = MF->getContext().createTempSymbol();
     OutStreamer->emitLabel(S);
@@ -2064,8 +2092,13 @@ void AsmPrinter::emitFunctionBody() {
         break;
       }
 
-      if (TM.Options.EmitCallGraphSection && MI.isCall())
+      if (TM.Options.EmitCallGraphSection && MI.isCall()) {
+        llvm::outs() << "Dump MI for calls \n";
+        MI.dump();
+        llvm::outs() << "CallSitesInfoMap.size() " << CallSitesInfoMap.size()
+                     << "\n";
         emitIndirectCalleeLabels(FuncInfo, CallSitesInfoMap, MI);
+      }
 
       // If there is a post-instruction symbol, emit a label for it here.
       if (MCSymbol *S = MI.getPostInstrSymbol())



More information about the llvm-commits mailing list