diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h --- a/lld/COFF/Config.h +++ b/lld/COFF/Config.h @@ -157,6 +157,11 @@ // Used for /opt:lldltocachepolicy=policy llvm::CachePruningPolicy ltoCachePolicy; + // Used for /opt:[no]ltonewpassmanager + bool ltoNewPassManager = false; + // Used for /opt:[no]ltodebugpassmanager + bool ltoDebugPassManager = false; + // Used for /merge:from=to (e.g. /merge:.rdata=.text) std::map merge; diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp --- a/lld/COFF/Driver.cpp +++ b/lld/COFF/Driver.cpp @@ -1513,6 +1513,8 @@ unsigned icfLevel = args.hasArg(OPT_profile) ? 0 : 1; // 0: off, 1: limited, 2: on unsigned tailMerge = 1; + bool ltoNewPM = false; + bool ltoDebugPM = false; for (auto *arg : args.filtered(OPT_opt)) { std::string str = StringRef(arg->getValue()).lower(); SmallVector vec; @@ -1530,6 +1532,14 @@ tailMerge = 2; } else if (s == "nolldtailmerge") { tailMerge = 0; + } else if (s == "ltonewpassmanager") { + ltoNewPM = true; + } else if (s == "noltonewpassmanager") { + ltoNewPM = false; + } else if (s == "ltodebugpassmanager") { + ltoDebugPM = true; + } else if (s == "noltodebugpassmanager") { + ltoDebugPM = false; } else if (s.startswith("lldlto=")) { StringRef optLevel = s.substr(7); if (optLevel.getAsInteger(10, config->ltoo) || config->ltoo > 3) @@ -1559,6 +1569,8 @@ config->doGC = doGC; config->doICF = icfLevel > 0; config->tailMerge = (tailMerge == 1 && config->doICF) || tailMerge == 2; + config->ltoNewPassManager = ltoNewPM; + config->ltoDebugPassManager = ltoDebugPM; // Handle /lldsavetemps if (args.hasArg(OPT_lldsavetemps)) diff --git a/lld/COFF/LTO.cpp b/lld/COFF/LTO.cpp --- a/lld/COFF/LTO.cpp +++ b/lld/COFF/LTO.cpp @@ -82,6 +82,8 @@ c.MAttrs = getMAttrs(); c.CGOptLevel = args::getCGOptLevel(config->ltoo); c.AlwaysEmitRegularLTOObj = !config->ltoObjPath.empty(); + c.UseNewPM = config->ltoNewPassManager; + c.DebugPassManager = config->ltoDebugPassManager; if (config->saveTemps) checkError(c.addSaveTemps(std::string(config->outputFile) + ".", diff --git a/lld/test/COFF/lto-new-pass-manager.ll b/lld/test/COFF/lto-new-pass-manager.ll new file mode 100644 --- /dev/null +++ b/lld/test/COFF/lto-new-pass-manager.ll @@ -0,0 +1,20 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %s.obj + +; RUN: lld-link %s.obj -entry:main -opt:ltonewpassmanager -opt:ltodebugpassmanager 2>&1 | FileCheck %s --check-prefix=ENABLED +; ENABLED: Starting llvm::Module pass manager run. +; ENABLED: Finished llvm::Module pass manager run. + +; Passing -time just to avoid empty FileCheck input +; RUN: lld-link %s.obj -entry:main -time -opt:ltonewpassmanager -opt:ltodebugpassmanager -opt:noltonewpassmanager 2>&1 | FileCheck %s --check-prefix=DISABLED +; RUN: lld-link %s.obj -entry:main -time -opt:ltonewpassmanager -opt:ltodebugpassmanager -opt:noltodebugpassmanager 2>&1 | FileCheck %s --check-prefix=DISABLED +; DISABLED-NOT: Starting llvm::Module pass manager run. +; DISABLED-NOT: Finished llvm::Module pass manager run. + +target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-windows-msvc19.11.0" + +define dso_local i32 @main(i32 %argc, i8** nocapture readnone %0) local_unnamed_addr { +entry: + ret i32 %argc +}