[PATCH] D42375: Add --print-icf flag
Rafael Avila de Espindola via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 31 15:00:00 PST 2018
LGTM
Owen Reynolds via Phabricator <reviews at reviews.llvm.org> writes:
> gbreynoo updated this revision to Diff 132140.
> gbreynoo added a comment.
>
> Change following Rui's comments, missed in last diff
>
>
> https://reviews.llvm.org/D42375
>
> Files:
> ELF/Config.h
> ELF/Driver.cpp
> ELF/ICF.cpp
> ELF/Options.td
> test/ELF/Inputs/print-icf.s
> test/ELF/icf-absolute.s
> test/ELF/icf-comdat.s
> test/ELF/icf-i386.s
> test/ELF/icf-merge-sec.s
> test/ELF/icf-merge.s
> test/ELF/icf-non-mergeable.s
> test/ELF/icf-none.s
> test/ELF/icf1.s
> test/ELF/icf2.s
> test/ELF/icf3.s
> test/ELF/icf4.s
> test/ELF/icf5.s
> test/ELF/icf6.s
> test/ELF/icf7.s
> test/ELF/icf9.s
> test/ELF/print-icf.s
>
> Index: test/ELF/print-icf.s
> ===================================================================
> --- test/ELF/print-icf.s
> +++ test/ELF/print-icf.s
> @@ -0,0 +1,48 @@
> +# REQUIRES: x86
> +
> +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
> +# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/inputs/print-icf.s -o %t1
> +# RUN: ld.lld %t %t1 -o %t2 --icf=all --print-icf-sections | FileCheck %s
> +# RUN: ld.lld %t %t1 -o %t2 --icf=all --no-print-icf-sections --print-icf-sections | FileCheck %s
> +# RUN: ld.lld %t %t1 -o %t2 --icf=all --print-icf-sections --no-print-icf-sections | FileCheck -allow-empty -check-prefix=PRINT %s
> +
> +# CHECK: selected section '.text.f2' from file [[T:'.*']]
> +# CHECK: removing identical section '.text.f4' from file [[T]]
> +# CHECK: removing identical section '.text.f7' from file [[T1:'.*']]
> +# CHECK: selected section '.text.f1' from file [[T]]
> +# CHECK: removing identical section '.text.f3' from file [[T]]
> +# CHECK: removing identical section '.text.f5' from file [[T]]
> +# CHECK: removing identical section '.text.f6' from file [[T1]]
> +
> +# PRINT-NOT: selected
> +# PRINT-NOT: removing
> +
> +.globl _start, f1, f2
> +_start:
> + ret
> +
> +.section .text.f1, "ax"
> +f1:
> + mov $60, %rax
> + mov $42, %rdi
> + syscall
> +
> + .section .text.f2, "ax"
> +f2:
> + mov $0, %rax
> +
> +.section .text.f3, "ax"
> +f3:
> + mov $60, %rax
> + mov $42, %rdi
> + syscall
> +
> +.section .text.f4, "ax"
> +f4:
> + mov $0, %rax
> +
> +.section .text.f5, "ax"
> +f5:
> + mov $60, %rax
> + mov $42, %rdi
> + syscall
> Index: test/ELF/icf9.s
> ===================================================================
> --- test/ELF/icf9.s
> +++ test/ELF/icf9.s
> @@ -7,15 +7,15 @@
>
> # SEC: .rodata PROGBITS 0000000000200120 000120 000002 00 A 0 0 1
>
> -# CHECK-NOT: selected .rodata.d1
> -# CHECK-NOT: selected .rodata.d2
> +# CHECK-NOT: selected section '.rodata.d1'
> +# CHECK-NOT: selected section '.rodata.d2'
>
> # We do merge rodata if passed --icf-data
> # RUN: ld.lld %t -o %t2 --icf=all --verbose --ignore-data-address-equality 2>&1 | FileCheck --check-prefix=DATA %s
> # RUN: llvm-readelf -S -W %t2 | FileCheck --check-prefix=DATA-SEC %s
>
> -# DATA: selected .rodata.d1
> -# DATA: removed .rodata.d2
> +# DATA: selected section '.rodata.d1' from file [[T:'.*']]
> +# DATA: removing identical section '.rodata.d2' from file [[T]]
>
> # DATA-SEC: .rodata PROGBITS 0000000000200120 000120 000001 00 A 0 0 1
>
> Index: test/ELF/icf7.s
> ===================================================================
> --- test/ELF/icf7.s
> +++ test/ELF/icf7.s
> @@ -4,8 +4,8 @@
> # RUN: ld.lld %t -o %t2 --icf=all --verbose 2>&1 | FileCheck %s
> # RUN: llvm-objdump -t %t2 | FileCheck -check-prefix=ALIGN %s
>
> -# CHECK: selected .text.f1
> -# CHECK: removed .text.f2
> +# CHECK: selected section '.text.f1' from file [[T:'.*']]
> +# CHECK: removing identical section '.text.f2' from file [[T]]
>
> # ALIGN: 0000000000201000 .text 00000000 _start
> # ALIGN: 0000000000201100 .text 00000000 f1
> Index: test/ELF/icf6.s
> ===================================================================
> --- test/ELF/icf6.s
> +++ test/ELF/icf6.s
> @@ -3,8 +3,8 @@
> # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
> # RUN: ld.lld %t -o %t2 --icf=all --verbose 2>&1 | FileCheck %s
>
> -# CHECK-NOT: Selected .text.f1
> -# CHECK-NOT: Selected .text.f2
> +# CHECK-NOT: selected section '.text.f1'
> +# CHECK-NOT: selected section '.text.f2'
>
> .globl _start, f1, f2
> _start:
> Index: test/ELF/icf5.s
> ===================================================================
> --- test/ELF/icf5.s
> +++ test/ELF/icf5.s
> @@ -3,8 +3,8 @@
> # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
> # RUN: ld.lld %t -o %t2 --icf=all --verbose 2>&1 | FileCheck %s
>
> -# CHECK-NOT: Selected .text.f1
> -# CHECK-NOT: Selected .text.f2
> +# CHECK-NOT: selected section '.text.f1'
> +# CHECK-NOT: selected section '.text.f2'
>
> .globl _start, f1, f2
> _start:
> Index: test/ELF/icf4.s
> ===================================================================
> --- test/ELF/icf4.s
> +++ test/ELF/icf4.s
> @@ -3,8 +3,8 @@
> # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
> # RUN: ld.lld %t -o %t2 --icf=all --verbose 2>&1 | FileCheck %s
>
> -# CHECK-NOT: Selected .text.f1
> -# CHECK-NOT: Selected .text.f2
> +# CHECK-NOT: selected section '.text.f1'
> +# CHECK-NOT: selected section '.text.f2'
>
> .globl _start, f1, f2
> _start:
> Index: test/ELF/icf3.s
> ===================================================================
> --- test/ELF/icf3.s
> +++ test/ELF/icf3.s
> @@ -4,8 +4,8 @@
> # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/icf2.s -o %t2
> # RUN: ld.lld %t1 %t2 -o %t --icf=all --verbose 2>&1 | FileCheck %s
>
> -# CHECK-NOT: Selected .text.f1
> -# CHECK-NOT: Selected .text.f2
> +# CHECK-NOT: selected section '.text.f1' from file
> +# CHECK-NOT: selected section '.text.f2' from file
>
> .globl _start, f1, f2
> _start:
> Index: test/ELF/icf2.s
> ===================================================================
> --- test/ELF/icf2.s
> +++ test/ELF/icf2.s
> @@ -4,8 +4,8 @@
> # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/icf2.s -o %t2
> # RUN: ld.lld %t1 %t2 -o %t --icf=all --verbose 2>&1 | FileCheck %s
>
> -# CHECK: selected .text.f1
> -# CHECK: removed .text.f2
> +# CHECK: selected section '.text.f1' from file
> +# CHECK: removing identical section '.text.f2' from file
>
> .globl _start, f1, f2
> _start:
> Index: test/ELF/icf1.s
> ===================================================================
> --- test/ELF/icf1.s
> +++ test/ELF/icf1.s
> @@ -3,8 +3,8 @@
> # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
> # RUN: ld.lld %t -o %t2 --icf=all --verbose 2>&1 | FileCheck %s
>
> -# CHECK: selected .text.f1
> -# CHECK: removed .text.f2
> +# CHECK: selected section '.text.f1' from file [[T:'.*']]
> +# CHECK: removing identical section '.text.f2' from file [[T]]
>
> .globl _start, f1, f2
> _start:
> Index: test/ELF/icf-none.s
> ===================================================================
> --- test/ELF/icf-none.s
> +++ test/ELF/icf-none.s
> @@ -3,7 +3,7 @@
> # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
> # RUN: ld.lld %t -o %t2 --icf=all --icf=none --verbose 2>&1 | FileCheck %s
>
> -# CHECK-NOT: selected .text.f1
> +# CHECK-NOT: selected section '.text.f1'
>
> .globl _start, f1, f2
> _start:
> Index: test/ELF/icf-non-mergeable.s
> ===================================================================
> --- test/ELF/icf-non-mergeable.s
> +++ test/ELF/icf-non-mergeable.s
> @@ -10,8 +10,8 @@
>
> // RUN: ld.lld %t1 %t2 -o %t3 --icf=all --verbose 2>&1 | FileCheck %s
>
> -// CHECK-NOT: selected .text.f1
> -// CHECK-NOT: removed .text.f2
> +// CHECK-NOT: selected section '.text.f1'
> +// CHECK-NOT: removing identical section '.text.f2'
>
> .globl _start, f1, f2, d1, d2
> _start:
> Index: test/ELF/icf-merge.s
> ===================================================================
> --- test/ELF/icf-merge.s
> +++ test/ELF/icf-merge.s
> @@ -10,10 +10,10 @@
> # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/icf-merge3.s -o %t3
> # RUN: ld.lld %t %t3 -o %t3.out --icf=all --verbose 2>&1 | FileCheck --check-prefix=NOMERGE %s
>
> -# CHECK: selected .text.f1
> -# CHECK: removed .text.f2
> +# CHECK: selected section '.text.f1' from file
> +# CHECK: removing identical section '.text.f2' from file
>
> -# NOMERGE-NOT: selected .text.f
> +# NOMERGE-NOT: selected section '.text.f
>
> .section .rodata.str,"aMS", at progbits,1
> foo:
> Index: test/ELF/icf-merge-sec.s
> ===================================================================
> --- test/ELF/icf-merge-sec.s
> +++ test/ELF/icf-merge-sec.s
> @@ -4,8 +4,8 @@
> # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/icf-merge-sec.s -o %t2
> # RUN: ld.lld %t %t2 -o %t3 --icf=all --verbose 2>&1 | FileCheck %s
>
> -# CHECK: selected .text.f1
> -# CHECK: removed .text.f2
> +# CHECK: selected section '.text.f1' from file
> +# CHECK: removing identical section '.text.f2' from file
>
> .section .rodata.str,"aMS", at progbits,1
> .asciz "foo"
> Index: test/ELF/icf-i386.s
> ===================================================================
> --- test/ELF/icf-i386.s
> +++ test/ELF/icf-i386.s
> @@ -4,9 +4,9 @@
> # RUN: llvm-mc -filetype=obj -triple=i386-unknown-linux %s -o %t
> # RUN: ld.lld %t -o %t2 --icf=all --verbose 2>&1 | FileCheck %s
>
> -# CHECK: selected .text.f1
> -# CHECK: removed .text.f2
> -# CHECK-NOT: removed .text.f3
> +# CHECK: selected section '.text.f1' from file [[T:'.*']]
> +# CHECK: removing identical section '.text.f2' from file [[T]]
> +# CHECK-NOT: removing identical section '.text.f3' from file [[T]]
>
> .globl _start, f1, f2, f3
> _start:
> Index: test/ELF/icf-comdat.s
> ===================================================================
> --- test/ELF/icf-comdat.s
> +++ test/ELF/icf-comdat.s
> @@ -3,8 +3,8 @@
> # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t
> # RUN: ld.lld %t -o %t2 --icf=all --verbose 2>&1 | FileCheck %s
>
> -# CHECK: selected .text.f1
> -# CHECK: removed .text.f2
> +# CHECK: selected section '.text.f1' from file [[T:'.*']]
> +# CHECK: removing identical section '.text.f2' from file [[T]]
>
> .globl _start, f1, f2
> _start:
> Index: test/ELF/icf-absolute.s
> ===================================================================
> --- test/ELF/icf-absolute.s
> +++ test/ELF/icf-absolute.s
> @@ -4,8 +4,8 @@
> # RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %S/Inputs/icf-absolute.s -o %t2
> # RUN: ld.lld %t %t2 -o %t3 --icf=all --verbose 2>&1 | FileCheck %s
>
> -# CHECK: selected .text.f1
> -# CHECK: removed .text.f2
> +# CHECK: selected section '.text.f1' from file
> +# CHECK: removing identical section '.text.f2' from file
>
> .globl _start, f1, f2
> _start:
> Index: test/ELF/Inputs/print-icf.s
> ===================================================================
> --- test/ELF/Inputs/print-icf.s
> +++ test/ELF/Inputs/print-icf.s
> @@ -0,0 +1,9 @@
> +.section .text.f6, "ax"
> +f6:
> + mov $60, %rax
> + mov $42, %rdi
> + syscall
> +
> + .section .text.f7, "ax"
> +f7:
> + mov $0, %rax
> Index: ELF/Options.td
> ===================================================================
> --- ELF/Options.td
> +++ ELF/Options.td
> @@ -222,6 +222,9 @@
> def no_print_gc_sections: F<"no-print-gc-sections">,
> HelpText<"Do not list removed unused sections">;
>
> +def no_print_icf_sections: F<"no-print-icf-sections">,
> + HelpText<"Do not list identical folded sections">;
> +
> def no_rosegment: F<"no-rosegment">,
> HelpText<"Do not put read-only non-executable sections in their own segment">;
>
> @@ -251,6 +254,9 @@
> def print_gc_sections: F<"print-gc-sections">,
> HelpText<"List removed unused sections">;
>
> +def print_icf_sections: F<"print-icf-sections">,
> + HelpText<"List identical folded sections">;
> +
> def print_map: F<"print-map">,
> HelpText<"Print a link map to the standard output">;
>
> Index: ELF/ICF.cpp
> ===================================================================
> --- ELF/ICF.cpp
> +++ ELF/ICF.cpp
> @@ -424,14 +424,28 @@
>
> log("ICF needed " + Twine(Cnt) + " iterations");
>
> + auto Print = [&](const Twine &Prefix, size_t I) {
> + if (!Config->Verbose && !Config->PrintIcfSections)
> + return;
> + std::string Filename =
> + Sections[I]->File ? Sections[I]->File->getName() : "<internal>";
> + std::string S = (Prefix + " section '" + Sections[I]->Name +
> + "' from file '" + Filename + "'")
> + .str();
> + if (Config->PrintIcfSections)
> + message(S);
> + else
> + log(S);
> + };
> +
> // Merge sections by the equivalence class.
> forEachClass([&](size_t Begin, size_t End) {
> if (End - Begin == 1)
> return;
>
> - log("selected " + Sections[Begin]->Name);
> + Print("selected", Begin);
> for (size_t I = Begin + 1; I < End; ++I) {
> - log(" removed " + Sections[I]->Name);
> + Print(" removing identical", I);
> Sections[Begin]->replace(Sections[I]);
> }
> });
> Index: ELF/Driver.cpp
> ===================================================================
> --- ELF/Driver.cpp
> +++ ELF/Driver.cpp
> @@ -643,6 +643,8 @@
> Config->OrphanHandling = getOrphanHandling(Args);
> Config->OutputFile = Args.getLastArgValue(OPT_o);
> Config->Pie = Args.hasFlag(OPT_pie, OPT_nopie, false);
> + Config->PrintIcfSections =
> + Args.hasFlag(OPT_print_icf_sections, OPT_no_print_icf_sections, false);
> Config->PrintGcSections =
> Args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false);
> Config->Rpath = getRpath(Args);
> Index: ELF/Config.h
> ===================================================================
> --- ELF/Config.h
> +++ ELF/Config.h
> @@ -139,6 +139,7 @@
> bool OptRemarksWithHotness;
> bool Pie;
> bool PrintGcSections;
> + bool PrintIcfSections;
> bool Relocatable;
> bool SaveTemps;
> bool SingleRoRx;
More information about the llvm-commits
mailing list