diff options
-rw-r--r-- | lld/ELF/Config.h | 1 | ||||
-rw-r--r-- | lld/ELF/Driver.cpp | 7 | ||||
-rw-r--r-- | lld/ELF/LTO.cpp | 8 | ||||
-rw-r--r-- | lld/ELF/Options.td | 1 | ||||
-rw-r--r-- | lld/test/ELF/lto/emit-llvm.ll | 14 |
5 files changed, 31 insertions, 0 deletions
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index 37f713f1843..8fb760e592e 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -135,6 +135,7 @@ struct Configuration { bool Demangle = true; bool DisableVerify; bool EhFrameHdr; + bool EmitLLVM; bool EmitRelocs; bool EnableNewDtags; bool ExecuteOnly; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index 37fab4c9642..a8582416732 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -776,6 +776,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) { 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 @@ template <class ELFT> void LinkerDriver::link(opt::InputArgList &Args) { 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<ELFT>(Wrapped); diff --git a/lld/ELF/LTO.cpp b/lld/ELF/LTO.cpp index c3e59b5b71e..ca44581780e 100644 --- a/lld/ELF/LTO.cpp +++ b/lld/ELF/LTO.cpp @@ -103,6 +103,14 @@ static lto::Config createConfig() { C.DebugPassManager = Config->LTODebugPassManager; C.DwoDir = Config->DwoDir; + if (Config->EmitLLVM) { + C.PostInternalizeModuleHook = [](size_t Task, const Module &M) { + if (std::unique_ptr<raw_fd_ostream> OS = openFile(Config->OutputFile)) + WriteBitcodeToFile(M, *OS, false); + return false; + }; + } + if (Config->SaveTemps) checkError(C.addSaveTemps(Config->OutputFile.str() + ".", /*UseInputModulePath*/ true)); diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td index 27cbade418a..e43a21b923d 100644 --- a/lld/ELF/Options.td +++ b/lld/ELF/Options.td @@ -458,6 +458,7 @@ def: F<"plugin-opt=debug-pass-manager">, def: F<"plugin-opt=disable-verify">, Alias<disable_verify>, 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<thinlto_jobs>, HelpText<"Alias for -thinlto-jobs">; def: J<"plugin-opt=lto-partitions=">, Alias<lto_partitions>, HelpText<"Alias for -lto-partitions">; def plugin_opt_mcpu_eq: J<"plugin-opt=mcpu=">; diff --git a/lld/test/ELF/lto/emit-llvm.ll b/lld/test/ELF/lto/emit-llvm.ll new file mode 100644 index 00000000000..bf38c982f02 --- /dev/null +++ b/lld/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 +} |