Skip to content

[BatchMode] Make driver report exits per-batch, not per-constituent. #14931

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 3, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
67 changes: 20 additions & 47 deletions lib/Driver/Compilation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -419,7 +419,7 @@ namespace driver {
/// TaskFinishedResponse::ContinueExecution from any of the constituent
/// calls.
TaskFinishedResponse
unpackAndFinishBatch(ProcessId Pid, int ReturnCode, StringRef Output,
unpackAndFinishBatch(int ReturnCode, StringRef Output,
StringRef Errors, const BatchJob *B) {
if (Comp.ShowJobLifecycle)
llvm::outs() << "Batch job finished: " << LogJob(B) << "\n";
Expand All @@ -428,7 +428,8 @@ namespace driver {
if (Comp.ShowJobLifecycle)
llvm::outs() << " ==> Unpacked batch constituent finished: "
<< LogJob(J) << "\n";
auto r = taskFinished(Pid, ReturnCode, Output, Errors, (void *)J);
auto r = taskFinished(llvm::sys::ProcessInfo::InvalidPid, ReturnCode, Output,
Errors, (void *)J);
if (r != TaskFinishedResponse::ContinueExecution)
res = r;
}
Expand All @@ -443,26 +444,29 @@ namespace driver {
StringRef Errors, void *Context) {
const Job *FinishedCmd = (const Job *)Context;

if (Comp.ShowDriverTimeCompilation) {
DriverTimers[FinishedCmd]->stopTimer();
if (Pid != llvm::sys::ProcessInfo::InvalidPid) {

if (Comp.ShowDriverTimeCompilation) {
DriverTimers[FinishedCmd]->stopTimer();
}

if (Comp.Level == OutputLevel::Parseable) {
// Parseable output was requested.
parseable_output::emitFinishedMessage(llvm::errs(), *FinishedCmd, Pid,
ReturnCode, Output);
} else {
// Otherwise, send the buffered output to stderr, though only if we
// support getting buffered output.
if (TaskQueue::supportsBufferingOutput())
llvm::errs() << Output;
}
}

if (BatchJobs.count(FinishedCmd) != 0) {
return unpackAndFinishBatch(Pid, ReturnCode, Output, Errors,
return unpackAndFinishBatch(ReturnCode, Output, Errors,
static_cast<const BatchJob *>(FinishedCmd));
}

if (Comp.Level == OutputLevel::Parseable) {
// Parseable output was requested.
parseable_output::emitFinishedMessage(llvm::errs(), *FinishedCmd, Pid,
ReturnCode, Output);
} else {
// Otherwise, send the buffered output to stderr, though only if we
// support getting buffered output.
if (TaskQueue::supportsBufferingOutput())
llvm::errs() << Output;
}

// In order to handle both old dependencies that have disappeared and new
// dependencies that have arisen, we need to reload the dependency file.
// Do this whether or not the build succeeded.
Expand Down Expand Up @@ -505,30 +509,6 @@ namespace driver {
return TaskFinishedResponse::ContinueExecution;
}

/// Unpack a \c BatchJob that has finished into its constituent \c Job
/// members, and call \c taskSignalled on each, propagating any \c
/// TaskFinishedResponse other than \c
/// TaskFinishedResponse::ContinueExecution from any of the constituent
/// calls.
TaskFinishedResponse
unpackAndSignalBatch(ProcessId Pid, StringRef ErrorMsg, StringRef Output,
StringRef Errors, const BatchJob *B,
Optional<int> Signal) {
if (Comp.ShowJobLifecycle)
llvm::outs() << "Batch job signalled: " << LogJob(B) << "\n";
auto res = TaskFinishedResponse::ContinueExecution;
for (const Job *J : B->getCombinedJobs()) {
if (Comp.ShowJobLifecycle)
llvm::outs() << " ==> Unpacked batch constituent signalled: "
<< LogJob(J) << "\n";
auto r = taskSignalled(Pid, ErrorMsg, Output, Errors,
(void *)J, Signal);
if (r != TaskFinishedResponse::ContinueExecution)
res = r;
}
return res;
}

TaskFinishedResponse
taskSignalled(ProcessId Pid, StringRef ErrorMsg, StringRef Output,
StringRef Errors, void *Context, Optional<int> Signal) {
Expand All @@ -538,12 +518,6 @@ namespace driver {
DriverTimers[SignalledCmd]->stopTimer();
}

if (BatchJobs.count(SignalledCmd) != 0) {
return unpackAndSignalBatch(Pid, ErrorMsg, Output, Errors,
static_cast<const BatchJob *>(SignalledCmd),
Signal);
}

if (Comp.Level == OutputLevel::Parseable) {
// Parseable output was requested.
parseable_output::emitSignalledMessage(llvm::errs(), *SignalledCmd,
Expand All @@ -554,7 +528,6 @@ namespace driver {
if (TaskQueue::supportsBufferingOutput())
llvm::errs() << Output;
}

if (!ErrorMsg.empty())
Comp.Diags.diagnose(SourceLoc(), diag::error_unable_to_execute_command,
ErrorMsg);
Expand Down
6 changes: 3 additions & 3 deletions lib/Driver/ParseableOutput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,9 +133,9 @@ class DetailedCommandBasedMessage : public CommandBasedMessage {
}
}
types::forAllTypes([&](types::ID Ty) {
auto Output = Cmd.getOutput().getAdditionalOutputForType(Ty);
if (!Output.empty())
Outputs.push_back(OutputPair(Ty, Output));
for (auto Output : Cmd.getOutput().getAdditionalOutputsForType(Ty)) {
Outputs.push_back(OutputPair(Ty, Output));
}
});
}

Expand Down
125 changes: 125 additions & 0 deletions test/Driver/batch_mode_parseable_output.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
// RUN: %empty-directory(%t)
// RUN: touch %t/file-01.swift %t/file-02.swift %t/file-03.swift
// RUN: echo 'public func main() {}' >%t/main.swift
//
// RUN: %swiftc_driver -enable-batch-mode -Xfrontend -bypass-batch-mode-checks -parseable-output -c -emit-module -module-name main -j 2 %t/file-01.swift %t/file-02.swift %t/file-03.swift %t/main.swift 2>&1 | %FileCheck %s
//
//
// CHECK: {{[1-9][0-9]*}}
// CHECK-NEXT: {
// CHECK-NEXT: "kind": "began",
// CHECK-NEXT: "name": "compile",
// CHECK-NEXT: "command": "{{.*}}/swift{{c?}} -frontend -c -primary-file {{.*}}/file-01.swift -primary-file {{.*}}/file-02.swift {{.*}}/file-03.swift {{.*}}/main.swift {{.*}} -emit-module-doc-path {{.*}}/file-01-[[SWIFTDOC01:[a-z0-9]+]].swiftdoc -emit-module-doc-path {{.*}}/file-02-[[SWIFTDOC02:[a-z0-9]+]].swiftdoc -module-name main -emit-module-path {{.*}}/file-01-[[MODULE01:[a-z0-9]+]].swiftmodule -emit-module-path {{.*}}/file-02-[[MODULE02:[a-z0-9]+]].swiftmodule -o {{.*}}/file-01-[[OBJ01:[a-z0-9]+]].o -o {{.*}}/file-02-[[OBJ02:[a-z0-9]+]].o",
// CHECK-NEXT: "inputs": [
// CHECK-NEXT: "{{.*}}/file-01.swift",
// CHECK-NEXT: "{{.*}}/file-02.swift"
// CHECK-NEXT: ],
// CHECK-NEXT: "outputs": [
// CHECK-NEXT: {
// CHECK-NEXT: "type": "object",
// CHECK-NEXT: "path": "{{.*}}/file-01-[[OBJ01]].o"
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: "type": "object",
// CHECK-NEXT: "path": "{{.*}}/file-02-[[OBJ02]].o"
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: "type": "swiftmodule",
// CHECK-NEXT: "path": "{{.*}}/file-01-[[MODULE01]].swiftmodule"
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: "type": "swiftmodule",
// CHECK-NEXT: "path": "{{.*}}/file-02-[[MODULE02]].swiftmodule"
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: "type": "swiftdoc",
// CHECK-NEXT: "path": "{{.*}}/file-01-[[SWIFTDOC01]].swiftdoc"
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: "type": "swiftdoc",
// CHECK-NEXT: "path": "{{.*}}/file-02-[[SWIFTDOC02]].swiftdoc"
// CHECK-NEXT: }
// CHECK-NEXT: ],
// CHECK-NEXT: "pid": {{[1-9][0-9]*}}
// CHECK-NEXT: }
// CHECK-NEXT: {{[1-9][0-9]*}}
// CHECK-NEXT: {
// CHECK-NEXT: "kind": "began",
// CHECK-NEXT: "name": "compile",
// CHECK-NEXT: "command": "{{.*}}/swift{{c?}} -frontend -c {{.*}}/file-01.swift {{.*}}/file-02.swift -primary-file {{.*}}/file-03.swift -primary-file {{.*}}/main.swift {{.*}} -emit-module-doc-path {{.*}}/file-03-[[SWIFTDOC03:[a-z0-9]+]].swiftdoc -emit-module-doc-path {{.*}}/main-[[SWIFTDOCMAIN:[a-z0-9]+]].swiftdoc -module-name main -emit-module-path {{.*}}/file-03-[[MODULE03:[a-z0-9]+]].swiftmodule -emit-module-path {{.*}}/main-[[MODULEMAIN:[a-z0-9]+]].swiftmodule -o {{.*}}/file-03-[[OBJ03:[a-z0-9]+]].o -o {{.*}}/main-[[OBJMAIN:[a-z0-9]+]].o",
// CHECK-NEXT: "inputs": [
// CHECK-NEXT: "{{.*}}/file-03.swift",
// CHECK-NEXT: "{{.*}}/main.swift"
// CHECK-NEXT: ],
// CHECK-NEXT: "outputs": [
// CHECK-NEXT: {
// CHECK-NEXT: "type": "object",
// CHECK-NEXT: "path": "{{.*}}/file-03-[[OBJ03]].o"
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: "type": "object",
// CHECK-NEXT: "path": "{{.*}}/main-[[OBJMAIN]].o"
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: "type": "swiftmodule",
// CHECK-NEXT: "path": "{{.*}}/file-03-[[MODULE03]].swiftmodule"
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: "type": "swiftmodule",
// CHECK-NEXT: "path": "{{.*}}/main-[[MODULEMAIN]].swiftmodule"
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: "type": "swiftdoc",
// CHECK-NEXT: "path": "{{.*}}/file-03-[[SWIFTDOC03]].swiftdoc"
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: "type": "swiftdoc",
// CHECK-NEXT: "path": "{{.*}}/main-[[SWIFTDOCMAIN]].swiftdoc"
// CHECK-NEXT: }
// CHECK-NEXT: ],
// CHECK-NEXT: "pid": {{[1-9][0-9]*}}
// CHECK-NEXT: }
// CHECK-NEXT: {{[1-9][0-9]*}}
// CHECK-NEXT: {
// CHECK-NEXT: "kind": "finished",
// CHECK-NEXT: "name": "compile",
// CHECK-NEXT: "pid": {{[1-9][0-9]*}},
// CHECK-NEXT: "exit-status": 0
// CHECK-NEXT: }
// CHECK-NEXT: {{[1-9][0-9]*}}
// CHECK-NEXT: {
// CHECK-NEXT: "kind": "finished",
// CHECK-NEXT: "name": "compile",
// CHECK-NEXT: "pid": {{[1-9][0-9]*}},
// CHECK-NEXT: "exit-status": 0
// CHECK-NEXT: }
// CHECK-NEXT: {{[1-9][0-9]*}}
// CHECK-NEXT: {
// CHECK-NEXT: "kind": "began",
// CHECK-NEXT: "name": "merge-module",
// CHECK-NEXT: "command": "{{.*}}/swift{{c?}} -frontend -merge-modules -emit-module {{.*}}/file-01-[[MODULE01]].swiftmodule {{.*}}/file-02-[[MODULE02]].swiftmodule {{.*}}/file-03-[[MODULE03]].swiftmodule {{.*}}/main-[[MODULEMAIN]].swiftmodule {{.*}} -emit-module-doc-path main.swiftdoc -module-name main -o main.swiftmodule",
// CHECK-NEXT: "inputs": [
// CHECK-NEXT: "{{.*}}/file-01-[[OBJ01]].o",
// CHECK-NEXT: "{{.*}}/file-02-[[OBJ02]].o",
// CHECK-NEXT: "{{.*}}/file-03-[[OBJ03]].o",
// CHECK-NEXT: "{{.*}}/main-[[OBJMAIN]].o"
// CHECK-NEXT: ],
// CHECK-NEXT: "outputs": [
// CHECK-NEXT: {
// CHECK-NEXT: "type": "swiftmodule",
// CHECK-NEXT: "path": "main.swiftmodule"
// CHECK-NEXT: },
// CHECK-NEXT: {
// CHECK-NEXT: "type": "swiftdoc",
// CHECK-NEXT: "path": "main.swiftdoc"
// CHECK-NEXT: }
// CHECK-NEXT: ],
// CHECK-NEXT: "pid": {{[1-9][0-9]*}}
// CHECK-NEXT: }
// CHECK-NEXT: {{[1-9][0-9]*}}
// CHECK-NEXT: {
// CHECK-NEXT: "kind": "finished",
// CHECK-NEXT: "name": "merge-module",
// CHECK-NEXT: "pid": {{[1-9][0-9]*}},
// CHECK-NEXT: "exit-status": 0
// CHECK-NEXT: }