From ab447e436daf038e88a2a75a72b6d4a94a1516b2 Mon Sep 17 00:00:00 2001 From: Rafael Espindola Date: Wed, 11 Mar 2015 19:58:37 +0000 Subject: [PATCH] Put jump tables in unique sections on COFF. If a function is going in an unique section (because of -ffunction-sections for example), putting a jump table in .rodata will keep .rodata alive and that will keep alive any other function that also has a jump table. Instead, put the jump table in a unique section that is associated with the function. llvm-svn: 231961 --- .../CodeGen/TargetLoweringObjectFileImpl.h | 4 +++ .../CodeGen/TargetLoweringObjectFileImpl.cpp | 25 +++++++++++++++++++ llvm/test/CodeGen/X86/global-sections.ll | 6 +++++ 3 files changed, 35 insertions(+) diff --git a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h index 0ca5365faae3..0d7c26cff8aa 100644 --- a/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -147,6 +147,10 @@ public: SectionKind Kind, Mangler &Mang, const TargetMachine &TM) const override; + const MCSection * + getSectionForJumpTable(const Function &F, Mangler &Mang, + const TargetMachine &TM) const override; + /// Extract the dependent library name from a linker option string. Returns /// StringRef() if the option does not specify a library. StringRef getDepLibFromLinkerOpt(StringRef LinkerOption) const override; diff --git a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index e8ef63aa5a99..725b8246a35d 100644 --- a/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -948,6 +948,31 @@ SelectSectionForGlobal(const GlobalValue *GV, SectionKind Kind, return DataSection; } +const MCSection *TargetLoweringObjectFileCOFF::getSectionForJumpTable( + const Function &F, Mangler &Mang, const TargetMachine &TM) const { + // If the function can be removed, produce a unique section so that + // the table doesn't prevent the removal. + const Comdat *C = F.getComdat(); + bool EmitUniqueSection = TM.getFunctionSections() || C; + if (!EmitUniqueSection) + return ReadOnlySection; + + // FIXME: we should produce a symbol for F instead. + if (F.hasPrivateLinkage()) + return ReadOnlySection; + + MCSymbol *Sym = TM.getSymbol(&F, Mang); + StringRef COMDATSymName = Sym->getName(); + + SectionKind Kind = SectionKind::getReadOnly(); + const char *Name = getCOFFSectionNameForUniqueGlobal(Kind); + unsigned Characteristics = getCOFFSectionFlags(Kind); + Characteristics |= COFF::IMAGE_SCN_LNK_COMDAT; + + return getContext().getCOFFSection(Name, Characteristics, Kind, COMDATSymName, + COFF::IMAGE_COMDAT_SELECT_ASSOCIATIVE); +} + StringRef TargetLoweringObjectFileCOFF:: getDepLibFromLinkerOpt(StringRef LinkerOption) const { const char *LibCmd = "/DEFAULTLIB:"; diff --git a/llvm/test/CodeGen/X86/global-sections.ll b/llvm/test/CodeGen/X86/global-sections.ll index cd42f99b7717..dcdc71efdc4e 100644 --- a/llvm/test/CodeGen/X86/global-sections.ll +++ b/llvm/test/CodeGen/X86/global-sections.ll @@ -6,6 +6,7 @@ ; RUN: llc < %s -mtriple=i386-unknown-linux-gnu -function-sections | FileCheck %s -check-prefix=LINUX-FUNC-SECTIONS ; RUN: llc < %s -mtriple=x86_64-pc-linux -data-sections -function-sections -relocation-model=pic | FileCheck %s -check-prefix=LINUX-SECTIONS-PIC ; RUN: llc < %s -mtriple=i686-pc-win32 -data-sections -function-sections | FileCheck %s -check-prefix=WIN32-SECTIONS +; RUN: llc < %s -mtriple=i686-pc-win32 -function-sections | FileCheck %s -check-prefix=WIN32-FUNC-SECTIONS define void @F1() { ret void @@ -48,6 +49,11 @@ bb5: ; LINUX-FUNC-SECTIONS-NEXT: .cfi_endproc ; LINUX-FUNC-SECTIONS-NEXT: .section .rodata.F2,"a",@progbits +; WIN32-FUNC-SECTIONS: .section .text,"xr",one_only,_F2 +; WIN32-FUNC-SECTIONS-NOT: .section +; WIN32-FUNC-SECTIONS: .section .rdata,"dr",associative,_F2 + + ; LINUX-SECTIONS-PIC: .section .text.F2,"ax",@progbits ; LINUX-SECTIONS-PIC: .size F2, ; LINUX-SECTIONS-PIC-NEXT: .cfi_endproc