Skip to content

Commit 07e3f30

Browse files
authored
Merge pull request #35034 from CodaFi/turnout-results
[NFC] Add Compilation::Result
2 parents 4f8556d + 905c3d8 commit 07e3f30

File tree

4 files changed

+74
-39
lines changed

4 files changed

+74
-39
lines changed

include/swift/Driver/Compilation.h

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "swift/Basic/OutputFileMap.h"
2525
#include "swift/Basic/Statistic.h"
2626
#include "swift/Driver/Driver.h"
27+
#include "swift/Driver/FineGrainedDependencyDriverGraph.h"
2728
#include "swift/Driver/Job.h"
2829
#include "swift/Driver/Util.h"
2930
#include "llvm/ADT/StringRef.h"
@@ -78,6 +79,29 @@ using CommandSet = llvm::SmallPtrSet<const Job *, 16>;
7879

7980
class Compilation {
8081
public:
82+
struct Result {
83+
/// Set to true if any job exits abnormally (i.e. crashes).
84+
bool hadAbnormalExit;
85+
/// The exit code of this driver process.
86+
int exitCode;
87+
/// The dependency graph built up during the compilation of this module.
88+
///
89+
/// This data is used for cross-module module dependencies.
90+
fine_grained_dependencies::ModuleDepGraph depGraph;
91+
92+
Result(const Result &) = delete;
93+
Result &operator=(const Result &) = delete;
94+
95+
Result(Result &&) = default;
96+
Result &operator=(Result &&) = default;
97+
98+
/// Construct a \c Compilation::Result from just an exit code.
99+
static Result code(int code) {
100+
return Compilation::Result{false, code,
101+
fine_grained_dependencies::ModuleDepGraph()};
102+
}
103+
};
104+
81105
class IncrementalSchemeComparator {
82106
const bool EnableIncrementalBuildWhenConstructed;
83107
const bool &EnableIncrementalBuild;
@@ -490,7 +514,7 @@ class Compilation {
490514
///
491515
/// \returns result code for the Compilation's Jobs; 0 indicates success and
492516
/// -2 indicates that one of the Compilation's Jobs crashed during execution
493-
int performJobs(std::unique_ptr<sys::TaskQueue> &&TQ);
517+
Compilation::Result performJobs(std::unique_ptr<sys::TaskQueue> &&TQ);
494518

495519
/// Returns whether the callee is permitted to pass -emit-loaded-module-trace
496520
/// to a frontend job.
@@ -534,13 +558,11 @@ class Compilation {
534558
private:
535559
/// Perform all jobs.
536560
///
537-
/// \param[out] abnormalExit Set to true if any job exits abnormally (i.e.
538-
/// crashes).
539561
/// \param TQ The task queue on which jobs will be scheduled.
540562
///
541563
/// \returns exit code of the first failed Job, or 0 on success. If a Job
542564
/// crashes during execution, a negative value will be returned.
543-
int performJobsImpl(bool &abnormalExit, std::unique_ptr<sys::TaskQueue> &&TQ);
565+
Compilation::Result performJobsImpl(std::unique_ptr<sys::TaskQueue> &&TQ);
544566

545567
/// Performs a single Job by executing in place, if possible.
546568
///
@@ -550,7 +572,7 @@ class Compilation {
550572
/// will no longer exist, or it will call exit() if the program was
551573
/// successfully executed. In the event of an error, this function will return
552574
/// a negative value indicating a failure to execute.
553-
int performSingleCommand(const Job *Cmd);
575+
Compilation::Result performSingleCommand(const Job *Cmd);
554576
};
555577

556578
} // end namespace driver

include/swift/Driver/FineGrainedDependencyDriverGraph.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -188,8 +188,8 @@ class ModuleDepGraph {
188188
std::unordered_map<std::string, unsigned> dotFileSequenceNumber;
189189

190190
public:
191-
const bool verifyFineGrainedDependencyGraphAfterEveryImport;
192-
const bool emitFineGrainedDependencyDotFileAfterEveryImport;
191+
bool verifyFineGrainedDependencyGraphAfterEveryImport;
192+
bool emitFineGrainedDependencyDotFileAfterEveryImport;
193193

194194
private:
195195
/// If tracing dependencies, holds a vector used to hold the current path
@@ -203,7 +203,7 @@ class ModuleDepGraph {
203203
dependencyPathsToJobs;
204204

205205
/// For helping with performance tuning, may be null:
206-
UnifiedStatsReporter *const stats;
206+
UnifiedStatsReporter *stats;
207207

208208
//==============================================================================
209209
// MARK: ModuleDepGraph - mutating dependencies

lib/Driver/Compilation.cpp

Lines changed: 43 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ namespace driver {
244244
std::unique_ptr<TaskQueue> TQ;
245245

246246
/// Cumulative result of PerformJobs(), accumulated from subprocesses.
247-
int Result = EXIT_SUCCESS;
247+
int ResultCode = EXIT_SUCCESS;
248248

249249
/// True if any Job crashed.
250250
bool AnyAbnormalExit = false;
@@ -719,8 +719,8 @@ namespace driver {
719719
// Store this task's ReturnCode as our Result if we haven't stored
720720
// anything yet.
721721

722-
if (Result == EXIT_SUCCESS)
723-
Result = ReturnCode;
722+
if (ResultCode == EXIT_SUCCESS)
723+
ResultCode = ReturnCode;
724724

725725
if (!isa<CompileJobAction>(FinishedCmd->getSource()) ||
726726
ReturnCode != EXIT_FAILURE) {
@@ -825,7 +825,7 @@ namespace driver {
825825
}
826826

827827
// Since the task signalled, unconditionally set result to -2.
828-
Result = -2;
828+
ResultCode = -2;
829829
AnyAbnormalExit = true;
830830

831831
return TaskFinishedResponse::StopExecution;
@@ -1536,7 +1536,7 @@ namespace driver {
15361536
_3, _4, _5, _6),
15371537
std::bind(&PerformJobsState::taskSignalled, this, _1,
15381538
_2, _3, _4, _5, _6, _7))) {
1539-
if (Result == EXIT_SUCCESS) {
1539+
if (ResultCode == EXIT_SUCCESS) {
15401540
// FIXME: Error from task queue while Result == EXIT_SUCCESS most
15411541
// likely means some fork/exec or posix_spawn failed; TaskQueue saw
15421542
// "an error" at some stage before even calling us with a process
@@ -1546,21 +1546,21 @@ namespace driver {
15461546
Comp.getDiags().diagnose(SourceLoc(),
15471547
diag::error_unable_to_execute_command,
15481548
"<unknown>");
1549-
Result = -2;
1549+
ResultCode = -2;
15501550
AnyAbnormalExit = true;
15511551
return;
15521552
}
15531553
}
15541554

15551555
// Returning without error from TaskQueue::execute should mean either an
15561556
// empty TaskQueue or a failed subprocess.
1557-
assert(!(Result == 0 && TQ->hasRemainingTasks()));
1557+
assert(!(ResultCode == 0 && TQ->hasRemainingTasks()));
15581558

15591559
// Task-exit callbacks from TaskQueue::execute may have unblocked jobs,
15601560
// which means there might be PendingExecution jobs to enqueue here. If
15611561
// there are, we need to continue trying to make progress on the
15621562
// TaskQueue before we start marking deferred jobs as skipped, below.
1563-
if (!PendingExecution.empty() && Result == 0) {
1563+
if (!PendingExecution.empty() && ResultCode == 0) {
15641564
formBatchJobsAndAddPendingJobsToTaskQueue();
15651565
continue;
15661566
}
@@ -1585,11 +1585,11 @@ namespace driver {
15851585

15861586
// If we added jobs to the TaskQueue, and we are not in an error state,
15871587
// we want to give the TaskQueue another run.
1588-
} while (Result == 0 && TQ->hasRemainingTasks());
1588+
} while (ResultCode == 0 && TQ->hasRemainingTasks());
15891589
}
15901590

15911591
void checkUnfinishedJobs() {
1592-
if (Result == 0) {
1592+
if (ResultCode == 0) {
15931593
assert(BlockingCommands.empty() &&
15941594
"some blocking commands never finished properly");
15951595
} else {
@@ -1693,10 +1693,14 @@ namespace driver {
16931693
});
16941694
}
16951695

1696-
int getResult() {
1697-
if (Result == 0)
1698-
Result = Comp.getDiags().hadAnyError();
1699-
return Result;
1696+
Compilation::Result takeResult() && {
1697+
if (ResultCode == 0)
1698+
ResultCode = Comp.getDiags().hadAnyError();
1699+
const bool forRanges = Comp.getEnableSourceRangeDependencies();
1700+
const bool hadAbnormalExit = hadAnyAbnormalExit();
1701+
const auto resultCode = ResultCode;
1702+
auto &&graph = std::move(*this).takeFineGrainedDepGraph(forRanges);
1703+
return Compilation::Result{hadAbnormalExit, resultCode, std::move(graph)};
17001704
}
17011705

17021706
bool hadAnyAbnormalExit() {
@@ -1756,6 +1760,12 @@ namespace driver {
17561760
getFineGrainedDepGraph(const bool forRanges) const {
17571761
return forRanges ? FineGrainedDepGraphForRanges : FineGrainedDepGraph;
17581762
}
1763+
1764+
fine_grained_dependencies::ModuleDepGraph &&
1765+
takeFineGrainedDepGraph(const bool forRanges) && {
1766+
return forRanges ? std::move(FineGrainedDepGraphForRanges)
1767+
: std::move(FineGrainedDepGraph);
1768+
}
17591769
};
17601770
} // namespace driver
17611771
} // namespace swift
@@ -1936,8 +1946,8 @@ static bool writeFilelistIfNecessary(const Job *job, const ArgList &args,
19361946
return ok;
19371947
}
19381948

1939-
int Compilation::performJobsImpl(bool &abnormalExit,
1940-
std::unique_ptr<TaskQueue> &&TQ) {
1949+
Compilation::Result
1950+
Compilation::performJobsImpl(std::unique_ptr<TaskQueue> &&TQ) {
19411951
PerformJobsState State(*this, std::move(TQ));
19421952

19431953
State.runJobs();
@@ -1946,36 +1956,39 @@ int Compilation::performJobsImpl(bool &abnormalExit,
19461956
InputInfoMap InputInfo;
19471957
State.populateInputInfoMap(InputInfo);
19481958
checkForOutOfDateInputs(Diags, InputInfo);
1959+
1960+
auto result = std::move(State).takeResult();
19491961
writeCompilationRecord(CompilationRecordPath, ArgsHash, BuildStartTime,
19501962
InputInfo);
1963+
return result;
1964+
} else {
1965+
return std::move(State).takeResult();
19511966
}
1952-
abnormalExit = State.hadAnyAbnormalExit();
1953-
return State.getResult();
19541967
}
19551968

1956-
int Compilation::performSingleCommand(const Job *Cmd) {
1969+
Compilation::Result Compilation::performSingleCommand(const Job *Cmd) {
19571970
assert(Cmd->getInputs().empty() &&
19581971
"This can only be used to run a single command with no inputs");
19591972

19601973
switch (Cmd->getCondition()) {
19611974
case Job::Condition::CheckDependencies:
1962-
return 0;
1975+
return Compilation::Result::code(0);
19631976
case Job::Condition::RunWithoutCascading:
19641977
case Job::Condition::Always:
19651978
case Job::Condition::NewlyAdded:
19661979
break;
19671980
}
19681981

19691982
if (!writeFilelistIfNecessary(Cmd, *TranslatedArgs.get(), Diags))
1970-
return 1;
1983+
return Compilation::Result::code(1);
19711984

19721985
switch (Level) {
19731986
case OutputLevel::Normal:
19741987
case OutputLevel::Parseable:
19751988
break;
19761989
case OutputLevel::PrintJobs:
19771990
Cmd->printCommandLineAndEnvironment(llvm::outs());
1978-
return 0;
1991+
return Compilation::Result::code(0);
19791992
case OutputLevel::Verbose:
19801993
Cmd->printCommandLine(llvm::errs());
19811994
break;
@@ -1999,11 +2012,12 @@ int Compilation::performSingleCommand(const Job *Cmd) {
19992012
"expected environment variable to be set successfully");
20002013
// Bail out early in release builds.
20012014
if (envResult != 0) {
2002-
return envResult;
2015+
return Compilation::Result::code(envResult);
20032016
}
20042017
}
20052018

2006-
return ExecuteInPlace(ExecPath, argv);
2019+
const auto returnCode = ExecuteInPlace(ExecPath, argv);
2020+
return Compilation::Result::code(returnCode);
20072021
}
20082022

20092023
static bool writeAllSourcesFile(DiagnosticEngine &diags, StringRef path,
@@ -2026,10 +2040,10 @@ static bool writeAllSourcesFile(DiagnosticEngine &diags, StringRef path,
20262040
return true;
20272041
}
20282042

2029-
int Compilation::performJobs(std::unique_ptr<TaskQueue> &&TQ) {
2043+
Compilation::Result Compilation::performJobs(std::unique_ptr<TaskQueue> &&TQ) {
20302044
if (AllSourceFilesPath)
20312045
if (!writeAllSourcesFile(Diags, AllSourceFilesPath, getInputFiles()))
2032-
return EXIT_FAILURE;
2046+
return Compilation::Result::code(EXIT_FAILURE);
20332047

20342048
// If we don't have to do any cleanup work, just exec the subprocess.
20352049
if (Level < OutputLevel::Parseable &&
@@ -2044,20 +2058,19 @@ int Compilation::performJobs(std::unique_ptr<TaskQueue> &&TQ) {
20442058
Diags.diagnose(SourceLoc(), diag::warning_parallel_execution_not_supported);
20452059
}
20462060

2047-
bool abnormalExit;
2048-
int result = performJobsImpl(abnormalExit, std::move(TQ));
2061+
auto result = performJobsImpl(std::move(TQ));
20492062

20502063
if (IncrementalComparator)
20512064
IncrementalComparator->outputComparison();
20522065

20532066
if (!SaveTemps) {
20542067
for (const auto &pathPair : TempFilePaths) {
2055-
if (!abnormalExit || pathPair.getValue() == PreserveOnSignal::No)
2068+
if (!result.hadAbnormalExit || pathPair.getValue() == PreserveOnSignal::No)
20562069
(void)llvm::sys::fs::remove(pathPair.getKey());
20572070
}
20582071
}
20592072
if (Stats)
2060-
Stats->noteCurrentProcessExitStatus(result);
2073+
Stats->noteCurrentProcessExitStatus(result.exitCode);
20612074
return result;
20622075
}
20632076

tools/driver/driver.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ static int run_driver(StringRef ExecName,
248248
std::unique_ptr<sys::TaskQueue> TQ = TheDriver.buildTaskQueue(*C);
249249
if (!TQ)
250250
return 1;
251-
return C->performJobs(std::move(TQ));
251+
return C->performJobs(std::move(TQ)).exitCode;
252252
}
253253

254254
return 0;

0 commit comments

Comments
 (0)