Index: lld/trunk/ELF/Config.h =================================================================== --- lld/trunk/ELF/Config.h +++ lld/trunk/ELF/Config.h @@ -135,6 +135,7 @@ bool Demangle = true; bool DisableVerify; bool EhFrameHdr; + bool EmitLLVM; bool EmitRelocs; bool EnableNewDtags; bool ExecuteOnly; Index: lld/trunk/ELF/Driver.cpp =================================================================== --- lld/trunk/ELF/Driver.cpp +++ lld/trunk/ELF/Driver.cpp @@ -776,6 +776,7 @@ Config->DynamicLinker = getDynamicLinker(Args); Config->EhFrameHdr = Args.hasFlag(OPT_eh_frame_hdr, OPT_no_eh_frame_hdr, false); + Config->EmitLLVM = Args.hasArg(OPT_plugin_opt_emit_llvm, false); Config->EmitRelocs = Args.hasArg(OPT_emit_relocs); Config->CallGraphProfileSort = Args.hasFlag( OPT_call_graph_profile_sort, OPT_no_call_graph_profile_sort, true); @@ -1581,6 +1582,12 @@ if (Config->ThinLTOIndexOnly) return; + // Likewise, --plugin-opt=emit-llvm is an option to make LTO create + // an output file in bitcode and exit, so that you can just get a + // combined bitcode file. + if (Config->EmitLLVM) + return; + // Apply symbol renames for -wrap. if (!Wrapped.empty()) wrapSymbols(Wrapped); Index: lld/trunk/ELF/LTO.cpp =================================================================== --- lld/trunk/ELF/LTO.cpp +++ lld/trunk/ELF/LTO.cpp @@ -103,6 +103,14 @@ C.DebugPassManager = Config->LTODebugPassManager; C.DwoDir = Config->DwoDir; + if (Config->EmitLLVM) { + C.PostInternalizeModuleHook = [](size_t Task, const Module &M) { + if (std::unique_ptr OS = openFile(Config->OutputFile)) + WriteBitcodeToFile(M, *OS, false); + return false; + }; + } + if (Config->SaveTemps) checkError(C.addSaveTemps(Config->OutputFile.str() + ".", /*UseInputModulePath*/ true)); Index: lld/trunk/ELF/Options.td =================================================================== --- lld/trunk/ELF/Options.td +++ lld/trunk/ELF/Options.td @@ -458,6 +458,7 @@ def: F<"plugin-opt=disable-verify">, Alias, HelpText<"Alias for -disable-verify">; def plugin_opt_dwo_dir_eq: J<"plugin-opt=dwo_dir=">, HelpText<"Directory to store .dwo files when LTO and debug fission are used">; +def plugin_opt_emit_llvm: F<"plugin-opt=emit-llvm">; def: J<"plugin-opt=jobs=">, Alias, HelpText<"Alias for -thinlto-jobs">; def: J<"plugin-opt=lto-partitions=">, Alias, HelpText<"Alias for -lto-partitions">; def plugin_opt_mcpu_eq: J<"plugin-opt=mcpu=">; Index: lld/trunk/test/ELF/lto/emit-llvm.ll =================================================================== --- lld/trunk/test/ELF/lto/emit-llvm.ll +++ lld/trunk/test/ELF/lto/emit-llvm.ll @@ -0,0 +1,14 @@ +; REQUIRES: x86 + +; RUN: opt -module-hash -module-summary %s -o %t.o +; RUN: ld.lld --plugin-opt=emit-llvm -o %t.out.o %t.o +; RUN: llvm-dis < %t.out.o -o - | FileCheck %s + +; CHECK: define internal void @main() + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +define void @main() { + ret void +}