0
0
mirror of https://github.com/llvm/llvm-project.git synced 2025-04-26 18:16:06 +00:00

[lld][BP] Order .Tgm symbols for startup ()

The Global Function Merger
(https://discourse.llvm.org/t/rfc-global-function-merging/82608) pass
optimistically creates merged instances of functions and suffixes their
names with `.Tgm`. Then in the linker, ICF will (hopefully) fold these
`.Tgm` functions. For example, a function `foo` might become a thunk
`foo` that calls a merged function `foo.Tgm`.

Since IRPGO runs before the global merger, we will only have a profile
for `foo`. We want to correlate this profile to both `foo` and `foo.Tgm`
so they can both be ordered to improve startup time.

I built a large binary and found that it increased the number of
functions ordered for startup, as expected.
```
Functions for startup: 12049 -> 12697
Functions for compression: 34733 -> 34707
```

The reason why we don't see a larger improvement is because there are
some cases where the code was accidentally working:
`getRootSymbol("foo.llvm.5555.Tgm")` already returns `foo`.
This commit is contained in:
Ellis Hoag 2025-02-13 12:10:58 -08:00 committed by GitHub
parent b5aa1c4783
commit 83632c039d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 32 additions and 10 deletions
lld

@ -147,11 +147,14 @@ static SmallVector<std::pair<unsigned, UtilityNodes>> getUnsForCompression(
return sectionUns; return sectionUns;
} }
/// Symbols can be appended with "(.__uniq.xxxx)?.llvm.yyyy" where "xxxx" and /// Symbols can be appended with "(.__uniq.xxxx)?(.llvm.yyyy)?(.Tgm)?" where
/// "yyyy" are numbers that could change between builds. We need to use the /// "xxxx" and "yyyy" are numbers that could change between builds, and .Tgm is
/// root symbol name before this suffix so these symbols can be matched with /// the global merge functions suffix
/// profiles which may have different suffixes. /// (see GlobalMergeFunc::MergingInstanceSuffix). We need to use the root symbol
/// name before this suffix so these symbols can be matched with profiles which
/// may have different suffixes.
inline StringRef getRootSymbol(StringRef name) { inline StringRef getRootSymbol(StringRef name) {
name.consume_back(".Tgm");
auto [P0, S0] = name.rsplit(".llvm."); auto [P0, S0] = name.rsplit(".llvm.");
auto [P1, S1] = P0.rsplit(".__uniq."); auto [P1, S1] = P0.rsplit(".__uniq.");
return P1; return P1;

@ -5,11 +5,12 @@
# RUN: llvm-profdata merge %t/a.proftext -o %t/a.profdata # RUN: llvm-profdata merge %t/a.proftext -o %t/a.profdata
# RUN: %no-fatal-warnings-lld -arch arm64 -lSystem -e _main -o %t/a.out %t/a.o --irpgo-profile-sort=%t/a.profdata --verbose-bp-section-orderer 2>&1 | FileCheck %s --check-prefix=STARTUP # RUN: %no-fatal-warnings-lld -arch arm64 -lSystem -e _main -o %t/a.out %t/a.o --irpgo-profile-sort=%t/a.profdata --verbose-bp-section-orderer 2>&1 | FileCheck %s --check-prefix=STARTUP
# RUN: %no-fatal-warnings-lld -arch arm64 -lSystem -e _main -o %t/a.out %t/a.o --irpgo-profile-sort=%t/a.profdata --verbose-bp-section-orderer --icf=all --compression-sort=none 2>&1 | FileCheck %s --check-prefix=STARTUP # RUN: %no-fatal-warnings-lld -arch arm64 -lSystem -e _main -o %t/a.out %t/a.o --irpgo-profile-sort=%t/a.profdata --verbose-bp-section-orderer --icf=all --compression-sort=none 2>&1 | FileCheck %s --check-prefix=STARTUP-ICF
# RUN: %lld -arch arm64 -lSystem -e _main -o %t/a.out %t/a.o --irpgo-profile %t/a.profdata --bp-startup-sort=function --verbose-bp-section-orderer 2>&1 | FileCheck %s --check-prefix=STARTUP # RUN: %lld -arch arm64 -lSystem -e _main -o %t/a.out %t/a.o --irpgo-profile %t/a.profdata --bp-startup-sort=function --verbose-bp-section-orderer 2>&1 | FileCheck %s --check-prefix=STARTUP
# RUN: %lld -arch arm64 -lSystem -e _main -o %t/a.out %t/a.o --irpgo-profile=%t/a.profdata --bp-startup-sort=function --verbose-bp-section-orderer --icf=all --bp-compression-sort=none 2>&1 | FileCheck %s --check-prefix=STARTUP # RUN: %lld -arch arm64 -lSystem -e _main -o %t/a.out %t/a.o --irpgo-profile=%t/a.profdata --bp-startup-sort=function --verbose-bp-section-orderer --icf=all --bp-compression-sort=none 2>&1 | FileCheck %s --check-prefix=STARTUP-ICF
# STARTUP: Ordered 3 sections using balanced partitioning # STARTUP: Ordered 5 sections using balanced partitioning
# STARTUP-ICF: Ordered 4 sections using balanced partitioning
# Check that orderfiles take precedence over BP # Check that orderfiles take precedence over BP
# RUN: %no-fatal-warnings-lld -arch arm64 -lSystem -e _main -o - %t/a.o -order_file %t/a.orderfile --irpgo-profile-sort=%t/a.profdata | llvm-nm --numeric-sort --format=just-symbols - | FileCheck %s --check-prefix=ORDERFILE # RUN: %no-fatal-warnings-lld -arch arm64 -lSystem -e _main -o - %t/a.o -order_file %t/a.orderfile --irpgo-profile-sort=%t/a.profdata | llvm-nm --numeric-sort --format=just-symbols - | FileCheck %s --check-prefix=ORDERFILE
@ -26,6 +27,8 @@
# ORDERFILE-DAG: _main # ORDERFILE-DAG: _main
# ORDERFILE-DAG: _B # ORDERFILE-DAG: _B
# ORDERFILE-DAG: l_C # ORDERFILE-DAG: l_C
# ORDERFILE-DAG: merged1.Tgm
# ORDERFILE-DAG: merged2.Tgm
# Data # Data
# ORDERFILE: s3 # ORDERFILE: s3
@ -80,10 +83,10 @@ F:
add w0, w0, #3 add w0, w0, #3
bl l_C.__uniq.111111111111111111111111111111111111111.llvm.2222222222222222222 bl l_C.__uniq.111111111111111111111111111111111111111.llvm.2222222222222222222
ret ret
merged1: merged1.Tgm:
add w0, w0, #101 add w0, w0, #101
ret ret
merged2: merged2.Tgm:
add w0, w0, #101 add w0, w0, #101
ret ret
@ -114,7 +117,7 @@ r4:
1 1
# Weight # Weight
1 1
A, B, C.__uniq.555555555555555555555555555555555555555.llvm.6666666666666666666 A, B, C.__uniq.555555555555555555555555555555555555555.llvm.6666666666666666666, merged1, merged2
A A
# Func Hash: # Func Hash:
@ -148,6 +151,22 @@ D
# Counter Values: # Counter Values:
1 1
merged1
# Func Hash:
5555
# Num Counters:
1
# Counter Values:
1
merged2
# Func Hash:
6666
# Num Counters:
1
# Counter Values:
1
#--- a.orderfile #--- a.orderfile
A A
F F