[lld] r318071 - Disable GC and ICF when /debug is present
Reid Kleckner via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 13 10:38:25 PST 2017
Author: rnk
Date: Mon Nov 13 10:38:25 2017
New Revision: 318071
URL: http://llvm.org/viewvc/llvm-project?rev=318071&view=rev
Log:
Disable GC and ICF when /debug is present
ICF and GC impair debugging, so MSVC disables these optimizations when
/debug is passed. They are still on by default when no PDB is produced.
This change also makes /opt:ref enable ICF, which is consistent with
MSVC: https://msdn.microsoft.com/en-us/library/bxwfs976.aspx
We should consider making /opt:icf fold readonly data in the near
future. LLD used to do this, but we disabled it because it breaks too
many programs. MSVC only does this if the user explicitly passes
/opt:icf.
Reviewers: ruiu, pcc
Subscribers: llvm-commits
Differential Revision: https://reviews.llvm.org/D39885
Modified:
lld/trunk/COFF/Driver.cpp
lld/trunk/test/COFF/icf-associative.test
lld/trunk/test/COFF/icf-simple.test
lld/trunk/test/COFF/pdb-global-gc.yaml
lld/trunk/test/COFF/pdb-import-gc.yaml
Modified: lld/trunk/COFF/Driver.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/COFF/Driver.cpp?rev=318071&r1=318070&r2=318071&view=diff
==============================================================================
--- lld/trunk/COFF/Driver.cpp (original)
+++ lld/trunk/COFF/Driver.cpp Mon Nov 13 10:38:25 2017
@@ -896,50 +896,51 @@ void LinkerDriver::link(ArrayRef<const c
if (auto *Arg = Args.getLastArg(OPT_implib))
Config->Implib = Arg->getValue();
- // Handle /opt
+ // Handle /opt.
+ bool DoGC = !Args.hasArg(OPT_debug);
+ unsigned ICFLevel = 1; // 0: off, 1: limited, 2: on
for (auto *Arg : Args.filtered(OPT_opt)) {
std::string Str = StringRef(Arg->getValue()).lower();
SmallVector<StringRef, 1> Vec;
StringRef(Str).split(Vec, ',');
for (StringRef S : Vec) {
- if (S == "noref") {
- Config->DoGC = false;
- Config->DoICF = false;
- continue;
- }
- if (S == "icf" || S.startswith("icf=")) {
- Config->DoICF = true;
- continue;
- }
- if (S == "noicf") {
- Config->DoICF = false;
- continue;
- }
- if (S.startswith("lldlto=")) {
+ if (S == "ref") {
+ DoGC = true;
+ } else if (S == "noref") {
+ DoGC = false;
+ } else if (S == "icf" || S.startswith("icf=")) {
+ ICFLevel = 2;
+ } else if (S == "noicf") {
+ ICFLevel = 0;
+ } else if (S.startswith("lldlto=")) {
StringRef OptLevel = S.substr(7);
if (OptLevel.getAsInteger(10, Config->LTOOptLevel) ||
Config->LTOOptLevel > 3)
error("/opt:lldlto: invalid optimization level: " + OptLevel);
- continue;
- }
- if (S.startswith("lldltojobs=")) {
+ } else if (S.startswith("lldltojobs=")) {
StringRef Jobs = S.substr(11);
if (Jobs.getAsInteger(10, Config->LTOJobs) || Config->LTOJobs == 0)
error("/opt:lldltojobs: invalid job count: " + Jobs);
- continue;
- }
- if (S.startswith("lldltopartitions=")) {
+ } else if (S.startswith("lldltopartitions=")) {
StringRef N = S.substr(17);
if (N.getAsInteger(10, Config->LTOPartitions) ||
Config->LTOPartitions == 0)
error("/opt:lldltopartitions: invalid partition count: " + N);
- continue;
- }
- if (S != "ref" && S != "lbr" && S != "nolbr")
+ } else if (S != "lbr" && S != "nolbr")
error("/opt: unknown option: " + S);
}
}
+ // Limited ICF is enabled if GC is enabled and ICF was never mentioned
+ // explicitly.
+ // FIXME: LLD only implements "limited" ICF, i.e. it only merges identical
+ // code. If the user passes /OPT:ICF explicitly, LLD should merge identical
+ // comdat readonly data.
+ if (ICFLevel == 1 && !DoGC)
+ ICFLevel = 0;
+ Config->DoGC = DoGC;
+ Config->DoICF = ICFLevel > 0;
+
// Handle /lldsavetemps
if (Args.hasArg(OPT_lldsavetemps))
Config->SaveTemps = true;
Modified: lld/trunk/test/COFF/icf-associative.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/icf-associative.test?rev=318071&r1=318070&r2=318071&view=diff
==============================================================================
--- lld/trunk/test/COFF/icf-associative.test (original)
+++ lld/trunk/test/COFF/icf-associative.test Mon Nov 13 10:38:25 2017
@@ -1,5 +1,5 @@
# RUN: yaml2obj < %s > %t.obj
-# RUN: lld-link /entry:foo /out:%t.exe /subsystem:console /include:bar \
+# RUN: lld-link /opt:icf /entry:foo /out:%t.exe /subsystem:console /include:bar \
# RUN: /debug /verbose %t.obj > %t.log 2>&1
# RUN: FileCheck %s < %t.log
Modified: lld/trunk/test/COFF/icf-simple.test
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/icf-simple.test?rev=318071&r1=318070&r2=318071&view=diff
==============================================================================
--- lld/trunk/test/COFF/icf-simple.test (original)
+++ lld/trunk/test/COFF/icf-simple.test Mon Nov 13 10:38:25 2017
@@ -1,5 +1,5 @@
# RUN: yaml2obj < %s > %t.obj
-# RUN: lld-link /entry:foo /out:%t.exe /subsystem:console /include:bar \
+# RUN: lld-link /opt:icf /entry:foo /out:%t.exe /subsystem:console /include:bar \
# RUN: /verbose %t.obj > %t.log 2>&1
# RUN: FileCheck -check-prefix=ICF %s < %t.log
@@ -13,6 +13,31 @@
# RUN: /verbose /opt:noref,noicf %t.obj > %t.log 2>&1
# RUN: FileCheck -check-prefix=NOICF %s < %t.log
+# ICF is on by default (no /opt: flags).
+# RUN: lld-link /entry:foo /out:%t.exe /subsystem:console \
+# RUN: /include:bar /verbose %t.obj > %t.log 2>&1
+# RUN: FileCheck -check-prefix=ICF %s < %t.log
+
+# /debug disables ICF.
+# RUN: lld-link /debug /entry:foo /out:%t.exe /subsystem:console \
+# RUN: /include:bar /verbose %t.obj > %t.log 2>&1
+# RUN: FileCheck -check-prefix=NOICF %s < %t.log
+
+# /opt:noref disables ICF.
+# RUN: lld-link /opt:noref /entry:foo /out:%t.exe /subsystem:console \
+# RUN: /include:bar /verbose %t.obj > %t.log 2>&1
+# RUN: FileCheck -check-prefix=NOICF %s < %t.log
+
+# /debug /opt:ref enables ICF.
+# RUN: lld-link /debug /opt:ref /entry:foo /out:%t.exe /subsystem:console \
+# RUN: /include:bar /verbose %t.obj > %t.log 2>&1
+# RUN: FileCheck -check-prefix=ICF %s < %t.log
+
+# /debug /opt:noicf,ref disables ICF.
+# RUN: lld-link /debug /opt:noicf,ref /entry:foo /out:%t.exe /subsystem:console \
+# RUN: /include:bar /verbose %t.obj > %t.log 2>&1
+# RUN: FileCheck -check-prefix=NOICF %s < %t.log
+
# NOICF-NOT: Removed foo
# NOICF-NOT: Removed bar
Modified: lld/trunk/test/COFF/pdb-global-gc.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/pdb-global-gc.yaml?rev=318071&r1=318070&r2=318071&view=diff
==============================================================================
--- lld/trunk/test/COFF/pdb-global-gc.yaml (original)
+++ lld/trunk/test/COFF/pdb-global-gc.yaml Mon Nov 13 10:38:25 2017
@@ -1,7 +1,7 @@
# RUN: yaml2obj %s -o %t.obj
# RUN: llvm-mc %S/Inputs/pdb-global-gc.s -triple x86_64-windows-msvc -filetype=obj -o %t2.obj
# RUN: lld-link %t.obj %t2.obj -debug -entry:main \
-# RUN: -nodefaultlib -debug -out:%t.exe -pdb:%t.pdb -verbose
+# RUN: -nodefaultlib -opt:ref -out:%t.exe -pdb:%t.pdb -verbose
# RUN: llvm-pdbutil dump -symbols -globals %t.pdb | FileCheck %s
# This tests the case where an __imp_ chunk is discarded by linker GC. The debug
Modified: lld/trunk/test/COFF/pdb-import-gc.yaml
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/test/COFF/pdb-import-gc.yaml?rev=318071&r1=318070&r2=318071&view=diff
==============================================================================
--- lld/trunk/test/COFF/pdb-import-gc.yaml (original)
+++ lld/trunk/test/COFF/pdb-import-gc.yaml Mon Nov 13 10:38:25 2017
@@ -1,6 +1,6 @@
# RUN: yaml2obj %s -o %t.obj
# RUN: lld-link %t.obj %S/Inputs/pdb-import-gc.lib -debug -entry:main \
-# RUN: -nodefaultlib -debug -out:%t.exe -pdb:%t.pdb
+# RUN: -nodefaultlib -opt:ref -out:%t.exe -pdb:%t.pdb
# RUN: llvm-pdbutil dump -globals -symbols %t.pdb | FileCheck %s
# This tests the case where an __imp_ chunk is discarded by linker GC. The debug
More information about the llvm-commits
mailing list