OSDN Git Service

[MC] - Add .stack_size sections into groups and link them with .text
authorGeorge Rimar <grimar@accesssoftek.com>
Fri, 22 Jun 2018 10:10:53 +0000 (10:10 +0000)
committerGeorge Rimar <grimar@accesssoftek.com>
Fri, 22 Jun 2018 10:10:53 +0000 (10:10 +0000)
D39788 added a '.stack-size' section containing metadata on function stack sizes
to output ELF files behind the new -stack-size-section flag.

This change does following two things on top:

1) Imagine the case when there are -ffunction-sections flag given and there are text sections in COMDATs.
    The patch adds a '.stack-size' section into corresponding COMDAT group, so that linker will be able to
    eliminate them fast during resolving the COMDATs.
2) Patch sets a SHF_LINK_ORDER flag and links '.stack-size' with the corresponding .text.
   With that linker will be able to do -gc-sections on dead stack sizes sections.

Differential revision: https://reviews.llvm.org/D46874

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@335332 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCObjectFileInfo.h
lib/CodeGen/AsmPrinter/AsmPrinter.cpp
lib/MC/MCObjectFileInfo.cpp
test/CodeGen/ARM/stack-size-section.ll
test/CodeGen/SystemZ/stack-size-section.ll
test/CodeGen/X86/stack-size-section-function-sections.ll [new file with mode: 0644]
test/CodeGen/X86/stack-size-section.ll

index d50c052..898ca71 100644 (file)
 #ifndef LLVM_MC_MCOBJECTFILEINFO_H
 #define LLVM_MC_MCOBJECTFILEINFO_H
 
