Skip to content

Commit

Permalink
[Clang] -fseparate-named-sections option (#91028)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
petrhosek committed May 7, 2024
1 parent e74a7a9 commit 8bcb073
Show file tree
Hide file tree
Showing 11 changed files with 110 additions and 12 deletions.
5 changes: 5 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,11 @@ New Compiler Flags
allow late parsing certain attributes in specific contexts where they would
not normally be late parsed.

- ``-fseparate-named-sections`` uses separate unique sections for global
symbols in named special sections (i.e. symbols annotated with
``__attribute__((section(...)))``. This enables linker GC to collect unused
symbols without having to use a per-symbol section.

Deprecated Compiler Flags
-------------------------

Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/CodeGenOptions.def
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ CODEGENOPT(UniqueSectionNames, 1, 1) ///< Set for -funique-section-names.
CODEGENOPT(UniqueBasicBlockSectionNames, 1, 1) ///< Set for -funique-basic-block-section-names,
///< Produce unique section names with
///< basic block sections.
CODEGENOPT(SeparateNamedSections, 1, 0) ///< Set for -fseparate-named-sections.
CODEGENOPT(EnableAIXExtendedAltivecABI, 1, 0) ///< Set for -mabi=vec-extabi. Enables the extended Altivec ABI on AIX.
CODEGENOPT(XCOFFReadOnlyPointers, 1, 0) ///< Set for -mxcoff-roptr.
CODEGENOPT(AllTocData, 1, 0) ///< AIX -mtocdata
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -4159,6 +4159,11 @@ defm unique_section_names : BoolFOption<"unique-section-names",
NegFlag<SetFalse, [], [ClangOption, CC1Option],
"Don't use unique names for text and data sections">,
PosFlag<SetTrue>>;
defm separate_named_sections : BoolFOption<"separate-named-sections",
CodeGenOpts<"SeparateNamedSections">, DefaultFalse,
PosFlag<SetTrue, [], [ClangOption, CC1Option],
"Use separate unique sections for named sections (ELF Only)">,
NegFlag<SetFalse>>;

defm split_machine_functions: BoolFOption<"split-machine-functions",
CodeGenOpts<"SplitMachineFunctions">, DefaultFalse,
Expand Down
1 change: 1 addition & 0 deletions clang/lib/CodeGen/BackendUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,7 @@ static bool initTargetOptions(DiagnosticsEngine &Diags,
Options.UniqueSectionNames = CodeGenOpts.UniqueSectionNames;
Options.UniqueBasicBlockSectionNames =
CodeGenOpts.UniqueBasicBlockSectionNames;
Options.SeparateNamedSections = CodeGenOpts.SeparateNamedSections;
Options.TLSSize = CodeGenOpts.TLSSize;
Options.EnableTLSDESC = CodeGenOpts.EnableTLSDESC;
Options.EmulatedTLS = CodeGenOpts.EmulatedTLS;
Expand Down
28 changes: 28 additions & 0 deletions clang/test/CodeGen/fseparate-named-sections.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// REQUIRES: x86-registered-target

// RUN: %clang_cc1 -triple x86_64-pc-linux -S -o - < %s | FileCheck %s
// RUN: %clang_cc1 -triple x86_64-pc-linux -S -fseparate-named-sections -o - < %s | FileCheck %s --check-prefix=SEPARATE

__attribute__((section("custom_text"))) void f(void) {}
__attribute__((section("custom_text"))) void g(void) {}

// CHECK: .section custom_text,"ax",@progbits{{$}}
// CHECK: f:
// CHECK: g:

// SEPARATE: .section custom_text,"ax",@progbits,unique,1{{$}}
// SEPARATE: f:
// SEPARATE: .section custom_text,"ax",@progbits,unique,2{{$}}
// SEPARATE: g:

__attribute__((section("custom_data"))) int i = 0;
__attribute__((section("custom_data"))) int j = 0;

// CHECK: .section custom_data,"aw",@progbits{{$}}
// CHECK: i:
// CHECK: j:

// SEPARATE: .section custom_data,"aw",@progbits,unique,3{{$}}
// SEPARATE: i:
// SEPARATE: .section custom_data,"aw",@progbits,unique,4{{$}}
// SEPARATE: j:
2 changes: 2 additions & 0 deletions llvm/include/llvm/CodeGen/CommandFlags.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ bool getUniqueSectionNames();

bool getUniqueBasicBlockSectionNames();

bool getSeparateNamedSections();

llvm::EABI getEABIVersion();

llvm::DebuggerKind getDebuggerTuningOpt();
Expand Down
4 changes: 4 additions & 0 deletions llvm/include/llvm/Target/TargetMachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,10 @@ class TargetMachine {
return Options.UniqueBasicBlockSectionNames;
}

bool getSeparateNamedSections() const {
return Options.SeparateNamedSections;
}

/// Return true if data objects should be emitted into their own section,
/// corresponds to -fdata-sections.
bool getDataSections() const {
Expand Down
21 changes: 12 additions & 9 deletions llvm/include/llvm/Target/TargetOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -144,15 +144,15 @@ namespace llvm {
DisableIntegratedAS(false), FunctionSections(false),
DataSections(false), IgnoreXCOFFVisibility(false),
XCOFFTracebackTable(true), UniqueSectionNames(true),
UniqueBasicBlockSectionNames(false), TrapUnreachable(false),
NoTrapAfterNoreturn(false), TLSSize(0), EmulatedTLS(false),
EnableTLSDESC(false), EnableIPRA(false), EmitStackSizeSection(false),
EnableMachineOutliner(false), EnableMachineFunctionSplitter(false),
SupportsDefaultOutlining(false), EmitAddrsig(false), BBAddrMap(false),
EmitCallSiteInfo(false), SupportsDebugEntryValues(false),
EnableDebugEntryValues(false), ValueTrackingVariableLocations(false),
ForceDwarfFrameSection(false), XRayFunctionIndex(true),
DebugStrictDwarf(false), Hotpatch(false),
UniqueBasicBlockSectionNames(false), SeparateNamedSections(false),
TrapUnreachable(false), NoTrapAfterNoreturn(false), TLSSize(0),
EmulatedTLS(false), EnableTLSDESC(false), EnableIPRA(false),
EmitStackSizeSection(false), EnableMachineOutliner(false),
EnableMachineFunctionSplitter(false), SupportsDefaultOutlining(false),
EmitAddrsig(false), BBAddrMap(false), EmitCallSiteInfo(false),
SupportsDebugEntryValues(false), EnableDebugEntryValues(false),
ValueTrackingVariableLocations(false), ForceDwarfFrameSection(false),
XRayFunctionIndex(true), DebugStrictDwarf(false), Hotpatch(false),
PPCGenScalarMASSEntries(false), JMCInstrument(false),
EnableCFIFixup(false), MisExpect(false), XCOFFReadOnlyPointers(false),
FPDenormalMode(DenormalMode::IEEE, DenormalMode::IEEE) {}
Expand Down Expand Up @@ -277,6 +277,9 @@ namespace llvm {
/// Use unique names for basic block sections.
unsigned UniqueBasicBlockSectionNames : 1;

/// Emit named sections with the same name into different sections.
unsigned SeparateNamedSections : 1;

/// Emit target-specific trap instruction for 'unreachable' IR instructions.
unsigned TrapUnreachable : 1;

Expand Down
8 changes: 8 additions & 0 deletions llvm/lib/CodeGen/CommandFlags.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ CGOPT_EXP(bool, EmulatedTLS)
CGOPT_EXP(bool, EnableTLSDESC)
CGOPT(bool, UniqueSectionNames)
CGOPT(bool, UniqueBasicBlockSectionNames)
CGOPT(bool, SeparateNamedSections)
CGOPT(EABI, EABIVersion)
CGOPT(DebuggerKind, DebuggerTuningOpt)
CGOPT(bool, EnableStackSizeSection)
Expand Down Expand Up @@ -419,6 +420,12 @@ codegen::RegisterCodeGenFlags::RegisterCodeGenFlags() {
cl::init(false));
CGBINDOPT(UniqueBasicBlockSectionNames);

static cl::opt<bool> SeparateNamedSections(
"separate-named-sections",
cl::desc("Use separate unique sections for named sections"),
cl::init(false));
CGBINDOPT(SeparateNamedSections);

static cl::opt<EABI> EABIVersion(
"meabi", cl::desc("Set EABI type (default depends on triple):"),
cl::init(EABI::Default),
Expand Down Expand Up @@ -569,6 +576,7 @@ codegen::InitTargetOptionsFromCodeGenFlags(const Triple &TheTriple) {
Options.BBSections = getBBSectionsMode(Options);
Options.UniqueSectionNames = getUniqueSectionNames();
Options.UniqueBasicBlockSectionNames = getUniqueBasicBlockSectionNames();
Options.SeparateNamedSections = getSeparateNamedSections();
Options.TLSSize = getTLSSize();
Options.EmulatedTLS =
getExplicitEmulatedTLS().value_or(TheTriple.hasDefaultEmulatedTLS());
Expand Down
11 changes: 8 additions & 3 deletions llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -733,15 +733,20 @@ calcUniqueIDUpdateFlagsAndSize(const GlobalObject *GO, StringRef SectionName,
Ctx.isELFGenericMergeableSection(SectionName);
// If this is the first ocurrence of this section name, treat it as the
// generic section
if (!SymbolMergeable && !SeenSectionNameBefore)
return MCContext::GenericSectionID;
if (!SymbolMergeable && !SeenSectionNameBefore) {
if (TM.getSeparateNamedSections())
return NextUniqueID++;
else
return MCContext::GenericSectionID;
}

// Symbols must be placed into sections with compatible entry sizes. Generate
// unique sections for symbols that have not been assigned to compatible
// sections.
const auto PreviousID =
Ctx.getELFUniqueIDForEntsize(SectionName, Flags, EntrySize);
if (PreviousID)
if (PreviousID && (!TM.getSeparateNamedSections() ||
*PreviousID == MCContext::GenericSectionID))
return *PreviousID;

// If the user has specified the same section name as would be created
Expand Down
36 changes: 36 additions & 0 deletions llvm/test/CodeGen/X86/elf-separate-named-sections.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
; Test that global values with explicit sections are placed into unique sections.

; RUN: llc < %s | FileCheck %s
; RUN: llc -separate-named-sections < %s | FileCheck %s --check-prefix=SEPARATE
target triple="x86_64-unknown-unknown-elf"

define i32 @f() section "custom_text" {
entry:
ret i32 0
}

define i32 @g() section "custom_text" {
entry:
ret i32 0
}

; CHECK: .section custom_text,"ax",@progbits{{$}}
; CHECK: f:
; CHECK: g:

; SEPARATE: .section custom_text,"ax",@progbits,unique,1{{$}}
; SEPARATE: f:
; SEPARATE: .section custom_text,"ax",@progbits,unique,2{{$}}
; SEPARATE: g:

@i = global i32 0, section "custom_data", align 8
@j = global i32 0, section "custom_data", align 8

; CHECK: .section custom_data,"aw",@progbits{{$}}
; CHECK: i:
; CHECK: j:

; SEPARATE: .section custom_data,"aw",@progbits,unique,3{{$}}
; SEPARATE: i:
; SEPARATE: .section custom_data,"aw",@progbits,unique,4{{$}}
; SEPARATE: j:

0 comments on commit 8bcb073

Please sign in to comment.