Skip to content

Commit 5cd6e21

Browse files
authored
[LLD][COFF] allow saving intermediate files with /lldsavetemps (#115131)
* Parity with the `-save-temps=` flag in the `ELF` `lld` driver.
1 parent 70d6789 commit 5cd6e21

File tree

6 files changed

+89
-6
lines changed

6 files changed

+89
-6
lines changed

lld/COFF/Config.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ struct Configuration {
166166
Symbol *delayLoadHelper = nullptr;
167167
Symbol *arm64ECIcallHelper = nullptr;
168168

169-
bool saveTemps = false;
169+
llvm::DenseSet<llvm::StringRef> saveTempsArgs;
170170

171171
// /guard:cf
172172
int guardCF = GuardCFLevel::Off;

lld/COFF/Driver.cpp

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1525,6 +1525,10 @@ getVFS(const opt::InputArgList &args) {
15251525
return nullptr;
15261526
}
15271527

1528+
constexpr const char *lldsaveTempsValues[] = {
1529+
"resolution", "preopt", "promote", "internalize", "import",
1530+
"opt", "precodegen", "prelink", "combinedindex"};
1531+
15281532
void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
15291533
ScopedTimer rootTimer(ctx.rootTimer);
15301534
Configuration *config = &ctx.config;
@@ -2012,8 +2016,18 @@ void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
20122016
config->ltoDebugPassManager = ltoDebugPM;
20132017

20142018
// Handle /lldsavetemps
2015-
if (args.hasArg(OPT_lldsavetemps))
2016-
config->saveTemps = true;
2019+
if (args.hasArg(OPT_lldsavetemps)) {
2020+
for (const char *s : lldsaveTempsValues)
2021+
config->saveTempsArgs.insert(s);
2022+
} else {
2023+
for (auto *arg : args.filtered(OPT_lldsavetemps_colon)) {
2024+
StringRef s = arg->getValue();
2025+
if (llvm::is_contained(lldsaveTempsValues, s))
2026+
config->saveTempsArgs.insert(s);
2027+
else
2028+
error("unknown /lldsavetemps value: " + s);
2029+
}
2030+
}
20172031

20182032
// Handle /lldemit
20192033
if (auto *arg = args.getLastArg(OPT_lldemit)) {

lld/COFF/LTO.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -102,9 +102,10 @@ lto::Config BitcodeCompiler::createConfig() {
102102
c.Options.MCOptions.AsmVerbose = true;
103103
}
104104

105-
if (ctx.config.saveTemps)
105+
if (!ctx.config.saveTempsArgs.empty())
106106
checkError(c.addSaveTemps(std::string(ctx.config.outputFile) + ".",
107-
/*UseInputModulePath*/ true));
107+
/*UseInputModulePath*/ true,
108+
ctx.config.saveTempsArgs));
108109
return c;
109110
}
110111

@@ -255,7 +256,7 @@ std::vector<InputFile *> BitcodeCompiler::compile() {
255256
sys::path::remove_dots(path, true);
256257
ltoObjName = saver().save(path.str());
257258
}
258-
if (ctx.config.saveTemps || emitASM)
259+
if (llvm::is_contained(ctx.config.saveTempsArgs, "prelink") || emitASM)
259260
saveBuffer(buf[i].second, ltoObjName);
260261
if (!emitASM)
261262
ret.push_back(make<ObjFile>(ctx, MemoryBufferRef(objBuf, ltoObjName)));

lld/COFF/Options.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,9 @@ def lldltocachepolicy : P<"lldltocachepolicy",
7979
"Pruning policy for the ThinLTO cache">;
8080
def lldsavetemps : F<"lldsavetemps">,
8181
HelpText<"Save intermediate LTO compilation results">;
82+
def lldsavetemps_colon : Joined<["/", "-", "/?", "-?"], "lldsavetemps:">,
83+
HelpText<"Save select intermediate LTO compilation results">,
84+
Values<"resolution,preopt,promote,internalize,import,opt,precodegen,prelink,combinedindex">;
8285
def lto_sample_profile: P<"lto-sample-profile", "Sample profile file path">;
8386
def machine : P<"machine", "Specify target platform">;
8487
def merge : P<"merge", "Combine sections">;

lld/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ Breaking changes
4242
COFF Improvements
4343
-----------------
4444
* ``/includeglob`` has been implemented to match the behavior of ``--undefined-glob`` available for ELF.
45+
* ``/lldsavetemps`` allows saving select intermediate LTO compilation results (e.g. resolution, preopt, promote, internalize, import, opt, precodegen, prelink, combinedindex).
4546