+#include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/Triple.h"
 #include "llvm/Support/CodeGen.h"
 
 namespace llvm {
 class MCContext;
 class MCSection;
+class MCSymbol;
 
 class MCObjectFileInfo {
 protected:
@@ -158,6 +160,7 @@ protected:
 
   /// Section containing metadata on function stack sizes.
   MCSection *StackSizesSection;
+  mutable DenseMap<const MCSymbol *, unsigned> StackSizesUniquing;
 
   // ELF specific sections.
   MCSection *DataRelROSection;
@@ -299,7 +302,7 @@ public:
   MCSection *getStackMapSection() const { return StackMapSection; }
   MCSection *getFaultMapSection() const { return FaultMapSection; }
 
-  MCSection *getStackSizesSection() const { return StackSizesSection; }
+  MCSection *getStackSizesSection(const MCSection &TextSec) const;
 
   // ELF specific sections.
   MCSection *getDataRelROSection() const { return DataRelROSection; }
index 9a74917..1b1edfb 100644 (file)
@@ -989,7 +989,8 @@ void AsmPrinter::emitStackSizeSection(const MachineFunction &MF) {
   if (!MF.getTarget().Options.EmitStackSizeSection)
     return;
 
-  MCSection *StackSizeSection = getObjFileLowering().getStackSizesSection();
+  MCSection *StackSizeSection =
+      getObjFileLowering().getStackSizesSection(*getCurrentSection());
   if (!StackSizeSection)
     return;
 
index b075f22..2b5c9c7 100644 (file)
@@ -948,3 +948,24 @@ MCSection *MCObjectFileInfo::getDwarfTypesSection(uint64_t Hash) const {
   return Ctx->getELFSection(".debug_types", ELF::SHT_PROGBITS, ELF::SHF_GROUP,
                             0, utostr(Hash));
 }
+
+MCSection *
+MCObjectFileInfo::getStackSizesSection(const MCSection &TextSec) const {
+  if (Env != IsELF)
+    return StackSizesSection;
+
+  const MCSectionELF &ElfSec = static_cast<const MCSectionELF &>(TextSec);
+  unsigned Flags = ELF::SHF_LINK_ORDER;
+  StringRef GroupName;
+  if (const MCSymbol *Group = ElfSec.getGroup()) {
+    GroupName = Group->getName();
+    Flags |= ELF::SHF_GROUP;
+  }
+
+  const MCSymbol *Link = TextSec.getBeginSymbol();
+  auto It = StackSizesUniquing.insert({Link, StackSizesUniquing.size()});
+  unsigned UniqueID = It.first->second;
+
+  return Ctx->getELFSection(".stack_sizes", ELF::SHT_PROGBITS, Flags, 0,
+                            GroupName, UniqueID, cast<MCSymbolELF>(Link));
+}
index 142261a..10f1564 100644 (file)
@@ -2,7 +2,7 @@
 
 ; CHECK-LABEL: func1:
 ; CHECK-NEXT: .Lfunc_begin0:
-; CHECK: .section .stack_sizes,"",%progbits
+; CHECK: .section .stack_sizes,"o",%progbits,.text,unique,0
 ; CHECK-NEXT: .long .Lfunc_begin0
 ; CHECK-NEXT: .byte 8
 define void @func1(i32, i32) #0 {
@@ -13,7 +13,7 @@ define void @func1(i32, i32) #0 {
 
 ; CHECK-LABEL: func2:
 ; CHECK-NEXT: .Lfunc_begin1:
-; CHECK: .section .stack_sizes,"",%progbits
+; CHECK: .section .stack_sizes,"o",%progbits,.text,unique,0
 ; CHECK-NEXT: .long .Lfunc_begin1
 ; CHECK-NEXT: .byte 16
 define void @func2() #0 {
index f0e421f..6aacc70 100644 (file)
@@ -2,7 +2,7 @@
 
 ; CHECK-LABEL: func1:
 ; CHECK-NEXT: .Lfunc_begin0:
-; CHECK: .section .stack_sizes,"",@progbits
+; CHECK: .section .stack_sizes,"o",@progbits,.text,unique,0
 ; CHECK-NEXT: .quad .Lfunc_begin0
 ; CHECK-NEXT: .byte 0
 define void @func1(i32, i32) #0 {
@@ -11,7 +11,7 @@ define void @func1(i32, i32) #0 {
 
 ; CHECK-LABEL: func2:
 ; CHECK-NEXT: .Lfunc_begin1:
-; CHECK: .section .stack_sizes,"",@progbits
+; CHECK: .section .stack_sizes,"o",@progbits,.text,unique,0
 ; CHECK-NEXT: .quad .Lfunc_begin1
 ; CHECK-NEXT: .ascii  "\250\001"
 define void @func2(i32, i32) #0 {
@@ -22,7 +22,7 @@ define void @func2(i32, i32) #0 {
 
 ; CHECK-LABEL: func3:
 ; CHECK-NEXT: .Lfunc_begin2:
-; CHECK: .section .stack_sizes,"",@progbits
+; CHECK: .section .stack_sizes,"o",@progbits,.text,unique,0
 ; CHECK-NEXT: .quad .Lfunc_begin2
 ; CHECK-NEXT: .ascii  "\250\001"
 define void @func3() #0 {
diff --git a/test/CodeGen/X86/stack-size-section-function-sections.ll b/test/CodeGen/X86/stack-size-section-function-sections.ll
new file mode 100644 (file)
index 0000000..c352bfe
--- /dev/null
@@ -0,0 +1,26 @@
+; RUN: llc < %s -mtriple=x86_64-linux -stack-size-section -function-sections | FileCheck %s
+
+; Check we add SHF_LINK_ORDER for .stack_sizes and link it with the corresponding .text sections.
+; CHECK: .section        .text._Z3barv,"ax",@progbits
+; CHECK: .section        .stack_sizes,"o",@progbits,.text._Z3barv,unique,0
+; CHECK: .section        .text._Z3foov,"ax",@progbits
+; CHECK: .section        .stack_sizes,"o",@progbits,.text._Z3foov,unique,1
+
+; Check we add .stack_size section to a COMDAT group with the corresponding .text section if such a COMDAT exists.
+; CHECK: .section        .text._Z4fooTIiET_v,"axG",@progbits,_Z4fooTIiET_v,comdat
+; CHECK: .section        .stack_sizes,"Go",@progbits,_Z4fooTIiET_v,comdat,.text._Z4fooTIiET_v,unique,2
+
+$_Z4fooTIiET_v = comdat any
+
+define dso_local i32 @_Z3barv() {
+  ret i32 0
+}
+
+define dso_local i32 @_Z3foov() {
+  %1 = call i32 @_Z4fooTIiET_v()
+  ret i32 %1
+}
+
+define linkonce_odr dso_local i32 @_Z4fooTIiET_v() comdat {
+  ret i32 0
+}
index 80fa2cc..7e7ba5b 100644 (file)
@@ -2,7 +2,7 @@
 
 ; CHECK-LABEL: func1:
 ; CHECK-NEXT: .Lfunc_begin0:
-; CHECK: .section .stack_sizes,"",@progbits
+; CHECK: .section .stack_sizes,"o",@progbits
 ; CHECK-NEXT: .quad .Lfunc_begin0
 ; CHECK-NEXT: .byte 8
 define void @func1(i32, i32) #0 {
@@ -13,7 +13,7 @@ define void @func1(i32, i32) #0 {
 
 ; CHECK-LABEL: func2:
 ; CHECK-NEXT: .Lfunc_begin1:
-; CHECK: .section .stack_sizes,"",@progbits
+; CHECK: .section .stack_sizes,"o",@progbits
 ; CHECK-NEXT: .quad .Lfunc_begin1
 ; CHECK-NEXT: .byte 24
 define void @func2() #0 {
@@ -22,6 +22,23 @@ define void @func2() #0 {
   ret void
 }
 
+; Check that we still put .stack_sizes into the corresponding COMDAT group if any.
+; CHECK: .section .text._Z4fooTIiET_v,"axG",@progbits,_Z4fooTIiET_v,comdat
+; CHECK: .section .stack_sizes,"Go",@progbits,_Z4fooTIiET_v,comdat,.text._Z4fooTIiET_v,unique,1
+$_Z4fooTIiET_v = comdat any
+define linkonce_odr dso_local i32 @_Z4fooTIiET_v() comdat {
+  ret i32 0
+}
+
+; Check that we assign a unique ID to .stack_sizes if it is linked with a unique .text section.
+; CHECK: .section .text.func3,"ax",@progbits
+; CHECK: .section .stack_sizes,"o",@progbits,.text.func3,unique,2
+define dso_local i32 @func3() section ".text.func3" {
+  %1 = alloca i32, align 4
+  store i32 0, i32* %1, align 4
+  ret i32 0
+}
+
 ; CHECK-LABEL: dynalloc:
 ; CHECK-NOT: .section .stack_sizes
 define void @dynalloc(i32 %N) #0 {