[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