Index: clang/lib/Frontend/CompilerInvocation.cpp =================================================================== --- clang/lib/Frontend/CompilerInvocation.cpp +++ clang/lib/Frontend/CompilerInvocation.cpp @@ -1383,8 +1383,7 @@ GenerateArg(Args, OPT_ftime_report, SA); } - if (Opts.FunctionSections && - (Opts.BBSections == "none" || Opts.BBSections == "labels")) + if (Opts.FunctionSections) GenerateArg(Args, OPT_ffunction_sections, SA); if (Opts.PrepareForLTO && !Opts.PrepareForThinLTO) @@ -1666,10 +1665,7 @@ } } - // Basic Block Sections implies Function Sections. - Opts.FunctionSections = - Args.hasArg(OPT_ffunction_sections) || - (Opts.BBSections != "none" && Opts.BBSections != "labels"); + Opts.FunctionSections = Args.hasArg(OPT_ffunction_sections); Opts.PrepareForLTO = Args.hasArg(OPT_flto, OPT_flto_EQ); Opts.PrepareForThinLTO = false; Index: clang/test/CodeGen/basic-block-sections.c =================================================================== --- clang/test/CodeGen/basic-block-sections.c +++ clang/test/CodeGen/basic-block-sections.c @@ -32,7 +32,7 @@ // BB_WORLD: world: // BB_WORLD: .section .text.world,"ax",@progbits,unique // BB_WORLD: world.__part.1: -// BB_WORLD: .section .text.another,"ax",@progbits +// BB_ALL: .section .text.another,"ax",@progbits // BB_ALL: .section .text.another,"ax",@progbits,unique // BB_ALL: another.__part.1: // BB_LIST-NOT: .section .text.another,"ax",@progbits,unique Index: llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h =================================================================== --- llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -71,6 +71,10 @@ const MachineBasicBlock &MBB, const TargetMachine &TM) const override; + MCSection * + getUniqueSectionForFunction(const Function &F, + const TargetMachine &TM) const override; + bool shouldPutJumpTableInFunctionSection(bool UsesLabelDifference, const Function &F) const override; Index: llvm/include/llvm/Target/TargetLoweringObjectFile.h =================================================================== --- llvm/include/llvm/Target/TargetLoweringObjectFile.h +++ llvm/include/llvm/Target/TargetLoweringObjectFile.h @@ -102,6 +102,10 @@ const MachineBasicBlock &MBB, const TargetMachine &TM) const; + virtual MCSection * + getUniqueSectionForFunction(const Function &F, + const TargetMachine &TM) const; + /// Classify the specified global variable into a set of target independent /// categories embodied in SectionKind. static SectionKind getKindForGlobal(const GlobalObject *GO, Index: llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp =================================================================== --- llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -709,7 +709,12 @@ emitConstantPool(); // Print the 'header' of function. - MF->setSection(getObjFileLowering().SectionForGlobal(&F, TM)); + // If basic block sections is desired and function sections is off, + // explicitly request a unique section for this function. + if (MF->front().isBeginSection() && !TM.getFunctionSections()) + MF->setSection(getObjFileLowering().getUniqueSectionForFunction(F, TM)); + else + MF->setSection(getObjFileLowering().SectionForGlobal(&F, TM)); OutStreamer->SwitchSection(MF->getSection()); if (!MAI->hasVisibilityOnlyWithLinkage()) Index: llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp =================================================================== --- llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -791,6 +791,23 @@ EntrySize, Group, UniqueID, AssociatedSymbol); } +static MCSection *selectELFSectionForGlobal( + MCContext &Ctx, const GlobalObject *GO, SectionKind Kind, Mangler &Mang, + const TargetMachine &TM, bool EmitUniqueSection, unsigned Flags, + unsigned *NextUniqueID) { + const MCSymbolELF *LinkedToSym = getLinkedToSymbol(GO, TM); + if (LinkedToSym) { + EmitUniqueSection = true; + Flags |= ELF::SHF_LINK_ORDER; + } + + MCSectionELF *Section = selectELFSectionForGlobal( + Ctx, GO, Kind, Mang, TM, EmitUniqueSection, Flags, + NextUniqueID, LinkedToSym); + assert(Section->getLinkedToSymbol() == LinkedToSym); + return Section; +} + MCSection *TargetLoweringObjectFileELF::SelectSectionForGlobal( const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { unsigned Flags = getELFSectionFlags(Kind); @@ -805,18 +822,17 @@ EmitUniqueSection = TM.getDataSections(); } EmitUniqueSection |= GO->hasComdat(); + return selectELFSectionForGlobal(getContext(), GO, Kind, getMangler(), TM, + EmitUniqueSection, Flags, &NextUniqueID); +} - const MCSymbolELF *LinkedToSym = getLinkedToSymbol(GO, TM); - if (LinkedToSym) { - EmitUniqueSection = true; - Flags |= ELF::SHF_LINK_ORDER; - } - - MCSectionELF *Section = selectELFSectionForGlobal( - getContext(), GO, Kind, getMangler(), TM, EmitUniqueSection, Flags, - &NextUniqueID, LinkedToSym); - assert(Section->getLinkedToSymbol() == LinkedToSym); - return Section; +MCSection *TargetLoweringObjectFileELF::getUniqueSectionForFunction( + const Function &F, const TargetMachine &TM) const { + SectionKind Kind = SectionKind::getText(); + unsigned Flags = getELFSectionFlags(Kind); + return selectELFSectionForGlobal(getContext(), &F, Kind, getMangler(), TM, + /* EmitUniqueSection = */ true, Flags, + &NextUniqueID); } MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable( Index: llvm/lib/Target/TargetLoweringObjectFile.cpp =================================================================== --- llvm/lib/Target/TargetLoweringObjectFile.cpp +++ llvm/lib/Target/TargetLoweringObjectFile.cpp @@ -380,6 +380,11 @@ return nullptr; } +MCSection *TargetLoweringObjectFile::getUniqueSectionForFunction( + const Function &F, const TargetMachine &TM) const { + return nullptr; +} + /// getTTypeGlobalReference - Return an MCExpr to use for a /// reference to the specified global variable from exception /// handling information. Index: llvm/test/CodeGen/X86/basic-block-sections-blockaddress-taken.ll =================================================================== --- llvm/test/CodeGen/X86/basic-block-sections-blockaddress-taken.ll +++ llvm/test/CodeGen/X86/basic-block-sections-blockaddress-taken.ll @@ -7,6 +7,7 @@ indirectbr i8* %1, [label %bb1, label %bb2] ; CHECK: .text +; CHECK: .section .text.foo,"ax",@progbits ; CHECK-LABEL: foo: ; CHECK: movl $.Ltmp0, %eax ; CHECK-NEXT: movl $.Ltmp1, %ecx @@ -16,7 +17,7 @@ bb1: ; preds = %entry %2 = call i32 @bar() ret void -; CHECK: .section .text,"ax",@progbits,unique,1 +; CHECK: .section .text.foo,"ax",@progbits,unique,1 ; CHECK-NEXT: .Ltmp0: ; CHECK-NEXT: foo.__part.1 ; CHECK-NEXT: callq bar @@ -25,7 +26,7 @@ bb2: ; preds = %entry %3 = call i32 @baz() ret void -; CHECK: .section .text,"ax",@progbits,unique,2 +; CHECK: .section .text.foo,"ax",@progbits,unique,2 ; CHECK-NEXT: .Ltmp1: ; CHECK-NEXT: foo.__part.2 ; CHECK-NEXT: callq baz Index: llvm/test/CodeGen/X86/basic-block-sections-list.ll =================================================================== --- llvm/test/CodeGen/X86/basic-block-sections-list.ll +++ llvm/test/CodeGen/X86/basic-block-sections-list.ll @@ -1,7 +1,7 @@ ; Check the basic block sections list option. ; RUN: echo '!_Z3foob' > %t -; RUN: llc < %s -mtriple=x86_64-pc-linux -function-sections -basic-block-sections=%t -unique-basic-block-section-names | FileCheck %s -check-prefix=LINUX-SECTIONS -; RUN: llc < %s -mtriple=x86_64-pc-linux -function-sections -basic-block-sections=%t -unique-basic-block-section-names -split-machine-functions | FileCheck %s -check-prefix=LINUX-SECTIONS +; RUN: llc < %s -mtriple=x86_64-pc-linux -function-sections -basic-block-sections=%t -unique-basic-block-section-names | FileCheck %s -check-prefix=LINUX-SECTIONS --check-prefix=LINUX-SECTIONS-FUNCTION-SECTION +; llc < %s -mtriple=x86_64-pc-linux -basic-block-sections=%t -unique-basic-block-section-names | FileCheck %s -check-prefix=LINUX-SECTIONS --check-prefix=LINUX-SECTIONS-NO-FUNCTION-SECTION define i32 @_Z3foob(i1 zeroext %0) nounwind { %2 = alloca i32, align 4 @@ -67,7 +67,8 @@ ; LINUX-SECTIONS: .section .text._Z3foob._Z3foob.__part.3,"ax",@progbits ; LINUX-SECTIONS: _Z3foob.__part.3: -; LINUX-SECTIONS: .section .text._Z3zipb,"ax",@progbits +; LINUX-SECTIONS-FUNCTION-SECTION: .section .text._Z3zipb,"ax",@progbits +; LINUX-SECIONS-NO-FUNCTION-SECTION-NOT: .section .text._Z3zipb,"ax",@progbits ; LINUX-SECTIONS: _Z3zipb: ; LINUX-SECTIONS-NOT: .section .text._Z3zipb._Z3zipb.__part.{{[0-9]+}},"ax",@progbits ; LINUX-SECTIONS-NOT: _Z3zipb.__part.{{[0-9]+}}: Index: llvm/test/CodeGen/X86/basic-block-sections-mir-parse.mir =================================================================== --- llvm/test/CodeGen/X86/basic-block-sections-mir-parse.mir +++ llvm/test/CodeGen/X86/basic-block-sections-mir-parse.mir @@ -122,10 +122,11 @@ ... +# CHECK: .section .text._Z3foob,"ax",@progbits # CHECK: _Z3foob: -# CHECK: .section .text,"ax",@progbits,unique +# CHECK: .section .text._Z3foob,"ax",@progbits,unique # CHECK: _Z3foob.__part.1: -# CHECK: .section .text,"ax",@progbits,unique +# CHECK: .section .text._Z3foob,"ax",@progbits,unique # CHECK: _Z3foob.__part.2: -# CHECK: .section .text,"ax",@progbits,unique +# CHECK: .section .text._Z3foob,"ax",@progbits,unique # CHECK: _Z3foob.__part.3: Index: llvm/test/CodeGen/X86/basic-block-sections-unreachable.ll =================================================================== --- llvm/test/CodeGen/X86/basic-block-sections-unreachable.ll +++ llvm/test/CodeGen/X86/basic-block-sections-unreachable.ll @@ -13,6 +13,6 @@ default: unreachable ; CHECK-NOSECTIONS: # %bb.2: # %default -; CHECK-SECTIONS: .section .text,"ax",@progbits,unique,2 +; CHECK-SECTIONS: .section .text.foo,"ax",@progbits,unique,2 ; CHECK-SECTIONS-NEXT: foo.__part.2: # %default } Index: llvm/test/CodeGen/X86/basic-block-sections.ll =================================================================== --- llvm/test/CodeGen/X86/basic-block-sections.ll +++ llvm/test/CodeGen/X86/basic-block-sections.ll @@ -1,6 +1,7 @@ ; RUN: llc < %s -mtriple=x86_64-pc-linux -function-sections -basic-block-sections=all -unique-basic-block-section-names | FileCheck %s -check-prefix=LINUX-SECTIONS +; RUN: llc < %s -mtriple=x86_64-pc-linux -basic-block-sections=all -unique-basic-block-section-names | FileCheck %s -check-prefix=LINUX-SECTIONS ; RUN: llc < %s -mtriple=i386-unknown-linux-gnu -function-sections -basic-block-sections=all -unique-basic-block-section-names | FileCheck %s -check-prefix=LINUX-SECTIONS -; RUN: llc < %s -mtriple=x86_64-pc-linux -function-sections -basic-block-sections=all -unique-basic-block-section-names -split-machine-functions | FileCheck %s -check-prefix=LINUX-SECTIONS +; RUN: llc < %s -mtriple=i386-unknown-linux-gnu -basic-block-sections=all -unique-basic-block-section-names | FileCheck %s -check-prefix=LINUX-SECTIONS define void @_Z3bazb(i1 zeroext) nounwind { %2 = alloca i8, align 1 Index: llvm/test/DebugInfo/X86/basic-block-sections_1.ll =================================================================== --- llvm/test/DebugInfo/X86/basic-block-sections_1.ll +++ llvm/test/DebugInfo/X86/basic-block-sections_1.ll @@ -16,10 +16,10 @@ ; NO-SECTIONS: DW_AT_high_pc [DW_FORM_data4] ({{.*}}) ; BB-SECTIONS: DW_AT_low_pc [DW_FORM_addr] (0x0000000000000000) ; BB-SECTIONS-NEXT: DW_AT_ranges [DW_FORM_sec_offset] -; BB-SECTIONS-NEXT: [{{.*}}) ".text._Z3fooi.__part.1" -; BB-SECTIONS-NEXT: [{{.*}}) ".text._Z3fooi.__part.2" -; BB-SECTIONS-NEXT: [{{.*}}) ".text._Z3fooi.__part.3" -; BB-SECTIONS-NEXT: [{{.*}}) ".text" +; BB-SECTIONS-NEXT: [{{.*}}) ".text._Z3fooi._Z3fooi.__part.1" +; BB-SECTIONS-NEXT: [{{.*}}) ".text._Z3fooi._Z3fooi.__part.2" +; BB-SECTIONS-NEXT: [{{.*}}) ".text._Z3fooi._Z3fooi.__part.3" +; BB-SECTIONS-NEXT: [{{.*}}) ".text._Z3fooi" ; BB-SECTIONS-ASM: _Z3fooi: ; BB-SECTIONS-ASM: .Ltmp{{[0-9]+}}: ; BB-SECTIONS-ASM-NEXT: .loc 1 2 9 prologue_end