Skip to content

Commit a9b49a9

Browse files
authored
Merge pull request #14931 from graydon/batch-mode-exit-per-batch
[BatchMode] Make driver report exits per-batch, not per-constituent.
2 parents a65da88 + 5edded1 commit a9b49a9

File tree

3 files changed

+148
-50
lines changed

3 files changed

+148
-50
lines changed

lib/Driver/Compilation.cpp

Lines changed: 20 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -419,7 +419,7 @@ namespace driver {
419419
/// TaskFinishedResponse::ContinueExecution from any of the constituent
420420
/// calls.
421421
TaskFinishedResponse
422-
unpackAndFinishBatch(ProcessId Pid, int ReturnCode, StringRef Output,
422+
unpackAndFinishBatch(int ReturnCode, StringRef Output,
423423
StringRef Errors, const BatchJob *B) {
424424
if (Comp.ShowJobLifecycle)
425425
llvm::outs() << "Batch job finished: " << LogJob(B) << "\n";
@@ -428,7 +428,8 @@ namespace driver {
428428
if (Comp.ShowJobLifecycle)
429429
llvm::outs() << " ==> Unpacked batch constituent finished: "
430430
<< LogJob(J) << "\n";
431-
auto r = taskFinished(Pid, ReturnCode, Output, Errors, (void *)J);
431+
auto r = taskFinished(llvm::sys::ProcessInfo::InvalidPid, ReturnCode, Output,
432+
Errors, (void *)J);
432433
if (r != TaskFinishedResponse::ContinueExecution)
433434
res = r;
434435
}
@@ -443,26 +444,29 @@ namespace driver {
443444
StringRef Errors, void *Context) {
444445
const Job *FinishedCmd = (const Job *)Context;
445446

446-
if (Comp.ShowDriverTimeCompilation) {
447-
DriverTimers[FinishedCmd]->stopTimer();
447+
if (Pid != llvm::sys::ProcessInfo::InvalidPid) {
448+
449+
if (Comp.ShowDriverTimeCompilation) {
450+
DriverTimers[FinishedCmd]->stopTimer();
451+
}
452+
453+
if (Comp.Level == OutputLevel::Parseable) {
454+
// Parseable output was requested.
455+
parseable_output::emitFinishedMessage(llvm::errs(), *FinishedCmd, Pid,
456+
ReturnCode, Output);
457+
} else {
458+
// Otherwise, send the buffered output to stderr, though only if we
459+
// support getting buffered output.
460+
if (TaskQueue::supportsBufferingOutput())
461+
llvm::errs() << Output;
462+
}
448463
}
449464

450465
if (BatchJobs.count(FinishedCmd) != 0) {
451-
return unpackAndFinishBatch(Pid, ReturnCode, Output, Errors,
466+
return unpackAndFinishBatch(ReturnCode, Output, Errors,
452467
static_cast<const BatchJob *>(FinishedCmd));
453468
}
454469

455-
if (Comp.Level == OutputLevel::Parseable) {
456-
// Parseable output was requested.
457-
parseable_output::emitFinishedMessage(llvm::errs(), *FinishedCmd, Pid,
458-
ReturnCode, Output);
459-
} else {
460-
// Otherwise, send the buffered output to stderr, though only if we
461-
// support getting buffered output.
462-
if (TaskQueue::supportsBufferingOutput())
463-
llvm::errs() << Output;
464-
}
465-
466470
// In order to handle both old dependencies that have disappeared and new
467471
// dependencies that have arisen, we need to reload the dependency file.
468472
// Do this whether or not the build succeeded.
@@ -505,30 +509,6 @@ namespace driver {
505509
return TaskFinishedResponse::ContinueExecution;
506510
}
507511

508-
/// Unpack a \c BatchJob that has finished into its constituent \c Job
509-
/// members, and call \c taskSignalled on each, propagating any \c
510-
/// TaskFinishedResponse other than \c
511-
/// TaskFinishedResponse::ContinueExecution from any of the constituent
512-
/// calls.
513-
TaskFinishedResponse
514-
unpackAndSignalBatch(ProcessId Pid, StringRef ErrorMsg, StringRef Output,
515-
StringRef Errors, const BatchJob *B,
516-
Optional<int> Signal) {
517-
if (Comp.ShowJobLifecycle)
518-
llvm::outs() << "Batch job signalled: " << LogJob(B) << "\n";
519-
auto res = TaskFinishedResponse::ContinueExecution;
520-
for (const Job *J : B->getCombinedJobs()) {
521-
if (Comp.ShowJobLifecycle)
522-
llvm::outs() << " ==> Unpacked batch constituent signalled: "
523-
<< LogJob(J) << "\n";
524-
auto r = taskSignalled(Pid, ErrorMsg, Output, Errors,
525-
(void *)J, Signal);
526-
if (r != TaskFinishedResponse::ContinueExecution)
527-
res = r;
528-
}
529-
return res;
530-
}
531-
532512
TaskFinishedResponse
533513
taskSignalled(ProcessId Pid, StringRef ErrorMsg, StringRef Output,
534514
StringRef Errors, void *Context, Optional<int> Signal) {
@@ -538,12 +518,6 @@ namespace driver {
538518
DriverTimers[SignalledCmd]->stopTimer();
539519
}
540520

541-
if (BatchJobs.count(SignalledCmd) != 0) {
542-
return unpackAndSignalBatch(Pid, ErrorMsg, Output, Errors,
543-
static_cast<const BatchJob *>(SignalledCmd),
544-
Signal);
545-
}
546-
547521
if (Comp.Level == OutputLevel::Parseable) {
548522
// Parseable output was requested.
549523
parseable_output::emitSignalledMessage(llvm::errs(), *SignalledCmd,
@@ -554,7 +528,6 @@ namespace driver {
554528
if (TaskQueue::supportsBufferingOutput())
555529
llvm::errs() << Output;
556530
}
557-
558531
if (!ErrorMsg.empty())
559532
Comp.Diags.diagnose(SourceLoc(), diag::error_unable_to_execute_command,
560533
ErrorMsg);

lib/Driver/ParseableOutput.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,9 @@ class DetailedCommandBasedMessage : public CommandBasedMessage {
133133
}
134134
}
135135
types::forAllTypes([&](types::ID Ty) {
136-
auto Output = Cmd.getOutput().getAdditionalOutputForType(Ty);
137-
if (!Output.empty())
138-
Outputs.push_back(OutputPair(Ty, Output));
136+
for (auto Output : Cmd.getOutput().getAdditionalOutputsForType(Ty)) {
137+
Outputs.push_back(OutputPair(Ty, Output));
138+
}
139139
});
140140
}
141141

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: touch %t/file-01.swift %t/file-02.swift %t/file-03.swift
3+
// RUN: echo 'public func main() {}' >%t/main.swift
4+
//
5+
// 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
6+
//
7+
//
8+
// CHECK: {{[1-9][0-9]*}}
9+
// CHECK-NEXT: {
10+
// CHECK-NEXT: "kind": "began",
11+
// CHECK-NEXT: "name": "compile",
12+
// 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",
13+
// CHECK-NEXT: "inputs": [
14+
// CHECK-NEXT: "{{.*}}/file-01.swift",
15+
// CHECK-NEXT: "{{.*}}/file-02.swift"
16+
// CHECK-NEXT: ],
17+
// CHECK-NEXT: "outputs": [
18+
// CHECK-NEXT: {
19+
// CHECK-NEXT: "type": "object",
20+
// CHECK-NEXT: "path": "{{.*}}/file-01-[[OBJ01]].o"
21+
// CHECK-NEXT: },
22+
// CHECK-NEXT: {
23+
// CHECK-NEXT: "type": "object",
24+
// CHECK-NEXT: "path": "{{.*}}/file-02-[[OBJ02]].o"
25+
// CHECK-NEXT: },
26+
// CHECK-NEXT: {
27+
// CHECK-NEXT: "type": "swiftmodule",
28+
// CHECK-NEXT: "path": "{{.*}}/file-01-[[MODULE01]].swiftmodule"
29+
// CHECK-NEXT: },
30+
// CHECK-NEXT: {
31+
// CHECK-NEXT: "type": "swiftmodule",
32+
// CHECK-NEXT: "path": "{{.*}}/file-02-[[MODULE02]].swiftmodule"
33+
// CHECK-NEXT: },
34+
// CHECK-NEXT: {
35+
// CHECK-NEXT: "type": "swiftdoc",
36+
// CHECK-NEXT: "path": "{{.*}}/file-01-[[SWIFTDOC01]].swiftdoc"
37+
// CHECK-NEXT: },
38+
// CHECK-NEXT: {
39+
// CHECK-NEXT: "type": "swiftdoc",
40+
// CHECK-NEXT: "path": "{{.*}}/file-02-[[SWIFTDOC02]].swiftdoc"
41+
// CHECK-NEXT: }
42+
// CHECK-NEXT: ],
43+
// CHECK-NEXT: "pid": {{[1-9][0-9]*}}
44+
// CHECK-NEXT: }
45+
// CHECK-NEXT: {{[1-9][0-9]*}}
46+
// CHECK-NEXT: {
47+
// CHECK-NEXT: "kind": "began",
48+
// CHECK-NEXT: "name": "compile",
49+
// 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",
50+
// CHECK-NEXT: "inputs": [
51+
// CHECK-NEXT: "{{.*}}/file-03.swift",
52+
// CHECK-NEXT: "{{.*}}/main.swift"
53+
// CHECK-NEXT: ],
54+
// CHECK-NEXT: "outputs": [
55+
// CHECK-NEXT: {
56+
// CHECK-NEXT: "type": "object",
57+
// CHECK-NEXT: "path": "{{.*}}/file-03-[[OBJ03]].o"
58+
// CHECK-NEXT: },
59+
// CHECK-NEXT: {
60+
// CHECK-NEXT: "type": "object",
61+
// CHECK-NEXT: "path": "{{.*}}/main-[[OBJMAIN]].o"
62+
// CHECK-NEXT: },
63+
// CHECK-NEXT: {
64+
// CHECK-NEXT: "type": "swiftmodule",
65+
// CHECK-NEXT: "path": "{{.*}}/file-03-[[MODULE03]].swiftmodule"
66+
// CHECK-NEXT: },
67+
// CHECK-NEXT: {
68+
// CHECK-NEXT: "type": "swiftmodule",
69+
// CHECK-NEXT: "path": "{{.*}}/main-[[MODULEMAIN]].swiftmodule"
70+
// CHECK-NEXT: },
71+
// CHECK-NEXT: {
72+
// CHECK-NEXT: "type": "swiftdoc",
73+
// CHECK-NEXT: "path": "{{.*}}/file-03-[[SWIFTDOC03]].swiftdoc"
74+
// CHECK-NEXT: },
75+
// CHECK-NEXT: {
76+
// CHECK-NEXT: "type": "swiftdoc",
77+
// CHECK-NEXT: "path": "{{.*}}/main-[[SWIFTDOCMAIN]].swiftdoc"
78+
// CHECK-NEXT: }
79+
// CHECK-NEXT: ],
80+
// CHECK-NEXT: "pid": {{[1-9][0-9]*}}
81+
// CHECK-NEXT: }
82+
// CHECK-NEXT: {{[1-9][0-9]*}}
83+
// CHECK-NEXT: {
84+
// CHECK-NEXT: "kind": "finished",
85+
// CHECK-NEXT: "name": "compile",
86+
// CHECK-NEXT: "pid": {{[1-9][0-9]*}},
87+
// CHECK-NEXT: "exit-status": 0
88+
// CHECK-NEXT: }
89+
// CHECK-NEXT: {{[1-9][0-9]*}}
90+
// CHECK-NEXT: {
91+
// CHECK-NEXT: "kind": "finished",
92+
// CHECK-NEXT: "name": "compile",
93+
// CHECK-NEXT: "pid": {{[1-9][0-9]*}},
94+
// CHECK-NEXT: "exit-status": 0
95+
// CHECK-NEXT: }
96+
// CHECK-NEXT: {{[1-9][0-9]*}}
97+
// CHECK-NEXT: {
98+
// CHECK-NEXT: "kind": "began",
99+
// CHECK-NEXT: "name": "merge-module",
100+
// 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",
101+
// CHECK-NEXT: "inputs": [
102+
// CHECK-NEXT: "{{.*}}/file-01-[[OBJ01]].o",
103+
// CHECK-NEXT: "{{.*}}/file-02-[[OBJ02]].o",
104+
// CHECK-NEXT: "{{.*}}/file-03-[[OBJ03]].o",
105+
// CHECK-NEXT: "{{.*}}/main-[[OBJMAIN]].o"
106+
// CHECK-NEXT: ],
107+
// CHECK-NEXT: "outputs": [
108+
// CHECK-NEXT: {
109+
// CHECK-NEXT: "type": "swiftmodule",
110+
// CHECK-NEXT: "path": "main.swiftmodule"
111+
// CHECK-NEXT: },
112+
// CHECK-NEXT: {
113+
// CHECK-NEXT: "type": "swiftdoc",
114+
// CHECK-NEXT: "path": "main.swiftdoc"
115+
// CHECK-NEXT: }
116+
// CHECK-NEXT: ],
117+
// CHECK-NEXT: "pid": {{[1-9][0-9]*}}
118+
// CHECK-NEXT: }
119+
// CHECK-NEXT: {{[1-9][0-9]*}}
120+
// CHECK-NEXT: {
121+
// CHECK-NEXT: "kind": "finished",
122+
// CHECK-NEXT: "name": "merge-module",
123+
// CHECK-NEXT: "pid": {{[1-9][0-9]*}},
124+
// CHECK-NEXT: "exit-status": 0
125+
// CHECK-NEXT: }

0 commit comments

Comments
 (0)