4647
MinGW Improvements
4748
------------------

lld/test/COFF/savetemps-colon.ll

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
; REQUIRES: x86
2+
; RUN: rm -fr %T/savetemps-colon
3+
; RUN: mkdir %T/savetemps-colon
4+
; RUN: opt -thinlto-bc -o %T/savetemps-colon/savetemps.obj %s
5+
; RUN: opt -thinlto-bc -o %T/savetemps-colon/thin1.obj %S/Inputs/thinlto.ll
6+
7+
;; Check preopt
8+
; RUN: lld-link /lldsavetemps:preopt /out:%T/savetemps-colon/savetemps.exe /entry:main \
9+
; RUN: /subsystem:console %T/savetemps-colon/savetemps.obj %T/savetemps-colon/thin1.obj
10+
; RUN: ls %T/savetemps-colon/*.obj.*.preopt.bc | count 2
11+
12+
;; Check promote
13+
; RUN: lld-link /lldsavetemps:promote /out:%T/savetemps-colon/savetemps.exe /entry:main \
14+
; RUN: /subsystem:console %T/savetemps-colon/savetemps.obj %T/savetemps-colon/thin1.obj
15+
; RUN: ls %T/savetemps-colon/*.obj.*.promote.bc | count 2
16+
17+
;; Check internalize
18+
; RUN: lld-link /lldsavetemps:internalize /out:%T/savetemps-colon/savetemps.exe /entry:main \
19+
; RUN: /subsystem:console %T/savetemps-colon/savetemps.obj %T/savetemps-colon/thin1.obj
20+
; RUN: ls %T/savetemps-colon/*.obj.*.internalize.bc | count 2
21+
22+
;; Check import
23+
; RUN: lld-link /lldsavetemps:import /out:%T/savetemps-colon/savetemps.exe /entry:main \
24+
; RUN: /subsystem:console %T/savetemps-colon/savetemps.obj %T/savetemps-colon/thin1.obj
25+
; RUN: ls %T/savetemps-colon/*.obj.*.import.bc | count 2
26+
27+
;; Check opt
28+
;; Not supported on Windows due to difficulty with escaping "opt" across platforms.
29+
30+
;; Check precodegen
31+
; RUN: lld-link /lldsavetemps:precodegen /out:%T/savetemps-colon/savetemps.exe /entry:main \
32+
; RUN: /subsystem:console %T/savetemps-colon/savetemps.obj %T/savetemps-colon/thin1.obj
33+
; RUN: ls %T/savetemps-colon/*.obj.*.precodegen.bc | count 2
34+
35+
;; Check combinedindex
36+
; RUN: lld-link /lldsavetemps:combinedindex /out:%T/savetemps-colon/savetemps.exe /entry:main \
37+
; RUN: /subsystem:console %T/savetemps-colon/savetemps.obj %T/savetemps-colon/thin1.obj
38+
; RUN: ls %T/savetemps-colon/*.exe.index.bc | count 1
39+
40+
;; Check prelink
41+
; RUN: lld-link /lldsavetemps:prelink /out:%T/savetemps-colon/savetemps.exe /entry:main \
42+
; RUN: /subsystem:console %T/savetemps-colon/savetemps.obj %T/savetemps-colon/thin1.obj
43+
; RUN: ls %T/savetemps-colon/*.exe.lto.*.obj | count 2
44+
45+
;; Check resolution
46+
; RUN: lld-link /lldsavetemps:resolution /out:%T/savetemps-colon/savetemps.exe /entry:main \
47+
; RUN: /subsystem:console %T/savetemps-colon/savetemps.obj %T/savetemps-colon/thin1.obj
48+
; RUN: ls %T/savetemps-colon/*.resolution.txt | count 1
49+
50+
;; Check error message
51+
; RUN: not lld-link /lldsavetemps:notastage /out:%T/savetemps-colon/savetemps.exe /entry:main \
52+
; RUN: /subsystem:console %T/savetemps-colon/savetemps.obj %T/savetemps-colon/thin1.obj 2>&1 \
53+
; RUN: | FileCheck %s
54+
; CHECK: unknown /lldsavetemps value: notastage
55+
56+
target datalayout = "e-m:w-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128"
57+
target triple = "x86_64-pc-windows-msvc"
58+
59+
declare void @g()
60+
61+
define i32 @main() {
62+
call void @g()
63+
ret i32 0
64+
}

0 commit comments

Comments
 (0)