[Driver] Load the standard library before starting parallel frontend invocations

Add a new action, LoadModuleJobAction, that the driver can use to schedule a
load of a given module before we fan out and invoke the frontend multiple
times. This gives the module interface loader a chance to compile it from a
module interface before we start with parallel invocations, avoiding starting
potentially dozens of redundant compiles of a large module. Start by using this
on the standard library.

Quick fix for rdar://52839445
This commit is contained in:
Harlan Haskins
2019-07-12 11:59:17 -07:00
parent ca1e808bde
commit 7022110a05
23 changed files with 280 additions and 78 deletions

View File

@@ -52,9 +52,10 @@ public:
GenerateDSYMJob,
VerifyDebugInfoJob,
GeneratePCHJob,
LoadModuleJob,
JobFirst = CompileJob,
JobLast = GeneratePCHJob
JobLast = LoadModuleJob
};
static const char *getClassName(Kind AC);
@@ -338,6 +339,24 @@ public:
}
};
/// An action that will attempt to load a specific module before any other
/// actions.
class LoadModuleJobAction : public JobAction {
virtual void anchor();
std::string moduleName;
public:
LoadModuleJobAction(StringRef moduleName)
: JobAction(Action::Kind::LoadModuleJob, {}, file_types::TY_Nothing),
moduleName(moduleName) {}
StringRef getModuleName() const { return moduleName; }
static bool classof(const Action *A) {
return A->getKind() == Action::Kind::LoadModuleJob;
}
};
} // end namespace driver
} // end namespace swift

View File

@@ -164,6 +164,9 @@ protected:
virtual InvocationInfo constructInvocation(const StaticLinkJobAction &job,
const JobContext &context) const;
virtual InvocationInfo constructInvocation(const LoadModuleJobAction &job,
const JobContext &context) const;
/// Searches for the given executable in appropriate paths relative to the
/// Swift binary.
///

View File

@@ -33,6 +33,7 @@ const char *Action::getClassName(Kind AC) {
case Kind::GenerateDSYMJob: return "generate-dSYM";
case Kind::VerifyDebugInfoJob: return "verify-debug-info";
case Kind::GeneratePCHJob: return "generate-pch";
case Kind::LoadModuleJob: return "load-module";
}
llvm_unreachable("invalid class");
@@ -65,3 +66,5 @@ void GenerateDSYMJobAction::anchor() {}
void VerifyDebugInfoJobAction::anchor() {}
void GeneratePCHJobAction::anchor() {}
void LoadModuleJobAction::anchor() {}

View File

