Skip to content

Commit d815e27

Browse files
committed
[NFC] Add Compilation::Result
In order to extract the module dependency graph from the compilation the driver just ran, define a separate semantic type to hold a result code and the graph itself.
1 parent 2f48a53 commit d815e27

File tree

3 files changed

+57
-32
lines changed

3 files changed

+57
-32
lines changed

include/swift/Driver/Compilation.h

Lines changed: 10 additions & 3 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,11 @@ using CommandSet = llvm::SmallPtrSet<const Job *, 16>;
7879

7980
class Compilation {
8081
public:
82+
struct Result {
83+
int exitCode;
84+
fine_grained_dependencies::ModuleDepGraph depGraph;
85+
};
86+
8187
class IncrementalSchemeComparator {
8288
const bool EnableIncrementalBuildWhenConstructed;
8389
const bool &EnableIncrementalBuild;
@@ -490,7 +496,7 @@ class Compilation {
490496
///
491497
/// \returns result code for the Compilation's Jobs; 0 indicates success and
492498
/// -2 indicates that one of the Compilation's Jobs crashed during execution
493-
int performJobs(std::unique_ptr<sys::TaskQueue> &&TQ);
499+
Compilation::Result performJobs(std::unique_ptr<sys::TaskQueue> &&TQ);
494500

495501
/// Returns whether the callee is permitted to pass -emit-loaded-module-trace
496502
/// to a frontend job.
@@ -540,7 +546,8 @@ class Compilation {
540546
///
541547
/// \returns exit code of the first failed Job, or 0 on success. If a Job
542548
/// crashes during execution, a negative value will be returned.
543-
int performJobsImpl(bool &abnormalExit, std::unique_ptr<sys::TaskQueue> &&TQ);
549+
Compilation::Result performJobsImpl(bool &abnormalExit,
550+
std::unique_ptr<sys::TaskQueue> &&TQ);
544551

545552
/// Performs a single Job by executing in place, if possible.
546553
///
@@ -550,7 +557,7 @@ class Compilation {
550557
/// will no longer exist, or it will call exit() if the program was
551558
/// successfully executed. In the event of an error, this function will return
552559
/// a negative value indicating a failure to execute.
553-
int performSingleCommand(const Job *Cmd);
560+
Compilation::Result performSingleCommand(const Job *Cmd);
554561
};
555562

556563
} // end namespace driver

lib/Driver/Compilation.cpp

Lines changed: 46 additions & 28 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,12 @@ 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+
return Compilation::Result{
1701+
ResultCode, std::move(*this).takeFineGrainedDepGraph(forRanges)};
17001702
}
17011703

17021704
bool hadAnyAbnormalExit() {
@@ -1756,6 +1758,12 @@ namespace driver {
17561758
getFineGrainedDepGraph(const bool forRanges) const {
17571759
return forRanges ? FineGrainedDepGraphForRanges : FineGrainedDepGraph;
17581760
}
1761+
1762+
fine_grained_dependencies::ModuleDepGraph &&
1763+
takeFineGrainedDepGraph(const bool forRanges) && {
1764+
return forRanges ? std::move(FineGrainedDepGraphForRanges)
1765+
: std::move(FineGrainedDepGraph);
1766+
}
17591767
};
17601768
} // namespace driver
17611769
} // namespace swift
@@ -1936,8 +1944,9 @@ static bool writeFilelistIfNecessary(const Job *job, const ArgList &args,
19361944
return ok;
19371945
}
19381946

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

19431952
State.runJobs();
@@ -1946,36 +1955,41 @@ int Compilation::performJobsImpl(bool &abnormalExit,
19461955
InputInfoMap InputInfo;
19471956
State.populateInputInfoMap(InputInfo);
19481957
checkForOutOfDateInputs(Diags, InputInfo);
1958+
1959+
abnormalExit = State.hadAnyAbnormalExit();
1960+
auto result = std::move(State).takeResult();
19491961
writeCompilationRecord(CompilationRecordPath, ArgsHash, BuildStartTime,
19501962
InputInfo);
1963+
return result;
1964+
} else {
1965+
abnormalExit = State.hadAnyAbnormalExit();
1966+
return std::move(State).takeResult();
19511967
}
1952-
abnormalExit = State.hadAnyAbnormalExit();
1953-
return State.getResult();
19541968
}
19551969

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

