[lld] [LLD][COFF] allow saving intermediate files with /lldsavetemps (PR #115131)

via llvm-commits llvm-commits at lists.llvm.org
Wed Nov 6 00:11:18 PST 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-platform-windows

Author: Miguel A. Arroyo (mayanez)

<details>
<summary>Changes</summary>

* Parity with the `-save-temps=` flag in the `ELF` `lld` driver.

---
Full diff: https://github.com/llvm/llvm-project/pull/115131.diff


6 Files Affected:

- (modified) lld/COFF/Config.h (+1-1) 
- (modified) lld/COFF/Driver.cpp (+16-2) 
- (modified) lld/COFF/LTO.cpp (+4-3) 
- (modified) lld/COFF/Options.td (+3) 
- (modified) lld/docs/ReleaseNotes.rst (+1) 
- (added) lld/test/COFF/savetemps-eq.ll (+58) 


``````````diff
diff --git a/lld/COFF/Config.h b/lld/COFF/Config.h
index 738776a971ea39..3d416e6985d02c 100644
--- a/lld/COFF/Config.h
+++ b/lld/COFF/Config.h
@@ -166,7 +166,7 @@ struct Configuration {
   Symbol *delayLoadHelper = nullptr;
   Symbol *arm64ECIcallHelper = nullptr;
 
-  bool saveTemps = false;
+  llvm::DenseSet<llvm::StringRef> saveTempsArgs;
 
   // /guard:cf
   int guardCF = GuardCFLevel::Off;
diff --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index d717afac473898..f2f570d8727748 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -1525,6 +1525,10 @@ getVFS(const opt::InputArgList &args) {
   return nullptr;
 }
 
+constexpr const char *lldsaveTempsValues[] = {
+    "resolution", "preopt",     "promote", "internalize",  "import",
+    "opt",        "precodegen", "prelink", "combinedindex"};
+
 void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
   ScopedTimer rootTimer(ctx.rootTimer);
   Configuration *config = &ctx.config;
@@ -2012,8 +2016,18 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
   config->ltoDebugPassManager = ltoDebugPM;
 
   // Handle /lldsavetemps
-  if (args.hasArg(OPT_lldsavetemps))
-    config->saveTemps = true;
+  if (args.hasArg(OPT_lldsavetemps)) {
+    for (const char *s : lldsaveTempsValues)
+      config->saveTempsArgs.insert(s);
+  } else {
+    for (auto *arg : args.filtered(OPT_lldsavetemps_eq)) {
+      StringRef s = arg->getValue();
+      if (llvm::is_contained(lldsaveTempsValues, s))
+        config->saveTempsArgs.insert(s);
+      else
+        error("unknown /lldsavetemps value: " + s);
+    }
+  }
 
   // Handle /lldemit
   if (auto *arg = args.getLastArg(OPT_lldemit)) {
diff --git a/lld/COFF/LTO.cpp b/lld/COFF/LTO.cpp
index da73fe7763ceea..d7e003ce3e2d88 100644
--- a/lld/COFF/LTO.cpp
+++ b/lld/COFF/LTO.cpp
@@ -102,9 +102,10 @@ lto::Config BitcodeCompiler::createConfig() {
     c.Options.MCOptions.AsmVerbose = true;
   }
 
-  if (ctx.config.saveTemps)
+  if (!ctx.config.saveTempsArgs.empty())
     checkError(c.addSaveTemps(std::string(ctx.config.outputFile) + ".",
-                              /*UseInputModulePath*/ true));
+                              /*UseInputModulePath*/ true,
+                              ctx.config.saveTempsArgs));
   return c;
 }
 
@@ -255,7 +256,7 @@ std::vector<InputFile *> BitcodeCompiler::compile() {
       sys::path::remove_dots(path, true);
       ltoObjName = saver().save(path.str());
     }
-    if (ctx.config.saveTemps || emitASM)
+    if (llvm::is_contained(ctx.config.saveTempsArgs, "prelink") || emitASM)
       saveBuffer(buf[i].second, ltoObjName);
     if (!emitASM)
       ret.push_back(make<ObjFile>(ctx, MemoryBufferRef(objBuf, ltoObjName)));
diff --git a/lld/COFF/Options.td b/lld/COFF/Options.td
index 7ceb824c068de3..0bc3d070bae6d4 100644
--- a/lld/COFF/Options.td
+++ b/lld/COFF/Options.td
@@ -79,6 +79,9 @@ def lldltocachepolicy : P<"lldltocachepolicy",
     "Pruning policy for the ThinLTO cache">;
 def lldsavetemps : F<"lldsavetemps">,
     HelpText<"Save intermediate LTO compilation results">;
+def lldsavetemps_eq : Joined<["/", "-", "/?", "-?"], "lldsavetemps:">,
+    HelpText<"Save select intermediate LTO compilation results">,
+    Values<"resolution,preopt,promote,internalize,import,opt,precodegen,prelink,combinedindex">;
 def lto_sample_profile: P<"lto-sample-profile", "Sample profile file path">;
 def machine : P<"machine", "Specify target platform">;
 def merge   : P<"merge", "Combine sections">;
