[llvm] [BOLT][AArch64] Remove thunk estimation and warn on margin exhaustion (PR #228069)

via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 1 06:08:41 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-bolt

Author: Alexandros Lamprineas (labrinea)

<details>
<summary>Changes</summary>

When performing branch range checks compare modeled hop distances with MaxClusterSize inclusively without charging estimated thunk bytes against it. This allows a thunk at an adjacent cluster boundary to reach its target.

Cap MaxClusterSize at 126 MiB to reserve minimum alignment headroom. Warn when thunk bytes plus text alignment exceed the remaining branch safety margin.

---
Full diff: https://github.com/llvm/llvm-project/pull/228069.diff


7 Files Affected:

- (modified) bolt/include/bolt/Passes/LongJmp.h (-4) 
- (modified) bolt/lib/Passes/LongJmp.cpp (+31-63) 
- (added) bolt/test/AArch64/relax-adjacent-cluster-boundary.s (+53) 
- (modified) bolt/test/AArch64/relax-branches-with-thunk-chain.s (+6-12) 
- (added) bolt/test/AArch64/relax-cluster-branch-margin-warning.s (+24) 
- (added) bolt/test/AArch64/relax-cluster-size-too-large.s (+20) 
- (modified) bolt/test/AArch64/relax-cross-fragment-calls.s (+8-16) 


``````````diff
diff --git a/bolt/include/bolt/Passes/LongJmp.h b/bolt/include/bolt/Passes/LongJmp.h
index 8c49f9a0bd4d6..7b4aa38dc04fd 100644
--- a/bolt/include/bolt/Passes/LongJmp.h
+++ b/bolt/include/bolt/Passes/LongJmp.h
@@ -70,10 +70,6 @@ class LongJmpPass : public BinaryFunctionPass {
   static constexpr size_t ShortestJumpBits = 11;
   static constexpr size_t ShortestJumpSpan = 1ULL << (ShortestJumpBits - 1);
 
-  /// The longest single-instruction branch.
-  static constexpr size_t LongestJumpBits = 28;
-  static constexpr size_t LongestJumpSpan = 1ULL << (LongestJumpBits - 1);
-
   /// Relax all internal function branches including those between fragments.
   /// Assume that fragments are placed in different sections but are within
   /// 128MB of each other. Return false and report an error if a branch cannot
diff --git a/bolt/lib/Passes/LongJmp.cpp b/bolt/lib/Passes/LongJmp.cpp
index 3dab645cfd61a..346d1f373bda0 100644
--- a/bolt/lib/Passes/LongJmp.cpp
+++ b/bolt/lib/Passes/LongJmp.cpp
@@ -15,7 +15,6 @@
 #include "bolt/Passes/BranchLivenessUtils.h"
 #include "bolt/Passes/RegAnalysis.h"
 #include "bolt/Utils/CommandLineOpts.h"
-#include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/SmallVector.h"
@@ -58,6 +57,10 @@ namespace bolt {
 
 constexpr unsigned ColdFragAlign = 16;
 
+/// The longest single-instruction AArch64 branch.
+constexpr unsigned LongestJumpBits = 28;
+constexpr uint64_t LongestJumpSpan = 1ULL << (LongestJumpBits - 1);
+
 static void relaxStubToShortJmp(BinaryBasicBlock &StubBB, const MCSymbol *Tgt) {
   const BinaryContext &BC = StubBB.getFunction()->getBinaryContext();
   InstructionListType Seq;
@@ -1063,11 +1066,8 @@ class ClusteredRelaxation {
     /// Estimated output offset of the cluster.
     uint64_t StartOffset{0};
 
-    /// Estimated bytes for thunks that may be inserted around this cluster.
-    uint64_t EstimatedThunkBytes{0};
-
-    /// Actual bytes for thunks emitted by this cluster.
-    uint64_t ActualThunkBytes{0};
+    /// Bytes for thunks emitted by this cluster.
+    uint64_t ThunkBytes{0};
 
     /// Number of function fragments in the cluster.
     size_t NumFragments{0};
@@ -1122,7 +1122,6 @@ class ClusteredRelaxation {
   void buildLayout();
   void printStats() const;
   void collectOutOfRangeReferences();
-  void estimateThunkBytes();
   const MCSymbol *getOrCreateBranchThunkChain(const OutOfRangeRef &Ref,
                                               unsigned MaxThunks);
   void relaxCalls();
@@ -1329,17 +1328,11 @@ void ClusteredRelaxation::printStats() const {
   for (size_t I = 0; I < Clusters.size(); ++I) {
     const FragmentCluster &FC = Clusters[I];
 
-    assert(FC.ActualThunkBytes <= FC.EstimatedThunkBytes &&
-           "thunk estimate exceeded; range checks used a stale safety margin");
-
     BC.outs() << "BOLT-INFO: cluster: " << I << '\n'
               << "BOLT-INFO:   " << FC.NumFragments << " fragment(s)\n"
               << "BOLT-INFO:   " << FC.Size
               << " estimated bytes without thunks\n"
-              << "BOLT-INFO:   " << FC.EstimatedThunkBytes
-              << " estimated thunk bytes\n"
-              << "BOLT-INFO:   " << FC.ActualThunkBytes
-              << " actual thunk bytes\n";
+              << "BOLT-INFO:   " << FC.ThunkBytes << " thunk bytes\n";
   }
 
   if (NumShortThunkCalls)
@@ -1444,47 +1437,6 @@ void ClusteredRelaxation::collectOutOfRangeReferences() {
   }
 }
 
-void ClusteredRelaxation::estimateThunkBytes() {
-  // Conservatively estimate both branch chains and long thunks without range
-  // checks or cross-cluster reuse. Deduplicate targets within each cluster.
-  SmallVector<DenseSet<const MCSymbol *>, 4> BranchThunkTargets;
-  SmallVector<DenseSet<const MCSymbol *>, 4> LongThunkTargets;
-  BranchThunkTargets.resize(Clusters.size());
-  LongThunkTargets.resize(Clusters.size());
-
-  auto estimateBranchThunks = [&](const OutOfRangeRef &Ref) {
-    const bool IsForward = Ref.SourceCluster < Ref.TargetCluster;
-    auto getClusterAtHop = [&](unsigned Hop) {
-      return IsForward ? Ref.SourceCluster + Hop : Ref.SourceCluster - Hop;
-    };
-    const unsigned NumHops =
-        getClusterDistance(Ref.SourceCluster, Ref.TargetCluster);
-    for (unsigned Hop = 0; Hop < NumHops; ++Hop) {
-      const unsigned Cluster = getClusterAtHop(Hop);
-      if (BranchThunkTargets[Cluster].insert(Ref.TargetSymbol).second)
-        Clusters[Cluster].EstimatedThunkBytes += ShortThunkSize;
-    }
-  };
-
-  auto estimateLongThunk = [&](const OutOfRangeRef &Ref) {
-    if (LongThunkTargets[Ref.SourceCluster].insert(Ref.TargetSymbol).second)
-      Clusters[Ref.SourceCluster].EstimatedThunkBytes += LongThunkSize;
-  };
-
-  for (const OutOfRangeRef &Call : OutOfLayoutCalls)
-    estimateLongThunk(Call);
-
-  for (const auto &Calls : CallsByDistance) {
-    for (const OutOfRangeRef &Call : Calls) {
-      estimateBranchThunks(Call);
-      estimateLongThunk(Call);
-    }
-  }
-
-  for (const OutOfRangeRef &Branch : Branches)
-    estimateBranchThunks(Branch);
-}
-
 const MCSymbol *
 ClusteredRelaxation::getOrCreateBranchThunkChain(const OutOfRangeRef &Ref,
                                                  unsigned MaxThunks) {
@@ -1540,7 +1492,7 @@ ClusteredRelaxation::getOrCreateBranchThunkChain(const OutOfRangeRef &Ref,
         IsForward ? Cluster.ForwardThunkList : Cluster.BackwardThunkList;
     ThunkList.push_back(Thunk);
     registerBranchThunk(Cluster, Ref.TargetSymbol, Thunk);
-    Cluster.ActualThunkBytes += ShortThunkSize;
+    Cluster.ThunkBytes += ShortThunkSize;
     return Thunk;
   };
 
@@ -1554,14 +1506,12 @@ ClusteredRelaxation::getOrCreateBranchThunkChain(const OutOfRangeRef &Ref,
   };
 
   auto isWithinClusterRange = [&](Position Source, Position Target) {
-    uint64_t EstimatedThunkBytes = 0;
-    for (unsigned I = Source.Cluster; I <= Target.Cluster; ++I)
-      EstimatedThunkBytes += Clusters[getClusterAtHop(I)].EstimatedThunkBytes;
-
     const uint64_t Distance = Source.Offset <= Target.Offset
                                   ? Target.Offset - Source.Offset
                                   : Source.Offset - Target.Offset;
-    return Distance + EstimatedThunkBytes < opts::MaxClusterSize;
+    // A hop across a full adjacent cluster can be exactly this far. The
+    // remaining branch range covers emitted thunks and output alignment.
+    return Distance <= opts::MaxClusterSize;
   };
 
   SmallVector<unsigned> ThunkClusters;
@@ -1661,7 +1611,7 @@ void ClusteredRelaxation::relaxCalls() {
         IsForward ? FC.ForwardThunkList : FC.BackwardThunkList;
     ThunkList.push_back(Thunk);
     registerLongThunk(FC, TargetSymbol, Thunk);
-    FC.ActualThunkBytes += LongThunkSize;
+    FC.ThunkBytes += LongThunkSize;
     return Thunk;
   };
 
@@ -1748,12 +1698,25 @@ bool ClusteredRelaxation::run() {
     return false;
 
   collectOutOfRangeReferences();
-  estimateThunkBytes();
   relaxCalls();
   relaxUnconditionalBranches();
   printStats();
   insertThunks();
 
+  // Warn if a cluster's thunks and a text-alignment gap exhaust the space
+  // reserved between a full cluster and the AArch64 B/BL branch reach. A hop
+  // can cross thunks from multiple clusters, so this is only a diagnostic.
+  const uint64_t Margin = LongestJumpSpan - opts::MaxClusterSize;
+  for (size_t I = 0; I < Clusters.size(); ++I) {
+    const uint64_t ThunkBytes = Clusters[I].ThunkBytes;
+    // Check alignment before subtracting it from the remaining range.
+    if (BC.AlignText > Margin || ThunkBytes > Margin - BC.AlignText)
+      BC.errs() << "BOLT-WARNING: cluster " << I << ": " << ThunkBytes
+                << " thunk bytes plus " << BC.AlignText
+                << " bytes for text alignment exceed the " << Margin
+                << "-byte branch safety margin\n";
+  }
+
   LLVM_DEBUG(dbgs() << "\nFunction layout with thunks:\n";
              for (const auto *BF : OutputFunctions) { dbgs() << *BF << '\n'; });
 
@@ -1775,6 +1738,11 @@ Error LongJmpPass::runOnFunctions(BinaryContext &BC) {
           opts::SplitStrategy != opts::SplitFunctionsStrategy::CDSplit) &&
          "LongJmp cannot work with functions split in more than two fragments");
 
+  // Reserve at least one huge page of headroom for text-section alignment.
+  if (opts::ExperimentalRelaxation &&
+      opts::MaxClusterSize > LongestJumpSpan - BinaryContext::HugePageSize)
+    return createFatalBOLTError("--max-cluster-size must be at most 126 MiB");
+
   DenseMap<BinaryFunction *, BranchLivenessInfo> BranchLiveness;
 
   if (opts::FixBranchesWithLiveness) {
diff --git a/bolt/test/AArch64/relax-adjacent-cluster-boundary.s b/bolt/test/AArch64/relax-adjacent-cluster-boundary.s
new file mode 100644
index 0000000000000..429d6b6ebbe64
--- /dev/null
+++ b/bolt/test/AArch64/relax-adjacent-cluster-boundary.s
@@ -0,0 +1,53 @@
+## A fills cluster 0 exactly. The call in B is beyond the modeled 64-byte
+## cluster range, but a thunk at the start of cluster 1 is exactly 64 bytes
+## from A. The equality case must allow that final backward hop.
+
+# REQUIRES: system-linux
+
+# RUN: %clang %cflags -Wl,-q -Wl,-e,A %s -o %t -nostdlib
+# RUN: link_fdata --no-lbr %s %t %t.fdata
+# RUN: llvm-strip --strip-unneeded %t
+# RUN: llvm-bolt %t -o %t.bolt --data %t.fdata --relax-exp \
+# RUN:   --max-cluster-size=64 | FileCheck %s --check-prefix=CHECK-BOLT
+# RUN: llvm-objdump -d --disassemble-symbols=A,B,__AArch64_backward_Thunk_A_0 \
+# RUN:   %t.bolt | FileCheck %s --check-prefix=CHECK-OUTPUT
+
+# CHECK-BOLT: BOLT-INFO: built 2 function fragment cluster(s)
+# CHECK-BOLT: BOLT-INFO: cluster: 0
+# CHECK-BOLT-NEXT: BOLT-INFO:   1 fragment(s)
+# CHECK-BOLT-NEXT: BOLT-INFO:   64 estimated bytes without thunks
+# CHECK-BOLT-NEXT: BOLT-INFO:   0 thunk bytes
+# CHECK-BOLT-NEXT: BOLT-INFO: cluster: 1
+# CHECK-BOLT-NEXT: BOLT-INFO:   1 fragment(s)
+# CHECK-BOLT-NEXT: BOLT-INFO:   24 estimated bytes without thunks
+# CHECK-BOLT-NEXT: BOLT-INFO:   4 thunk bytes
+# CHECK-BOLT: BOLT-INFO: relaxed 1 calls with short thunks
+# CHECK-BOLT: BOLT-INFO: 1 short thunks created
+
+  .text
+  .globl A
+  .type A, %function
+A:
+.A_entry:
+# FDATA: 1 A #.A_entry# 100
+  ret
+  .space 0x34
+  .size A, .-A
+
+  .globl B
+  .type B, %function
+B:
+.B_entry:
+# FDATA: 1 B #.B_entry# 100
+  mov x0, #1
+  bl A
+  ret
+  .size B, .-B
+
+## Force relocation mode.
+  .reloc 0, R_AARCH64_NONE
+
+# CHECK-OUTPUT:      <__AArch64_backward_Thunk_A_0>:
+# CHECK-OUTPUT-NEXT:   b {{.*}} <A>
+# CHECK-OUTPUT:      <B>:
+# CHECK-OUTPUT:        bl {{.*}} <__AArch64_backward_Thunk_A_0>
diff --git a/bolt/test/AArch64/relax-branches-with-thunk-chain.s b/bolt/test/AArch64/relax-branches-with-thunk-chain.s
index 26527f488ebc6..0db2a6f69dde0 100644
--- a/bolt/test/AArch64/relax-branches-with-thunk-chain.s
+++ b/bolt/test/AArch64/relax-branches-with-thunk-chain.s
@@ -39,18 +39,15 @@
 # CHECK-BOLT-NEXT: BOLT-INFO: cluster: 0
 # CHECK-BOLT-NEXT: BOLT-INFO:   4 fragment(s)
 # CHECK-BOLT-NEXT: BOLT-INFO:   117440604 estimated bytes without thunks
-# CHECK-BOLT-NEXT: BOLT-INFO:   8 estimated thunk bytes
-# CHECK-BOLT-NEXT: BOLT-INFO:   8 actual thunk bytes
+# CHECK-BOLT-NEXT: BOLT-INFO:   8 thunk bytes
 # CHECK-BOLT-NEXT: BOLT-INFO: cluster: 1
 # CHECK-BOLT-NEXT: BOLT-INFO:   4 fragment(s)
 # CHECK-BOLT-NEXT: BOLT-INFO:   117440584 estimated bytes without thunks
-# CHECK-BOLT-NEXT: BOLT-INFO:   24 estimated thunk bytes
-# CHECK-BOLT-NEXT: BOLT-INFO:   16 actual thunk bytes
+# CHECK-BOLT-NEXT: BOLT-INFO:   16 thunk bytes
 # CHECK-BOLT-NEXT: BOLT-INFO: cluster: 2
 # CHECK-BOLT-NEXT: BOLT-INFO:   4 fragment(s)
 # CHECK-BOLT-NEXT: BOLT-INFO:   67108944 estimated bytes without thunks
-# CHECK-BOLT-NEXT: BOLT-INFO:   16 estimated thunk bytes
-# CHECK-BOLT-NEXT: BOLT-INFO:   8 actual thunk bytes
+# CHECK-BOLT-NEXT: BOLT-INFO:   8 thunk bytes
 # CHECK-BOLT: BOLT-INFO: relaxed 7 unconditional branches
 # CHECK-BOLT: BOLT-INFO: 8 branch thunks created
 # CHECK-BOLT: BOLT-INFO: 2 branch thunks reused
@@ -59,18 +56,15 @@
 # CHECK-BOLT-HFE-NEXT: BOLT-INFO: cluster: 0
 # CHECK-BOLT-HFE-NEXT: BOLT-INFO:   4 fragment(s)
 # CHECK-BOLT-HFE-NEXT: BOLT-INFO:   67108944 estimated bytes without thunks
-# CHECK-BOLT-HFE-NEXT: BOLT-INFO:   16 estimated thunk bytes
-# CHECK-BOLT-HFE-NEXT: BOLT-INFO:   8 actual thunk bytes
+# CHECK-BOLT-HFE-NEXT: BOLT-INFO:   8 thunk bytes
 # CHECK-BOLT-HFE-NEXT: BOLT-INFO: cluster: 1
 # CHECK-BOLT-HFE-NEXT: BOLT-INFO:   4 fragment(s)
 # CHECK-BOLT-HFE-NEXT: BOLT-INFO:   117440604 estimated bytes without thunks
-# CHECK-BOLT-HFE-NEXT: BOLT-INFO:   24 estimated thunk bytes
-# CHECK-BOLT-HFE-NEXT: BOLT-INFO:   12 actual thunk bytes
+# CHECK-BOLT-HFE-NEXT: BOLT-INFO:   12 thunk bytes
 # CHECK-BOLT-HFE-NEXT: BOLT-INFO: cluster: 2
 # CHECK-BOLT-HFE-NEXT: BOLT-INFO:   4 fragment(s)
 # CHECK-BOLT-HFE-NEXT: BOLT-INFO:   117440584 estimated bytes without thunks
-# CHECK-BOLT-HFE-NEXT: BOLT-INFO:   8 estimated thunk bytes
-# CHECK-BOLT-HFE-NEXT: BOLT-INFO:   4 actual thunk bytes
+# CHECK-BOLT-HFE-NEXT: BOLT-INFO:   4 thunk bytes
 # CHECK-BOLT-HFE: BOLT-INFO: relaxed 4 unconditional branches
 # CHECK-BOLT-HFE: BOLT-INFO: 6 branch thunks created
 
diff --git a/bolt/test/AArch64/relax-cluster-branch-margin-warning.s b/bolt/test/AArch64/relax-cluster-branch-margin-warning.s
new file mode 100644
index 0000000000000..69a8b36ade336
--- /dev/null
+++ b/bolt/test/AArch64/relax-cluster-branch-margin-warning.s
@@ -0,0 +1,24 @@
+## The text alignment allowance consumes the branch safety margin at the
+## 126 MiB cluster-size ceiling. A call outside the emitted layout adds a
+## long thunk, so the pass warns and still completes.
+
+# REQUIRES: system-linux
+
+# RUN: %clang %cflags -shared -Wl,-q %s -o %t
+# RUN: llvm-bolt %t -o %t.bolt --relax-exp \
+# RUN:   --max-cluster-size=132120576 --align-text=2097152 > %t.log 2>&1
+# RUN: FileCheck %s < %t.log
+
+# CHECK: BOLT-INFO: built 1 function fragment cluster(s)
+# CHECK: BOLT-INFO:   12 thunk bytes
+# CHECK: BOLT-WARNING: cluster 0: 12 thunk bytes plus 2097152 bytes
+# CHECK-SAME: for text alignment exceed the 2097152-byte branch safety margin
+
+  .text
+  .weak external_func
+  .globl A
+  .type A, %function
+A:
+  bl external_func
+  ret
+  .size A, .-A
diff --git a/bolt/test/AArch64/relax-cluster-size-too-large.s b/bolt/test/AArch64/relax-cluster-size-too-large.s
new file mode 100644
index 0000000000000..35646d7abad32
--- /dev/null
+++ b/bolt/test/AArch64/relax-cluster-size-too-large.s
@@ -0,0 +1,20 @@
+## Experimental relaxation rejects cluster sizes above 126 MiB.
+
+# REQUIRES: system-linux
+
+# RUN: %clang %cflags -Wl,-q -Wl,-e,A %s -o %t -nostdlib
+# RUN: not llvm-bolt %t -o %t.bolt --relax-exp \
+# RUN:   --max-cluster-size=132120580 > %t.log 2>&1
+# RUN: FileCheck %s < %t.log
+
+# CHECK: FATAL BOLT-ERROR: --max-cluster-size must be at most 126 MiB
+
+  .text
+  .globl A
+  .type A, %function
+A:
+  ret
+  .size A, .-A
+
+## Force relocation mode.
+  .reloc 0, R_AARCH64_NONE
diff --git a/bolt/test/AArch64/relax-cross-fragment-calls.s b/bolt/test/AArch64/relax-cross-fragment-calls.s
index 843b2241f3925..98a239e618e2d 100644
--- a/bolt/test/AArch64/relax-cross-fragment-calls.s
+++ b/bolt/test/AArch64/relax-cross-fragment-calls.s
@@ -53,23 +53,19 @@
 # CHECK-BOLT-NEXT: BOLT-INFO: cluster: 0
 # CHECK-BOLT-NEXT: BOLT-INFO:   2 fragment(s)
 # CHECK-BOLT-NEXT: BOLT-INFO:   88080456 estimated bytes without thunks
-# CHECK-BOLT-NEXT: BOLT-INFO:   40 estimated thunk bytes
-# CHECK-BOLT-NEXT: BOLT-INFO:   12 actual thunk bytes
+# CHECK-BOLT-NEXT: BOLT-INFO:   12 thunk bytes
 # CHECK-BOLT-NEXT: BOLT-INFO: cluster: 1
 # CHECK-BOLT-NEXT: BOLT-INFO:   2 fragment(s)
 # CHECK-BOLT-NEXT: BOLT-INFO:   88080448 estimated bytes without thunks
-# CHECK-BOLT-NEXT: BOLT-INFO:   40 estimated thunk bytes
-# CHECK-BOLT-NEXT: BOLT-INFO:   24 actual thunk bytes
+# CHECK-BOLT-NEXT: BOLT-INFO:   24 thunk bytes
 # CHECK-BOLT-NEXT: BOLT-INFO: cluster: 2
 # CHECK-BOLT-NEXT: BOLT-INFO:   2 fragment(s)
 # CHECK-BOLT-NEXT: BOLT-INFO:   88080440 estimated bytes without thunks
-# CHECK-BOLT-NEXT: BOLT-INFO:   56 estimated thunk bytes
-# CHECK-BOLT-NEXT: BOLT-INFO:   16 actual thunk bytes
+# CHECK-BOLT-NEXT: BOLT-INFO:   16 thunk bytes
 # CHECK-BOLT-NEXT: BOLT-INFO: cluster: 3
 # CHECK-BOLT-NEXT: BOLT-INFO:   2 fragment(s)
 # CHECK-BOLT-NEXT: BOLT-INFO:   88080448 estimated bytes without thunks
-# CHECK-BOLT-NEXT: BOLT-INFO:   40 estimated thunk bytes
-# CHECK-BOLT-NEXT: BOLT-INFO:   28 actual thunk bytes
+# CHECK-BOLT-NEXT: BOLT-INFO:   28 thunk bytes
 # CHECK-BOLT: BOLT-INFO: relaxed 2 calls with short thunks
 # CHECK-BOLT: BOLT-INFO: relaxed 4 calls with long thunks
 # CHECK-BOLT: BOLT-INFO: 2 short thunks created
@@ -82,23 +78,19 @@
 # CHECK-BOLT-HFE-NEXT: BOLT-INFO: cluster: 0
 # CHECK-BOLT-HFE-NEXT: BOLT-INFO:   2 fragment(s)
 # CHECK-BOLT-HFE-NEXT: BOLT-INFO:   88080440 estimated bytes without thunks
-# CHECK-BOLT-HFE-NEXT: BOLT-INFO:   40 estimated thunk bytes
-# CHECK-BOLT-HFE-NEXT: BOLT-INFO:   24 actual thunk bytes
+# CHECK-BOLT-HFE-NEXT: BOLT-INFO:   24 thunk bytes
 # CHECK-BOLT-HFE-NEXT: BOLT-INFO: cluster: 1
 # CHECK-BOLT-HFE-NEXT: BOLT-INFO:   2 fragment(s)
 # CHECK-BOLT-HFE-NEXT: BOLT-INFO:   88080448 estimated bytes without thunks
-# CHECK-BOLT-HFE-NEXT: BOLT-INFO:   56 estimated thunk bytes
-# CHECK-BOLT-HFE-NEXT: BOLT-INFO:   20 actual thunk bytes
+# CHECK-BOLT-HFE-NEXT: BOLT-INFO:   20 thunk bytes
 # CHECK-BOLT-HFE-NEXT: BOLT-INFO: cluster: 2
 # CHECK-BOLT-HFE-NEXT: BOLT-INFO:   2 fragment(s)
 # CHECK-BOLT-HFE-NEXT: BOLT-INFO:   88080456 estimated bytes without thunks
-# CHECK-BOLT-HFE-NEXT: BOLT-INFO:   56 estimated thunk bytes
-# CHECK-BOLT-HFE-NEXT: BOLT-INFO:   20 actual thunk bytes
+# CHECK-BOLT-HFE-NEXT: BOLT-INFO:   20 thunk bytes
 # CHECK-BOLT-HFE-NEXT: BOLT-INFO: cluster: 3
 # CHECK-BOLT-HFE-NEXT: BOLT-INFO:   2 fragment(s)
 # CHECK-BOLT-HFE-NEXT: BOLT-INFO:   88080448 estimated bytes without thunks
-# CHECK-BOLT-HFE-NEXT: BOLT-INFO:   24 estimated thunk bytes
-# CHECK-BOLT-HFE-NEXT: BOLT-INFO:   8 actual thunk bytes
+# CHECK-BOLT-HFE-NEXT: BOLT-INFO:   8 thunk bytes
 # CHECK-BOLT-HFE: BOLT-INFO: relaxed 3 calls with short thunks
 # CHECK-BOLT-HFE: BOLT-INFO: relaxed 2 calls with long thunks
 # CHECK-BOLT-HFE: BOLT-INFO: 3 short thunks created

``````````

</details>


https://github.com/llvm/llvm-project/pull/228069


More information about the llvm-commits mailing list