[llvm] [BOLT] Check CallProfile annotation in buildCallGraph (PR #134733)

Amir Ayupov via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 8 13:50:18 PDT 2025


https://github.com/aaupov updated https://github.com/llvm/llvm-project/pull/134733

>From 144687ce25dfc0520ee33be24cae1fc88876d44b Mon Sep 17 00:00:00 2001
From: Amir Ayupov <aaupov at fb.com>
Date: Mon, 7 Apr 2025 14:15:09 -0700
Subject: [PATCH 1/2] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?=
 =?UTF-8?q?itial=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Created using spr 1.3.4
---
 bolt/lib/Core/BinaryFunctionCallGraph.cpp |  3 +-
 bolt/test/X86/unknown-cf-call-graph.s     | 67 +++++++++++++++++++++++
 2 files changed, 69 insertions(+), 1 deletion(-)
 create mode 100644 bolt/test/X86/unknown-cf-call-graph.s

diff --git a/bolt/lib/Core/BinaryFunctionCallGraph.cpp b/bolt/lib/Core/BinaryFunctionCallGraph.cpp
index b4b7897aa426a..76fc5245c013a 100644
--- a/bolt/lib/Core/BinaryFunctionCallGraph.cpp
+++ b/bolt/lib/Core/BinaryFunctionCallGraph.cpp
@@ -252,7 +252,8 @@ buildCallGraph(BinaryContext &BC, CgFilterFunction Filter, bool CgFromPerfData,
 
         for (MCInst &Inst : *BB) {
           // Find call instructions and extract target symbols from each one.
-          if (BC.MIB->isCall(Inst)) {
+          if (BC.MIB->isCall(Inst) ||
+              BC.MIB->hasAnnotation(Inst, "CallProfile")) {
             const CallInfoTy CallInfo = getCallInfo(BB, Inst);
 
             if (!CallInfo.empty()) {
diff --git a/bolt/test/X86/unknown-cf-call-graph.s b/bolt/test/X86/unknown-cf-call-graph.s
new file mode 100644
index 0000000000000..07b8ce335fbde
--- /dev/null
+++ b/bolt/test/X86/unknown-cf-call-graph.s
@@ -0,0 +1,67 @@
+## Check that indirect jumps with unknown control flow and set call profile are
+## handled in call graph construction.
+
+# RUN: split-file %s %t
+# RUN: llvm-mc -filetype=obj -triple x86_64-unknown-unknown %t/src -o %t.o
+# RUN: %clang %cflags %t.o -o %t.exe -Wl,-q
+# RUN: llvm-bolt %t.exe -o %t.out --lite=0 -print-cfg -data %t/yaml \
+# RUN:   --print-only=main --reorder-functions=cdsort --dump-cg=%t.dot \
+# RUN:   --profile-ignore-hash | FileCheck %s
+# RUN: FileCheck --input-file %t.dot --check-prefix=CHECK-CG %s
+# CHECK-CG:      digraph g {
+# CHECK-CG-NEXT: f0 [label="main
+# CHECK-CG-NEXT: f1 [label="foo
+# CHECK-CG-NEXT: f0 -> f1 [label="normWgt=0.000,weight=1000,callOffset=0.0"];
+# CHECK-CG-NEXT: }
+#--- src
+  .globl main
+  .type main, %function
+  .p2align 2
+main:
+   jmpq *%rax
+# CHECK: jmpq *%rax # UNKNOWN CONTROL FLOW # CallProfile: 1000 (0 misses) :
+# CHECK-NEXT:                              { foo: 1000 (0 misses) }
+   jmpq *%rbx
+.size main, .-main
+
+  .globl foo
+  .type foo, %function
+  .p2align 2
+foo:
+   ud2
+.size foo, .-foo
+.reloc 0, R_X86_64_NONE
+#--- yaml
+---
+header:
+  profile-version: 1
+  binary-name:     'test'
+  binary-build-id: 0
+  profile-flags:   [ lbr ]
+  profile-origin:  perf data aggregator
+  profile-events:  ''
+  dfs-order:       false
+  hash-func:       xxh3
+functions:
+  - name:    main
+    fid:     1
+    hash:    0x1
+    exec:    1000
+    nblocks: 1
+    blocks:
+      - bid:   0
+        insns: 1
+        hash:  0x1
+        exec:  1000
+        calls: [ { off: 0x0, fid: 2, cnt: 1000 } ]
+  - name:    foo
+    fid:     2
+    hash:    0x2
+    exec:    1000
+    nblocks: 1
+    blocks:
+      - bid:   0
+        insns: 1
+        hash:  0x1
+        exec:  1000
+...

>From abfbac2b6d63ef0604f65e55999ecab6f7095cd6 Mon Sep 17 00:00:00 2001
From: Amir Ayupov <aaupov at fb.com>
Date: Tue, 8 Apr 2025 13:50:09 -0700
Subject: [PATCH 2/2] update comment

Created using spr 1.3.4
---
 bolt/lib/Core/BinaryFunctionCallGraph.cpp | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/bolt/lib/Core/BinaryFunctionCallGraph.cpp b/bolt/lib/Core/BinaryFunctionCallGraph.cpp
index 76fc5245c013a..5f99d008ebfe1 100644
--- a/bolt/lib/Core/BinaryFunctionCallGraph.cpp
+++ b/bolt/lib/Core/BinaryFunctionCallGraph.cpp
@@ -252,6 +252,8 @@ buildCallGraph(BinaryContext &BC, CgFilterFunction Filter, bool CgFromPerfData,
 
         for (MCInst &Inst : *BB) {
           // Find call instructions and extract target symbols from each one.
+          // Check CallProfile annotation if the instruction is not recognized
+          // as a call, e.g. unknown control flow indirect jump.
           if (BC.MIB->isCall(Inst) ||
               BC.MIB->hasAnnotation(Inst, "CallProfile")) {
             const CallInfoTy CallInfo = getCallInfo(BB, Inst);



More information about the llvm-commits mailing list