Skip to content

Commit 8bcb073

Browse files
authored
[Clang] -fseparate-named-sections option (#91028)
When set, the compiler will use separate unique sections for global symbols in named special sections (e.g. symbols that are annotated with __attribute__((section(...)))). Doing so enables linker GC to collect unused symbols without having to use a different section per-symbol.
1 parent e74a7a9 commit 8bcb073

File tree

11 files changed

+110
-12
lines changed

11 files changed

+110
-12
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -303,6 +303,11 @@ New Compiler Flags
303303
allow late parsing certain attributes in specific contexts where they would
304304
not normally be late parsed.
305305

306+
- ``-fseparate-named-sections`` uses separate unique sections for global
307+
symbols in named special sections (i.e. symbols annotated with
308+
``__attribute__((section(...)))``. This enables linker GC to collect unused
309+
symbols without having to use a per-symbol section.
310+
306311
Deprecated Compiler Flags
307312
-------------------------
308313

clang/include/clang/Basic/CodeGenOptions.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ CODEGENOPT(UniqueSectionNames, 1, 1) ///< Set for -funique-section-names.
5757
CODEGENOPT(UniqueBasicBlockSectionNames, 1, 1) ///< Set for -funique-basic-block-section-names,
5858
///< Produce unique section names with
5959
///< basic block sections.
60+
CODEGENOPT(SeparateNamedSections, 1, 0) ///< Set for -fseparate-named-sections.
6061
CODEGENOPT(EnableAIXExtendedAltivecABI, 1, 0) ///< Set for -mabi=vec-extabi. Enables the extended Altivec ABI on AIX.
6162
CODEGENOPT(XCOFFReadOnlyPointers, 1, 0) ///< Set for -mxcoff-roptr.
6263
CODEGENOPT(AllTocData, 1, 0) ///< AIX -mtocdata

clang/include/clang/Driver/Options.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4159,6 +4159,11 @@ defm unique_section_names : BoolFOption<"unique-section-names",
41594159
NegFlag<SetFalse, [], [ClangOption, CC1Option],
41604160
"Don't use unique names for text and data sections">,
41614161
PosFlag<SetTrue>>;
4162+
defm separate_named_sections : BoolFOption<"separate-named-sections",
4163+
CodeGenOpts<"SeparateNamedSections">, DefaultFalse,
4164+
PosFlag<SetTrue, [], [ClangOption, CC1Option],
4165+
"Use separate unique sections for named sections (ELF Only)">,
4166+
NegFlag<SetFalse>>;
41624167

41634168
defm split_machine_functions: BoolFOption<"split-machine-functions",
41644169
CodeGenOpts<"SplitMachineFunctions">, DefaultFalse,

clang/lib/CodeGen/BackendUtil.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,7 @@ static bool initTargetOptions(DiagnosticsEngine &Diags,
423423
Options.UniqueSectionNames = CodeGenOpts.UniqueSectionNames;
424424
Options.UniqueBasicBlockSectionNames =
425425
CodeGenOpts.UniqueBasicBlockSectionNames;
426+
Options.SeparateNamedSections = CodeGenOpts.SeparateNamedSections;
426427
Options.TLSSize = CodeGenOpts.TLSSize;
427428
Options.EnableTLSDESC = CodeGenOpts.EnableTLSDESC;
428429
Options.EmulatedTLS = CodeGenOpts.EmulatedTLS;
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// REQUIRES: x86-registered-target
2+
3+
// RUN: %clang_cc1 -triple x86_64-pc-linux -S -o - < %s | FileCheck %s
4+
// RUN: %clang_cc1 -triple x86_64-pc-linux -S -fseparate-named-sections -o - < %s | FileCheck %s --check-prefix=SEPARATE
5+
6+
__attribute__((section("custom_text"))) void f(void) {}
7+
__attribute__((section("custom_text"))) void g(void) {}
8+
9+
// CHECK: .section custom_text,"ax",@progbits{{$}}
10+
// CHECK: f:
11+
// CHECK: g:
12+
13+
// SEPARATE: .section custom_text,"ax",@progbits,unique,1{{$}}
14+
// SEPARATE: f:
15+
// SEPARATE: .section custom_text,"ax",@progbits,unique,2{{$}}
16+
// SEPARATE: g:
17+
18+
__attribute__((section("custom_data"))) int i = 0;
19+
__attribute__((section("custom_data"))) int j = 0;
20+
21+
// CHECK: .section custom_data,"aw",@progbits{{$}}
22+
// CHECK: i:
23+
// CHECK: j:
24+
25+
// SEPARATE: .section custom_data,"aw",@progbits,unique,3{{$}}
26+
// SEPARATE: i:
27+
// SEPARATE: .section custom_data,"aw",@progbits,unique,4{{$}}
28+
// SEPARATE: j:

llvm/include/llvm/CodeGen/CommandFlags.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ bool getUniqueSectionNames();
122122

123123
bool getUniqueBasicBlockSectionNames();
124124

125+
bool getSeparateNamedSections();
126+
125127
llvm::EABI getEABIVersion();
126128

127129
llvm::DebuggerKind getDebuggerTuningOpt();

llvm/include/llvm/Target/TargetMachine.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,10 @@ class TargetMachine {
288288
return Options.UniqueBasicBlockSectionNames;
289289
}
290290

291+
bool getSeparateNamedSections() const {
292+
return Options.SeparateNamedSections;
293+
}
294+
291295
/// Return true if data objects should be emitted into their own section,
292296
/// corresponds to -fdata-sections.
293297
bool getDataSections() const {

llvm/include/llvm/Target/TargetOptions.h

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -144,15 +144,15 @@ namespace llvm {
144144
DisableIntegratedAS(false), FunctionSections(false),
145145
DataSections(false), IgnoreXCOFFVisibility(false),
146146
XCOFFTracebackTable(true), UniqueSectionNames(true),
147-
UniqueBasicBlockSectionNames(false), TrapUnreachable(false),
148-
NoTrapAfterNoreturn(false), TLSSize(0), EmulatedTLS(false),
149-
EnableTLSDESC(false), EnableIPRA(false), EmitStackSizeSection(false),
150-
EnableMachineOutliner(false), EnableMachineFunctionSplitter(false),
151-
SupportsDefaultOutlining(false), EmitAddrsig(false), BBAddrMap(false),
152-
EmitCallSiteInfo(false), SupportsDebugEntryValues(false),
153-
EnableDebugEntryValues(false), ValueTrackingVariableLocations(false),
154-
ForceDwarfFrameSection(false), XRayFunctionIndex(true),
155-
DebugStrictDwarf(false), Hotpatch(false),
147+
UniqueBasicBlockSectionNames(false), SeparateNamedSections(false),
148+
TrapUnreachable(false), NoTrapAfterNoreturn(false), TLSSize(0),
149+
EmulatedTLS(false), EnableTLSDESC(false), EnableIPRA(false),
150+
EmitStackSizeSection(false), EnableMachineOutliner(false),
151+
EnableMachineFunctionSplitter(false), SupportsDefaultOutlining(false),
152+
EmitAddrsig(false), BBAddrMap(false), EmitCallSiteInfo(false),
153+
SupportsDebugEntryValues(false), EnableDebugEntryValues(false),
154+
ValueTrackingVariableLocations(false), ForceDwarfFrameSection(false),
155+
XRayFunctionIndex(true), DebugStrictDwarf(false), Hotpatch(false),
156156
PPCGenScalarMASSEntries(false), JMCInstrument(false),
157157
EnableCFIFixup(false), MisExpect(false), XCOFFReadOnlyPointers(false),
158158
FPDenormalMode(DenormalMode::IEEE, DenormalMode::IEEE) {}
@@ -277,6 +277,9 @@ namespace llvm {
277277
/// Use unique names for basic block sections.
278278
unsigned UniqueBasicBlockSectionNames : 1;
279279

280+
/// Emit named sections with the same name into different sections.
281+
unsigned SeparateNamedSections : 1;
282+
280283
/// Emit target-specific trap instruction for 'unreachable' IR instructions.
281284
unsigned TrapUnreachable : 1;
282285

llvm/lib/CodeGen/CommandFlags.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ CGOPT_EXP(bool, EmulatedTLS)
9696
CGOPT_EXP(bool, EnableTLSDESC)
9797
CGOPT(bool, UniqueSectionNames)
9898
CGOPT(bool, UniqueBasicBlockSectionNames)
99+
CGOPT(bool, SeparateNamedSections)
99100
CGOPT(EABI, EABIVersion)
100101
CGOPT(DebuggerKind, DebuggerTuningOpt)
101102
CGOPT(bool, EnableStackSizeSection)
@@ -419,6 +420,12 @@ codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() {
419420
cl::init(false));
420421
CGBINDOPT(UniqueBasicBlockSectionNames);
421422

423+
static cl::opt<bool> SeparateNamedSections(
424+
"separate-named-sections",
425+
cl::desc("Use separate unique sections for named sections"),
426+
cl::init(false));
427+
CGBINDOPT(SeparateNamedSections);
428+
422429
static cl::opt<EABI> EABIVersion(
423430
"meabi", cl::desc("Set EABI type (default depends on triple):"),
424431
cl::init(EABI::Default),
@@ -569,6 +576,7 @@ codegen::InitTargetOptionsFromCodeGenFlags(const Triple &TheTriple) {
569576
Options.BBSections = getBBSectionsMode(Options);
570577
Options.UniqueSectionNames = getUniqueSectionNames();
571578
Options.UniqueBasicBlockSectionNames = getUniqueBasicBlockSectionNames();
579+
Options.SeparateNamedSections = getSeparateNamedSections();
572580
Options.TLSSize = getTLSSize();
573581
Options.EmulatedTLS =
574582
getExplicitEmulatedTLS().value_or(TheTriple.hasDefaultEmulatedTLS());

llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -733,15 +733,20 @@ calcUniqueIDUpdateFlagsAndSize(const GlobalObject *GO, StringRef SectionName,
733733
Ctx.isELFGenericMergeableSection(SectionName);
734734
// If this is the first ocurrence of this section name, treat it as the
735735
// generic section
736-
if (!SymbolMergeable && !SeenSectionNameBefore)
737-
return MCContext::GenericSectionID;
736+
if (!SymbolMergeable && !SeenSectionNameBefore) {
737+
if (TM.getSeparateNamedSections())
738+
return NextUniqueID++;
739+
else
740+
return MCContext::GenericSectionID;
741+
}
738742

739743
// Symbols must be placed into sections with compatible entry sizes. Generate
740744
// unique sections for symbols that have not been assigned to compatible
741745
// sections.
742746
const auto PreviousID =
743747
Ctx.getELFUniqueIDForEntsize(SectionName, Flags, EntrySize);
744-
if (PreviousID)
748+
if (PreviousID && (!TM.getSeparateNamedSections() ||
749+
*PreviousID == MCContext::GenericSectionID))
745750
return *PreviousID;
746751

747752
// If the user has specified the same section name as would be created
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
; Test that global values with explicit sections are placed into unique sections.
2+
3+
; RUN: llc < %s | FileCheck %s
4+
; RUN: llc -separate-named-sections < %s | FileCheck %s --check-prefix=SEPARATE
5+
target triple="x86_64-unknown-unknown-elf"
6+
7+
define i32 @f() section "custom_text" {
8+
entry:
9+
ret i32 0
10+
}
11+
12+
define i32 @g() section "custom_text" {
13+
entry:
14+
ret i32 0
15+
}
16+
17+
; CHECK: .section custom_text,"ax",@progbits{{$}}
18+
; CHECK: f:
19+
; CHECK: g:
20+
21+
; SEPARATE: .section custom_text,"ax",@progbits,unique,1{{$}}
22+
; SEPARATE: f:
23+
; SEPARATE: .section custom_text,"ax",@progbits,unique,2{{$}}
24+
; SEPARATE: g:
25+
26+
@i = global i32 0, section "custom_data", align 8
27+
@j = global i32 0, section "custom_data", align 8
28+
29+
; CHECK: .section custom_data,"aw",@progbits{{$}}
30+
; CHECK: i:
31+
; CHECK: j:
32+
33+
; SEPARATE: .section custom_data,"aw",@progbits,unique,3{{$}}
34+
; SEPARATE: i:
35+
; SEPARATE: .section custom_data,"aw",@progbits,unique,4{{$}}
36+
; SEPARATE: j:

0 commit comments

Comments
 (0)