summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lld/ELF/Config.h1
-rw-r--r--lld/ELF/Driver.cpp1
-rw-r--r--lld/ELF/Options.td3
-rw-r--r--lld/ELF/SymbolTable.cpp9
-rw-r--r--lld/test/ELF/lto/Inputs/save-temps.ll6
-rw-r--r--lld/test/ELF/lto/save-temps.ll17
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
OpenPOWER on IntegriCloud