Index: llvm/trunk/include/llvm/MC/MCObjectFileInfo.h =================================================================== --- llvm/trunk/include/llvm/MC/MCObjectFileInfo.h +++ llvm/trunk/include/llvm/MC/MCObjectFileInfo.h @@ -14,12 +14,14 @@ #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 @@ /// Section containing metadata on function stack sizes. MCSection *StackSizesSection; + mutable DenseMap StackSizesUniquing; // ELF specific sections. MCSection *DataRelROSection; @@ -299,7 +302,7 @@ 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: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp =================================================================== --- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp +++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp @@ -989,7 +989,8 @@ if (!MF.getTarget().Options.EmitStackSizeSection) return; - MCSection *StackSizeSection = getObjFileLowering().getStackSizesSection(); + MCSection *StackSizeSection = + getObjFileLowering().getStackSizesSection(*getCurrentSection()); if (!StackSizeSection) return; Index: llvm/trunk/lib/MC/MCObjectFileInfo.cpp =================================================================== --- llvm/trunk/lib/MC/MCObjectFileInfo.cpp +++ llvm/trunk/lib/MC/MCObjectFileInfo.cpp @@ -948,3 +948,24 @@ 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(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(Link)); +} Index: llvm/trunk/test/CodeGen/ARM/stack-size-section.ll =================================================================== --- llvm/trunk/test/CodeGen/ARM/stack-size-section.ll +++ llvm/trunk/test/CodeGen/ARM/stack-size-section.ll @@ -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 @@ ; 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: llvm/trunk/test/CodeGen/SystemZ/stack-size-section.ll =================================================================== --- llvm/trunk/test/CodeGen/SystemZ/stack-size-section.ll +++ llvm/trunk/test/CodeGen/SystemZ/stack-size-section.ll @@ -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 @@ ; 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 @@ ; 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 { Index: llvm/trunk/test/CodeGen/X86/stack-size-section-function-sections.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/stack-size-section-function-sections.ll +++ llvm/trunk/test/CodeGen/X86/stack-size-section-function-sections.ll @@ -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: llvm/trunk/test/CodeGen/X86/stack-size-section.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/stack-size-section.ll +++ llvm/trunk/test/CodeGen/X86/stack-size-section.ll @@ -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 @@ ; 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 @@ 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 {