19601974
switch (Cmd->getCondition()) {
19611975
case Job::Condition::CheckDependencies:
1962-
return 0;
1976+
return Compilation::Result{0, fine_grained_dependencies::ModuleDepGraph()};
19631977
case Job::Condition::RunWithoutCascading:
19641978
case Job::Condition::Always:
19651979
case Job::Condition::NewlyAdded:
19661980
break;
19671981
}
19681982

19691983
if (!writeFilelistIfNecessary(Cmd, *TranslatedArgs.get(), Diags))
1970-
return 1;
1984+
return Compilation::Result{1, fine_grained_dependencies::ModuleDepGraph()};
19711985

19721986
switch (Level) {
19731987
case OutputLevel::Normal:
19741988
case OutputLevel::Parseable:
19751989
break;
19761990
case OutputLevel::PrintJobs:
19771991
Cmd->printCommandLineAndEnvironment(llvm::outs());
1978-
return 0;
1992+
return Compilation::Result{0, fine_grained_dependencies::ModuleDepGraph()};
19791993
case OutputLevel::Verbose:
19801994
Cmd->printCommandLine(llvm::errs());
19811995
break;
@@ -1999,11 +2013,14 @@ int Compilation::performSingleCommand(const Job *Cmd) {
19992013
"expected environment variable to be set successfully");
20002014
// Bail out early in release builds.
20012015
if (envResult != 0) {
2002-
return envResult;
2016+
return Compilation::Result{envResult,
2017+
fine_grained_dependencies::ModuleDepGraph()};
20032018
}
20042019
}
20052020

2006-
return ExecuteInPlace(ExecPath, argv);
2021+
const auto returnCode = ExecuteInPlace(ExecPath, argv);
2022+
return Compilation::Result{returnCode,
2023+
fine_grained_dependencies::ModuleDepGraph()};
20072024
}
20082025

20092026
static bool writeAllSourcesFile(DiagnosticEngine &diags, StringRef path,
@@ -2026,10 +2043,11 @@ static bool writeAllSourcesFile(DiagnosticEngine &diags, StringRef path,
20262043
return true;
20272044
}
20282045

2029-
int Compilation::performJobs(std::unique_ptr<TaskQueue> &&TQ) {
2046+
Compilation::Result Compilation::performJobs(std::unique_ptr<TaskQueue> &&TQ) {
20302047
if (AllSourceFilesPath)
20312048
if (!writeAllSourcesFile(Diags, AllSourceFilesPath, getInputFiles()))
2032-
return EXIT_FAILURE;
2049+
return Compilation::Result{EXIT_FAILURE,
2050+
fine_grained_dependencies::ModuleDepGraph()};
20332051

20342052
// If we don't have to do any cleanup work, just exec the subprocess.
20352053
if (Level < OutputLevel::Parseable &&
@@ -2045,7 +2063,7 @@ int Compilation::performJobs(std::unique_ptr<TaskQueue> &&TQ) {
20452063
}
20462064

20472065
bool abnormalExit;
2048-
int result = performJobsImpl(abnormalExit, std::move(TQ));
2066+
auto result = performJobsImpl(abnormalExit, std::move(TQ));
20492067

20502068
if (IncrementalComparator)
20512069
IncrementalComparator->outputComparison();
@@ -2057,7 +2075,7 @@ int Compilation::performJobs(std::unique_ptr<TaskQueue> &&TQ) {
20572075
}
20582076
}
20592077
if (Stats)
2060-
Stats->noteCurrentProcessExitStatus(result);
2078+
Stats->noteCurrentProcessExitStatus(result.exitCode);
20612079
return result;
20622080
}
20632081

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)