Skip to content

Commit 4d348f7

Browse files
authored
[RISCV] Let -data-sections also work on sbss/sdata sections (#87040)
Add an unique suffix to .sbss/.sdata if -fdata-sections. Without assigning an unique .sbss/.sdata section to each symbols, a linker may not be able to remove unused part when gc-section since all used and unused symbols are all mixed in the same .sbss/.sdata section. I believe this also matches the behavior of gcc.
1 parent 5def27c commit 4d348f7

File tree

2 files changed

+66
-4
lines changed

2 files changed

+66
-4
lines changed

llvm/lib/Target/RISCV/RISCVTargetObjectFile.cpp

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -105,10 +105,34 @@ bool RISCVELFTargetObjectFile::isGlobalInSmallSection(
105105
MCSection *RISCVELFTargetObjectFile::SelectSectionForGlobal(
106106
const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
107107
// Handle Small Section classification here.
108-
if (Kind.isBSS() && isGlobalInSmallSection(GO, TM))
109-
return SmallBSSSection;
110-
if (Kind.isData() && isGlobalInSmallSection(GO, TM))
111-
return SmallDataSection;
108+
if (isGlobalInSmallSection(GO, TM)) {
109+
// Emit to an unique sdata/sbss section when -fdata-section is set.
110+
// However, if a symbol has an explicit sdata/sbss section, place it in that
111+
// section.
112+
bool EmitUniquedSection = TM.getDataSections() && !GO->hasSection();
113+
114+
if (Kind.isBSS()) {
115+
if (EmitUniquedSection) {
116+
SmallString<128> Name(".sbss.");
117+
Name.append(GO->getName());
118+
return getContext().getELFSection(Name.str(), ELF::SHT_NOBITS,
119+
ELF::SHF_WRITE | ELF::SHF_ALLOC);
120+
}
121+
122+
return SmallBSSSection;
123+
}
124+
125+
if (Kind.isData()) {
126+
if (EmitUniquedSection) {
127+
SmallString<128> Name(".sdata.");
128+
Name.append(GO->getName());
129+
return getContext().getELFSection(Name.str(), ELF::SHT_PROGBITS,
130+
ELF::SHF_WRITE | ELF::SHF_ALLOC);
131+
}
132+
133+
return SmallDataSection;
134+
}
135+
}
112136

113137
// Otherwise, we work the same as ELF.
114138
return TargetLoweringObjectFileELF::SelectSectionForGlobal(GO, Kind, TM);
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
; RUN: llc -mtriple=riscv32 -data-sections < %s | FileCheck -check-prefix=RV32 %s
2+
; RUN: llc -mtriple=riscv64 -data-sections < %s | FileCheck -check-prefix=RV64 %s
3+
4+
; Append an unique name to each sdata/sbss section when -data-section.
5+
6+
@v = dso_local global i32 0, align 4
7+
@r = dso_local global i64 7, align 8
8+
9+
; If a symbol has an explicit section name, we should honor it.
10+
@vv = dso_local global i32 0, section ".sbss", align 4
11+
@rr = dso_local global i64 7, section ".sdata", align 8
12+
@bb = dso_local global i32 0, section ".sbss_like", align 4
13+
@tt = dso_local global i64 7, section ".sdata_like", align 8
14+
@nn = dso_local global i32 0, section ".custom_a", align 4
15+
@yy = dso_local global i64 7, section ".custom_b", align 8
16+
17+
; SmallDataLimit set to 8, so we expect @v will be put in sbss
18+
; and @r will be put in sdata.
19+
!llvm.module.flags = !{!0}
20+
!0 = !{i32 8, !"SmallDataLimit", i32 8}
21+
22+
; RV32: .section .sbss.v,"aw"
23+
; RV32: .section .sdata.r,"aw"
24+
; RV32: .section .sbss,"aw"
25+
; RV32: .section .sdata,"aw"
26+
; RV32: .section .sbss_like,"aw"
27+
; RV32: .section .sdata_like,"aw"
28+
; RV32: .section .custom_a,"aw"
29+
; RV32: .section .custom_b,"aw"
30+
31+
; RV64: .section .sbss.v,"aw"
32+
; RV64: .section .sdata.r,"aw"
33+
; RV64: .section .sbss,"aw"
34+
; RV64: .section .sdata,"aw"
35+
; RV64: .section .sbss_like,"aw"
36+
; RV64: .section .sdata_like,"aw"
37+
; RV64: .section .custom_a,"aw"
38+
; RV64: .section .custom_b,"aw"

0 commit comments

Comments
 (0)