Skip to content

Add Real Enable/Disable Flags for Cross-Module Incremental Builds #36111

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 4 commits into from
Mar 3, 2021
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
2 changes: 1 addition & 1 deletion include/swift/Frontend/FrontendOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ class FrontendOptions {
///
/// This flag is currently only propagated from the driver to
/// any merge-modules jobs.
bool EnableExperimentalCrossModuleIncrementalBuild = false;
bool DisableCrossModuleIncrementalBuild = false;

/// Best effort to output a .swiftmodule regardless of any compilation
/// errors. SIL generation and serialization is skipped entirely when there
Expand Down
12 changes: 12 additions & 0 deletions include/swift/Option/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -1111,6 +1111,18 @@ def emit_supported_features : Flag<["-"], "emit-supported-features">,
HelpText<"Emit a JSON file including all supported compiler features">, ModeOpt,
Flags<[FrontendOption, NoInteractiveOption, DoesNotAffectIncrementalBuild]>;

def enable_incremental_imports :
Flag<["-"], "enable-incremental-imports">,
Flags<[FrontendOption]>,
HelpText<"Enable cross-module incremental build metadata and "
"driver scheduling for Swift modules">;

def disable_incremental_imports :
Flag<["-"], "disable-incremental-imports">,
Flags<[FrontendOption]>,
HelpText<"Disable cross-module incremental build metadata and "
"driver scheduling for Swift modules">;

def index_file : Flag<["-"], "index-file">,
HelpText<"Produce index data for a source file">, ModeOpt,
Flags<[NoInteractiveOption, DoesNotAffectIncrementalBuild]>;
Expand Down
2 changes: 1 addition & 1 deletion include/swift/Serialization/SerializationOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ namespace swift {
bool SerializeAllSIL = false;
bool SerializeOptionsForDebugging = false;
bool IsSIB = false;
bool ExperimentalCrossModuleIncrementalInfo = false;
bool DisableCrossModuleIncrementalInfo = false;
};

} // end namespace swift
Expand Down
5 changes: 3 additions & 2 deletions lib/Driver/Driver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1008,8 +1008,9 @@ Driver::buildCompilation(const ToolChain &TC,
const bool EmitFineGrainedDependencyDotFileAfterEveryImport = ArgList->hasArg(
options::
OPT_driver_emit_fine_grained_dependency_dot_file_after_every_import);
const bool EnableCrossModuleDependencies = ArgList->hasArg(
options::OPT_enable_experimental_cross_module_incremental_build);
const bool EnableCrossModuleDependencies
= ArgList->hasArg(options::OPT_enable_incremental_imports,
options::OPT_disable_incremental_imports, true);

// clang-format off
C = std::make_unique<Compilation>(
Expand Down
4 changes: 1 addition & 3 deletions lib/Driver/ToolChains.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1050,9 +1050,7 @@ ToolChain::constructInvocation(const MergeModuleJobAction &job,

context.Args.AddLastArg(Arguments, options::OPT_import_objc_header);

context.Args.AddLastArg(
Arguments,
options::OPT_enable_experimental_cross_module_incremental_build);
context.Args.AddLastArg(Arguments, options::OPT_disable_incremental_imports);

Arguments.push_back("-module-name");
Arguments.push_back(context.Args.MakeArgString(context.OI.ModuleName));
Expand Down
4 changes: 2 additions & 2 deletions lib/Frontend/ArgsToFrontendOptionsConverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,8 +103,8 @@ bool ArgsToFrontendOptionsConverter::convert(

Opts.ImportPrescan |= Args.hasArg(OPT_import_prescan);

Opts.EnableExperimentalCrossModuleIncrementalBuild |=
Args.hasArg(OPT_enable_experimental_cross_module_incremental_build);
Opts.DisableCrossModuleIncrementalBuild |=
Args.hasArg(OPT_disable_incremental_imports);

// Always track system dependencies when scanning dependencies.
if (const Arg *ModeArg = Args.getLastArg(OPT_modes_Group)) {
Expand Down
4 changes: 2 additions & 2 deletions lib/Frontend/Frontend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,8 @@ SerializationOptions CompilerInvocation::computeSerializationOptions(
opts.SerializeOptionsForDebugging.getValueOr(
!isModuleExternallyConsumed(module));

serializationOpts.ExperimentalCrossModuleIncrementalInfo =
opts.EnableExperimentalCrossModuleIncrementalBuild;
serializationOpts.DisableCrossModuleIncrementalInfo =
opts.DisableCrossModuleIncrementalBuild;

return serializationOpts;
}
Expand Down
11 changes: 7 additions & 4 deletions lib/Frontend/ModuleInterfaceBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,10 +79,13 @@ bool ModuleInterfaceBuilder::collectDepsForSerialization(
path::native(ResourcePath);

auto DTDeps = SubInstance.getDependencyTracker()->getDependencies();
SmallVector<StringRef, 16> InitialDepNames(DTDeps.begin(), DTDeps.end());
InitialDepNames.push_back(interfacePath);
InitialDepNames.insert(InitialDepNames.end(),
extraDependencies.begin(), extraDependencies.end());
SmallVector<std::string, 16> InitialDepNames(DTDeps.begin(), DTDeps.end());
auto IncDeps = SubInstance.getDependencyTracker()->getIncrementalDependencyPaths();
InitialDepNames.append(IncDeps.begin(), IncDeps.end());
InitialDepNames.push_back(interfacePath.str());
for (const auto &extra : extraDependencies) {
InitialDepNames.push_back(extra.str());
}
SmallString<128> Scratch;

for (const auto &InitialDepName : InitialDepNames) {
Expand Down
6 changes: 5 additions & 1 deletion lib/FrontendTool/FrontendTool.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1536,7 +1536,11 @@ static bool performCompileStepsPostSILGen(CompilerInstance &Instance,

SerializationOptions serializationOpts =
Invocation.computeSerializationOptions(outs, Instance.getMainModule());
if (serializationOpts.ExperimentalCrossModuleIncrementalInfo) {

const bool canEmitIncrementalInfoIntoModule =
!serializationOpts.DisableCrossModuleIncrementalInfo &&
(Action == FrontendOptions::ActionType::MergeModules);
if (canEmitIncrementalInfoIntoModule) {
const auto alsoEmitDotFile =
Instance.getInvocation()
.getLangOptions()
Expand Down
6 changes: 5 additions & 1 deletion lib/FrontendTool/LoadedModuleTrace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,11 @@ static void computeSwiftModuleTraceInfo(
path::replace_extension(modPath, swiftInterfaceExt);
};

for (auto &depPath : depTracker.getDependencies()) {
auto deps = depTracker.getDependencies();
SmallVector<std::string, 16> dependencies{deps.begin(), deps.end()};
auto incrDeps = depTracker.getIncrementalDependencyPaths();
dependencies.append(incrDeps.begin(), incrDeps.end());
for (const auto &depPath : dependencies) {

// Decide if this is a swiftmodule based on the extension of the raw
// dependency path, as the true file may have a different one.
Expand Down
2 changes: 1 addition & 1 deletion lib/Serialization/Serialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5482,7 +5482,7 @@ void Serializer::writeToStream(
S.writeInputBlock(options);
S.writeSIL(SILMod, options.SerializeAllSIL);
S.writeAST(DC);
if (options.ExperimentalCrossModuleIncrementalInfo && DepGraph) {
if (!options.DisableCrossModuleIncrementalInfo && DepGraph) {
fine_grained_dependencies::writeFineGrainedDependencyGraph(
S.Out, *DepGraph, fine_grained_dependencies::Purpose::ForSwiftModule);
}
Expand Down
4 changes: 2 additions & 2 deletions test/Driver/cross_module.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// RUN: %empty-directory(%t/sub)
// RUN: echo "{\"\": {\"swift-dependencies\": \"cross_module.swiftdeps\"}}" > %t/ofm.json
// RUN: %swiftc_driver -incremental -emit-module -module-name cross_module -output-file-map=%/t/ofm.json -driver-print-jobs -target x86_64-apple-macosx10.9 %s -enable-experimental-cross-module-incremental-build 2>^1 | %FileCheck -check-prefix ENABLE %s
// RUN: %swiftc_driver -incremental -emit-module -module-name cross_module -output-file-map=%/t/ofm.json -driver-print-jobs -target x86_64-apple-macosx10.9 %s -disable-incremental-imports 2>^1 | %FileCheck -check-prefix ENABLE %s

// ENABLE: {{bin(/|\\\\)swift(-frontend|c)?(\.exe)?"?}} -frontend -merge-modules
// ENABLE-SAME: -enable-experimental-cross-module-incremental-build
// ENABLE-SAME: -disable-incremental-imports
18 changes: 9 additions & 9 deletions test/Incremental/CrossModule/external-cascade.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@
// Set up a clean incremental build of all three modules
//

// RUN: cd %t && %target-swiftc_driver -c -incremental -emit-dependencies -emit-module -emit-module-path %t/C.swiftmodule -enable-experimental-cross-module-incremental-build -module-name C -I %t -output-file-map %t/C.json -working-directory %t -import-objc-header %t/bridging-header.h -Xfrontend -validate-tbd-against-ir=none -driver-show-incremental -driver-show-job-lifecycle C.swift
// RUN: cd %t && %target-swiftc_driver -c -incremental -emit-dependencies -emit-module -emit-module-path %t/B.swiftmodule -enable-experimental-cross-module-incremental-build -module-name B -I %t -output-file-map %t/B.json -working-directory %t -driver-show-incremental -driver-show-job-lifecycle B.swift
// RUN: cd %t && %target-swiftc_driver -c -incremental -emit-dependencies -emit-module -emit-module-path %t/A.swiftmodule -enable-experimental-cross-module-incremental-build -module-name A -I %t -output-file-map %t/A.json -working-directory %t -driver-show-incremental -driver-show-job-lifecycle A.swift
// RUN: cd %t && %target-swiftc_driver -c -incremental -emit-dependencies -emit-module -emit-module-path %t/C.swiftmodule -module-name C -I %t -output-file-map %t/C.json -working-directory %t -import-objc-header %t/bridging-header.h -Xfrontend -validate-tbd-against-ir=none -driver-show-incremental -driver-show-job-lifecycle C.swift
// RUN: cd %t && %target-swiftc_driver -c -incremental -emit-dependencies -emit-module -emit-module-path %t/B.swiftmodule -module-name B -I %t -output-file-map %t/B.json -working-directory %t -driver-show-incremental -driver-show-job-lifecycle B.swift
// RUN: cd %t && %target-swiftc_driver -c -incremental -emit-dependencies -emit-module -emit-module-path %t/A.swiftmodule -module-name A -I %t -output-file-map %t/A.json -working-directory %t -driver-show-incremental -driver-show-job-lifecycle A.swift

//
// Now change a header and ensure that the rebuild cascades outwards
Expand All @@ -29,10 +29,10 @@
// RUN: rm %t/another-header.h
// RUN: cp %S/Inputs/external-cascade/another-header.h %t/another-header.h
// RUN: touch %t/another-header.h
// RUN: cd %t && %target-swiftc_driver -c -incremental -emit-dependencies -emit-module -emit-module-path %t/C.swiftmodule -enable-experimental-cross-module-incremental-build -module-name C -I %t -output-file-map %t/C.json -working-directory %t -import-objc-header %t/bridging-header.h -Xfrontend -validate-tbd-against-ir=none -driver-show-incremental -driver-show-job-lifecycle C.swift 2>&1 | %FileCheck -check-prefix MODULE-C %s
// RUN: cd %t && %target-swiftc_driver -c -incremental -emit-dependencies -emit-module -emit-module-path %t/B.swiftmodule -enable-experimental-cross-module-incremental-build -module-name B -I %t -output-file-map %t/B.json -working-directory %t -driver-show-incremental -driver-show-job-lifecycle B.swift 2>&1 | %FileCheck -check-prefix MODULE-B %s
// RUN: cd %t && %target-swiftc_driver -c -incremental -emit-dependencies -emit-module -emit-module-path %t/C.swiftmodule -module-name C -I %t -output-file-map %t/C.json -working-directory %t -import-objc-header %t/bridging-header.h -Xfrontend -validate-tbd-against-ir=none -driver-show-incremental -driver-show-job-lifecycle C.swift 2>&1 | %FileCheck -check-prefix MODULE-C %s
// RUN: cd %t && %target-swiftc_driver -c -incremental -emit-dependencies -emit-module -emit-module-path %t/B.swiftmodule -module-name B -I %t -output-file-map %t/B.json -working-directory %t -driver-show-incremental -driver-show-job-lifecycle B.swift 2>&1 | %FileCheck -check-prefix MODULE-B %s
// RUN: touch %t/B.swiftmodule
// RUN: cd %t && %target-swiftc_driver -c -incremental -emit-dependencies -emit-module -emit-module-path %t/A.swiftmodule -enable-experimental-cross-module-incremental-build -module-name A -I %t -output-file-map %t/A.json -working-directory %t -driver-show-incremental -driver-show-job-lifecycle A.swift 2>&1 | %FileCheck -check-prefix MODULE-A %s
// RUN: cd %t && %target-swiftc_driver -c -incremental -emit-dependencies -emit-module -emit-module-path %t/A.swiftmodule -module-name A -I %t -output-file-map %t/A.json -working-directory %t -driver-show-incremental -driver-show-job-lifecycle A.swift 2>&1 | %FileCheck -check-prefix MODULE-A %s

// MODULE-C: Job finished: {generate-pch: bridging-header-[[BRIDGING_HEADER:.*]].pch <= bridging-header.h}
// MODULE-C: Job finished: {compile: C.o <= C.swift bridging-header-[[BRIDGING_HEADER]].pch}
Expand All @@ -51,9 +51,9 @@
// And ensure that the null build really is null.
//

// RUN: cd %t && %target-swiftc_driver -c -incremental -emit-dependencies -emit-module -emit-module-path %t/C.swiftmodule -enable-experimental-cross-module-incremental-build -module-name C -I %t -output-file-map %t/C.json -working-directory %t -import-objc-header %t/bridging-header.h -Xfrontend -validate-tbd-against-ir=none -driver-show-incremental -driver-show-job-lifecycle C.swift 2>&1 | %FileCheck -check-prefix MODULE-C-NULL %s
// RUN: cd %t && %target-swiftc_driver -c -incremental -emit-dependencies -emit-module -emit-module-path %t/B.swiftmodule -enable-experimental-cross-module-incremental-build -module-name B -I %t -output-file-map %t/B.json -working-directory %t -driver-show-incremental -driver-show-job-lifecycle B.swift 2>&1 | %FileCheck -check-prefix MODULE-B-NULL %s
// RUN: cd %t && %target-swiftc_driver -c -incremental -emit-dependencies -emit-module -emit-module-path %t/A.swiftmodule -enable-experimental-cross-module-incremental-build -module-name A -I %t -output-file-map %t/A.json -working-directory %t -driver-show-incremental -driver-show-job-lifecycle A.swift 2>&1 | %FileCheck -check-prefix MODULE-A-NULL %s
// RUN: cd %t && %target-swiftc_driver -c -incremental -emit-dependencies -emit-module -emit-module-path %t/C.swiftmodule -module-name C -I %t -output-file-map %t/C.json -working-directory %t -import-objc-header %t/bridging-header.h -Xfrontend -validate-tbd-against-ir=none -driver-show-incremental -driver-show-job-lifecycle C.swift 2>&1 | %FileCheck -check-prefix MODULE-C-NULL %s
// RUN: cd %t && %target-swiftc_driver -c -incremental -emit-dependencies -emit-module -emit-module-path %t/B.swiftmodule -module-name B -I %t -output-file-map %t/B.json -working-directory %t -driver-show-incremental -driver-show-job-lifecycle B.swift 2>&1 | %FileCheck -check-prefix MODULE-B-NULL %s
// RUN: cd %t && %target-swiftc_driver -c -incremental -emit-dependencies -emit-module -emit-module-path %t/A.swiftmodule -module-name A -I %t -output-file-map %t/A.json -working-directory %t -driver-show-incremental -driver-show-job-lifecycle A.swift 2>&1 | %FileCheck -check-prefix MODULE-A-NULL %s

// MODULE-C-NULL: Job finished: {generate-pch: bridging-header-[[BRIDGING_HEADER:.*]].pch <= bridging-header.h}
// MODULE-C-NULL: Job skipped: {compile: C.o <= C.swift bridging-header-[[BRIDGING_HEADER]].pch}
Expand Down
18 changes: 9 additions & 9 deletions test/Incremental/CrossModule/linear.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,18 @@
// Set up a clean incremental build of all three modules
//

// RUN: cd %t && %target-swiftc_driver -c -incremental -emit-dependencies -emit-module -emit-module-path %t/C.swiftmodule -enable-experimental-cross-module-incremental-build -module-name C -I %t -output-file-map %t/C.json -working-directory %t -driver-show-incremental -driver-show-job-lifecycle -DOLD C.swift
// RUN: cd %t && %target-swiftc_driver -c -incremental -emit-dependencies -emit-module -emit-module-path %t/B.swiftmodule -enable-experimental-cross-module-incremental-build -module-name B -I %t -output-file-map %t/B.json -working-directory %t -driver-show-incremental -driver-show-job-lifecycle B.swift
// RUN: cd %t && %target-swiftc_driver -c -incremental -emit-dependencies -emit-module -emit-module-path %t/A.swiftmodule -enable-experimental-cross-module-incremental-build -module-name A -I %t -output-file-map %t/A.json -working-directory %t -driver-show-incremental -driver-show-job-lifecycle A.swift
// RUN: cd %t && %target-swiftc_driver -c -incremental -emit-dependencies -emit-module -emit-module-path %t/C.swiftmodule -module-name C -I %t -output-file-map %t/C.json -working-directory %t -driver-show-incremental -driver-show-job-lifecycle -DOLD C.swift
// RUN: cd %t && %target-swiftc_driver -c -incremental -emit-dependencies -emit-module -emit-module-path %t/B.swiftmodule -module-name B -I %t -output-file-map %t/B.json -working-directory %t -driver-show-incremental -driver-show-job-lifecycle B.swift
// RUN: cd %t && %target-swiftc_driver -c -incremental -emit-dependencies -emit-module -emit-module-path %t/A.swiftmodule -module-name A -I %t -output-file-map %t/A.json -working-directory %t -driver-show-incremental -driver-show-job-lifecycle A.swift

//
// Now change C and ensure that B rebuilds but A does not
//

// RUN: cd %t && %target-swiftc_driver -c -incremental -emit-dependencies -emit-module -emit-module-path %t/C.swiftmodule -enable-experimental-cross-module-incremental-build -module-name C -I %t -output-file-map %t/C.json -working-directory %t -driver-show-incremental -driver-show-job-lifecycle -DNEW C.swift 2>&1 | %FileCheck -check-prefix MODULE-C %s
// RUN: cd %t && %target-swiftc_driver -c -incremental -emit-dependencies -emit-module -emit-module-path %t/C.swiftmodule -module-name C -I %t -output-file-map %t/C.json -working-directory %t -driver-show-incremental -driver-show-job-lifecycle -DNEW C.swift 2>&1 | %FileCheck -check-prefix MODULE-C %s
// RUN: touch %t/C.swiftmodule
// RUN: cd %t && %target-swiftc_driver -c -incremental -emit-dependencies -emit-module -emit-module-path %t/B.swiftmodule -enable-experimental-cross-module-incremental-build -module-name B -I %t -output-file-map %t/B.json -working-directory %t -driver-show-incremental -driver-show-job-lifecycle B.swift 2>&1 | %FileCheck -check-prefix MODULE-B %s
// RUN: cd %t && %target-swiftc_driver -c -incremental -emit-dependencies -emit-module -emit-module-path %t/A.swiftmodule -enable-experimental-cross-module-incremental-build -module-name A -I %t -output-file-map %t/A.json -working-directory %t -driver-show-incremental -driver-show-job-lifecycle A.swift 2>&1 | %FileCheck -check-prefix MODULE-A %s
// RUN: cd %t && %target-swiftc_driver -c -incremental -emit-dependencies -emit-module -emit-module-path %t/B.swiftmodule -module-name B -I %t -output-file-map %t/B.json -working-directory %t -driver-show-incremental -driver-show-job-lifecycle B.swift 2>&1 | %FileCheck -check-prefix MODULE-B %s
// RUN: cd %t && %target-swiftc_driver -c -incremental -emit-dependencies -emit-module -emit-module-path %t/A.swiftmodule -module-name A -I %t -output-file-map %t/A.json -working-directory %t -driver-show-incremental -driver-show-job-lifecycle A.swift 2>&1 | %FileCheck -check-prefix MODULE-A %s

// MODULE-C: Incremental compilation has been disabled

Expand All @@ -44,9 +44,9 @@
// And ensure that the null build really is null.
//

// RUN: cd %t && %target-swiftc_driver -c -incremental -emit-dependencies -emit-module -emit-module-path %t/C.swiftmodule -enable-experimental-cross-module-incremental-build -module-name C -I %t -output-file-map %t/C.json -working-directory %t -driver-show-incremental -driver-show-job-lifecycle -DNEW C.swift 2>&1 | %FileCheck -check-prefix MODULE-C-NULL %s
// RUN: cd %t && %target-swiftc_driver -c -incremental -emit-dependencies -emit-module -emit-module-path %t/B.swiftmodule -enable-experimental-cross-module-incremental-build -module-name B -I %t -output-file-map %t/B.json -working-directory %t -driver-show-incremental -driver-show-job-lifecycle B.swift 2>&1 | %FileCheck -check-prefix MODULE-B-NULL %s
// RUN: cd %t && %target-swiftc_driver -c -incremental -emit-dependencies -emit-module -emit-module-path %t/A.swiftmodule -enable-experimental-cross-module-incremental-build -module-name A -I %t -output-file-map %t/A.json -working-directory %t -driver-show-incremental -driver-show-job-lifecycle A.swift 2>&1 | %FileCheck -check-prefix MODULE-A-NULL %s
// RUN: cd %t && %target-swiftc_driver -c -incremental -emit-dependencies -emit-module -emit-module-path %t/C.swiftmodule -module-name C -I %t -output-file-map %t/C.json -working-directory %t -driver-show-incremental -driver-show-job-lifecycle -DNEW C.swift 2>&1 | %FileCheck -check-prefix MODULE-C-NULL %s
// RUN: cd %t && %target-swiftc_driver -c -incremental -emit-dependencies -emit-module -emit-module-path %t/B.swiftmodule -module-name B -I %t -output-file-map %t/B.json -working-directory %t -driver-show-incremental -driver-show-job-lifecycle B.swift 2>&1 | %FileCheck -check-prefix MODULE-B-NULL %s
// RUN: cd %t && %target-swiftc_driver -c -incremental -emit-dependencies -emit-module -emit-module-path %t/A.swiftmodule -module-name A -I %t -output-file-map %t/A.json -working-directory %t -driver-show-incremental -driver-show-job-lifecycle A.swift 2>&1 | %FileCheck -check-prefix MODULE-A-NULL %s

// MODULE-C-NULL: Job skipped: {compile: C.o <= C.swift}
// MODULE-C-NULL: Job skipped: {merge-module: C.swiftmodule <= C.o}
Expand Down
Loading