Change -save-temps to emit unoptimized bitcode files.
It is often convenient to use -save-temps to collect the intermediate
results of a compilation, e.g., when triaging a bug report. Besides the
temporary files for preprocessed source and assembly code, this adds the
unoptimized bitcode files as well.
This adds a new BackendJobAction, which is mostly mechanical, to run after
the CompileJobAction. When not using -save-temps, the BackendJobAction is
combined into one job with the CompileJobAction, similar to the way the
integrated assembler is handled. I've implemented this entirely as a
driver change, so under the hood, it is just using -disable-llvm-optzns
to get the unoptimized bitcode.
Based in part on a patch by Steven Wu.
rdar://problem/18909437
llvm-svn: 224503
diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp
index 99d8443..c093ffc 100644
--- a/clang/lib/Driver/Driver.cpp
+++ b/clang/lib/Driver/Driver.cpp
@@ -165,7 +165,7 @@
(PhaseArg = DAL.getLastArg(options::OPT__SLASH_P))) {
FinalPhase = phases::Preprocess;
- // -{fsyntax-only,-analyze,emit-ast,S} only run up to the compiler.
+ // -{fsyntax-only,-analyze,emit-ast} only run up to the compiler.
} else if ((PhaseArg = DAL.getLastArg(options::OPT_fsyntax_only)) ||
(PhaseArg = DAL.getLastArg(options::OPT_module_file_info)) ||
(PhaseArg = DAL.getLastArg(options::OPT_verify_pch)) ||
@@ -174,10 +174,13 @@
(PhaseArg = DAL.getLastArg(options::OPT__migrate)) ||
(PhaseArg = DAL.getLastArg(options::OPT__analyze,
options::OPT__analyze_auto)) ||
- (PhaseArg = DAL.getLastArg(options::OPT_emit_ast)) ||
- (PhaseArg = DAL.getLastArg(options::OPT_S))) {
+ (PhaseArg = DAL.getLastArg(options::OPT_emit_ast))) {
FinalPhase = phases::Compile;
+ // -S only runs up to the backend.
+ } else if ((PhaseArg = DAL.getLastArg(options::OPT_S))) {
+ FinalPhase = phases::Backend;
+
// -c only runs up to the assembler.
} else if ((PhaseArg = DAL.getLastArg(options::OPT_c))) {
FinalPhase = phases::Assemble;
@@ -849,7 +852,9 @@
/// \brief Check whether the given input tree contains any compilation or
/// assembly actions.
static bool ContainsCompileOrAssembleAction(const Action *A) {
- if (isa<CompileJobAction>(A) || isa<AssembleJobAction>(A))
+ if (isa<CompileJobAction>(A) ||
+ isa<BackendJobAction>(A) ||
+ isa<AssembleJobAction>(A))
return true;
for (Action::const_iterator it = A->begin(), ie = A->end(); it != ie; ++it)
@@ -1346,17 +1351,21 @@
if (Args.hasArg(options::OPT_verify_pch))
return llvm::make_unique<VerifyPCHJobAction>(std::move(Input),
types::TY_Nothing);
+ return llvm::make_unique<CompileJobAction>(std::move(Input),
+ types::TY_LLVM_BC);
+ }
+ case phases::Backend: {
if (IsUsingLTO(Args)) {
types::ID Output =
Args.hasArg(options::OPT_S) ? types::TY_LTO_IR : types::TY_LTO_BC;
- return llvm::make_unique<CompileJobAction>(std::move(Input), Output);
+ return llvm::make_unique<BackendJobAction>(std::move(Input), Output);
}
if (Args.hasArg(options::OPT_emit_llvm)) {
types::ID Output =
Args.hasArg(options::OPT_S) ? types::TY_LLVM_IR : types::TY_LLVM_BC;
- return llvm::make_unique<CompileJobAction>(std::move(Input), Output);
+ return llvm::make_unique<BackendJobAction>(std::move(Input), Output);
}
- return llvm::make_unique<CompileJobAction>(std::move(Input),
+ return llvm::make_unique<BackendJobAction>(std::move(Input),
types::TY_PP_Asm);
}
case phases::Assemble:
@@ -1486,7 +1495,7 @@
// See if we should look for a compiler with an integrated assembler. We match
// bottom up, so what we are actually looking for is an assembler job with a
- // compiler input.
+ // compiler or backend input.
if (TC->useIntegratedAs() &&
!C.getArgs().hasArg(options::OPT_save_temps) &&
@@ -1494,12 +1503,14 @@
!C.getArgs().hasArg(options::OPT__SLASH_FA) &&
!C.getArgs().hasArg(options::OPT__SLASH_Fa) &&
isa<AssembleJobAction>(JA) &&
- Inputs->size() == 1 && isa<CompileJobAction>(*Inputs->begin())) {
+ Inputs->size() == 1 && (isa<CompileJobAction>(*Inputs->begin()) ||
+ isa<BackendJobAction>(*Inputs->begin()))) {
const Tool *Compiler =
TC->SelectTool(cast<JobAction>(**Inputs->begin()));
if (!Compiler)
return nullptr;
if (Compiler->hasIntegratedAssembler()) {
+ JA = cast<JobAction>(*Inputs->begin());
Inputs = &(*Inputs)[0]->getInputs();
ToolForJob = Compiler;
}
@@ -1509,6 +1520,12 @@
if (!ToolForJob)
ToolForJob = TC->SelectTool(*JA);
+ // Unless OPT_save_temps is enabled, combine the compile and backend jobs.
+ if (isa<BackendJobAction>(JA) &&
+ Inputs->size() == 1 && isa<CompileJobAction>(*Inputs->begin()) &&
+ !C.getArgs().hasArg(options::OPT_save_temps))
+ Inputs = &(*Inputs)[0]->getInputs();
+
// See if we should use an integrated preprocessor. We do so when we have
// exactly one input, since this is the only use case we care about
// (irrelevant since we don't support combine yet).
@@ -1751,6 +1768,12 @@
Suffixed += "-";
Suffixed.append(BoundArch);
}
+ // When using both -save-temps and -emit-llvm, use a ".tmp.bc" suffix for
+ // the unoptimized bitcode so that it does not get overwritten by the ".bc"
+ // optimized bitcode output.
+ if (!AtTopLevel && C.getArgs().hasArg(options::OPT_emit_llvm) &&
+ JA.getType() == types::TY_LLVM_BC)
+ Suffixed += ".tmp";
Suffixed += '.';
Suffixed += Suffix;
NamedOutput = C.getArgs().MakeArgString(Suffixed.c_str());
@@ -2083,7 +2106,7 @@
// Otherwise make sure this is an action clang understands.
if (!isa<PreprocessJobAction>(JA) && !isa<PrecompileJobAction>(JA) &&
- !isa<CompileJobAction>(JA))
+ !isa<CompileJobAction>(JA) && !isa<BackendJobAction>(JA))
return false;
return true;