Basic block sections should enable function sections implicitly.

Basic block sections enables function sections implicitly, this is not needed
and is inefficient with "=list" option.

We had basic block sections enable function sections implicitly in clang. This
is particularly inefficient with "=list" option as it places functions that do
not have any basic block sections in separate sections. This causes unnecessary
object file overhead for large applications.

This patch disables this implicit behavior. It only creates function sections
for those functions that require basic block sections.

Further, there was an inconistent behavior with llc as llc was not turning on
function sections by default. This patch makes llc and clang consistent and
tests are added to check the new behavior.

This is the first of two patches and this adds functionality in LLVM to
create a new section for the entry block if function sections is not
enabled.

Differential Revision: https://reviews.llvm.org/D93876

GitOrigin-RevId: d1a838babcc3360eb7e311006a4acd1eee61b8f2
diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
index 98a0207..73df97a 100644
--- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
+++ b/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;
 
diff --git a/include/llvm/Target/TargetLoweringObjectFile.h b/include/llvm/Target/TargetLoweringObjectFile.h
index 921063b..93bfdd2 100644
--- a/include/llvm/Target/TargetLoweringObjectFile.h
+++ b/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,
diff --git a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp b/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
index 764293e..e292d5b 100644
--- a/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
+++ b/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())
diff --git a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
index eef0555..f0f4516 100644
--- a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
+++ b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
@@ -798,6 +798,23 @@
                            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);
@@ -812,18 +829,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(
diff --git a/lib/Target/TargetLoweringObjectFile.cpp b/lib/Target/TargetLoweringObjectFile.cpp
index 81af4ee..239f12c 100644
--- a/lib/Target/TargetLoweringObjectFile.cpp
+++ b/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.
diff --git a/test/CodeGen/X86/basic-block-sections-blockaddress-taken.ll b/test/CodeGen/X86/basic-block-sections-blockaddress-taken.ll
index 4957916..8d3a5ff 100644
--- a/test/CodeGen/X86/basic-block-sections-blockaddress-taken.ll
+++ b/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
diff --git a/test/CodeGen/X86/basic-block-sections-list.ll b/test/CodeGen/X86/basic-block-sections-list.ll
index ab5abdc..d2408a0 100644
--- a/test/CodeGen/X86/basic-block-sections-list.ll
+++ b/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]+}}:
diff --git a/test/CodeGen/X86/basic-block-sections-mir-parse.mir b/test/CodeGen/X86/basic-block-sections-mir-parse.mir
index 6a2cee0..ae67f16 100644
--- a/test/CodeGen/X86/basic-block-sections-mir-parse.mir
+++ b/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:
diff --git a/test/CodeGen/X86/basic-block-sections-unreachable.ll b/test/CodeGen/X86/basic-block-sections-unreachable.ll
index 8c77070..838e2d9 100644
--- a/test/CodeGen/X86/basic-block-sections-unreachable.ll
+++ b/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
 }
diff --git a/test/CodeGen/X86/basic-block-sections.ll b/test/CodeGen/X86/basic-block-sections.ll
index a6dc6e5..0ae7922 100644
--- a/test/CodeGen/X86/basic-block-sections.ll
+++ b/test/CodeGen/X86/basic-block-sections.ll
@@ -1,6 +1,8 @@
 ; 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=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 -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  -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
diff --git a/test/DebugInfo/X86/basic-block-sections_1.ll b/test/DebugInfo/X86/basic-block-sections_1.ll
index 959ba67..1e5df81 100644
--- a/test/DebugInfo/X86/basic-block-sections_1.ll
+++ b/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