summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJames Henderson <jh7370@my.bristol.ac.uk>2018-02-01 16:00:46 +0000
committerJames Henderson <jh7370@my.bristol.ac.uk>2018-02-01 16:00:46 +0000
commit9c6e2fd5a4d37df0cf82486e0648583650b297f9 (patch)
tree5b9d358ddeb51a37a2668e9ba17aaa05802689d8
parent91af9048b26b02b82b4eee637dabb6c81e275905 (diff)
downloadbcm5719-llvm-9c6e2fd5a4d37df0cf82486e0648583650b297f9.tar.gz
bcm5719-llvm-9c6e2fd5a4d37df0cf82486e0648583650b297f9.zip
[ELF] Add --print-icf-sections flag
Currently ICF information is output through stderr if the "--verbose" flag is used. This differs to Gold for example, which uses an explicit flag to output this to stdout. This commit adds the "--print-icf-sections" and "--no-print-icf-sections" flags and changes the output message format for clarity and consistency with "--print-gc-sections". These messages are still output to stderr if using the verbose flag. However to avoid intermingled message output to console, this will not occur when the "--print-icf-sections" flag is used. Existing tests have been modified to expect the new message format from stderr. Patch by Owen Reynolds. Differential Revision: https://reviews.llvm.org/D42375 Reviewers: ruiu, rafael Reviewed by: llvm-svn: 323976
-rw-r--r--lld/ELF/Config.h1
-rw-r--r--lld/ELF/Driver.cpp2
-rw-r--r--lld/ELF/ICF.cpp18
-rw-r--r--lld/ELF/Options.td6
-rw-r--r--lld/test/ELF/Inputs/print-icf.s9
-rw-r--r--lld/test/ELF/icf-absolute.s4
-rw-r--r--lld/test/ELF/icf-comdat.s4
-rw-r--r--lld/test/ELF/icf-i386.s6
-rw-r--r--lld/test/ELF/icf-merge-sec.s4
-rw-r--r--lld/test/ELF/icf-merge.s6
-rw-r--r--lld/test/ELF/icf-non-mergeable.s4
-rw-r--r--lld/test/ELF/icf-none.s2
-rw-r--r--lld/test/ELF/icf1.s4
-rw-r--r--lld/test/ELF/icf2.s4
-rw-r--r--lld/test/ELF/icf3.s4
-rw-r--r--lld/test/ELF/icf4.s4
-rw-r--r--lld/test/ELF/icf5.s4
-rw-r--r--lld/test/ELF/icf6.s4
-rw-r--r--lld/test/ELF/icf7.s4
-rw-r--r--lld/test/ELF/icf9.s8
-rw-r--r--lld/test/ELF/print-icf.s48
21 files changed, 115 insertions, 35 deletions
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h
index 28326a84cf1..0fa1564f1ac 100644
--- a/lld/ELF/Config.h
+++ b/lld/ELF/Config.h
@@ -140,6 +140,7 @@ struct Configuration {
bool OptRemarksWithHotness;
bool Pie;
bool PrintGcSections;
+ bool PrintIcfSections;
bool Relocatable;
bool SaveTemps;
bool SingleRoRx;
diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index bbf28ade61d..4b7f90253f2 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -643,6 +643,8 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) {
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);
diff --git a/lld/ELF/ICF.cpp b/lld/ELF/ICF.cpp
index bcc901bfa95..a4dab446773 100644
--- a/lld/ELF/ICF.cpp
+++ b/lld/ELF/ICF.cpp
@@ -424,14 +424,28 @@ template <class ELFT> void ICF<ELFT>::run() {
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]);
}
});
diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td
index 86aa99eaf44..d642c5e0988 100644
--- a/lld/ELF/Options.td
+++ b/lld/ELF/Options.td
@@ -222,6 +222,9 @@ def no_omagic: Flag<["--"], "no-omagic">, MetaVarName<"<magic>">,
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 pie: F<"pie">, HelpText<"Create a position independent executable">;
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">;
diff --git a/lld/test/ELF/Inputs/print-icf.s b/lld/test/ELF/Inputs/print-icf.s
new file mode 100644
index 00000000000..a67bee2f185
--- /dev/null
+++ b/lld/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
diff --git a/lld/test/ELF/icf-absolute.s b/lld/test/ELF/icf-absolute.s
index 09f6790907a..42d2ebedd93 100644
--- a/lld/test/ELF/icf-absolute.s
+++ b/lld/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:
diff --git a/lld/test/ELF/icf-comdat.s b/lld/test/ELF/icf-comdat.s
index aab6a00f484..029088c26e0 100644
--- a/lld/test/ELF/icf-comdat.s
+++ b/lld/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:
diff --git a/lld/test/ELF/icf-i386.s b/lld/test/ELF/icf-i386.s
index b01e0503d40..c00739b994a 100644
--- a/lld/test/ELF/icf-i386.s
+++ b/lld/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:
diff --git a/lld/test/ELF/icf-merge-sec.s b/lld/test/ELF/icf-merge-sec.s
index 1e866a0caa4..14114f0ee25 100644
--- a/lld/test/ELF/icf-merge-sec.s
+++ b/lld/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",@progbits,1
.asciz "foo"
diff --git a/lld/test/ELF/icf-merge.s b/lld/test/ELF/icf-merge.s
index 06e852fe9dd..e5cb8be8d07 100644
--- a/lld/test/ELF/icf-merge.s
+++ b/lld/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",@progbits,1
foo:
diff --git a/lld/test/ELF/icf-non-mergeable.s b/lld/test/ELF/icf-non-mergeable.s
index 48ba2008cac..cefe36070c3 100644
--- a/lld/test/ELF/icf-non-mergeable.s
+++ b/lld/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:
diff --git a/lld/test/ELF/icf-none.s b/lld/test/ELF/icf-none.s
index 9ec1406de8a..ed3e2dcea30 100644
--- a/lld/test/ELF/icf-none.s
+++ b/lld/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:
diff --git a/lld/test/ELF/icf1.s b/lld/test/ELF/icf1.s
index e2562b5a83e..fe207031493 100644
--- a/lld/test/ELF/icf1.s
+++ b/lld/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:
diff --git a/lld/test/ELF/icf2.s b/lld/test/ELF/icf2.s
index fd0a311cbd1..9bebfb8f9c6 100644
--- a/lld/test/ELF/icf2.s
+++ b/lld/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:
diff --git a/lld/test/ELF/icf3.s b/lld/test/ELF/icf3.s
index 40067cefb20..d2a7b40d92f 100644
--- a/lld/test/ELF/icf3.s
+++ b/lld/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:
diff --git a/lld/test/ELF/icf4.s b/lld/test/ELF/icf4.s
index b7f40e80573..b44e71e83ca 100644
--- a/lld/test/ELF/icf4.s
+++ b/lld/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:
diff --git a/lld/test/ELF/icf5.s b/lld/test/ELF/icf5.s
index 749cc5e923a..bdc28c1c2c5 100644
--- a/lld/test/ELF/icf5.s
+++ b/lld/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:
diff --git a/lld/test/ELF/icf6.s b/lld/test/ELF/icf6.s
index 6420868523b..97449ca6530 100644
--- a/lld/test/ELF/icf6.s
+++ b/lld/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:
diff --git a/lld/test/ELF/icf7.s b/lld/test/ELF/icf7.s
index 00fca793aee..3e78c99184c 100644
--- a/lld/test/ELF/icf7.s
+++ b/lld/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
diff --git a/lld/test/ELF/icf9.s b/lld/test/ELF/icf9.s
index bfa18914beb..652fb361a3c 100644
--- a/lld/test/ELF/icf9.s
+++ b/lld/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
diff --git a/lld/test/ELF/print-icf.s b/lld/test/ELF/print-icf.s
new file mode 100644
index 00000000000..c1e58aaf5b2
--- /dev/null
+++ b/lld/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
OpenPOWER on IntegriCloud