[BOLT] Don't fold hot text mover functions in ICF (#180367)

Hot text mover functions are placed in special sections (e.g.,
.never_hugify) to avoid being placed on hot/huge pages. Folding them
with functions from other sections could defeat this purpose.

Add a check in ICF's isIdenticalWith() to prevent folding when either
function is a hot text mover.
This commit is contained in:
Maksim Panchenko 2026-02-07 20:39:24 -08:00 committed by GitHub
parent 74aa875346
commit 1e5493b1b8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 31 additions and 0 deletions

View File

@ -33,6 +33,8 @@ namespace opts {
extern cl::OptionCategory BoltOptCategory;
extern bool isHotTextMover(const BinaryFunction &Function);
static cl::opt<bool>
ICFUseDFS("icf-dfs", cl::desc("use DFS ordering when using -icf option"),
cl::ReallyHidden, cl::cat(BoltOptCategory));
@ -186,6 +188,11 @@ static bool isIdenticalWith(const BinaryFunction &A, const BinaryFunction &B,
bool CongruentSymbols) {
assert(A.hasCFG() && B.hasCFG() && "both functions should have CFG");
// Hot text mover functions should not be folded. They need to stay in their
// original section to avoid being placed on hot/huge pages.
if (opts::isHotTextMover(A) || opts::isHotTextMover(B))
return false;
// Compare the two functions, one basic block at a time.
// Currently we require two identical basic blocks to have identical
// instruction sequences and the same index in their corresponding

View File

@ -0,0 +1,24 @@
// Check that ICF does not fold hot text mover functions.
// Hot text mover functions are placed in special sections (e.g., .never_hugify)
// to avoid being placed on hot/huge pages.
// clang-format off
// REQUIRES: system-linux, asserts
// RUN: %clang %cflags -O0 %s -o %t.exe -Wl,-q
// RUN: llvm-bolt %t.exe --icf --hot-text-move-sections=.never_hugify \
// RUN: -debug-only=bolt-icf -o %t.bolt 2>&1 | FileCheck %s
// FuncA is in .text, FuncB is in .never_hugify (a hot text mover section).
// They are identical, but FuncB should NOT be folded because it is a hot text mover.
// CHECK: ICF iteration 1
// CHECK-NOT: folding FuncB into FuncA
// CHECK-NOT: folding FuncA into FuncB
__attribute__((noinline)) int FuncA(void) { return 42; }
__attribute__((section(".never_hugify"), noinline)) int FuncB(void) {
return 42;
}
int main(void) { return FuncA() + FuncB(); }