Skip to content

Commit 3923e61

Browse files
authored
[lld][COFF][LTO] Implement /lldemit:llvm option (#66964)
With this new option, bitcode will be emited instead of object code. This is analogous to the `--plugin-opt=emit-llvm` option in the ELF linker.
1 parent 93e0127 commit 3923e61

File tree

5 files changed

+40
-1
lines changed

5 files changed

+40
-1
lines changed

lld/COFF/Config.h

+3
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,8 @@ enum class ExportSource {
4848
ModuleDefinition,
4949
};
5050

51+
enum class EmitKind { Obj, LLVM };
52+
5153
// Represents an /export option.
5254
struct Export {
5355
StringRef name; // N in /export:N or /export:E=N
@@ -311,6 +313,7 @@ struct Configuration {
311313
bool pseudoRelocs = false;
312314
bool stdcallFixup = false;
313315
bool writeCheckSum = false;
316+
EmitKind emit = EmitKind::Obj;
314317
};
315318

316319
} // namespace lld::coff

lld/COFF/Driver.cpp

+13-1
Original file line numberDiff line numberDiff line change
@@ -1852,6 +1852,17 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
18521852
if (args.hasArg(OPT_lldsavetemps))
18531853
config->saveTemps = true;
18541854

1855+
// Handle /lldemit
1856+
if (auto *arg = args.getLastArg(OPT_lldemit)) {
1857+
StringRef s = arg->getValue();
1858+
if (s == "obj")
1859+
config->emit = EmitKind::Obj;
1860+
else if (s == "llvm")
1861+
config->emit = EmitKind::LLVM;
1862+
else
1863+
error("/lldemit: unknown option: " + s);
1864+
}
1865+
18551866
// Handle /kill-at
18561867
if (args.hasArg(OPT_kill_at))
18571868
config->killAt = true;
@@ -2395,7 +2406,8 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
23952406
// If -thinlto-index-only is given, we should create only "index
23962407
// files" and not object files. Index file creation is already done
23972408
// in addCombinedLTOObject, so we are done if that's the case.
2398-
if (config->thinLTOIndexOnly)
2409+
// Likewise, don't emit object files for other /lldemit options.
2410+
if (config->emit != EmitKind::Obj || config->thinLTOIndexOnly)
23992411
return;
24002412

24012413
// If we generated native object files from bitcode files, this resolves

lld/COFF/LTO.cpp

+9
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,15 @@ lto::Config BitcodeCompiler::createConfig() {
8787
c.RunCSIRInstr = ctx.config.ltoCSProfileGenerate;
8888
c.PGOWarnMismatch = ctx.config.ltoPGOWarnMismatch;
8989

90+
if (ctx.config.emit == EmitKind::LLVM) {
91+
c.PostInternalizeModuleHook = [this](size_t task, const Module &m) {
92+
if (std::unique_ptr<raw_fd_ostream> os =
93+
openLTOOutputFile(ctx.config.outputFile))
94+
WriteBitcodeToFile(m, *os, false);
95+
return false;
96+
};
97+
}
98+
9099
if (ctx.config.saveTemps)
91100
checkError(c.addSaveTemps(std::string(ctx.config.outputFile) + ".",
92101
/*UseInputModulePath*/ true));

lld/COFF/Options.td

+1
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ defm demangle : B<"demangle",
232232
def include_optional : Joined<["/", "-", "/?", "-?"], "includeoptional:">,
233233
HelpText<"Add symbol as undefined, but allow it to remain undefined">;
234234
def kill_at : F<"kill-at">;
235+
def lldemit : P<"lldemit", "Specify output type">;
235236
def lldmingw : F<"lldmingw">;
236237
def noseh : F<"noseh">;
237238
def osversion : P_priv<"osversion">;

lld/test/COFF/lto-emit-llvm.ll

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
; REQUIRES: x86
2+
; RUN: llvm-as -o %T/lto.obj %s
3+
4+
; RUN: lld-link /lldemit:llvm /out:%T/lto.bc /entry:main /subsystem:console %T/lto.obj
5+
; RUN: llvm-dis %T/lto.bc -o - | FileCheck %s
6+
7+
; CHECK: define void @main()
8+
9+
target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
10+
target triple = "x86_64-pc-windows-msvc"
11+
12+
define void @main() {
13+
ret void
14+
}

0 commit comments

Comments
 (0)