Index: llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp =================================================================== --- llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ llvm/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -713,9 +713,9 @@ emitConstantPool(); // Print the 'header' of function. - // 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()) + // If basic block sections are desired, explicitly request a unique section + // for this function's entry block. + if (MF->front().isBeginSection()) MF->setSection(getObjFileLowering().getUniqueSectionForFunction(F, TM)); else MF->setSection(getObjFileLowering().SectionForGlobal(&F, TM)); Index: llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp =================================================================== --- llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -652,8 +652,10 @@ }; } -MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal( - const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { +static MCSection *selectExplicitSectionGlobal( + const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM, + MCContext &Ctx, Mangler &Mang, unsigned *NextUniqueID, + bool Retain, bool ForceUnique) { StringRef SectionName = GO->getSection(); // Check if '#pragma clang section' name is applicable. @@ -696,22 +698,22 @@ unsigned UniqueID = MCContext::GenericSectionID; const MCSymbolELF *LinkedToSym = getLinkedToSymbol(GO, TM); const bool Associated = GO->getMetadata(LLVMContext::MD_associated); - const bool Retain = Used.count(GO); if (Associated || Retain) { - UniqueID = NextUniqueID++; + UniqueID = *NextUniqueID; + (*NextUniqueID)++; if (Associated) Flags |= ELF::SHF_LINK_ORDER; - if (Retain && (getContext().getAsmInfo()->useIntegratedAssembler() || - getContext().getAsmInfo()->binutilsIsAtLeast(2, 36))) + if (Retain && (Ctx.getAsmInfo()->useIntegratedAssembler() || + Ctx.getAsmInfo()->binutilsIsAtLeast(2, 36))) Flags |= ELF::SHF_GNU_RETAIN; } else { - if (getContext().getAsmInfo()->useIntegratedAssembler() || - getContext().getAsmInfo()->binutilsIsAtLeast(2, 35)) { + if (Ctx.getAsmInfo()->useIntegratedAssembler() || + Ctx.getAsmInfo()->binutilsIsAtLeast(2, 35)) { // Symbols must be placed into sections with compatible entry // sizes. Generate unique sections for symbols that have not // been assigned to compatible sections. if (Flags & ELF::SHF_MERGE) { - auto maybeID = getContext().getELFUniqueIDForEntsize(SectionName, Flags, + auto maybeID = Ctx.getELFUniqueIDForEntsize(SectionName, Flags, EntrySize); if (maybeID) UniqueID = *maybeID; @@ -721,20 +723,27 @@ // to unique the section as the entry size for this symbol will be // compatible with implicitly created sections. SmallString<128> ImplicitSectionNameStem = getELFSectionNameForGlobal( - GO, Kind, getMangler(), TM, EntrySize, false); - if (!(getContext().isELFImplicitMergeableSectionNamePrefix( + GO, Kind, Mang, TM, EntrySize, false); + if (!(Ctx.isELFImplicitMergeableSectionNamePrefix( SectionName) && - SectionName.startswith(ImplicitSectionNameStem))) - UniqueID = NextUniqueID++; + SectionName.startswith(ImplicitSectionNameStem))) { + UniqueID = *NextUniqueID; + (*NextUniqueID)++; + } } } else { // We need to unique the section if the user has explicity // assigned a non-mergeable symbol to a section name for // a generic mergeable section. - if (getContext().isELFGenericMergeableSection(SectionName)) { - auto maybeID = getContext().getELFUniqueIDForEntsize( + if (Ctx.isELFGenericMergeableSection(SectionName)) { + auto maybeID = Ctx.getELFUniqueIDForEntsize( SectionName, Flags, EntrySize); - UniqueID = maybeID ? *maybeID : NextUniqueID++; + if (maybeID) + UniqueID = *maybeID; + else { + UniqueID = *NextUniqueID; + (*NextUniqueID)++; + } } } } else { @@ -749,7 +758,15 @@ } } - MCSectionELF *Section = getContext().getELFSection( + // Increment uniqueID if we are forced to emit a unique section. + // This works perfectly fine with section attribute or pragma section as the + // sections with the same name are grouped together by the assembler. + if (ForceUnique && UniqueID == MCContext::GenericSectionID) { + UniqueID = *NextUniqueID; + (*NextUniqueID)++; + } + + MCSectionELF *Section = Ctx.getELFSection( SectionName, getELFSectionType(SectionName, Kind), Flags, EntrySize, Group, IsComdat, UniqueID, LinkedToSym); // Make sure that we did not get some other section with incompatible sh_link. @@ -757,8 +774,8 @@ assert(Section->getLinkedToSymbol() == LinkedToSym && "Associated symbol mismatch between sections"); - if (!(getContext().getAsmInfo()->useIntegratedAssembler() || - getContext().getAsmInfo()->binutilsIsAtLeast(2, 35))) { + if (!(Ctx.getAsmInfo()->useIntegratedAssembler() || + Ctx.getAsmInfo()->binutilsIsAtLeast(2, 35))) { // If we are using GNU as before 2.35, then this symbol might have // been placed in an incompatible mergeable section. Emit an error if this // is the case to avoid creating broken output. @@ -777,6 +794,12 @@ return Section; } +MCSection *TargetLoweringObjectFileELF::getExplicitSectionGlobal( + const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const { + return selectExplicitSectionGlobal(GO, Kind, TM, getContext(), getMangler(), + &NextUniqueID, Used.count(GO), false); +} + static MCSectionELF *selectELFSectionForGlobal( MCContext &Ctx, const GlobalObject *GO, SectionKind Kind, Mangler &Mang, const TargetMachine &TM, bool EmitUniqueSection, unsigned Flags, @@ -859,9 +882,16 @@ const Function &F, const TargetMachine &TM) const { SectionKind Kind = SectionKind::getText(); unsigned Flags = getELFSectionFlags(Kind); - return selectELFSectionForGlobal( - getContext(), &F, Kind, getMangler(), TM, Used.count(&F), - /*EmitUniqueSection=*/true, Flags, &NextUniqueID); + // If the function's section names is pre-determined via pragma or a + // section attribute, call selectExplicitSectionGlobal. + if (F.hasSection() || F.hasFnAttribute("implicit-section-name")) + return selectExplicitSectionGlobal( + &F, Kind, TM, getContext(), getMangler(), &NextUniqueID, + Used.count(&F), /* ForceUnique = */true); + else + return selectELFSectionForGlobal( + getContext(), &F, Kind, getMangler(), TM, Used.count(&F), + /*EmitUniqueSection=*/true, Flags, &NextUniqueID); } MCSection *TargetLoweringObjectFileELF::getSectionForJumpTable( Index: llvm/test/CodeGen/X86/basic-block-sections-named-section.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/X86/basic-block-sections-named-section.ll @@ -0,0 +1,42 @@ +; RUN: llc < %s -mtriple=x86_64-pc-linux -basic-block-sections=all | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-pc-linux -function-sections -basic-block-sections=all | FileCheck %s +; RUN: echo "!_Z3fooi" > %t.order.txt +; RUN: echo "!!2" >> %t.order.txt +; RUN: llc < %s -mtriple=x86_64-pc-linux -basic-block-sections=%t.order.txt | FileCheck %s --check-prefix=LIST +; RUN: llc < %s -mtriple=x86_64-pc-linux -function-sections -basic-block-sections=%t.order.txt | FileCheck %s --check-prefix=LIST + +; CHECK: .section foo_section,"ax",@progbits,unique,1 +; CHECK-LABEL: _Z3fooi: +; CHECK: .section foo_section,"ax",@progbits,unique,2 +; CHECK-NEXT: _Z3fooi.__part.1: +; CHECK: .section foo_section,"ax",@progbits,unique,3 +; CHECK-NEXT: _Z3fooi.__part.2: + +; LIST: .section foo_section,"ax",@progbits,unique,1 +; LIST-LABEL: _Z3fooi: +; LIST: .section foo_section,"ax",@progbits,unique,2 +; LIST-NEXT: _Z3fooi.__part.0: +; LIST-NOT: .section foo_section,"ax",@progbits,unique,3 + +;; Source to generate the IR: +;; __attribute__((section("foo_section"))) +;; int foo(int n) { +;; if (n < 0) +;; exit(-1); +;; return 0; +;; } + +define dso_local i32 @_Z3fooi(i32 %n) local_unnamed_addr section "foo_section" { +entry: + %cmp = icmp slt i32 %n, 0 + br i1 %cmp, label %if.then, label %if.end + +if.then: ; preds = %entry + tail call void @exit(i32 -1) #2 + unreachable + +if.end: ; preds = %entry + ret i32 0 +} + +declare dso_local void @exit(i32) local_unnamed_addr Index: llvm/test/CodeGen/X86/basic-block-sections-pragma-sections.ll =================================================================== --- /dev/null +++ llvm/test/CodeGen/X86/basic-block-sections-pragma-sections.ll @@ -0,0 +1,44 @@ +; RUN: llc < %s -mtriple=x86_64-pc-linux -basic-block-sections=all | FileCheck %s +; RUN: llc < %s -mtriple=x86_64-pc-linux -function-sections -basic-block-sections=all | FileCheck %s +; RUN: echo "!_Z3fooi" > %t.order.txt +; RUN: echo "!!2" >> %t.order.txt +; RUN: llc < %s -mtriple=x86_64-pc-linux -basic-block-sections=%t.order.txt | FileCheck %s --check-prefix=LIST +; RUN: llc < %s -mtriple=x86_64-pc-linux -function-sections -basic-block-sections=%t.order.txt | FileCheck %s --check-prefix=LIST + +; CHECK: .section foo_section,"ax",@progbits,unique,1 +; CHECK-LABEL: _Z3fooi: +; CHECK: .section foo_section,"ax",@progbits,unique,2 +; CHECK-NEXT: _Z3fooi.__part.1: +; CHECK: .section foo_section,"ax",@progbits,unique,3 +; CHECK-NEXT: _Z3fooi.__part.2: + +; LIST: .section foo_section,"ax",@progbits,unique,1 +; LIST-LABEL: _Z3fooi: +; LIST: .section foo_section,"ax",@progbits,unique,2 +; LIST-NEXT: _Z3fooi.__part.0: +; LIST-NOT: .section foo_section,"ax",@progbits,unique,3 + +;; Source to generate the IR: +;; #pragma clang section text = "foo_section" +;; int foo(int n) { +;; if (n < 0) +;; exit(-1); +;; return 0; +;; } + +define dso_local i32 @_Z3fooi(i32 %n) local_unnamed_addr #0 { +entry: + %cmp = icmp slt i32 %n, 0 + br i1 %cmp, label %if.then, label %if.end + +if.then: ; preds = %entry + tail call void @exit(i32 -1) #2 + unreachable + +if.end: ; preds = %entry + ret i32 0 +} + +declare dso_local void @exit(i32) local_unnamed_addr + +attributes #0 = {"implicit-section-name"="foo_section" }