diff options
| -rw-r--r-- | lld/ELF/Config.h | 1 | ||||
| -rw-r--r-- | lld/ELF/Driver.cpp | 1 | ||||
| -rw-r--r-- | lld/ELF/Options.td | 3 | ||||
| -rw-r--r-- | lld/ELF/SymbolTable.cpp | 9 | ||||
| -rw-r--r-- | lld/test/ELF/lto/Inputs/save-temps.ll | 6 | ||||
| -rw-r--r-- | lld/test/ELF/lto/save-temps.ll | 17 |
6 files changed, 37 insertions, 0 deletions
diff --git a/lld/ELF/Config.h b/lld/ELF/Config.h index 47f21fa68ba..273b756c0a5 100644 --- a/lld/ELF/Config.h +++ b/lld/ELF/Config.h @@ -69,6 +69,7 @@ struct Configuration { bool NoinhibitExec; bool PrintGcSections; bool Relocatable; + bool SaveTemps; bool Shared; bool Static = false; bool StripAll; diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp index c4773d8b02d..720be75c716 100644 --- a/lld/ELF/Driver.cpp +++ b/lld/ELF/Driver.cpp @@ -239,6 +239,7 @@ void LinkerDriver::readConfigs(opt::InputArgList &Args) { Config->NoinhibitExec = Args.hasArg(OPT_noinhibit_exec); Config->PrintGcSections = Args.hasArg(OPT_print_gc_sections); Config->Relocatable = Args.hasArg(OPT_relocatable); + Config->SaveTemps = Args.hasArg(OPT_save_temps); Config->Shared = Args.hasArg(OPT_shared); Config->StripAll = Args.hasArg(OPT_strip_all); Config->Verbose = Args.hasArg(OPT_verbose); diff --git a/lld/ELF/Options.td b/lld/ELF/Options.td index 99a208080a1..24e984119c4 100644 --- a/lld/ELF/Options.td +++ b/lld/ELF/Options.td @@ -182,3 +182,6 @@ def G : Separate<["-"], "G">; // Aliases for ignored options def alias_version_script_version_script : Joined<["--"], "version-script=">, Alias<version_script>; + +// Debugging options +def save_temps : Flag<["-"], "save-temps">; diff --git a/lld/ELF/SymbolTable.cpp b/lld/ELF/SymbolTable.cpp index 8e8d77f117f..0f3f02b870d 100644 --- a/lld/ELF/SymbolTable.cpp +++ b/lld/ELF/SymbolTable.cpp @@ -147,6 +147,13 @@ static void addBitcodeFile(IRMover &Mover, BitcodeFile &F, Mover.move(std::move(M), Keep, [](GlobalValue &, IRMover::ValueAdder) {}); } +static void saveBCFile(std::string Path, Module &M) { + std::error_code EC; + raw_fd_ostream OS(Path, EC, sys::fs::OpenFlags::F_None); + check(EC); + WriteBitcodeToFile(&M, OS, /* ShouldPreserveUseListOrder */ true); +} + // Merge all the bitcode files we have seen, codegen the result and return // the resulting ObjectFile. template <class ELFT> @@ -156,6 +163,8 @@ ObjectFile<ELFT> *SymbolTable<ELFT>::createCombinedLtoObject() { IRMover Mover(Combined); for (const std::unique_ptr<BitcodeFile> &F : BitcodeFiles) addBitcodeFile(Mover, *F, Context); + if (Config->SaveTemps) + saveBCFile(Config->OutputFile.str() + ".lto.bc", Combined); std::unique_ptr<InputFile> F = codegen(Combined); ObjectFiles.emplace_back(cast<ObjectFile<ELFT>>(F.release())); return &*ObjectFiles.back(); diff --git a/lld/test/ELF/lto/Inputs/save-temps.ll b/lld/test/ELF/lto/Inputs/save-temps.ll new file mode 100644 index 00000000000..d6e6eb661f3 --- /dev/null +++ b/lld/test/ELF/lto/Inputs/save-temps.ll @@ -0,0 +1,6 @@ +target triple = "x86_64-unknown-linux-gnu" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define void @bar() { + ret void +} diff --git a/lld/test/ELF/lto/save-temps.ll b/lld/test/ELF/lto/save-temps.ll new file mode 100644 index 00000000000..54ffa0807a1 --- /dev/null +++ b/lld/test/ELF/lto/save-temps.ll @@ -0,0 +1,17 @@ +; REQUIRES: x86 +; RUN: rm -f %t.so %t.so.lto.bc +; RUN: llvm-as %s -o %t.o +; RUN: llvm-as %p/Inputs/save-temps.ll -o %t2.o +; RUN: ld.lld -shared -m elf_x86_64 %t.o %t2.o -o %t.so -save-temps +; RUN: llvm-nm %t.so | FileCheck %s +; RUN: llvm-nm %t.so.lto.bc | FileCheck %s + +target triple = "x86_64-unknown-linux-gnu" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" + +define void @foo() { + ret void +} + +; CHECK-DAG: T bar +; CHECK-DAG: T foo |

