[llvm] [llvm][AsmPrinter] Add direct calls to callgraph section (PR #155706)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 28 13:49:36 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-backend-x86
Author: Prabhu Rajasekaran (Prabhuk)
<details>
<summary>Changes</summary>
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.
---
Full diff: https://github.com/llvm/llvm-project/pull/155706.diff
3 Files Affected:
- (modified) llvm/include/llvm/CodeGen/AsmPrinter.h (+3-2)
- (modified) llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (+38-10)
- (modified) llvm/test/CodeGen/X86/call-graph-section-assembly.ll (+24-3)
``````````diff
diff --git a/llvm/include/llvm/CodeGen/AsmPrinter.h b/llvm/include/llvm/CodeGen/AsmPrinter.h
index 91c014236f6cb..89333348232b0 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 {
@@ -385,9 +386,9 @@ class LLVM_ABI AsmPrinter : public MachineFunctionPass {
/// are available. Returns empty string otherwise.
StringRef getConstantSectionSuffix(const Constant *C) const;
- /// Generate and emit labels for callees of the indirect callsites which will
+ /// Generate and emit labels for callees of all callsites which will
/// be used to populate the .callgraph section.
- void emitIndirectCalleeLabels(
+ void emitCallsiteLabelsForCallgraph(
FunctionInfo &FuncInfo,
const MachineFunction::CallSiteInfoMap &CallSitesInfoMap,
const MachineInstr &MI);
diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 1641c3eb535a9..4319e8a15c193 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();
}
@@ -1866,20 +1875,39 @@ static StringRef getMIMnemonic(const MachineInstr &MI, MCStreamer &Streamer) {
return Name;
}
-void AsmPrinter::emitIndirectCalleeLabels(
+void AsmPrinter::emitCallsiteLabelsForCallgraph(
FunctionInfo &FuncInfo,
const MachineFunction::CallSiteInfoMap &CallSitesInfoMap,
const MachineInstr &MI) {
- // Only indirect calls have type identifiers set.
- const auto &CallSiteInfo = CallSitesInfoMap.find(&MI);
- if (CallSiteInfo == CallSitesInfoMap.end())
- return;
-
- for (ConstantInt *CalleeTypeId : CallSiteInfo->second.CalleeTypeIds) {
+ assert(MI.isCall() && "Callsite labels are meant for call instruction only.");
+ const MachineOperand &CalleeOperand = MI.getOperand(0);
+ if (CalleeOperand.isGlobal() || CalleeOperand.isSymbol()) {
+ // Handle direct calls.
+ 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(
+ "Expected to only handle direct call instructions here.");
+ }
MCSymbol *S = MF->getContext().createTempSymbol();
OutStreamer->emitLabel(S);
- uint64_t CalleeTypeIdVal = CalleeTypeId->getZExtValue();
- FuncInfo.CallSiteLabels.emplace_back(CalleeTypeIdVal, S);
+ FuncInfo.DirectCallSiteLabels.emplace_back(S, CalleeSymbol);
+ } else {
+ // Handle indirect callsite info.
+ // Only indirect calls have type identifiers set.
+ const auto &CallSiteInfo = CallSitesInfoMap.find(&MI);
+ for (ConstantInt *CalleeTypeId : CallSiteInfo->second.CalleeTypeIds) {
+ MCSymbol *S = MF->getContext().createTempSymbol();
+ OutStreamer->emitLabel(S);
+ uint64_t CalleeTypeIdVal = CalleeTypeId->getZExtValue();
+ FuncInfo.CallSiteLabels.emplace_back(CalleeTypeIdVal, S);
+ }
}
}
@@ -2065,7 +2093,7 @@ void AsmPrinter::emitFunctionBody() {
}
if (TM.Options.EmitCallGraphSection && MI.isCall())
- emitIndirectCalleeLabels(FuncInfo, CallSitesInfoMap, MI);
+ emitCallsiteLabelsForCallgraph(FuncInfo, CallSitesInfoMap, MI);
// If there is a post-instruction symbol, emit a label for it here.
if (MCSymbol *S = MI.getPostInstrSymbol())
diff --git a/llvm/test/CodeGen/X86/call-graph-section-assembly.ll b/llvm/test/CodeGen/X86/call-graph-section-assembly.ll
index 11362873fb151..950e2f0bdd17a 100644
--- a/llvm/test/CodeGen/X86/call-graph-section-assembly.ll
+++ b/llvm/test/CodeGen/X86/call-graph-section-assembly.ll
@@ -1,9 +1,16 @@
-;; Test if temporary labels are generated for each indirect callsite with a callee_type metadata.
-;; Test if the .callgraph section contains the MD5 hash of callee type ids generated from
-;; generalized type id strings.
+;; Test if temporary labels are generated for each callsite.
+;; Test if the .callgraph section contains the MD5 hash of callees' type (type id)
+;; is correctly paired with its corresponding temporary label generated for indirect
+;; call sites annotated with !callee_type metadata.
+;; Test if the .callgraph section contains direct callsite temporary labels paired
+;; correctly with the corresponding callee symbol.
; RUN: llc -mtriple=x86_64-unknown-linux --call-graph-section -o - < %s | FileCheck %s
+declare !type !0 void @direct_foo()
+declare !type !1 i32 @direct_bar(i8)
+declare !type !2 ptr @direct_baz(ptr)
+
; CHECK: ball:
; CHECK-NEXT: [[LABEL_FUNC:\.Lfunc_begin[0-9]+]]:
define ptr @ball() {
@@ -11,12 +18,18 @@ entry:
%fp_foo_val = load ptr, ptr null, align 8
; CHECK: [[LABEL_TMP0:\.L.*]]:
call void (...) %fp_foo_val(), !callee_type !0
+ ; CHECK: [[LABEL_TMP_DIRECT0:\.L.*]]:
+ call void @direct_foo()
%fp_bar_val = load ptr, ptr null, align 8
; CHECK: [[LABEL_TMP1:\.L.*]]:
%call_fp_bar = call i32 %fp_bar_val(i8 0), !callee_type !2
+ ; CHECK: [[LABEL_TMP_DIRECT1:\.L.*]]:
+ %call_fp_bar_direct = call i32 @direct_bar(i8 1)
%fp_baz_val = load ptr, ptr null, align 8
; CHECK: [[LABEL_TMP2:\.L.*]]:
%call_fp_baz = call ptr %fp_baz_val(ptr null), !callee_type !4
+ ; CHECK: [[LABEL_TMP_DIRECT2:\.L.*]]:
+ %call_fp_baz_direct = call ptr @direct_baz(ptr null)
ret ptr %call_fp_baz
}
@@ -41,3 +54,11 @@ entry:
;; Test for MD5 hash of _ZTSFPvS_E.generalized and the generated temporary callsite label.
; CHECK-NEXT: .quad 8646233951371320954
; CHECK-NEXT: .quad [[LABEL_TMP2]]
+;; Test for number of direct calls and {callsite_label, callee} pairs.
+; CHECK-NEXT: .quad 3
+; CHECK-NEXT: .quad [[LABEL_TMP_DIRECT0]]
+; CHECK-NEXT: .quad direct_foo
+; CHECK-NEXT: .quad [[LABEL_TMP_DIRECT1]]
+; CHECK-NEXT: .quad direct_bar
+; CHECK-NEXT: .quad [[LABEL_TMP_DIRECT2]]
+; CHECK-NEXT: .quad direct_baz
``````````
</details>
https://github.com/llvm/llvm-project/pull/155706
More information about the llvm-commits
mailing list