diff --git a/lld/docs/ReleaseNotes.rst b/lld/docs/ReleaseNotes.rst
index da93da9196af70..5dfb31a360e4e8 100644
--- a/lld/docs/ReleaseNotes.rst
+++ b/lld/docs/ReleaseNotes.rst
@@ -42,6 +42,7 @@ Breaking changes
 COFF Improvements
 -----------------
 * ``/includeglob`` has been implemented to match the behavior of ``--undefined-glob`` available for ELF.
+* ``/lldsavetemps`` allows saving select intermediate LTO compilation results (e.g. resolution, preopt, promote, internalize, import, opt, precodegen, prelink, combinedindex).
 
 MinGW Improvements
 ------------------
diff --git a/lld/test/COFF/savetemps-eq.ll b/lld/test/COFF/savetemps-eq.ll
new file mode 100644
index 00000000000000..42a728d69ebe47
--- /dev/null
+++ b/lld/test/COFF/savetemps-eq.ll
@@ -0,0 +1,58 @@
+; REQUIRES: x86
+; RUN: rm -fr %T/savetemps-eq
+; RUN: mkdir %T/savetemps-eq
+; RUN: opt -thinlto-bc -o %T/savetemps-eq/savetemps.obj %s
+; RUN: opt -thinlto-bc -o %T/savetemps-eq/thin1.obj %S/Inputs/thinlto.ll
+
+;; Check preopt
+; RUN: lld-link /lldsavetemps:preopt /out:%T/savetemps-eq/savetemps.exe /entry:main \
+; RUN:     /subsystem:console %T/savetemps-eq/savetemps.obj %T/savetemps-eq/thin1.obj
+; RUN: ls %T/savetemps-eq/*.obj.*.preopt.bc | count 2
+
+;; Check promote
+; RUN: lld-link /lldsavetemps:promote /out:%T/savetemps-eq/savetemps.exe /entry:main \
+; RUN:     /subsystem:console %T/savetemps-eq/savetemps.obj %T/savetemps-eq/thin1.obj
+; RUN: ls %T/savetemps-eq/*.obj.*.promote.bc | count 2
+
+;; Check internalize
+; RUN: lld-link /lldsavetemps:internalize /out:%T/savetemps-eq/savetemps.exe /entry:main \
+; RUN:     /subsystem:console %T/savetemps-eq/savetemps.obj %T/savetemps-eq/thin1.obj
+; RUN: ls %T/savetemps-eq/*.obj.*.internalize.bc | count 2
+
+;; Check import
+; RUN: lld-link /lldsavetemps:import /out:%T/savetemps-eq/savetemps.exe /entry:main \
+; RUN:     /subsystem:console %T/savetemps-eq/savetemps.obj %T/savetemps-eq/thin1.obj
+; RUN: ls %T/savetemps-eq/*.obj.*.import.bc | count 2
+
+;; Check opt
+;; Not supported on Windows due to difficulty with escaping "opt" across platforms.
+
+;; Check precodegen
+; RUN: lld-link /lldsavetemps:precodegen /out:%T/savetemps-eq/savetemps.exe /entry:main \
+; RUN:     /subsystem:console %T/savetemps-eq/savetemps.obj %T/savetemps-eq/thin1.obj
+; RUN: ls %T/savetemps-eq/*.obj.*.precodegen.bc | count 2
+
+;; Check combinedindex
+; RUN: lld-link /lldsavetemps:combinedindex /out:%T/savetemps-eq/savetemps.exe /entry:main \
+; RUN:     /subsystem:console %T/savetemps-eq/savetemps.obj %T/savetemps-eq/thin1.obj
+; RUN: ls %T/savetemps-eq/*.exe.index.bc | count 1
+
+;; Check prelink
+; RUN: lld-link /lldsavetemps:prelink /out:%T/savetemps-eq/savetemps.exe /entry:main \
+; RUN:     /subsystem:console %T/savetemps-eq/savetemps.obj %T/savetemps-eq/thin1.obj
+; RUN: ls %T/savetemps-eq/*.exe.lto.*.obj | count 2
+
+;; Check resolution
+; RUN: lld-link /lldsavetemps:resolution /out:%T/savetemps-eq/savetemps.exe /entry:main \
+; RUN:     /subsystem:console %T/savetemps-eq/savetemps.obj %T/savetemps-eq/thin1.obj
+; RUN: ls %T/savetemps-eq/*.resolution.txt | count 1
+
+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-msvc"
+
+declare void @g()
+
+define i32 @main() {
+  call void @g()
+  ret i32 0
+}

``````````

</details>


https://github.com/llvm/llvm-project/pull/115131


More information about the llvm-commits mailing list