summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/COFF/Config.h1
-rw-r--r--lld/COFF/Driver.cpp6
-rw-r--r--lld/COFF/InputFiles.cpp4
-rw-r--r--lld/test/COFF/string-tail-merge.s18
4 files changed, 27 insertions, 2 deletions
diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h
index f7086a71706..d457f59bac5 100644
--- a/lld/COFF/Config.h
+++ b/lld/COFF/Config.h
@@ -92,6 +92,7 @@ struct Configuration {
std::string ImportName;
bool DoGC = true;
bool DoICF = true;
+ bool TailMerge;
bool Relocatable = true;
bool Force = false;
bool Debug = false;
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index 62c0b49ac01..8076efe51bf 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -1049,6 +1049,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
bool DoGC = !Args.hasArg(OPT_debug) || Args.hasArg(OPT_profile);
unsigned ICFLevel =
Args.hasArg(OPT_profile) ? 0 : 1; // 0: off, 1: limited, 2: on
+ unsigned TailMerge = 1;
for (auto *Arg : Args.filtered(OPT_opt)) {
std::string Str = StringRef(Arg->getValue()).lower();
SmallVector<StringRef, 1> Vec;
@@ -1062,6 +1063,10 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
ICFLevel = 2;
} else if (S == "noicf") {
ICFLevel = 0;
+ } else if (S == "lldtailmerge") {
+ TailMerge = 2;
+ } else if (S == "nolldtailmerge") {
+ TailMerge = 0;
} else if (S.startswith("lldlto=")) {
StringRef OptLevel = S.substr(7);
if (OptLevel.getAsInteger(10, Config->LTOOptLevel) ||
@@ -1090,6 +1095,7 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
ICFLevel = 0;
Config->DoGC = DoGC;
Config->DoICF = ICFLevel > 0;
+ Config->TailMerge = (TailMerge == 1 && Config->DoICF) || TailMerge == 2;
// Handle /lldsavetemps
if (Args.hasArg(OPT_lldsavetemps))
diff --git a/lld/COFF/InputFiles.cpp b/lld/COFF/InputFiles.cpp
index 8f18910617b..9e2345b0a51 100644
--- a/lld/COFF/InputFiles.cpp
+++ b/lld/COFF/InputFiles.cpp
@@ -190,8 +190,8 @@ SectionChunk *ObjFile::readSection(uint32_t SectionNumber,
GuardLJmpChunks.push_back(C);
else if (Name == ".sxdata")
SXDataChunks.push_back(C);
- else if (Config->DoICF && Sec->NumberOfRelocations == 0 && Name == ".rdata" &&
- LeaderName.startswith("??_C@"))
+ else if (Config->TailMerge && Sec->NumberOfRelocations == 0 &&
+ Name == ".rdata" && LeaderName.startswith("??_C@"))
// COFF sections that look like string literal sections (i.e. no
// relocations, in .rdata, leader symbol name matches the MSVC name mangling
// for string literals) are subject to string tail merging.
diff --git a/lld/test/COFF/string-tail-merge.s b/lld/test/COFF/string-tail-merge.s
index b4c02c62fa1..2e3b735dbf9 100644
--- a/lld/test/COFF/string-tail-merge.s
+++ b/lld/test/COFF/string-tail-merge.s
@@ -2,20 +2,31 @@
# RUN: llvm-mc -triple=x86_64-windows-msvc -filetype=obj -o %t.obj %s
# RUN: lld-link %t.obj /out:%t.exe /entry:main /subsystem:console
# RUN: llvm-objdump -s %t.exe | FileCheck %s
+# RUN: lld-link %t.obj /out:%t.exe /entry:main /subsystem:console /opt:noicf /opt:lldtailmerge
+# RUN: llvm-objdump -s %t.exe | FileCheck %s
+# RUN: lld-link %t.obj /out:%t.exe /entry:main /subsystem:console /opt:noicf
+# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=NOSTM %s
+# RUN: lld-link %t.obj /out:%t.exe /entry:main /subsystem:console /opt:nolldtailmerge
+# RUN: llvm-objdump -s %t.exe | FileCheck --check-prefix=NOSTM %s
# CHECK: Contents of section .text:
+# NOSTM: Contents of section .text:
.globl main
main:
# CHECK-NEXT: 140001000 11200040 01000000 17200040 01000000
+# NOSTM-NEXT: 140001000 00200040 01000000 0c200040 01000000
.8byte "??_C@_0M@LACCCNMM@hello?5world?$AA@"
.8byte "??_C@_05MCBCHHEJ@world?$AA@"
# CHECK-NEXT: 140001010 2a200040 01000000 36200040 01000000
+# NOSTM-NEXT: 140001010 12200040 01000000 2a200040 01000000
.8byte "??_C@_1BI@HHJHKLLN@?$AAh?$AAe?$AAl?$AAl?$AAo?$AA?5?$AAw?$AAo?$AAr?$AAl?$AAd?$AA?$AA@"
.8byte "??_C@_1M@NBBDDHIO@?$AAw?$AAo?$AAr?$AAl?$AAd?$AA?$AA@"
# CHECK-NEXT: 140001020 00200040 01000000 0c200040 01000000
+# NOSTM-NEXT: 140001020 36200040 01000000 42200040 01000000
.8byte "??_D@not_a_string_literal"
.8byte "??_C@string_literal_with_relocs"
# CHECK-NEXT: 140001030 00300040 01000000 1e200040 01000000
+# NOSTM-NEXT: 140001030 00300040 01000000 48200040 01000000
.8byte "??_C@string_literal_in_wrong_section"
.8byte "??_C@overaligned_string_literal"
@@ -26,6 +37,13 @@ main:
# CHECK-NEXT: 140002030 6c006f00 20007700 6f007200 6c006400 l.o. .w.o.r.l.d.
# CHECK-NEXT: 140002040 0000 ..
+# NOSTM: Contents of section .rdata:
+# NOSTM-NEXT: 140002000 68656c6c 6f20776f 726c6400 776f726c hello world.worl
+# NOSTM-NEXT: 140002010 64006800 65006c00 6c006f00 20007700 d.h.e.l.l.o. .w.
+# NOSTM-NEXT: 140002020 6f007200 6c006400 00007700 6f007200 o.r.l.d...w.o.r.
+# NOSTM-NEXT: 140002030 6c006400 00006865 6c6c6f20 776f726c l.d...hello worl
+# NOSTM-NEXT: 140002040 64006f82 6ca40000 68656c6c 6f20776f d.o.l...hello wo
+# NOSTM-NEXT: 140002050 726c6400 rld.
.section .rdata,"dr",discard,"??_C@_0M@LACCCNMM@hello?5world?$AA@"
.globl "??_C@_0M@LACCCNMM@hello?5world?$AA@"
OpenPOWER on IntegriCloud