[llvm] [BOLT] Adding a unittest that covers Arm SPE PBT aggregation (PR #160095)

Ádám Kallai via llvm-commits llvm-commits at lists.llvm.org
Mon Sep 22 06:37:06 PDT 2025


https://github.com/kaadam updated https://github.com/llvm/llvm-project/pull/160095

>From 9f1fa8a4f4ca7e4bdd8afa64c4312823f9efe8f9 Mon Sep 17 00:00:00 2001
From: Adam Kallai <kadam at inf.u-szeged.hu>
Date: Tue, 16 Sep 2025 11:09:41 +0200
Subject: [PATCH] [BOLT] Add unit test for SPE PBT feature

When the SPE previous branch target address (named as PBT) feature is
available, it records the previous branch target before the sampled operation.

One SPE sample by combining this feature, has two entries. It forms a chain
of two consecutive branches. Arm SPE stores the latest branch into
the first entry, and the previous branch address is stored into the second entry.
However PBT doesn't provide as much information as SPE does.
It lacks those information such as the address of source branch, branch type,
and prediction bit. These information filled with zero.

Consider the following example:

FROM/TO/P/-/-/1/COND/-  FROM/TO/-/-/-/0//-
0xffff8000807216b4/0xffff800080721704/P/-/-/1/COND/-  0x0/0xffff8000807216ac/-/-/-/0//-

Where the first entry is the newest pair, the second one is the oldest pair.
---
 bolt/unittests/Profile/PerfSpeEvents.cpp | 54 ++++++++++++++++++++++++
 1 file changed, 54 insertions(+)

diff --git a/bolt/unittests/Profile/PerfSpeEvents.cpp b/bolt/unittests/Profile/PerfSpeEvents.cpp
index 8d023cd7b7e74..0c1ddbd67b88c 100644
--- a/bolt/unittests/Profile/PerfSpeEvents.cpp
+++ b/bolt/unittests/Profile/PerfSpeEvents.cpp
@@ -161,4 +161,58 @@ TEST_F(PerfSpeEventsTestHelper, SpeBranchesWithBrstack) {
   parseAndCheckBrstackEvents(1234, ExpectedSamples);
 }
 
+TEST_F(PerfSpeEventsTestHelper, SpeBranchesWithBrstackAndPbt) {
+  // Check perf input with SPE branch events as brstack format by
+  // combining with the previous branch target address (named as PBT).
+  // Example collection command:
+  // ```
+  // perf record -e 'arm_spe_0/branch_filter=1/u' -- BINARY
+  // ```
+  // How Bolt extracts the branch events:
+  // ```
+  // perf script -F pid,brstack --itrace=bl
+  // ```
+
+  opts::ArmSPE = true;
+  opts::ReadPerfEvents =
+      "  4567  0xa002/0xa003/PN/-/-/10/COND/- 0x0/0xa001/-/-/-/0//-\n"
+      "  4567  0xb002/0xb003/P/-/-/4/RET/- 0x0/0xb001/-/-/-/0//-\n"
+      "  4567  0xc456/0xc789/P/-/-/13/-/- 0x0/0xc123/-/-/-/0//-\n"
+      "  4567  0xd456/0xd789/M/-/-/7/RET/- 0x0/0xd123/-/-/-/0//-\n"
+      "  4567  0xe005/0xe009/P/-/-/14/RET/- 0x0/0xe001/-/-/-/0//-\n"
+      "  4567  0xd456/0xd789/M/-/-/7/RET/- 0x0/0xd123/-/-/-/0//-\n"
+      "  4567  0xf002/0xf003/MN/-/-/8/COND/- 0x0/0xf001/-/-/-/0//-\n"
+      "  4567  0xc456/0xc789/P/-/-/13/-/- 0x0/0xc123/-/-/-/0//-\n";
+
+  // ExpectedSamples contains the aggregated information about
+  // a branch {{From, To, TraceTo}, {TakenCount, MispredCount}}.
+  // If the PBT feture is availabe, an SPE sample has two entries.
+  // These two entries form a chain of two consecutive branches.
+  // However PBT lacks associated information such as branch
+  // source address, branch type, and prediction bit.
+  // For the first branch stack, please see the description above.
+  // Consider this example for PBT trace: {{0x0, 0xc123, 0xc456}, {2, 0}}.
+  // This entry has a TakenCount = 2, as we have two samples for
+  // this entry (0x0,d123) in our input. It has MispredsCount = 0,
+  // as it lacks prediction information.
+  // It also has no infromation about source branch address therefore
+  // the 'From' field filled with zero (0x0).
+  // TraceTo = 0xc456, means the execution jumped from 0xc123 to 0xc456.
+  std::vector<std::pair<Trace, TakenBranchInfo>> ExpectedSamples = {
+      {{0xa002, 0xa003, Trace::BR_ONLY}, {1, 0}},
+      {{0x0, 0xa001, 0xa002}, {1, 0}},
+      {{0xb002, 0xb003, Trace::BR_ONLY}, {1, 0}},
+      {{0x0, 0xb001, 0xb002}, {1, 0}},
+      {{0xc456, 0xc789, Trace::BR_ONLY}, {2, 0}},
+      {{0x0, 0xc123, 0xc456}, {2, 0}},
+      {{0xd456, 0xd789, Trace::BR_ONLY}, {2, 2}},
+      {{0x0, 0xd123, 0xd456}, {2, 0}},
+      {{0xe005, 0xe009, Trace::BR_ONLY}, {1, 0}},
+      {{0x0, 0xe001, 0xe005}, {1, 0}},
+      {{0xf002, 0xf003, Trace::BR_ONLY}, {1, 1}},
+      {{0x0, 0xf001, 0xf002}, {1, 0}}};
+
+  parseAndCheckBrstackEvents(4567, ExpectedSamples);
+}
+
 #endif



More information about the llvm-commits mailing list