@@ -1731,6 +1731,25 @@ Driver::computeCompilerMode(const DerivedArgList &Args,
return OutputInfo::Mode::SingleCompile;
}
/// Determines whether the given set of inputs has multiple .swift, .sil, or
/// .sib inputs, which will require loading the standard library.
static bool hasMultipleSourceFileInputs(ArrayRef<InputPair> inputs) {
bool hasFoundOneSourceFileAlready = false;
for (const InputPair &input : inputs) {
switch (input.first) {
case file_types::TY_Swift:
case file_types::TY_SIL:
case file_types::TY_SIB:
if (hasFoundOneSourceFileAlready)
return true;
hasFoundOneSourceFileAlready = true;
break;
default: break;
}
}
return false;
}
void Driver::buildActions(SmallVectorImpl<const Action *> &TopLevelActions,
const ToolChain &TC, const OutputInfo &OI,
const InputInfoMap *OutOfDateMap,
@@ -1749,6 +1768,18 @@ void Driver::buildActions(SmallVectorImpl<const Action *> &TopLevelActions,
switch (OI.CompilerMode) {
case OutputInfo::Mode::StandardCompile: {
// If we're not compiling the standard library, and we're going to schedule
// multiple parallel compile jobs, add an action before any others that
// will quickly load the standard library module.
// This will ensure that, if we need to build the standard library from
// a module interface, it happens once, rather than once per parallel
// invocation.
LoadModuleJobAction *preLoadStdlib = nullptr;
if (!Args.hasArg(options::OPT_parse_stdlib) &&
hasMultipleSourceFileInputs(Inputs)) {
preLoadStdlib = C.createAction<LoadModuleJobAction>(STDLIB_NAME);
}
// If the user is importing a textual (.h) bridging header and we're in
// standard-compile (non-WMO) mode, we take the opportunity to precompile
// the header into a temporary PCH, and replace the import argument with the
@@ -1772,6 +1803,15 @@ void Driver::buildActions(SmallVectorImpl<const Action *> &TopLevelActions,
}
}
// Adds the implicit dependencies for this job action, either generating
// a PCH, or pre-loading the standard library, or both.
auto addImplicitDeps = [&](Action *action) {
if (PCH)
cast<JobAction>(action)->addInput(PCH);
if (preLoadStdlib)
cast<JobAction>(action)->addInput(preLoadStdlib);
};
for (const InputPair &Input : Inputs) {
file_types::ID InputType = Input.first;
const Arg *InputArg = Input.second;
@@ -1793,8 +1833,7 @@ void Driver::buildActions(SmallVectorImpl<const Action *> &TopLevelActions,
if (Args.hasArg(options::OPT_embed_bitcode)) {
Current = C.createAction<CompileJobAction>(
Current, file_types::TY_LLVM_BC, previousBuildState);
if (PCH)
cast<JobAction>(Current)->addInput(PCH);
addImplicitDeps(Current);
AllModuleInputs.push_back(Current);
Current = C.createAction<BackendJobAction>(Current,
OI.CompilerOutputType, 0);
@@ -1802,8 +1841,7 @@ void Driver::buildActions(SmallVectorImpl<const Action *> &TopLevelActions,
Current = C.createAction<CompileJobAction>(Current,
OI.CompilerOutputType,
previousBuildState);
if (PCH)
cast<JobAction>(Current)->addInput(PCH);
addImplicitDeps(Current);
AllModuleInputs.push_back(Current);
}
AllLinkerInputs.push_back(Current);

View File

@@ -383,9 +383,14 @@ void Job::printSummary(raw_ostream &os) const {
if (const auto *IA = dyn_cast<InputAction>(A))
Inputs.push_back(IA->getInputArg().getValue());
for (const Job *J : getInputs())
for (const Job *J : getInputs()) {
// Some jobs might produce no output, so don't include them in the
// list of inputs.
if (J->getOutput().getPrimaryOutputType() == file_types::TY_Nothing)
continue;
for (StringRef f : J->getOutput().getPrimaryOutputFilenames())
Inputs.push_back(f);
}
size_t limit = 3;
size_t actual_in = Inputs.size();

View File

@@ -146,13 +146,27 @@ public:
});
}
/// Subclasses can override this to determine if they should print empty
/// arrays for `inputs` and `output`, or if they can omit them.
virtual bool requireInputsAndOutputs() {
return false;
}
void provideMapping(swift::json::Output &out) override {
Message::provideMapping(out);
out.mapRequired("command", CommandLine); // Deprecated, do not document
out.mapRequired("command_executable", Executable);
out.mapRequired("command_arguments", Arguments);
out.mapOptional("inputs", Inputs);
out.mapOptional("outputs", Outputs);
// Some commands can choose to print empty arrays if their inputs and
// outputs are empty.
if (requireInputsAndOutputs()) {
out.mapRequired("inputs", Inputs);
out.mapRequired("outputs", Outputs);
} else {
out.mapOptional("inputs", Inputs);
out.mapOptional("outputs", Outputs);
}
}
};
@@ -177,6 +191,12 @@ public:
: DetailedCommandBasedMessage("began", Cmd), Pid(Pid),
ProcInfo(ProcInfo) {}
bool requireInputsAndOutputs() override {
/// `began` messages should always print inputs and outputs, even if they
/// are empty.
return true;
}
void provideMapping(swift::json::Output &out) override {
DetailedCommandBasedMessage::provideMapping(out);
out.mapRequired("pid", Pid);

View File

@@ -106,6 +106,7 @@ std::unique_ptr<Job> ToolChain::constructJob(
CASE(GeneratePCHJob)
CASE(AutolinkExtractJob)
CASE(REPLJob)
CASE(LoadModuleJob)
#undef CASE
case Action::Kind::Input:
llvm_unreachable("not a JobAction");

View File

@@ -1113,6 +1113,40 @@ ToolChain::constructInvocation(const StaticLinkJobAction &job,
llvm_unreachable("archiving not implemented for this toolchain");
}
ToolChain::InvocationInfo
ToolChain::constructInvocation(const LoadModuleJobAction &job,
const JobContext &context) const {
// Invoke the frontend, passing `-import-module ModuleName` for whatever
// module the job is supposed to load.
InvocationInfo II{SWIFT_EXECUTABLE_NAME};
ArgStringList &Arguments = II.Arguments;
II.allowsResponseFiles = true;
for (auto &s : getDriver().getSwiftProgramArgs())
Arguments.push_back(s.c_str());
Arguments.push_back("-frontend");
Arguments.push_back("-typecheck");
// Force importing the module that this job specifies.
Arguments.push_back("-import-module");
Arguments.push_back(context.Args.MakeArgString(job.getModuleName()));
// Pass along the relevant arguments to the frontend invocation.
addCommonFrontendArgs(*this, context.OI, context.Output, context.Args,
Arguments);
// Create an empty temporary file to typecheck.
auto tempFile = context.getTemporaryFilePath("tmp", "swift");
Arguments.push_back(context.Args.MakeArgString(tempFile));
return II;
}
void ToolChain::addPathEnvironmentVariableIfNeeded(
Job::EnvironmentVector &env, const char *name, const char *separator,
options::ID optionID, const ArgList &args,

View File

@@ -23,6 +23,11 @@ import sys
assert sys.argv[1] == '-frontend'
# If we're handling a frontend action that doesn't produce output or have a
# primary-file, (e.g. a -typecheck action), then don't do anything.
if '-primary-file' not in sys.argv or '-o' not in sys.argv:
sys.exit(0)
primaryFile = sys.argv[sys.argv.index('-primary-file') + 1]
outputFile = sys.argv[sys.argv.index('-o') + 1]

View File

@@ -23,6 +23,11 @@ import sys
assert sys.argv[1] == '-frontend'
# If we're handling a frontend action that doesn't produce output
# (e.g. a -typecheck action), then don't do anything.
if '-o' not in sys.argv:
sys.exit(0)
if '-primary-file' in sys.argv:
primaryFileIndex = sys.argv.index('-primary-file') + 1
primaryFile = sys.argv[primaryFileIndex]

View File

@@ -26,6 +26,11 @@ import sys
assert sys.argv[1] == '-frontend'
# If we don't have a -primary-file, for example if this is a -typecheck job,
# then don't do anything with this script.
if '-primary-file' not in sys.argv:
sys.exit(0)
primaryFile = sys.argv[sys.argv.index('-primary-file') + 1]
if (os.path.basename(primaryFile) == 'bad.swift' or

View File

@@ -35,6 +35,11 @@ import sys
assert sys.argv[1] == '-frontend'
# If we're handling a frontend action that doesn't produce output
# (e.g. a -typecheck action), then don't do anything.
if '-o' not in sys.argv:
sys.exit(0)
# NB: The bitcode options automatically specify a -primary-file, even in cases
# where we do not wish to use a dependencies file in the test.
if '-primary-file' in sys.argv \

View File

@@ -5,21 +5,21 @@
// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -output-file-map %t/output.json 2>&1 | %FileCheck %s -check-prefix=MUST-EXEC-INITIAL
// MUST-EXEC-INITIAL-NOT: warning
// MUST-EXEC-INITIAL: inputs: ["./main.swift"], output: {{[{].*[}]}}, condition: run-without-cascading
// MUST-EXEC-INITIAL: inputs: ["./other.swift"], output: {{[{].*[}]}}, condition: run-without-cascading
// MUST-EXEC-INITIAL: inputs: ["./yet-another.swift"], output: {{[{].*[}]}}, condition: run-without-cascading
// MUST-EXEC-INITIAL: inputs: ["./main.swift", ""], output: {{[{].*[}]}}, condition: run-without-cascading
// MUST-EXEC-INITIAL: inputs: ["./other.swift", ""], output: {{[{].*[}]}}, condition: run-without-cascading
// MUST-EXEC-INITIAL: inputs: ["./yet-another.swift", ""], output: {{[{].*[}]}}, condition: run-without-cascading
// MUST-EXEC-ALL-NOT: warning
// MUST-EXEC-ALL: inputs: ["./main.swift"], output: {{[{].*[}]$}}
// MUST-EXEC-ALL: inputs: ["./other.swift"], output: {{[{].*[}]$}}
// MUST-EXEC-ALL: inputs: ["./yet-another.swift"], output: {{[{].*[}]$}}
// MUST-EXEC-ALL: inputs: ["./main.swift", ""], output: {{[{].*[}]$}}
// MUST-EXEC-ALL: inputs: ["./other.swift", ""], output: {{[{].*[}]$}}
// MUST-EXEC-ALL: inputs: ["./yet-another.swift", ""], output: {{[{].*[}]$}}
// RUN: cd %t && %swiftc_driver -c -module-name main -driver-use-frontend-path "%{python};%S/Inputs/update-dependencies.py" ./main.swift ./other.swift ./yet-another.swift -incremental -output-file-map %t/output.json
// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -output-file-map %t/output.json 2>&1 | %FileCheck %s -check-prefix=NO-EXEC
// NO-EXEC: inputs: ["./main.swift"], output: {{[{].*[}]}}, condition: check-dependencies
// NO-EXEC: inputs: ["./other.swift"], output: {{[{].*[}]}}, condition: check-dependencies
// NO-EXEC: inputs: ["./yet-another.swift"], output: {{[{].*[}]}}, condition: check-dependencies
// NO-EXEC: inputs: ["./main.swift", ""], output: {{[{].*[}]}}, condition: check-dependencies
// NO-EXEC: inputs: ["./other.swift", ""], output: {{[{].*[}]}}, condition: check-dependencies
// NO-EXEC: inputs: ["./yet-another.swift", ""], output: {{[{].*[}]}}, condition: check-dependencies
// RUN: cd %t && %swiftc_driver -c -module-name main -driver-print-bindings -serialize-diagnostics ./main.swift ./other.swift ./yet-another.swift -incremental -output-file-map %t/output.json 2>&1 | %FileCheck %s -check-prefix=NO-EXEC

View File

@@ -6,41 +6,41 @@
// RUN: cd %t && %swiftc_driver -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -output-file-map %t/output.json 2>&1 | %FileCheck %s -check-prefix=MUST-EXEC
// MUST-EXEC-NOT: warning
// MUST-EXEC: inputs: ["./main.swift"], output: {{[{].*[}]}}, condition: run-without-cascading
// MUST-EXEC: inputs: ["./other.swift"], output: {{[{].*[}]}}, condition: run-without-cascading
// MUST-EXEC: inputs: ["./yet-another.swift"], output: {{[{].*[}]}}, condition: run-without-cascading
// MUST-EXEC: inputs: ["./main.swift", ""], output: {{[{].*[}]}}, condition: run-without-cascading
// MUST-EXEC: inputs: ["./other.swift", ""], output: {{[{].*[}]}}, condition: run-without-cascading
// MUST-EXEC: inputs: ["./yet-another.swift", ""], output: {{[{].*[}]}}, condition: run-without-cascading
// RUN: echo '{version: "'$(%swiftc_driver_plain -version | head -n1)'", inputs: {"./main.swift": [443865900, 0], "./other.swift": [443865900, 0], "./yet-another.swift": [443865900, 0]}, build_time: [443865901, 0]}' > %t/main~buildrecord.swiftdeps
// RUN: cd %t && %swiftc_driver -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -output-file-map %t/output.json 2>&1 | %FileCheck %s -check-prefix=NO-EXEC
// NO-EXEC: inputs: ["./main.swift"], output: {{[{].*[}]}}, condition: check-dependencies
// NO-EXEC: inputs: ["./other.swift"], output: {{[{].*[}]}}, condition: check-dependencies
// NO-EXEC: inputs: ["./yet-another.swift"], output: {{[{].*[}]}}, condition: check-dependencies
// NO-EXEC: inputs: ["./main.swift", ""], output: {{[{].*[}]}}, condition: check-dependencies
// NO-EXEC: inputs: ["./other.swift", ""], output: {{[{].*[}]}}, condition: check-dependencies
// NO-EXEC: inputs: ["./yet-another.swift", ""], output: {{[{].*[}]}}, condition: check-dependencies
// RUN: echo '{version: "'$(%swiftc_driver_plain -version | head -n1)'", inputs: {"./main.swift": [443865900, 0], "./other.swift": !private [443865900, 0], "./yet-another.swift": !dirty [443865900, 0]}, build_time: [443865901, 0]}' > %t/main~buildrecord.swiftdeps
// RUN: cd %t && %swiftc_driver -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -output-file-map %t/output.json 2>&1 | %FileCheck %s -check-prefix=BUILD-RECORD
// BUILD-RECORD: inputs: ["./main.swift"], output: {{[{].*[}]}}, condition: check-dependencies{{$}}
// BUILD-RECORD: inputs: ["./other.swift"], output: {{[{].*[}]}}, condition: run-without-cascading{{$}}
// BUILD-RECORD: inputs: ["./yet-another.swift"], output: {{[{].*[}]$}}
// BUILD-RECORD: inputs: ["./main.swift", ""], output: {{[{].*[}]}}, condition: check-dependencies{{$}}
// BUILD-RECORD: inputs: ["./other.swift", ""], output: {{[{].*[}]}}, condition: run-without-cascading{{$}}
// BUILD-RECORD: inputs: ["./yet-another.swift", ""], output: {{[{].*[}]$}}
// RUN: cd %t && %swiftc_driver -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift ./added.swift -incremental -output-file-map %t/output.json 2>&1 > %t/added.txt
// RUN: %FileCheck %s -check-prefix=BUILD-RECORD < %t/added.txt
// RUN: %FileCheck %s -check-prefix=FILE-ADDED < %t/added.txt
// FILE-ADDED: inputs: ["./added.swift"], output: {{[{].*[}]}}, condition: newly-added{{$}}
// FILE-ADDED: inputs: ["./added.swift", ""], output: {{[{].*[}]}}, condition: newly-added{{$}}
// RUN: %{python} %S/Inputs/touch.py 443865960 %t/main.swift
// RUN: cd %t && %swiftc_driver -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -output-file-map %t/output.json 2>&1 | %FileCheck %s -check-prefix=BUILD-RECORD-PLUS-CHANGE
// BUILD-RECORD-PLUS-CHANGE: inputs: ["./main.swift"], output: {{[{].*[}]}}, condition: run-without-cascading
// BUILD-RECORD-PLUS-CHANGE: inputs: ["./other.swift"], output: {{[{].*[}]}}, condition: run-without-cascading{{$}}
// BUILD-RECORD-PLUS-CHANGE: inputs: ["./yet-another.swift"], output: {{[{].*[}]$}}
// BUILD-RECORD-PLUS-CHANGE: inputs: ["./main.swift", ""], output: {{[{].*[}]}}, condition: run-without-cascading
// BUILD-RECORD-PLUS-CHANGE: inputs: ["./other.swift", ""], output: {{[{].*[}]}}, condition: run-without-cascading{{$}}
// BUILD-RECORD-PLUS-CHANGE: inputs: ["./yet-another.swift", ""], output: {{[{].*[}]$}}
// RUN: %{python} %S/Inputs/touch.py 443865900 %t/*
// RUN: cd %t && %swiftc_driver -driver-print-bindings ./main.swift ./other.swift -incremental -output-file-map %t/output.json 2>&1 | %FileCheck %s -check-prefix=FILE-REMOVED
// FILE-REMOVED: inputs: ["./main.swift"], output: {{[{].*[}]$}}
// FILE-REMOVED: inputs: ["./other.swift"], output: {{[{].*[}]$}}
// FILE-REMOVED: inputs: ["./main.swift", ""], output: {{[{].*[}]$}}
// FILE-REMOVED: inputs: ["./other.swift", ""], output: {{[{].*[}]$}}
// FILE-REMOVED-NOT: yet-another.swift
@@ -48,6 +48,6 @@
// RUN: cd %t && %swiftc_driver -driver-print-bindings ./main.swift ./other.swift ./yet-another.swift -incremental -output-file-map %t/output.json 2>&1 | %FileCheck %s -check-prefix=INVALID-RECORD
// INVALID-RECORD-NOT: warning
// INVALID-RECORD: inputs: ["./main.swift"], output: {{[{].*[}]$}}
// INVALID-RECORD: inputs: ["./other.swift"], output: {{[{].*[}]$}}
// INVALID-RECORD: inputs: ["./yet-another.swift"], output: {{[{].*[}]$}}
// INVALID-RECORD: inputs: ["./main.swift", ""], output: {{[{].*[}]$}}
// INVALID-RECORD: inputs: ["./other.swift", ""], output: {{[{].*[}]$}}
// INVALID-RECORD: inputs: ["./yet-another.swift", ""], output: {{[{].*[}]$}}

View File

@@ -8,7 +8,7 @@
// CHECK-FIRST: Queuing (initial): {compile: main.o <= main.swift}
// RUN: cd %t && %swiftc_driver -c -driver-use-frontend-path "%{python};%S/Inputs/update-dependencies.py" -output-file-map %t/output.json -incremental -driver-always-rebuild-dependents ./main.swift ./other.swift -module-name main -j1 -v -driver-show-incremental 2>&1 | %FileCheck -check-prefix=CHECK-SECOND %s
// CHECK-SECOND-NOT: Queuing
// CHECK-SECOND-NOT: Queuing (initial): {compile
// RUN: touch -t 201401240006 %t/other.swift
// RUN: cd %t && %swiftc_driver -c -driver-use-frontend-path "%{python};%S/Inputs/update-dependencies.py" -output-file-map %t/output.json -incremental -driver-always-rebuild-dependents ./main.swift ./other.swift -module-name main -j1 -v -driver-show-incremental 2>&1 | %FileCheck -check-prefix=CHECK-THIRD %s

View File

@@ -7,6 +7,17 @@
// RUN: cd %t && %swiftc_driver -c -driver-use-frontend-path "%{python};%S/Inputs/fake-build-for-bitcode.py" -output-file-map %t/output.json -incremental ./main.swift ./other.swift -embed-bitcode -module-name main -j1 -parseable-output 2>&1 | %FileCheck -check-prefix=CHECK-FIRST %s
// CHECK-FIRST-NOT: warning
// CHECK-FIRST: {{^{$}}
// CHECK-FIRST: "kind": "began"
// CHECK-FIRST: "name": "load-module"
// CHECK-FIRST: {{^}$}}
// CHECK-FIRST: {{^{$}}
// CHECK-FIRST: "kind": "finished"
// CHECK-FIRST: "name": "load-module"
// CHECK-FIRST: {{^}$}}
// CHECK-FIRST: {{^{$}}
// CHECK-FIRST: "kind": "began"
// CHECK-FIRST: "name": "compile"
@@ -59,6 +70,10 @@
// RUN: touch -t 201401240006 %t/other.swift
// RUN: cd %t && %swiftc_driver -c -driver-use-frontend-path "%{python};%S/Inputs/fake-build-for-bitcode.py" -output-file-map %t/output.json -incremental ./main.swift ./other.swift -embed-bitcode -module-name main -j2 -parseable-output 2>&1 | %FileCheck -check-prefix=CHECK-SECOND %s
// CHECK-SECOND: "kind": "began"
// CHECK-SECOND: "name": "load-module"
// CHECK-SECOND: {{^}$}}
// CHECK-SECOND: "kind": "began"
// CHECK-SECOND: "name": "compile"
// CHECK-SECOND: ".\/main.swift"

View File

@@ -26,6 +26,11 @@ else:
if primaryFile and primaryFile.endswith(".bc"):
sys.exit()
# If we're handling a frontend action that doesn't produce have a
# filelist, (e.g. a -typecheck action), then don't do anything.
if '-filelist' not in sys.argv:
sys.exit(0)
filelistFile = sys.argv[sys.argv.index('-filelist') + 1]
with open(filelistFile, 'r') as f:

View File

@@ -61,15 +61,16 @@
// RUN: %swiftc_driver -driver-print-actions -target x86_64-apple-macosx10.9 -g -gnone -emit-executable -emit-module %s 2>&1 | %FileCheck %s -check-prefix=EXEC-AND-MODULE
// RUN: %swiftc_driver -driver-print-actions -target x86_64-apple-macosx10.9 -g %S/Inputs/main.swift %S/../Inputs/empty.swift %s -module-name actions 2>&1 | %FileCheck %s -check-prefix=DEBUG-MULTI
// DEBUG-MULTI: 0: input, "{{.*}}Inputs/main.swift", swift
// DEBUG-MULTI: 1: compile, {0}, object
// DEBUG-MULTI: 2: input, "{{.*}}Inputs/empty.swift", swift
// DEBUG-MULTI: 3: compile, {2}, object
// DEBUG-MULTI: 4: input, "{{.*}}actions-dsym.swift", swift
// DEBUG-MULTI: 5: compile, {4}, object
// DEBUG-MULTI: 6: merge-module, {1, 3, 5}, swiftmodule
// DEBUG-MULTI: 7: link, {1, 3, 5, 6}, image
// DEBUG-MULTI: 8: generate-dSYM, {7}, dSYM
// DEBUG-MULTI: 0: load-module, {}
// DEBUG-MULTI: 1: input, "{{.*}}Inputs/main.swift", swift
// DEBUG-MULTI: 2: compile, {1, 0}, object
// DEBUG-MULTI: 3: input, "{{.*}}Inputs/empty.swift", swift
// DEBUG-MULTI: 4: compile, {3, 0}, object
// DEBUG-MULTI: 5: input, "{{.*}}actions-dsym.swift", swift
// DEBUG-MULTI: 6: compile, {5, 0}, object
// DEBUG-MULTI: 7: merge-module, {2, 4, 6}, swiftmodule
// DEBUG-MULTI: 8: link, {2, 4, 6, 7}, image
// DEBUG-MULTI: 9: generate-dSYM, {8}, dSYM
// RUN: touch %t/a.o %t/b.o

View File

@@ -108,30 +108,31 @@
// RUN: %swiftc_driver -driver-print-actions -g -gnone -emit-executable -emit-module %s 2>&1 | %FileCheck %s -check-prefix=EXEC-AND-MODULE
// RUN: %swiftc_driver -driver-print-actions %S/Inputs/main.swift %S/../Inputs/empty.swift %s -module-name actions 2>&1 | %FileCheck %s -check-prefix=MULTI -check-prefix MULTI-%target-object-format
// MULTI: 0: input, "{{.*}}Inputs/main.swift", swift
// MULTI: 1: compile, {0}, object
// MULTI: 2: input, "{{.*}}Inputs/empty.swift", swift
// MULTI: 3: compile, {2}, object
// MULTI: 4: input, "{{.*}}actions.swift", swift
// MULTI: 5: compile, {4}, object
// MULTI-COFF: 6: link, {1, 3, 5}, image
// MULTI-ELF: 6: swift-autolink-extract, {1, 3, 5}, autolink
// MULTI-ELF: 7: link, {1, 3, 5, 6}, image
// MULTI-MACHO: 6: link, {1, 3, 5}, image
// MULTI: 0: load-module, {}
// MULTI: 1: input, "{{.*}}Inputs/main.swift", swift
// MULTI: 2: compile, {1, 0}, object
// MULTI: 3: input, "{{.*}}Inputs/empty.swift", swift
// MULTI: 4: compile, {3, 0}, object
// MULTI: 5: input, "{{.*}}actions.swift", swift
// MULTI: 6: compile, {5, 0}, object
// MULTI-COFF: 7: link, {2, 4, 6}, image
// MULTI-ELF: 7: swift-autolink-extract, {2, 4, 6}, autolink
// MULTI-ELF: 8: link, {2, 4, 6, 7}, image
// MULTI-MACHO: 7: link, {2, 4, 6}, image
// RUN: %swiftc_driver -driver-print-actions -g %S/Inputs/main.swift %S/../Inputs/empty.swift %s -module-name actions 2>&1 | %FileCheck %s -check-prefix=DEBUG-MULTI -check-prefix DEBUG-MULTI-%target-object-format
// DEBUG-MULTI: 0: input, "{{.*}}Inputs/main.swift", swift
// DEBUG-MULTI: 1: compile, {0}, object
// DEBUG-MULTI: 2: input, "{{.*}}Inputs/empty.swift", swift
// DEBUG-MULTI: 3: compile, {2}, object
// DEBUG-MULTI: 4: input, "{{.*}}actions.swift", swift
// DEBUG-MULTI: 5: compile, {4}, object
// DEBUG-MULTI: 6: merge-module, {1, 3, 5}, swiftmodule
// DEBUG-MULTI-COFF: 7: modulewrap, {6}, object
// DEBUG-MULTI-COFF: 8: link, {1, 3, 5, 7}, image
// DEBUG-MULTI-ELF: 7: modulewrap, {6}, object
// DEBUG-MULTI-ELF: 8: link, {1, 3, 5, 7}, image
// DEBUG-MULTI-MACHO: 7: link, {1, 3, 5, 6}, image
// DEBUG-MULTI: 1: input, "{{.*}}Inputs/main.swift", swift
// DEBUG-MULTI: 2: compile, {1, 0}, object
// DEBUG-MULTI: 3: input, "{{.*}}Inputs/empty.swift", swift
// DEBUG-MULTI: 4: compile, {3, 0}, object
// DEBUG-MULTI: 5: input, "{{.*}}actions.swift", swift
// DEBUG-MULTI: 6: compile, {5, 0}, object
// DEBUG-MULTI: 7: merge-module, {2, 4, 6}, swiftmodule
// DEBUG-MULTI-COFF: 8: modulewrap, {7}, object
// DEBUG-MULTI-COFF: 9: link, {2, 4, 6, 8}, image
// DEBUG-MULTI-ELF: 8: modulewrap, {7}, object
// DEBUG-MULTI-ELF: 9: link, {2, 4, 6, 8}, image
// DEBUG-MULTI-MACHO: 8: link, {2, 4, 6, 7}, image
// RUN: touch %t/a.o %t/b.o

View File

@@ -19,9 +19,9 @@
// DUMPOFM-NEXT: {{.*}}/advanced_output_file_map.swift -> swiftdoc: "/build/swiftmodule/advanced_output_file_map_x.swiftdoc"
// DUMPOFM-NEXT: {{.*}}/advanced_output_file_map.swift -> diagnostics: "/build/dia/advanced_output_file_map.dia"
// BINDINGS: # "x86_64-apple-macosx10.9" - "swift{{c?(\.EXE)?}}", inputs: ["{{.*}}/advanced_output_file_map.swift"], output: {object: "/build/obj/advanced_output_file_map.o", dependencies: "/build/d/advanced_output_file_map.d", swiftmodule: "/build/swiftmodule/advanced_output_file_map.swiftmodule", swiftdoc: "/build/swiftmodule/advanced_output_file_map_x.swiftdoc", diagnostics: "/build/dia/advanced_output_file_map.dia"}
// BINDINGS: # "x86_64-apple-macosx10.9" - "swift{{c?(\.EXE)?}}", inputs: ["{{.*}}/Inputs/main.swift"], output: {object: "/build/obj/main.o", dependencies: "/build/d/main.d", swiftmodule: "/build/swiftmodule/main.swiftmodule", swiftdoc: "/build/swiftmodule/main_x.swiftdoc", diagnostics: "/build/dia/main.dia"}
// BINDINGS: # "x86_64-apple-macosx10.9" - "swift{{c?(\.EXE)?}}", inputs: ["{{.*}}/Inputs/lib.swift"], output: {object: "/build/obj/lib.o", dependencies: "/build/d/lib.d", swiftmodule: "/build/swiftmodule/lib.swiftmodule", swiftdoc: "/build/swiftmodule/lib_x.swiftdoc", diagnostics: "/build/dia/lib.dia"}
// BINDINGS: # "x86_64-apple-macosx10.9" - "swift{{c?(\.EXE)?}}", inputs: ["{{.*}}/advanced_output_file_map.swift", ""], output: {object: "/build/obj/advanced_output_file_map.o", dependencies: "/build/d/advanced_output_file_map.d", swiftmodule: "/build/swiftmodule/advanced_output_file_map.swiftmodule", swiftdoc: "/build/swiftmodule/advanced_output_file_map_x.swiftdoc", diagnostics: "/build/dia/advanced_output_file_map.dia"}
// BINDINGS: # "x86_64-apple-macosx10.9" - "swift{{c?(\.EXE)?}}", inputs: ["{{.*}}/Inputs/main.swift", ""], output: {object: "/build/obj/main.o", dependencies: "/build/d/main.d", swiftmodule: "/build/swiftmodule/main.swiftmodule", swiftdoc: "/build/swiftmodule/main_x.swiftdoc", diagnostics: "/build/dia/main.dia"}
// BINDINGS: # "x86_64-apple-macosx10.9" - "swift{{c?(\.EXE)?}}", inputs: ["{{.*}}/Inputs/lib.swift", ""], output: {object: "/build/obj/lib.o", dependencies: "/build/d/lib.d", swiftmodule: "/build/swiftmodule/lib.swiftmodule", swiftdoc: "/build/swiftmodule/lib_x.swiftdoc", diagnostics: "/build/dia/lib.dia"}
// BINDINGS: # "x86_64-apple-macosx10.9" - "swift{{c?(\.EXE)?}}", inputs: ["/build/obj/advanced_output_file_map.o", "/build/obj/main.o", "/build/obj/lib.o"], output: {swiftmodule: "/build/OutputFileMap.swiftmodule", swiftdoc: "/build/OutputFileMap.swiftdoc"}
// BINDINGS: # "x86_64-apple-macosx10.9" - "ld{{(.exe)?}}", inputs: ["/build/obj/advanced_output_file_map.o", "/build/obj/main.o", "/build/obj/lib.o", "/build/OutputFileMap.swiftmodule"], output: {image: "/build/advanced_output_file_map.out"}
// BINDINGS: # "x86_64-apple-macosx10.9" - "dsymutil{{(\.exe)?}}", inputs: ["/build/advanced_output_file_map.out"], output: {dSYM: "/build/advanced_output_file_map.out.dSYM"}

View File

@@ -7,7 +7,7 @@
// DUMPOFM: {{.*}}/Inputs/main.swift -> object: "/build/main.o"
// DUMPOFM: {{.*}}/basic_output_file_map.swift -> object: "/build/basic_output_file_map.o"
// BINDINGS: # "x86_64-apple-macosx10.9" - "swift{{c?(\.EXE)?}}", inputs: ["{{.*}}/basic_output_file_map.swift"], output: {object: "/build/basic_output_file_map.o"}
// BINDINGS: # "x86_64-apple-macosx10.9" - "swift{{c?(\.EXE)?}}", inputs: ["{{.*}}/Inputs/main.swift"], output: {object: "/build/main.o"}
// BINDINGS: # "x86_64-apple-macosx10.9" - "swift{{c?(\.EXE)?}}", inputs: ["{{.*}}/Inputs/lib.swift"], output: {object: "/build/lib.o"}
// BINDINGS: # "x86_64-apple-macosx10.9" - "swift{{c?(\.EXE)?}}", inputs: ["{{.*}}/basic_output_file_map.swift", ""], output: {object: "/build/basic_output_file_map.o"}
// BINDINGS: # "x86_64-apple-macosx10.9" - "swift{{c?(\.EXE)?}}", inputs: ["{{.*}}/Inputs/main.swift", ""], output: {object: "/build/main.o"}
// BINDINGS: # "x86_64-apple-macosx10.9" - "swift{{c?(\.EXE)?}}", inputs: ["{{.*}}/Inputs/lib.swift", ""], output: {object: "/build/lib.o"}
// BINDINGS: # "x86_64-apple-macosx10.9" - "ld{{(\.exe)?}}", inputs: ["/build/basic_output_file_map.o", "/build/main.o", "/build/lib.o"], output: {image: "/build/basic_output_file_map.out"}

View File

@@ -5,6 +5,39 @@
// RUN: %swiftc_driver -enable-batch-mode -parseable-output -driver-skip-execution -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": "load-module",
// CHECK-NEXT: "command": "{{.*[\\/]}}swift{{c?(\.EXE)?(\\")?}} -frontend -typecheck -import-module Swift {{.*}}tmp{{.*}}.swift",
// CHECK-NEXT: "command_executable": "{{.*[\\/]}}swift{{c?(\.EXE)?(\\")?}}",
// CHECK-NEXT: "command_arguments": [
// CHECK-NEXT: "-frontend",
// CHECK-NEXT: "-typecheck",
// CHECK-NEXT: "-import-module",
// CHECK-NEXT: "Swift",
// CHECK: "{{.*}}tmp{{.*}}.swift"
// CHECK-NEXT: ],
// CHECK-NEXT: "inputs": [],
// CHECK-NEXT: "outputs": [],
// CHECK-NEXT: "pid": {{[1-9][0-9]*}},
// CHECK-NEXT: "process": {
// CHECK-NEXT: "real_pid": {{[1-9][0-9]*}}
// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK: {{[1-9][0-9]*}}
// CHECK-NEXT: {
// CHECK-NEXT: "kind": "finished",
// CHECK-NEXT: "name": "load-module",
// CHECK-NEXT: "pid": {{[1-9][0-9]*}},
// CHECK-NEXT: "output": "Output placeholder\n",
// CHECK-NEXT: "process": {
// CHECK-NEXT: "real_pid": {{[1-9][0-9]*}}
// CHECK-NEXT: },
// CHECK-NEXT: "exit-status": 0
// CHECK-NEXT: }
// CHECK: {{[1-9][0-9]*}}
// CHECK-NEXT: {
// CHECK-NEXT: "kind": "began",
@@ -29,7 +62,8 @@
// CHECK-NEXT: "{{.*[\\/]}}file-01-[[OBJ01:[a-z0-9]+]].o"
// CHECK-NEXT: ],
// CHECK-NEXT: "inputs": [
// CHECK-NEXT: "{{.*[\\/]}}file-01.swift"
// CHECK-NEXT: "{{.*[\\/]}}file-01.swift",
// CHECK-NEXT: ""
// CHECK-NEXT: ],
// CHECK-NEXT: "outputs": [
// CHECK-NEXT: {
@@ -74,7 +108,8 @@
// CHECK-NEXT: "{{.*[\\/]}}file-02-[[OBJ02:[a-z0-9]+]].o"
// CHECK-NEXT: ],
// CHECK-NEXT: "inputs": [
// CHECK-NEXT: "{{.*[\\/]}}file-02.swift"
// CHECK-NEXT: "{{.*[\\/]}}file-02.swift",
// CHECK-NEXT: ""
// CHECK-NEXT: ],
// CHECK-NEXT: "outputs": [
// CHECK-NEXT: {
@@ -119,7 +154,8 @@
// CHECK-NEXT: "{{.*[\\/]}}file-03-[[OBJ03:[a-z0-9]+]].o"
// CHECK-NEXT: ],
// CHECK-NEXT: "inputs": [
// CHECK-NEXT: "{{.*[\\/]}}file-03.swift"
// CHECK-NEXT: "{{.*[\\/]}}file-03.swift",
// CHECK-NEXT: ""
// CHECK-NEXT: ],
// CHECK-NEXT: "outputs": [
// CHECK-NEXT: {
@@ -164,7 +200,8 @@
// CHECK-NEXT: "{{.*[\\/]}}main-[[OBJMAIN:[a-z0-9]+]].o"
// CHECK-NEXT: ],
// CHECK-NEXT: "inputs": [
// CHECK-NEXT: "{{.*[\\/]}}main.swift"
// CHECK-NEXT: "{{.*[\\/]}}main.swift",
// CHECK-NEXT: ""
// CHECK-NEXT: ],
// CHECK-NEXT: "outputs": [
// CHECK-NEXT: {

View File

@@ -58,7 +58,7 @@
// PERSISTENT-YESPCHJOB-DIAG2: {{.*}}swift{{c?(\.EXE)?"?}} -frontend {{.*}} -serialize-diagnostics-path {{.*}}/pch-out-dir{{/|\\\\}}bridging-header-{{.*}}.dia{{"?}} {{.*}} -emit-pch -pch-output-dir {{.*}}/pch-out-dir
// RUN: %target-build-swift -typecheck -import-objc-header %S/Inputs/bridging-header.h -pch-output-dir %t/pch -parseable-output -driver-skip-execution %s 2>&1 | %FileCheck %s -check-prefix=PERSISTENT-OUTPUT
// PERSISTENT-OUTPUT-NOT: "outputs": [
// PERSISTENT-OUTPUT-NOT: "outputs": [{{$}}
// RUN: %target-build-swift -typecheck -driver-print-jobs -import-objc-header %S/Inputs/bridging-header.h -pch-output-dir %t/pch -whole-module-optimization %s 2>&1 | %FileCheck %s -check-prefix=PERSISTENT-WMO-YESPCHJOB --implicit-check-not pch-disable-validation
// PERSISTENT-WMO-YESPCHJOB: {{.*}}swift{{c?(\.EXE)?"?}} -frontend {{.*}} -import-objc-header {{.*}}bridging-header.h{{"?}} -pch-output-dir {{.*}}/pch