[lld] d12b99a - [lld][COFF][LTO] Implement /lldemit:asm option (#67079)

via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 3 16:25:00 PDT 2023


Author: Matheus Izvekov
Date: 2023-10-04T01:24:54+02:00
New Revision: d12b99a4313816cf99e97cb5f579e2d51ba72b0b

URL: https://github.com/llvm/llvm-project/commit/d12b99a4313816cf99e97cb5f579e2d51ba72b0b
DIFF: https://github.com/llvm/llvm-project/commit/d12b99a4313816cf99e97cb5f579e2d51ba72b0b.diff

LOG: [lld][COFF][LTO] Implement /lldemit:asm option (#67079)

With this new option, assembly code will be emited instead of object
code.
This is analogous to the `--lto-emit-asm` option in the ELF linker.

Added: 
    lld/test/COFF/lto-emit-asm.ll

Modified: 
    lld/COFF/Config.h
    lld/COFF/Driver.cpp
    lld/COFF/LTO.cpp
    lld/test/COFF/pdb-thinlto.ll

Removed: 
    


################################################################################
diff  --git a/lld/COFF/Config.h b/lld/COFF/Config.h
index e66ab3a32c56721..562af7e0d23c19f 100644
--- a/lld/COFF/Config.h
+++ b/lld/COFF/Config.h
@@ -48,7 +48,7 @@ enum class ExportSource {
   ModuleDefinition,
 };
 
-enum class EmitKind { Obj, LLVM };
+enum class EmitKind { Obj, LLVM, ASM };
 
 // Represents an /export option.
 struct Export {

diff  --git a/lld/COFF/Driver.cpp b/lld/COFF/Driver.cpp
index 75ac6d965eba626..554db5969ea13dd 100644
--- a/lld/COFF/Driver.cpp
+++ b/lld/COFF/Driver.cpp
@@ -1859,6 +1859,8 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
       config->emit = EmitKind::Obj;
     else if (s == "llvm")
       config->emit = EmitKind::LLVM;
+    else if (s == "asm")
+      config->emit = EmitKind::ASM;
     else
       error("/lldemit: unknown option: " + s);
   }

diff  --git a/lld/COFF/LTO.cpp b/lld/COFF/LTO.cpp
index 6e835d055479c82..09d722849c38270 100644
--- a/lld/COFF/LTO.cpp
+++ b/lld/COFF/LTO.cpp
@@ -94,6 +94,9 @@ lto::Config BitcodeCompiler::createConfig() {
         WriteBitcodeToFile(m, *os, false);
       return false;
     };
+  } else if (ctx.config.emit == EmitKind::ASM) {
+    c.CGFileType = CodeGenFileType::AssemblyFile;
+    c.Options.MCOptions.AsmVerbose = true;
   }
 
   if (ctx.config.saveTemps)
@@ -213,6 +216,8 @@ std::vector<InputFile *> BitcodeCompiler::compile() {
     pruneCache(ctx.config.ltoCache, ctx.config.ltoCachePolicy, files);
 
   std::vector<InputFile *> ret;
+  bool emitASM = ctx.config.emit == EmitKind::ASM;
+  const char *Ext = emitASM ? ".s" : ".obj";
   for (unsigned i = 0; i != maxTasks; ++i) {
     StringRef bitcodeFilePath;
     // Get the native object contents either from the cache or from memory.  Do
@@ -235,20 +240,21 @@ std::vector<InputFile *> BitcodeCompiler::compile() {
     if (bitcodeFilePath == "ld-temp.o") {
       ltoObjName =
           saver().save(Twine(ctx.config.outputFile) + ".lto" +
-                       (i == 0 ? Twine("") : Twine('.') + Twine(i)) + ".obj");
+                       (i == 0 ? Twine("") : Twine('.') + Twine(i)) + Ext);
     } else {
       StringRef directory = sys::path::parent_path(bitcodeFilePath);
-      StringRef baseName = sys::path::filename(bitcodeFilePath);
+      StringRef baseName = sys::path::stem(bitcodeFilePath);
       StringRef outputFileBaseName = sys::path::filename(ctx.config.outputFile);
       SmallString<64> path;
       sys::path::append(path, directory,
-                        outputFileBaseName + ".lto." + baseName);
+                        outputFileBaseName + ".lto." + baseName + Ext);
       sys::path::remove_dots(path, true);
       ltoObjName = saver().save(path.str());
     }
-    if (ctx.config.saveTemps)
+    if (ctx.config.saveTemps || emitASM)
       saveBuffer(buf[i].second, ltoObjName);
-    ret.push_back(make<ObjFile>(ctx, MemoryBufferRef(objBuf, ltoObjName)));
+    if (!emitASM)
+      ret.push_back(make<ObjFile>(ctx, MemoryBufferRef(objBuf, ltoObjName)));
   }
 
   return ret;

diff  --git a/lld/test/COFF/lto-emit-asm.ll b/lld/test/COFF/lto-emit-asm.ll
new file mode 100644
index 000000000000000..bb32a7d8a72709f
--- /dev/null
+++ b/lld/test/COFF/lto-emit-asm.ll
@@ -0,0 +1,28 @@
+; REQUIRES: x86
+; RUN: llvm-as %s -o %t.obj
+
+; RUN: lld-link /lldemit:asm /dll /noentry /include:f1 /include:f2 %t.obj /opt:lldltopartitions=1 /out:%t.1p /lldsavetemps
+; RUN: cat %t.1p.lto.s | FileCheck %s
+; RUN: llvm-dis %t.1p.0.4.opt.bc -o - | FileCheck --check-prefix=OPT %s
+
+; RUN: lld-link /lldemit:asm /dll /noentry /include:f1 /include:f2 %t.obj /opt:lldltopartitions=2 /out:%t.2p
+; RUN: cat %t.2p.lto.s %t.2p.lto.1.s | FileCheck %s
+
+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"
+
+;; Note: we also check for the presence of comments; /lldemit:asm output should be verbose.
+
+; CHECK-DAG: # -- Begin function f1
+; CHECK-DAG: f1:
+; OPT: define void @f1()
+define void @f1() {
+  ret void
+}
+
+; CHECK-DAG: # -- Begin function f2
+; CHECK-DAG: f2:
+; OPT: define void @f2()
+define void @f2() {
+  ret void
+}

diff  --git a/lld/test/COFF/pdb-thinlto.ll b/lld/test/COFF/pdb-thinlto.ll
index 6ea0f28e1ef1e77..10559e2191650e4 100644
--- a/lld/test/COFF/pdb-thinlto.ll
+++ b/lld/test/COFF/pdb-thinlto.ll
@@ -29,8 +29,8 @@ declare void @foo()
 
 ; CHECK:                           Modules
 ; CHECK: ============================================================
-; CHECK: Mod 0000 | `{{.*}}main.exe.lto.main.bc`:
-; CHECK: Obj: `{{.*}}main.exe.lto.main.bc`:
-; CHECK: Mod 0001 | `{{.*}}main.exe.lto.foo.bc`:
-; CHECK: Obj: `{{.*}}main.exe.lto.foo.bc`:
+; CHECK: Mod 0000 | `{{.*}}main.exe.lto.main.obj`:
+; CHECK: Obj: `{{.*}}main.exe.lto.main.obj`:
+; CHECK: Mod 0001 | `{{.*}}main.exe.lto.foo.obj`:
+; CHECK: Obj: `{{.*}}main.exe.lto.foo.obj`:
 ; CHECK: Mod 0002 | `* Linker *`:


        


More information about the llvm-commits mailing list