Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions lld/ELF/BPSectionOrderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,10 +76,12 @@ DenseMap<const InputSectionBase *, int> elf::runBalancedPartitioning(
if (!d)
return;
auto *sec = dyn_cast_or_null<InputSection>(d->section);
// Skip empty, discarded, ICF folded sections, .bss. Skipping ICF folded
// sections reduces duplicate detection work in BPSectionOrderer.
if (!sec || sec->size == 0 || !sec->isLive() || sec->repl != sec ||
!sec->content().data() || !orderer.secToSym.try_emplace(sec, d).second)
// Skip section symbols. Skip empty, discarded, ICF folded sections, .bss.
// Skipping ICF folded sections reduces duplicate detection work in
// BPSectionOrderer.
if (sym.isSection() || !sec || sec->size == 0 || !sec->isLive() ||
sec->repl != sec || !sec->content().data() ||
!orderer.secToSym.try_emplace(sec, d).second)
return;
rootSymbolToSectionIdxs[CachedHashStringRef(
lld::utils::getRootSymbol(sym.getName()))]
Expand Down
90 changes: 67 additions & 23 deletions lld/test/ELF/bp-section-orderer.s
Original file line number Diff line number Diff line change
Expand Up @@ -21,38 +21,38 @@
# RUN: llvm-profdata merge a.proftext -o a.profdata
# RUN: ld.lld a.o --irpgo-profile=a.profdata --bp-startup-sort=function --verbose-bp-section-orderer --icf=all --gc-sections 2>&1 | FileCheck %s --check-prefix=STARTUP-FUNC-ORDER

# STARTUP-FUNC-ORDER: Ordered 3 sections ([[#]] bytes) using balanced partitioning
# STARTUP-FUNC-ORDER: Total area under the page fault curve: 3.
# STARTUP-FUNC-ORDER: Ordered 4 sections ([[#]] bytes) using balanced partitioning
# STARTUP-FUNC-ORDER: Total area under the page fault curve: 4.

# RUN: ld.lld -o out.s a.o --irpgo-profile=a.profdata --bp-startup-sort=function
# RUN: llvm-nm -jn out.s | tr '\n' , | FileCheck %s --check-prefix=STARTUP
# STARTUP: s5,s4,s3,s2,s1,A,B,C,F,E,D,merged1,merged2,_start,d4,d3,d2,d1,g1,{{$}}
# STARTUP: s5,s4,s3,s2,s1,A,B,C,L1,F,E,D,merged1,merged2,G,_start,d4,d3,d2,d1,g1,{{$}}

# RUN: ld.lld -o out.os a.o --irpgo-profile=a.profdata --bp-startup-sort=function --symbol-ordering-file a.txt
# RUN: llvm-nm -jn out.os | tr '\n' , | FileCheck %s --check-prefix=ORDER-STARTUP
# ORDER-STARTUP: s2,s1,s5,s4,s3,A,F,E,D,B,C,merged1,merged2,_start,d3,d2,d4,d1,g1,{{$}}
# ORDER-STARTUP: s2,s1,s5,s4,s3,A,F,E,D,B,C,L1,merged1,merged2,G,_start,d3,d2,d4,d1,g1,{{$}}

# RUN: ld.lld -o out.cf a.o --verbose-bp-section-orderer --bp-compression-sort=function 2>&1 | FileCheck %s --check-prefix=BP-COMPRESSION-FUNC
# RUN: ld.lld -o out.cf.icf a.o --verbose-bp-section-orderer --bp-compression-sort=function --icf=all --gc-sections 2>&1 | FileCheck %s --check-prefix=BP-COMPRESSION-ICF-FUNC
# RUN: llvm-nm -jn out.cf | tr '\n' , | FileCheck %s --check-prefix=CFUNC
# CFUNC: s5,s4,s3,s2,s1,A,F,merged1,merged2,C,E,D,B,_start,d4,d3,d2,d1,g1,{{$}}
# CFUNC: s5,s4,s3,s2,s1,C,E,D,B,G,F,merged1,merged2,A,_start,L1,d4,d3,d2,d1,g1,{{$}}

# RUN: ld.lld -o out.cd a.o --verbose-bp-section-orderer --bp-compression-sort=data 2>&1 | FileCheck %s --check-prefix=BP-COMPRESSION-DATA
# RUN: llvm-nm -jn out.cd | tr '\n' , | FileCheck %s --check-prefix=CDATA
# CDATA: s5,s3,s4,s2,s1,F,C,E,D,B,A,merged1,merged2,_start,d4,d1,d3,d2,g1,{{$}}
# CDATA: s5,s3,s4,s2,s1,F,C,E,D,B,A,merged1,merged2,L1,G,_start,d4,d1,d3,d2,g1,{{$}}

# RUN: ld.lld -o out.cb a.o --verbose-bp-section-orderer --bp-compression-sort=both 2>&1 | FileCheck %s --check-prefix=BP-COMPRESSION-BOTH
# RUN: llvm-nm -jn out.cb | tr '\n' , | FileCheck %s --check-prefix=CBOTH
# CBOTH: s5,s3,s4,s2,s1,A,F,merged1,merged2,C,E,D,B,_start,d4,d1,d3,d2,g1,{{$}}
# CBOTH: s5,s3,s4,s2,s1,C,E,D,B,G,F,merged1,merged2,A,_start,L1,d4,d1,d3,d2,g1,{{$}}

# RUN: ld.lld -o out.cbs a.o --verbose-bp-section-orderer --bp-compression-sort=both --irpgo-profile=a.profdata --bp-startup-sort=function 2>&1 | FileCheck %s --check-prefix=BP-COMPRESSION-BOTH
# RUN: llvm-nm -jn out.cbs | tr '\n' , | FileCheck %s --check-prefix=CBOTH-STARTUP
# CBOTH-STARTUP: s5,s3,s4,s2,s1,A,B,C,F,E,D,merged1,merged2,_start,d4,d1,d3,d2,g1,{{$}}
# CBOTH-STARTUP: s5,s3,s4,s2,s1,A,B,C,L1,F,E,D,merged1,merged2,G,_start,d4,d1,d3,d2,g1,{{$}}

# BP-COMPRESSION-FUNC: Ordered 9 sections ([[#]] bytes) using balanced partitioning
# BP-COMPRESSION-ICF-FUNC: Ordered 8 sections ([[#]] bytes) using balanced partitioning
# BP-COMPRESSION-FUNC: Ordered 11 sections ([[#]] bytes) using balanced partitioning
# BP-COMPRESSION-ICF-FUNC: Ordered 9 sections ([[#]] bytes) using balanced partitioning
# BP-COMPRESSION-DATA: Ordered 9 sections ([[#]] bytes) using balanced partitioning
# BP-COMPRESSION-BOTH: Ordered 18 sections ([[#]] bytes) using balanced partitioning
# BP-COMPRESSION-BOTH: Ordered 20 sections ([[#]] bytes) using balanced partitioning

#--- a.proftext
:ir
Expand All @@ -63,7 +63,7 @@
1
# Weight
1
A, B, C
A, B, C, L1

A
# Func Hash:
Expand Down Expand Up @@ -97,6 +97,14 @@ D
# Counter Values:
1

L1
# Func Hash:
5555
# Num Counters:
1
# Counter Values:
1

#--- a.txt
A
F
Expand Down Expand Up @@ -137,6 +145,9 @@ void A() {}
RETAIN int merged1(int a) { return F(a + 101); }
int merged2(int a) { return F(a + 101); }

RETAIN static int L1(int a) { return a + 103; }
int G(int a) { return L1(a); }

int _start() { return 0; }

#--- gen
Expand All @@ -148,7 +159,7 @@ clang --target=aarch64-linux-gnu -O0 -ffunction-sections -fdata-sections -fno-as
.p2align 2
.type F,@function
F: // @F
// %bb.0: // %entry
// %bb.0:
sub sp, sp, #32
stp x29, x30, [sp, #16] // 16-byte Folded Spill
add x29, sp, #16
Expand All @@ -167,7 +178,7 @@ F: // @F
.p2align 2
.type C,@function
C: // @C
// %bb.0: // %entry
// %bb.0:
sub sp, sp, #32
stp x29, x30, [sp, #16] // 16-byte Folded Spill
add x29, sp, #16
Expand All @@ -186,7 +197,7 @@ C: // @C
.p2align 2
.type E,@function
E: // @E
// %bb.0: // %entry
// %bb.0:
sub sp, sp, #32
stp x29, x30, [sp, #16] // 16-byte Folded Spill
add x29, sp, #16
Expand All @@ -205,7 +216,7 @@ E: // @E
.p2align 2
.type D,@function
D: // @D
// %bb.0: // %entry
// %bb.0:
sub sp, sp, #32
stp x29, x30, [sp, #16] // 16-byte Folded Spill
add x29, sp, #16
Expand All @@ -224,7 +235,7 @@ D: // @D
.p2align 2
.type B,@function
B: // @B
// %bb.0: // %entry
// %bb.0:
sub sp, sp, #32
stp x29, x30, [sp, #16] // 16-byte Folded Spill
add x29, sp, #16
Expand All @@ -243,7 +254,7 @@ B: // @B
.p2align 2
.type A,@function
A: // @A
// %bb.0: // %entry
// %bb.0:
ret
.Lfunc_end5:
.size A, .Lfunc_end5-A
Expand All @@ -253,7 +264,7 @@ A: // @A
.p2align 2
.type merged1,@function
merged1: // @merged1
// %bb.0: // %entry
// %bb.0:
sub sp, sp, #32
stp x29, x30, [sp, #16] // 16-byte Folded Spill
add x29, sp, #16
Expand All @@ -272,7 +283,7 @@ merged1: // @merged1
.p2align 2
.type merged2,@function
merged2: // @merged2
// %bb.0: // %entry
// %bb.0:
sub sp, sp, #32
stp x29, x30, [sp, #16] // 16-byte Folded Spill
add x29, sp, #16
Expand All @@ -286,16 +297,48 @@ merged2: // @merged2
.Lfunc_end7:
.size merged2, .Lfunc_end7-merged2
// -- End function
.section .text.L1,"axR",@progbits
.p2align 2 // -- Begin function L1
.type L1,@function
L1: // @L1
Comment on lines +300 to +303
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't look like this section has zero size? Can you also explain why these sections would have zero size?

Copy link
Contributor Author

@Colibrow Colibrow Aug 1, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fix: Remove the d->size == 0 check and use sym.isSection() to skip reordering section symbols. I found a similar problem, see https://reviews.llvm.org/D59311?id=190644#inline-528590.

https://github.com/llvm/llvm-project/blob/f7226696027ec48266080549391982b1f9a840b6/lld/test/ELF/bp-section-orderer.s#L300-L313

This piece of code creates three symbols:

  • .text.L1: a STT_SECTION symbol where the symbol name is empty but d->section->size is not 0
  • L1: a STT_FUNC symbol, which is the one we want in Temporal Profiling
  • $x: a mapping symbol

These three symbols all match the section .text.L1, and sym.isSection() helps us filter out the unnamed section symbols in BP reorder.
@ellishg

// %bb.0:
sub sp, sp, #16
str w0, [sp, #12]
ldr w8, [sp, #12]
add w0, w8, #103
add sp, sp, #16
ret
.Lfunc_end8:
.size L1, .Lfunc_end8-L1
// -- End function
.section .text.G,"ax",@progbits
.globl G // -- Begin function G
.p2align 2
.type G,@function
G: // @G
// %bb.0:
sub sp, sp, #32
stp x29, x30, [sp, #16] // 16-byte Folded Spill
add x29, sp, #16
stur w0, [x29, #-4]
ldur w0, [x29, #-4]
bl L1
ldp x29, x30, [sp, #16] // 16-byte Folded Reload
add sp, sp, #32
ret
.Lfunc_end9:
.size G, .Lfunc_end9-G
// -- End function
.section .text._start,"ax",@progbits
.globl _start // -- Begin function _start
.p2align 2
.type _start,@function
_start: // @_start
// %bb.0: // %entry
// %bb.0:
mov w0, wzr
ret
.Lfunc_end8:
.size _start, .Lfunc_end8-_start
.Lfunc_end10:
.size _start, .Lfunc_end10-_start
// -- End function
.type s5,@object // @s5
.section .rodata.s5,"a",@progbits
Expand Down Expand Up @@ -395,3 +438,4 @@ g1:
.addrsig_sym B
.addrsig_sym A
.addrsig_sym merged1
.addrsig_sym L1