[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