[llvm] [bolt] Use --reorder-functions option directly (PR #179486)

Alexey Moksyakov via llvm-commits llvm-commits at lists.llvm.org
Tue Feb 3 08:27:29 PST 2026


https://github.com/yavtuk updated https://github.com/llvm/llvm-project/pull/179486

>From cd96f79b780a1612be5d9bc80d1cfcf9b8bc388d Mon Sep 17 00:00:00 2001
From: yavtuk <yavtuk at ya.ru>
Date: Tue, 3 Feb 2026 17:40:32 +0300
Subject: [PATCH 1/7] [bolt][NFC] early exit for ReorderFunctions pass

---
 bolt/lib/Passes/ReorderFunctions.cpp | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/bolt/lib/Passes/ReorderFunctions.cpp b/bolt/lib/Passes/ReorderFunctions.cpp
index 9214c2fdecac5..df050ae6f1164 100644
--- a/bolt/lib/Passes/ReorderFunctions.cpp
+++ b/bolt/lib/Passes/ReorderFunctions.cpp
@@ -270,6 +270,9 @@ Error ReorderFunctions::readFunctionOrderFile(
 }
 
 Error ReorderFunctions::runOnFunctions(BinaryContext &BC) {
+  if (opts::ReorderFunctions == RT_NONE)
+    return Error::success();
+
   auto &BFs = BC.getBinaryFunctions();
   if (opts::ReorderFunctions != RT_NONE &&
       opts::ReorderFunctions != RT_EXEC_COUNT &&

>From e59b8bf9be68ec644f0938935a1e93477ff84962 Mon Sep 17 00:00:00 2001
From: yavtuk <yavtuk at ya.ru>
Date: Tue, 3 Feb 2026 17:55:01 +0300
Subject: [PATCH 2/7] [bolt] Exclude plt functions from ReorderFunctions pass

---
 bolt/include/bolt/Passes/ReorderFunctions.h |  2 +-
 bolt/lib/Passes/ReorderFunctions.cpp        | 33 +++++++++++----------
 2 files changed, 19 insertions(+), 16 deletions(-)

diff --git a/bolt/include/bolt/Passes/ReorderFunctions.h b/bolt/include/bolt/Passes/ReorderFunctions.h
index 7da32324bc933..cae30e1069391 100644
--- a/bolt/include/bolt/Passes/ReorderFunctions.h
+++ b/bolt/include/bolt/Passes/ReorderFunctions.h
@@ -21,7 +21,7 @@ class ReorderFunctions : public BinaryFunctionPass {
   BinaryFunctionCallGraph Cg;
 
   void reorder(BinaryContext &BC, std::vector<Cluster> &&Clusters,
-               std::map<uint64_t, BinaryFunction> &BFs);
+               BinaryFunctionListType &BFs);
 
   void printStats(BinaryContext &BC, const std::vector<Cluster> &Clusters,
                   const std::vector<uint64_t> &FuncAddr);
diff --git a/bolt/lib/Passes/ReorderFunctions.cpp b/bolt/lib/Passes/ReorderFunctions.cpp
index df050ae6f1164..c1770c04b0861 100644
--- a/bolt/lib/Passes/ReorderFunctions.cpp
+++ b/bolt/lib/Passes/ReorderFunctions.cpp
@@ -117,7 +117,7 @@ using Node = CallGraph::Node;
 
 void ReorderFunctions::reorder(BinaryContext &BC,
                                std::vector<Cluster> &&Clusters,
-                               std::map<uint64_t, BinaryFunction> &BFs) {
+                               BinaryFunctionListType &BFs) {
   std::vector<uint64_t> FuncAddr(Cg.numNodes()); // Just for computing stats
   uint64_t TotalSize = 0;
   uint32_t Index = 0;
@@ -132,10 +132,9 @@ void ReorderFunctions::reorder(BinaryContext &BC,
   }
 
   // Assign valid index for functions with valid profile.
-  for (auto &It : BFs) {
-    BinaryFunction &BF = It.second;
-    if (!BF.hasValidIndex() && BF.hasValidProfile())
-      BF.setIndex(Index++);
+  for (BinaryFunction *BF : BFs) {
+    if (!BF->hasValidIndex() && BF->hasValidProfile())
+      BF->setIndex(Index++);
   }
 
   if (opts::ReorderFunctions == RT_NONE)
@@ -273,7 +272,13 @@ Error ReorderFunctions::runOnFunctions(BinaryContext &BC) {
   if (opts::ReorderFunctions == RT_NONE)
     return Error::success();
 
-  auto &BFs = BC.getBinaryFunctions();
+  BinaryFunctionListType BFs;
+  BFs.reserve(BC.getBinaryFunctions().size());
+  llvm::transform(llvm::make_second_range(BC.getBinaryFunctions()),
+                  std::back_inserter(BFs),
+                  [](BinaryFunction &BF) { return &BF; });
+  llvm::erase_if(BFs,
+                 [](BinaryFunction *BF) { return BF->isPLTFunction(); });
   if (opts::ReorderFunctions != RT_NONE &&
       opts::ReorderFunctions != RT_EXEC_COUNT &&
       opts::ReorderFunctions != RT_USER) {
@@ -284,6 +289,8 @@ Error ReorderFunctions::runOnFunctions(BinaryContext &BC) {
             return true;
           if (BF.getState() != BinaryFunction::State::CFG)
             return true;
+          if (BF.isPLTFunction())
+            return true;
           return false;
         },
         opts::CgFromPerfData,
@@ -299,9 +306,7 @@ Error ReorderFunctions::runOnFunctions(BinaryContext &BC) {
   case RT_NONE:
     break;
   case RT_EXEC_COUNT: {
-    BinaryFunctionListType SortedFunctions(BFs.size());
-    llvm::transform(llvm::make_second_range(BFs), SortedFunctions.begin(),
-                    [](BinaryFunction &BF) { return &BF; });
+    BinaryFunctionListType SortedFunctions = BFs;
     llvm::stable_sort(SortedFunctions,
                       [&](const BinaryFunction *A, const BinaryFunction *B) {
                         if (A->isIgnored())
@@ -376,10 +381,10 @@ Error ReorderFunctions::runOnFunctions(BinaryContext &BC) {
   case RT_USER: {
     // Build LTOCommonNameMap
     StringMap<std::vector<uint64_t>> LTOCommonNameMap;
-    for (const BinaryFunction &BF : llvm::make_second_range(BFs))
-      for (StringRef Name : BF.getNames())
+    for (const BinaryFunction *BF : BFs)
+      for (StringRef Name : BF->getNames())
         if (std::optional<StringRef> LTOCommonName = getLTOCommonName(Name))
-          LTOCommonNameMap[*LTOCommonName].push_back(BF.getAddress());
+          LTOCommonNameMap[*LTOCommonName].push_back(BF->getAddress());
 
     uint32_t Index = 0;
     uint32_t InvalidEntries = 0;
@@ -474,9 +479,7 @@ Error ReorderFunctions::runOnFunctions(BinaryContext &BC) {
   }
 
   if (FuncsFile || LinkSectionsFile) {
-    BinaryFunctionListType SortedFunctions(BFs.size());
-    llvm::transform(llvm::make_second_range(BFs), SortedFunctions.begin(),
-                    [](BinaryFunction &BF) { return &BF; });
+    BinaryFunctionListType SortedFunctions = BFs;
 
     // Sort functions by index.
     llvm::stable_sort(SortedFunctions, compareBinaryFunctionByIndex);

>From 6e672a6bc683370124c356aa30b16c14d562e0b7 Mon Sep 17 00:00:00 2001
From: yavtuk <yavtuk at ya.ru>
Date: Tue, 3 Feb 2026 18:00:27 +0300
Subject: [PATCH 3/7] [bolt][NFC] exclude plt functions from ReorderBasicBlocks
 pass

---
 bolt/lib/Passes/BinaryPasses.cpp | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/bolt/lib/Passes/BinaryPasses.cpp b/bolt/lib/Passes/BinaryPasses.cpp
index 480d0cef58f43..7d5ccc1f39a77 100644
--- a/bolt/lib/Passes/BinaryPasses.cpp
+++ b/bolt/lib/Passes/BinaryPasses.cpp
@@ -398,7 +398,8 @@ bool ReorderBasicBlocks::shouldPrint(const BinaryFunction &BF) const {
 
 bool ReorderBasicBlocks::shouldOptimize(const BinaryFunction &BF) const {
   // Apply execution count threshold
-  if (BF.getKnownExecutionCount() < opts::ExecutionCountThreshold)
+  if (BF.getKnownExecutionCount() < opts::ExecutionCountThreshold ||
+      BF.isPLTFunction())
     return false;
 
   return BinaryFunctionPass::shouldOptimize(BF);

>From eb6b74d9675a73e5f50ecfde6e4226491939875a Mon Sep 17 00:00:00 2001
From: yavtuk <yavtuk at ya.ru>
Date: Tue, 3 Feb 2026 18:12:55 +0300
Subject: [PATCH 4/7] [bolt][NFC] Use --reorder-functions options directly in
 the tests

---
 bolt/test/AArch64/compact-code-model.s             | 2 +-
 bolt/test/AArch64/lite-mode.s                      | 5 +++--
 bolt/test/X86/bb-with-two-tail-calls.s             | 1 +
 bolt/test/X86/cdsplit-call-scale.s                 | 2 ++
 bolt/test/X86/cdsplit-symbol-names.s               | 1 +
 bolt/test/X86/pie-eh-split-undo.s                  | 1 +
 bolt/test/X86/register-fragments-bolt-symbols.s    | 4 +++-
 bolt/test/X86/yaml-secondary-entry-discriminator.s | 6 ++++--
 bolt/test/code-at-high-address.c                   | 1 +
 9 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/bolt/test/AArch64/compact-code-model.s b/bolt/test/AArch64/compact-code-model.s
index d5d10c6bbd13f..938b8041975fa 100644
--- a/bolt/test/AArch64/compact-code-model.s
+++ b/bolt/test/AArch64/compact-code-model.s
@@ -8,7 +8,7 @@
 # RUN: llvm-strip --strip-unneeded %t.o
 # RUN: %clang %cflags %t.o -o %t.exe -Wl,-q -static
 # RUN: llvm-bolt %t.exe -o %t.bolt --data %t.fdata --split-functions \
-# RUN:   --keep-nops --compact-code-model
+# RUN:   --keep-nops --compact-code-model --reorder-functions=cdsort
 # RUN: llvm-objdump -d \
 # RUN:   --disassemble-symbols=_start,_start.cold.0,foo,foo.cold.0 %t.bolt \
 # RUN:   | FileCheck %s
diff --git a/bolt/test/AArch64/lite-mode.s b/bolt/test/AArch64/lite-mode.s
index f2d06219f7a2d..e0f35a12fff5d 100644
--- a/bolt/test/AArch64/lite-mode.s
+++ b/bolt/test/AArch64/lite-mode.s
@@ -8,9 +8,10 @@
 # RUN: llvm-strip --strip-unneeded %t*.o
 # RUN: %clang %cflags %t.o -o %t.exe -Wl,-q -static
 # RUN: %clang %cflags %t.compact.o -o %t.compact.exe -Wl,-q -static
-# RUN: llvm-bolt %t.exe -o %t.bolt --data %t.fdata --lite
+# RUN: llvm-bolt %t.exe -o %t.bolt --data %t.fdata --lite \
+# RUN:   --reorder-functions=cdsort
 # RUN: llvm-bolt %t.compact.exe -o %t.compact.bolt --data %t.fdata --lite \
-# RUN:   --compact-code-model
+# RUN:   --compact-code-model --reorder-functions=cdsort
 # RUN: llvm-objdump -d --disassemble-symbols=cold_function %t.exe \
 # RUN:   | FileCheck %s --check-prefix=CHECK-INPUT
 # RUN: llvm-objdump -d --disassemble-symbols=cold_function %t.bolt \
diff --git a/bolt/test/X86/bb-with-two-tail-calls.s b/bolt/test/X86/bb-with-two-tail-calls.s
index 71807510527f9..0ded11550d9d7 100644
--- a/bolt/test/X86/bb-with-two-tail-calls.s
+++ b/bolt/test/X86/bb-with-two-tail-calls.s
@@ -7,6 +7,7 @@
 # RUN: llvm-strip --strip-unneeded %t.o
 # RUN: %clang %cflags %t.o -o %t.exe -Wl,-q -nostdlib
 # RUN: llvm-bolt %t.exe -o %t.out --data %t.fdata --lite=0 --dyno-stats \
+# RUN:    --reorder-functions=cdsort \
 # RUN:    --print-sctc --print-only=_start -enable-bat 2>&1 | FileCheck %s
 # RUN: llvm-objdump --syms %t.out > %t.log
 # RUN: llvm-bat-dump %t.out --dump-all >> %t.log
diff --git a/bolt/test/X86/cdsplit-call-scale.s b/bolt/test/X86/cdsplit-call-scale.s
index caa11b6feb6c4..45f90c8a817dc 100644
--- a/bolt/test/X86/cdsplit-call-scale.s
+++ b/bolt/test/X86/cdsplit-call-scale.s
@@ -15,10 +15,12 @@
 # RUN:         --data=%t.fdata --reorder-blocks=ext-tsp \
 # RUN:     2>&1 | FileCheck --check-prefix=LOWINCENTIVE %s
 # RUN: llvm-bolt %t.exe -o %t.bolt --split-functions --split-strategy=cdsplit \
+# RUN:         --reorder-functions=exec-count \
 # RUN:         --call-scale=1.0 --print-split --print-only=chain \
 # RUN:         --data=%t.fdata --reorder-blocks=ext-tsp \
 # RUN:     2>&1 | FileCheck --check-prefix=MEDINCENTIVE %s
 # RUN: llvm-bolt %t.exe -o %t.bolt --split-functions --split-strategy=cdsplit \
+# RUN:         --reorder-functions=exec-count \
 # RUN:         --call-scale=1000.0 --print-split --print-only=chain \
 # RUN:         --data=%t.fdata --reorder-blocks=ext-tsp \
 # RUN:     2>&1 | FileCheck --check-prefix=HIGHINCENTIVE %s
diff --git a/bolt/test/X86/cdsplit-symbol-names.s b/bolt/test/X86/cdsplit-symbol-names.s
index 0960020d74789..6a52686027f76 100644
--- a/bolt/test/X86/cdsplit-symbol-names.s
+++ b/bolt/test/X86/cdsplit-symbol-names.s
@@ -7,6 +7,7 @@
 # RUN: llvm-strip --strip-unneeded %t.o
 # RUN: %clang %cflags %t.o -o %t.exe -Wl,-q
 # RUN: llvm-bolt %t.exe -o %t.bolt --split-functions --split-strategy=cdsplit \
+# RUN:         --reorder-functions=exec-count \
 # RUN:         --call-scale=2 --data=%t.fdata --reorder-blocks=ext-tsp
 # RUN: llvm-objdump --syms %t.bolt | FileCheck %s --check-prefix=CHECK-SYMS-WARM
 
diff --git a/bolt/test/X86/pie-eh-split-undo.s b/bolt/test/X86/pie-eh-split-undo.s
index 6192dfa768aff..f171aa68a35e5 100644
--- a/bolt/test/X86/pie-eh-split-undo.s
+++ b/bolt/test/X86/pie-eh-split-undo.s
@@ -6,6 +6,7 @@
 # RUN: ld.lld --pie %t.o -o %t.exe -q
 # RUN: llvm-bolt %t.exe -o %t.out --data %t.fdata --split-functions --split-eh \
 # RUN:   --split-all-cold --print-after-lowering  --print-only=_start 2>&1 \
+# RUN:   --reorder-functions=exec-count \
 # RUN:   | FileCheck %s
 
 ## _start has two landing pads: one hot and one cold. Hence, BOLT will introduce
diff --git a/bolt/test/X86/register-fragments-bolt-symbols.s b/bolt/test/X86/register-fragments-bolt-symbols.s
index 20e7345541d95..0a0b863474fc4 100644
--- a/bolt/test/X86/register-fragments-bolt-symbols.s
+++ b/bolt/test/X86/register-fragments-bolt-symbols.s
@@ -8,6 +8,7 @@
 ## Check warm fragment name matching (produced by cdsplit)
 # RUN: %clang %cflags %t.main.o -o %t.warm.exe -Wl,-q
 # RUN: llvm-bolt %t.warm.exe -o %t.warm.bolt --split-functions --split-strategy=cdsplit \
+# RUN:   --reorder-functions=exec-count \
 # RUN:   --call-scale=2 --data=%t.fdata --reorder-blocks=ext-tsp --enable-bat
 # RUN: link_fdata %s %t.warm.bolt %t.preagg.warm PREAGGWARM
 # PREAGGWARM: B X:0 #chain.warm# 1 0
@@ -24,7 +25,8 @@
 # RUN: llvm-objcopy --localize-symbol=chain %t.main.o
 # RUN: %clang %cflags %t.chain.o %t.main.o -o %t.exe -Wl,-q
 # RUN: llvm-bolt %t.exe -o %t.bolt --split-functions --split-strategy=randomN \
-# RUN:   --reorder-blocks=ext-tsp --enable-bat --bolt-seed=7 --data=%t.fdata
+# RUN:   --reorder-blocks=ext-tsp --enable-bat --bolt-seed=7 --data=%t.fdata \
+# RUN:   --reorder-functions=exec-count
 # RUN: llvm-objdump --syms %t.bolt | FileCheck %s --check-prefix=CHECK-SYMS
 
 # RUN: link_fdata %s %t.bolt %t.preagg PREAGG
diff --git a/bolt/test/X86/yaml-secondary-entry-discriminator.s b/bolt/test/X86/yaml-secondary-entry-discriminator.s
index 5d6e291fd7c22..b8a73b6fc89a7 100644
--- a/bolt/test/X86/yaml-secondary-entry-discriminator.s
+++ b/bolt/test/X86/yaml-secondary-entry-discriminator.s
@@ -36,7 +36,8 @@
 ## YAML BAT test of calling BAT secondary entry from non-BAT function
 ## Now force-split func and skip main (making it call secondary entries)
 # RUN: llvm-bolt %t.exe -o %t.bat --data %t.fdata --funcs=func \
-# RUN:   --split-functions --split-strategy=all --split-all-cold --enable-bat
+# RUN:   --split-functions --split-strategy=all --split-all-cold --enable-bat \
+# RUN:   --reorder-functions=exec-count
 
 ## Prepare pre-aggregated profile using %t.bat
 # RUN: link_fdata %s %t.bat %t.preagg PREAGG
@@ -57,7 +58,8 @@
 
 ## YAML BAT test of calling BAT secondary entry from BAT function
 # RUN: llvm-bolt %t.exe -o %t.bat2 --data %t.fdata --funcs=main,func \
-# RUN:   --split-functions --split-strategy=all --split-all-cold --enable-bat
+# RUN:   --split-functions --split-strategy=all --split-all-cold --enable-bat \
+# RUN:   --reorder-functions=exec-count
 
 ## Prepare pre-aggregated profile using %t.bat
 # RUN: link_fdata %s %t.bat2 %t.preagg2 PREAGG2
diff --git a/bolt/test/code-at-high-address.c b/bolt/test/code-at-high-address.c
index 0cdfe4f533d09..f8ee9f0783cb5 100644
--- a/bolt/test/code-at-high-address.c
+++ b/bolt/test/code-at-high-address.c
@@ -8,6 +8,7 @@
 // RUN: link_fdata %s %t %t.fdata
 // RUN: llvm-bolt %t -o %t.bolt --data %t.fdata --use-old-text \
 // RUN:   --align-functions=1 --no-huge-pages --align-text=1 --use-gnu-stack \
+// RUN:   --reorder-functions=cdsort \
 // RUN:    --hot-functions-at-end | FileCheck %s --check-prefix=CHECK-BOLT
 // RUN: llvm-readelf --sections %t.bolt | FileCheck %s
 

>From 9c772bc2c695c740818b0c84ec9581553e377bc9 Mon Sep 17 00:00:00 2001
From: yavtuk <yavtuk at ya.ru>
Date: Tue, 3 Feb 2026 18:15:15 +0300
Subject: [PATCH 5/7] [bolt] Extend skip list functons for RemoveNops pass

---
 bolt/lib/Passes/BinaryPasses.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bolt/lib/Passes/BinaryPasses.cpp b/bolt/lib/Passes/BinaryPasses.cpp
index 7d5ccc1f39a77..0635c74ac7f7d 100644
--- a/bolt/lib/Passes/BinaryPasses.cpp
+++ b/bolt/lib/Passes/BinaryPasses.cpp
@@ -2072,7 +2072,7 @@ Error RemoveNops::runOnFunctions(BinaryContext &BC) {
   };
 
   ParallelUtilities::PredicateTy SkipFunc = [&](const BinaryFunction &BF) {
-    return BF.shouldPreserveNops();
+    return BF.shouldPreserveNops() || !BinaryFunctionPass::shouldOptimize(BF);
   };
 
   ParallelUtilities::runOnEachFunction(

>From cb5c99a114404cb22df9ead57427e70bf31d244d Mon Sep 17 00:00:00 2001
From: yavtuk <yavtuk at ya.ru>
Date: Tue, 3 Feb 2026 18:19:48 +0300
Subject: [PATCH 6/7] [bolt][NFC] Exclude plt function from Top list

---
 bolt/lib/Rewrite/RewriteInstance.cpp | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/bolt/lib/Rewrite/RewriteInstance.cpp b/bolt/lib/Rewrite/RewriteInstance.cpp
index b475c6e137909..fdff7d2a22372 100644
--- a/bolt/lib/Rewrite/RewriteInstance.cpp
+++ b/bolt/lib/Rewrite/RewriteInstance.cpp
@@ -3335,6 +3335,8 @@ void RewriteInstance::selectFunctionsToProcess() {
     std::vector<const BinaryFunction *> TopFunctions;
     for (auto &BFI : BC->getBinaryFunctions()) {
       const BinaryFunction &Function = BFI.second;
+      if (Function.isPLTFunction())
+        continue;
       if (ProfileReader->mayHaveProfileData(Function))
         TopFunctions.push_back(&Function);
     }
@@ -3465,7 +3467,7 @@ void RewriteInstance::selectFunctionsToProcess() {
   // - if the parent is processed, process the fragment(s) as well.
   for (auto &BFI : BC->getBinaryFunctions()) {
     BinaryFunction &Function = BFI.second;
-    if (!Function.isFragment())
+    if (!Function.isFragment() || Function.isPLTFunction())
       continue;
     if (mustSkip(Function)) {
       for (BinaryFunction *Parent : Function.ParentFragments) {

>From f6a9ed2244c5ae065b4a146a6eb4e16f8b7a8ec3 Mon Sep 17 00:00:00 2001
From: yavtuk <yavtuk at ya.ru>
Date: Tue, 3 Feb 2026 19:23:34 +0300
Subject: [PATCH 7/7] [bolt] Update skip list for RemoveNops pass

---
 bolt/lib/Passes/BinaryPasses.cpp | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/bolt/lib/Passes/BinaryPasses.cpp b/bolt/lib/Passes/BinaryPasses.cpp
index 0635c74ac7f7d..735c901af9068 100644
--- a/bolt/lib/Passes/BinaryPasses.cpp
+++ b/bolt/lib/Passes/BinaryPasses.cpp
@@ -2072,7 +2072,7 @@ Error RemoveNops::runOnFunctions(BinaryContext &BC) {
   };
 
   ParallelUtilities::PredicateTy SkipFunc = [&](const BinaryFunction &BF) {
-    return BF.shouldPreserveNops() || !BinaryFunctionPass::shouldOptimize(BF);
+    return BF.shouldPreserveNops() || BF.isPLTFunction();
   };
 
   ParallelUtilities::runOnEachFunction(



More information about the llvm-commits mailing list