[clang] [llvm] [Clang] -fseparate-named-sections option (PR #91028)
Petr Hosek via llvm-commits
llvm-commits at lists.llvm.org
Fri May 3 16:09:24 PDT 2024
https://github.com/petrhosek created https://github.com/llvm/llvm-project/pull/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.
>From 78193f68a149e378fbb180a1a5fa1f4551f2af66 Mon Sep 17 00:00:00 2001
From: Petr Hosek <phosek at google.com>
Date: Fri, 3 May 2024 15:48:31 -0700
Subject: [PATCH] [Clang] -fseparate-named-sections option
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.
---
clang/include/clang/Basic/CodeGenOptions.def | 1 +
clang/include/clang/Driver/Options.td | 5 +++
clang/lib/CodeGen/BackendUtil.cpp | 1 +
llvm/include/llvm/CodeGen/CommandFlags.h | 2 ++
llvm/include/llvm/Target/TargetMachine.h | 4 +++
llvm/include/llvm/Target/TargetOptions.h | 20 ++++++-----
llvm/lib/CodeGen/CommandFlags.cpp | 8 +++++
.../CodeGen/TargetLoweringObjectFileImpl.cpp | 16 +++++++--
.../X86/elf-separate-named-sections.ll | 36 +++++++++++++++++++
9 files changed, 81 insertions(+), 12 deletions(-)
create mode 100644 llvm/test/CodeGen/X86/elf-separate-named-sections.ll
diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index 340b08dd7e2a33..b964e45574782c 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -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
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 9f86808145d9ab..deb1c2253c1ed2 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -4136,6 +4136,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,
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 22c3f8642ad8eb..119ec4704002cf 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -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;
diff --git a/llvm/include/llvm/CodeGen/CommandFlags.h b/llvm/include/llvm/CodeGen/CommandFlags.h
index 244dabd38cf65b..d5448d781363d4 100644
--- a/llvm/include/llvm/CodeGen/CommandFlags.h
+++ b/llvm/include/llvm/CodeGen/CommandFlags.h
@@ -122,6 +122,8 @@ bool getUniqueSectionNames();
bool getUniqueBasicBlockSectionNames();
+bool getSeparateNamedSections();
+
llvm::EABI getEABIVersion();
llvm::DebuggerKind getDebuggerTuningOpt();
diff --git a/llvm/include/llvm/Target/TargetMachine.h b/llvm/include/llvm/Target/TargetMachine.h
index 48ea3cfe02775b..1ba99730ca7024 100644
--- a/llvm/include/llvm/Target/TargetMachine.h
+++ b/llvm/include/llvm/Target/TargetMachine.h
@@ -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 {
diff --git a/llvm/include/llvm/Target/TargetOptions.h b/llvm/include/llvm/Target/TargetOptions.h
index d37e9d9576ba75..25d1f3f81fc142 100644
--- a/llvm/include/llvm/Target/TargetOptions.h
+++ b/llvm/include/llvm/Target/TargetOptions.h
@@ -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) {}
@@ -277,6 +277,8 @@ namespace llvm {
/// Use unique names for basic block sections.
unsigned UniqueBasicBlockSectionNames : 1;
+ unsigned SeparateNamedSections : 1;
+
/// Emit target-specific trap instruction for 'unreachable' IR instructions.
unsigned TrapUnreachable : 1;
diff --git a/llvm/lib/CodeGen/CommandFlags.cpp b/llvm/lib/CodeGen/CommandFlags.cpp
index 14ac4b2102c2fa..677460a2d8e401 100644
--- a/llvm/lib/CodeGen/CommandFlags.cpp
+++ b/llvm/lib/CodeGen/CommandFlags.cpp
@@ -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)
@@ -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),
@@ -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());
diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index 2a77a683a901f1..1217559e1e2276 100644
--- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -75,6 +75,10 @@ static cl::opt<bool> JumpTableInFunctionSection(
"jumptable-in-function-section", cl::Hidden, cl::init(false),
cl::desc("Putting Jump Table in function section"));
+static cl::opt<bool> UniqueExplicitSections(
+ "unique-explicit-sections", cl::Hidden, cl::init(true),
+ cl::desc("Putting symbols with explicit section into unique sections"));
+
static void GetObjCImageInfo(Module &M, unsigned &Version, unsigned &Flags,
StringRef &Section) {
SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags;
@@ -733,16 +737,22 @@ 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
// implicitly for this symbol e.g. .rodata.str1.1, then we don't need
diff --git a/llvm/test/CodeGen/X86/elf-separate-named-sections.ll b/llvm/test/CodeGen/X86/elf-separate-named-sections.ll
new file mode 100644
index 00000000000000..0631b604afab8e
--- /dev/null
+++ b/llvm/test/CodeGen/X86/elf-separate-named-sections.ll
@@ -0,0 +1,36 @@
+; Test that global values with explicit sections are placed into unique sections.
+
+; RUN: llc < %s 2>&1 | FileCheck %s
+; RUN: llc -separate-named-sections < %s 2>&1 | 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", at progbits{{$}}
+; CHECK: f:
+; CHECK: g:
+
+; SEPARATE: .section custom_text,"ax", at progbits,unique,1{{$}}
+; SEPARATE: f:
+; SEPARATE: .section custom_text,"ax", at progbits,unique,2{{$}}
+; SEPARATE: g:
+
+ at i = global i32 0, section "custom_data", align 8
+ at j = global i32 0, section "custom_data", align 8
+
+; CHECK: .section custom_data,"aw", at progbits{{$}}
+; CHECK: i:
+; CHECK: j:
+
+; SEPARATE: .section custom_data,"aw", at progbits,unique,3{{$}}
+; SEPARATE: i:
+; SEPARATE: .section custom_data,"aw", at progbits,unique,4{{$}}
+; SEPARATE: j:
More information about the llvm-commits
mailing list