[lld] r318547 - All .xdata sections are eligble for ICF
Reid Kleckner via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 17 11:50:10 PST 2017
Author: rnk
Date: Fri Nov 17 11:50:10 2017
New Revision: 318547
URL: http://llvm.org/viewvc/llvm-project?rev=318547&view=rev
Log:
All .xdata sections are eligble for ICF
Summary:
Many small functions have identical unwind info because they push the
same sets of CSRs in the same order and have the same stack and prologue
size. The VC linker merges duplicate .xdata, and so should LLD.
This reduces the .xdata section size of clang.exe from 1.8MB to 94KB.
Reviewers: pcc, ruiu
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D40160
Added:
lld/trunk/test/COFF/icf-xdata.s
Modified:
lld/trunk/COFF/ICF.cpp
Modified: lld/trunk/COFF/ICF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/ICF.cpp?rev=318547&r1=318546&r2=318547&view=diff
==============================================================================
--- lld/trunk/COFF/ICF.cpp (original)
+++ lld/trunk/COFF/ICF.cpp Fri Nov 17 11:50:10 2017
@@ -73,12 +73,23 @@ uint32_t ICF::getHash(SectionChunk *C) {
// 2017) says that /opt:icf folds both functions and read-only data.
// Despite that, the MSVC linker folds only functions. We found
// a few instances of programs that are not safe for data merging.
-// Therefore, we merge only functions just like the MSVC tool.
+// Therefore, we merge only functions just like the MSVC tool. However, we merge
+// identical .xdata sections, because the address of unwind information is
+// insignificant to the user program and the Visual C++ linker does this.
bool ICF::isEligible(SectionChunk *C) {
+ // Non-comdat chunks, dead chunks, and writable chunks are not elegible.
+ bool Writable = C->getPermissions() & llvm::COFF::IMAGE_SCN_MEM_WRITE;
+ if (!C->isCOMDAT() || !C->isLive() || Writable)
+ return false;
+
+ // Code sections with external symbols are eligible.
bool Global = C->Sym && C->Sym->isExternal();
bool Executable = C->getPermissions() & llvm::COFF::IMAGE_SCN_MEM_EXECUTE;
- bool Writable = C->getPermissions() & llvm::COFF::IMAGE_SCN_MEM_WRITE;
- return C->isCOMDAT() && C->isLive() && Global && Executable && !Writable;
+ if (Global && Executable)
+ return true;
+
+ // .xdata unwind info sections are eligble.
+ return C->getSectionName().split('$').first == ".xdata";
}
// Split an equivalence class into smaller classes.
Added: lld/trunk/test/COFF/icf-xdata.s
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/icf-xdata.s?rev=318547&view=auto
==============================================================================
--- lld/trunk/test/COFF/icf-xdata.s (added)
+++ lld/trunk/test/COFF/icf-xdata.s Fri Nov 17 11:50:10 2017
@@ -0,0 +1,86 @@
+# RUN: llvm-mc %s -triple x86_64-windows-msvc -filetype=obj -o %t.obj
+# RUN: lld-link %t.obj -dll -noentry -out:%t.dll
+# RUN: llvm-readobj -sections %t.dll | FileCheck %s
+
+# There shouldn't be much xdata, because all three .pdata entries (12 bytes
+# each) should use the same .xdata unwind info.
+# CHECK: Name: .pdata
+# CHECK-NEXT: VirtualSize: 0x24
+# CHECK: Name: .xdata
+# CHECK-NEXT: VirtualSize: 0x8
+
+ .text
+callee:
+ ret
+
+ .def xdata1;
+ .scl 2;
+ .type 32;
+ .endef
+ .section .text,"xr",one_only,xdata1
+ .globl xdata1 # -- Begin function xdata1
+ .p2align 4, 0x90
+xdata1: # @xdata1
+.seh_proc xdata1
+# BB#0: # %entry
+ subq $40, %rsp
+ .seh_stackalloc 40
+ .seh_endprologue
+ callq callee
+ nop
+ addq $40, %rsp
+ jmp callee # TAILCALL
+ .seh_handlerdata
+ .section .text,"xr",one_only,xdata1
+ .seh_endproc
+ # -- End function
+ .def xdata2;
+ .scl 2;
+ .type 32;
+ .endef
+ .section .text,"xr",one_only,xdata2
+ .globl xdata2 # -- Begin function xdata2
+ .p2align 4, 0x90
+xdata2: # @xdata2
+.seh_proc xdata2
+# BB#0: # %entry
+ subq $40, %rsp
+ .seh_stackalloc 40
+ .seh_endprologue
+ callq callee
+ callq callee
+ nop
+ addq $40, %rsp
+ jmp callee # TAILCALL
+ .seh_handlerdata
+ .section .text,"xr",one_only,xdata2
+ .seh_endproc
+ # -- End function
+ .def xdata3;
+ .scl 2;
+ .type 32;
+ .endef
+ .section .text,"xr",one_only,xdata3
+ .globl xdata3 # -- Begin function xdata3
+ .p2align 4, 0x90
+xdata3: # @xdata3
+.seh_proc xdata3
+# BB#0: # %entry
+ subq $40, %rsp
+ .seh_stackalloc 40
+ .seh_endprologue
+ callq callee
+ callq callee
+ callq callee
+ nop
+ addq $40, %rsp
+ jmp callee # TAILCALL
+ .seh_handlerdata
+ .section .text,"xr",one_only,xdata3
+ .seh_endproc
+ # -- End function
+ .section .drectve,"yn"
+ .ascii " -export:xdata1"
+ .ascii " -export:xdata2"
+ .ascii " -export:xdata3"
+
More information about the llvm-commits
mailing list