Skip to content

Commit 69b196d

Browse files
committed
[COFF] added support for /lldsavetemps
Summary: This adds an option to save temporary files generated during link-time optimization. This can be useful for debugging. Reviewers: ruiu, pcc Reviewed By: ruiu, pcc Subscribers: mehdi_amini Differential Revision: https://reviews.llvm.org/D29518 llvm-svn: 294498
1 parent d93d775 commit 69b196d

File tree

5 files changed

+54
-3
lines changed

5 files changed

+54
-3
lines changed

lld/COFF/Config.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ struct Configuration {
105105
std::map<std::string, int> DLLOrder;
106106
SymbolBody *DelayLoadHelper = nullptr;
107107

108+
bool SaveTemps = false;
109+
108110
// Used for SafeSEH.
109111
Symbol *SEHTable = nullptr;
110112
Symbol *SEHCount = nullptr;

lld/COFF/Driver.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -622,6 +622,10 @@ void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
622622
}
623623
}
624624

625+
// Handle /lldsavetemps
626+
if (Args.hasArg(OPT_lldsavetemps))
627+
Config->SaveTemps = true;
628+
625629
// Handle /failifmismatch
626630
for (auto *Arg : Args.filtered(OPT_failifmismatch))
627631
checkFailIfMismatch(Arg->getValue());

lld/COFF/LTO.cpp

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,24 @@ static void checkError(Error E) {
5454
});
5555
}
5656

57+
static void saveBuffer(StringRef Buffer, const Twine &Path) {
58+
std::error_code EC;
59+
raw_fd_ostream OS(Path.str(), EC, sys::fs::OpenFlags::F_None);
60+
if (EC)
61+
error("cannot create " + Path + ": " + EC.message());
62+
OS << Buffer;
63+
}
64+
5765
static std::unique_ptr<lto::LTO> createLTO() {
5866
lto::Config Conf;
5967
Conf.Options = InitTargetOptionsFromCodeGenFlags();
6068
Conf.RelocModel = Reloc::PIC_;
6169
Conf.DisableVerify = true;
6270
Conf.DiagHandler = diagnosticHandler;
6371
Conf.OptLevel = Config->LTOOptLevel;
72+
if (Config->SaveTemps)
73+
checkError(Conf.addSaveTemps(std::string(Config->OutputFile) + ".",
74+
/*UseInputModulePath*/ true));
6475
lto::ThinBackend Backend;
6576
if (Config->LTOJobs != -1u)
6677
Backend = lto::createInProcessThinBackend(Config->LTOJobs);
@@ -116,8 +127,16 @@ std::vector<StringRef> BitcodeCompiler::compile() {
116127
}));
117128

118129
std::vector<StringRef> Ret;
119-
for (unsigned I = 0; I != MaxTasks; ++I)
120-
if (!Buff[I].empty())
121-
Ret.emplace_back(Buff[I].data(), Buff[I].size());
130+
for (unsigned I = 0; I != MaxTasks; ++I) {
131+
if (Buff[I].empty())
132+
continue;
133+
if (Config->SaveTemps) {
134+
if (I == 0)
135+
saveBuffer(Buff[I], Config->OutputFile + ".lto.obj");
136+
else
137+
saveBuffer(Buff[I], Config->OutputFile + Twine(I) + ".lto.obj");
138+
}
139+
Ret.emplace_back(Buff[I].data(), Buff[I].size());
140+
}
122141
return Ret;
123142
}

lld/COFF/Options.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ def heap : P<"heap", "Size of the heap">;
2828
def implib : P<"implib", "Import library name">;
2929
def libpath : P<"libpath", "Additional library search path">;
3030
def linkrepro : P<"linkrepro", "Dump linker invocation and input files for debugging">;
31+
def lldsavetemps : F<"lldsavetemps">,
32+
HelpText<"Save temporary files instead of deleting them">;
3133
def machine : P<"machine", "Specify target platform">;
3234
def merge : P<"merge", "Combine sections">;
3335
def mllvm : P<"mllvm", "Options to pass to LLVM">;

lld/test/COFF/savetemps.ll

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
; RUN: rm -f %T/savetemps.*
2+
; RUN: llvm-as -o %T/savetemps.obj %s
3+
; RUN: lld-link /out:%T/savetemps.exe /entry:main /subsystem:console %T/savetemps.obj
4+
; RUN: not llvm-dis -o - %T/savetemps.exe.0.0.preopt.bc
5+
; RUN: not llvm-dis -o - %T/savetemps.exe.0.2.internalize.bc
6+
; RUN: not llvm-dis -o - %T/savetemps.exe.0.4.opt.bc
7+
; RUN: not llvm-dis -o - %T/savetemps.exe.0.5.precodegen.bc
8+
; RUN: not llvm-objdump -s %T/savetemps.exe.lto.obj
9+
; RUN: lld-link /lldsavetemps /out:%T/savetemps.exe /entry:main /subsystem:console %T/savetemps.obj
10+
; RUN: llvm-dis -o - %T/savetemps.exe.0.0.preopt.bc | FileCheck %s
11+
; RUN: llvm-dis -o - %T/savetemps.exe.0.2.internalize.bc | FileCheck %s
12+
; RUN: llvm-dis -o - %T/savetemps.exe.0.4.opt.bc | FileCheck %s
13+
; RUN: llvm-dis -o - %T/savetemps.exe.0.5.precodegen.bc | FileCheck %s
14+
; RUN: llvm-objdump -s %T/savetemps.exe.lto.obj | FileCheck --check-prefix=CHECK-OBJDUMP %s
15+
16+
; CHECK: define i32 @main()
17+
; CHECK-OBJDUMP: file format COFF
18+
19+
target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
20+
target triple = "x86_64-pc-windows-msvc"
21+
22+
define i32 @main() {
23+
ret i32 0
24+
}

0 commit comments

Comments
 (0)