Author: Petr Hosek Date: 2024-05-07T09:18:55-07:00 New Revision: 8bcb0737056163686e967821bea7f9e87c57cdfc
URL: https://github.com/llvm/llvm-project/commit/8bcb0737056163686e967821bea7f9e87c57cdfc DIFF: https://github.com/llvm/llvm-project/commit/8bcb0737056163686e967821bea7f9e87c57cdfc.diff LOG: [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. Added: clang/test/CodeGen/fseparate-named-sections.c llvm/test/CodeGen/X86/elf-separate-named-sections.ll Modified: clang/docs/ReleaseNotes.rst clang/include/clang/Basic/CodeGenOptions.def clang/include/clang/Driver/Options.td clang/lib/CodeGen/BackendUtil.cpp llvm/include/llvm/CodeGen/CommandFlags.h llvm/include/llvm/Target/TargetMachine.h llvm/include/llvm/Target/TargetOptions.h llvm/lib/CodeGen/CommandFlags.cpp llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index a85095e424b6..cc3108bf41d6 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -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 ------------------------- diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index 340b08dd7e2a..b964e4557478 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 c9f7c4e5f718..2c319ba38a29 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -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, diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index 22c3f8642ad8..119ec4704002 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/clang/test/CodeGen/fseparate-named-sections.c b/clang/test/CodeGen/fseparate-named-sections.c new file mode 100644 index 000000000000..7a247dbd085c --- /dev/null +++ b/clang/test/CodeGen/fseparate-named-sections.c @@ -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: diff --git a/llvm/include/llvm/CodeGen/CommandFlags.h b/llvm/include/llvm/CodeGen/CommandFlags.h index 244dabd38cf6..d5448d781363 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 48ea3cfe0277..1ba99730ca70 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 d37e9d9576ba..98a8b7ba337c 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,9 @@ namespace llvm { /// Use unique names for basic block sections. unsigned UniqueBasicBlockSectionNames : 1; + /// Emit named sections with the same name into diff erent sections. + 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 14ac4b2102c2..677460a2d8e4 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 2a77a683a901..81f3864ee4d0 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -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 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 000000000000..18efc20aa945 --- /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 | 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: _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits