Index: clang/lib/Frontend/CompilerInvocation.cpp =================================================================== --- clang/lib/Frontend/CompilerInvocation.cpp +++ clang/lib/Frontend/CompilerInvocation.cpp @@ -1139,11 +1139,7 @@ Opts.BBSections = std::string(Args.getLastArgValue(OPT_fbasic_block_sections_EQ, "none")); - // 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.DataSections = Args.hasArg(OPT_fdata_sections); Opts.StackSizeSection = Args.hasArg(OPT_fstack_size_section); Opts.UniqueSectionNames = !Args.hasArg(OPT_fno_unique_section_names); 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 @@ -710,7 +710,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 @@ -926,6 +926,22 @@ nullptr); } +MCSection *TargetLoweringObjectFileELF::getUniqueSectionForFunction( + const Function &F, const TargetMachine &TM) const { + SectionKind Kind = SectionKind::getText(); + unsigned Flags = getELFSectionFlags(Kind); + const MCSymbolELF *LinkedToSym = getLinkedToSymbol(&F, TM); + if (LinkedToSym) + Flags |= ELF::SHF_LINK_ORDER; + + MCSectionELF *Section = selectELFSectionForGlobal( + getContext(), &F, Kind, getMangler(), TM, true, Flags, + &NextUniqueID, LinkedToSym); + assert(Section->getLinkedToSymbol() == LinkedToSym); + return Section; + +} + static MCSectionELF *getStaticStructorSection(MCContext &Ctx, bool UseInitArray, bool IsCtor, unsigned Priority, const MCSymbol *KeySym) { 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-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,5 +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=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