From 71d4c3ac5591d7002d83486d7cddee6c2c1a19b6 Mon Sep 17 00:00:00 2001 From: Robert Widmann Date: Mon, 1 Jun 2020 10:41:27 -0700 Subject: [PATCH] Add a Test Demonstrating Superfluous Cascading Across Module Boundaries The idea is this: If we can have private intra-module dependencies, why not also have private inter-module dependencies. Currently, this is impossible because all edges from the CompilerInstance-level DependencyTracker are unconditionally registered as cascading. In addition, module loads are charged as depenendents to all files in a given batch, which means the exact set of external dependencies is some (non-deterministic) superset of the external dependencies of each files in the batch. This test case demonstrates one outcome of this approach: we recompile *way* too much when a dependent module changes. --- .../doesNotUseLib.swift | 3 ++ .../main.swift | 1 + .../ofm.json | 22 +++++++++++ .../submodule/lib-after.swift | 8 ++++ .../submodule/lib-before.swift | 7 ++++ .../submodule/ofm.json | 10 +++++ .../usesLib.swift | 7 ++++ .../usesLibTransitively.swift | 3 ++ .../superfluous-cascade-across-modules.swift | 39 +++++++++++++++++++ 9 files changed, 100 insertions(+) create mode 100644 test/Incremental/Inputs/superfluous-cascade-across-modules/doesNotUseLib.swift create mode 100644 test/Incremental/Inputs/superfluous-cascade-across-modules/main.swift create mode 100644 test/Incremental/Inputs/superfluous-cascade-across-modules/ofm.json create mode 100644 test/Incremental/Inputs/superfluous-cascade-across-modules/submodule/lib-after.swift create mode 100644 test/Incremental/Inputs/superfluous-cascade-across-modules/submodule/lib-before.swift create mode 100644 test/Incremental/Inputs/superfluous-cascade-across-modules/submodule/ofm.json create mode 100644 test/Incremental/Inputs/superfluous-cascade-across-modules/usesLib.swift create mode 100644 test/Incremental/Inputs/superfluous-cascade-across-modules/usesLibTransitively.swift create mode 100644 test/Incremental/superfluous-cascade-across-modules.swift diff --git a/test/Incremental/Inputs/superfluous-cascade-across-modules/doesNotUseLib.swift b/test/Incremental/Inputs/superfluous-cascade-across-modules/doesNotUseLib.swift new file mode 100644 index 0000000000000..caa55673f93b5 --- /dev/null +++ b/test/Incremental/Inputs/superfluous-cascade-across-modules/doesNotUseLib.swift @@ -0,0 +1,3 @@ +extension Map { + func pin() {} +} diff --git a/test/Incremental/Inputs/superfluous-cascade-across-modules/main.swift b/test/Incremental/Inputs/superfluous-cascade-across-modules/main.swift new file mode 100644 index 0000000000000..8b137891791fe --- /dev/null +++ b/test/Incremental/Inputs/superfluous-cascade-across-modules/main.swift @@ -0,0 +1 @@ + diff --git a/test/Incremental/Inputs/superfluous-cascade-across-modules/ofm.json b/test/Incremental/Inputs/superfluous-cascade-across-modules/ofm.json new file mode 100644 index 0000000000000..2d6538c292696 --- /dev/null +++ b/test/Incremental/Inputs/superfluous-cascade-across-modules/ofm.json @@ -0,0 +1,22 @@ +{ + "main.swift": { + "object": "./main.o", + "swift-dependencies": "./main.swiftdeps" + }, + "usesLib.swift": { + "object": "./usesLib.o", + "swift-dependencies": "./usesLib.swiftdeps" + }, + "usesLibTransitively.swift": { + "object": "./usesLib.o", + "swift-dependencies": "./usesLib.swiftdeps" + }, + "doesNotUseLib.swift": { + "object": "./doesNotUseLib.o", + "swift-dependencies": "./doesNotUseLib.swiftdeps" + }, + "": { + "swift-dependencies": "./main~buildrecord.swiftdeps" + } +} + diff --git a/test/Incremental/Inputs/superfluous-cascade-across-modules/submodule/lib-after.swift b/test/Incremental/Inputs/superfluous-cascade-across-modules/submodule/lib-after.swift new file mode 100644 index 0000000000000..347f0da653baa --- /dev/null +++ b/test/Incremental/Inputs/superfluous-cascade-across-modules/submodule/lib-after.swift @@ -0,0 +1,8 @@ +public struct Library { + var catalog: [Book] +} + +public struct Book { + var title: String + var checkOutCount: Int +} diff --git a/test/Incremental/Inputs/superfluous-cascade-across-modules/submodule/lib-before.swift b/test/Incremental/Inputs/superfluous-cascade-across-modules/submodule/lib-before.swift new file mode 100644 index 0000000000000..c9bb3d05e9d03 --- /dev/null +++ b/test/Incremental/Inputs/superfluous-cascade-across-modules/submodule/lib-before.swift @@ -0,0 +1,7 @@ +public struct Library { + var catalog: [Book] +} + +public struct Book { + var title: String +} diff --git a/test/Incremental/Inputs/superfluous-cascade-across-modules/submodule/ofm.json b/test/Incremental/Inputs/superfluous-cascade-across-modules/submodule/ofm.json new file mode 100644 index 0000000000000..d2f9889464c48 --- /dev/null +++ b/test/Incremental/Inputs/superfluous-cascade-across-modules/submodule/ofm.json @@ -0,0 +1,10 @@ +{ + "lib.swift": { + "object": "./lib.o", + "swift-dependencies": "./lib.swiftdeps" + }, + "": { + "swift-dependencies": "./submodule~buildrecord.swiftdeps" + } +} + diff --git a/test/Incremental/Inputs/superfluous-cascade-across-modules/usesLib.swift b/test/Incremental/Inputs/superfluous-cascade-across-modules/usesLib.swift new file mode 100644 index 0000000000000..96bb74c8750cd --- /dev/null +++ b/test/Incremental/Inputs/superfluous-cascade-across-modules/usesLib.swift @@ -0,0 +1,7 @@ +import Lib + +public struct District { + var libraries: [Library] +} + +struct Map {} diff --git a/test/Incremental/Inputs/superfluous-cascade-across-modules/usesLibTransitively.swift b/test/Incremental/Inputs/superfluous-cascade-across-modules/usesLibTransitively.swift new file mode 100644 index 0000000000000..a205027f286c7 --- /dev/null +++ b/test/Incremental/Inputs/superfluous-cascade-across-modules/usesLibTransitively.swift @@ -0,0 +1,3 @@ +struct County { + var districts: [District] +} diff --git a/test/Incremental/superfluous-cascade-across-modules.swift b/test/Incremental/superfluous-cascade-across-modules.swift new file mode 100644 index 0000000000000..0c76afd0864ad --- /dev/null +++ b/test/Incremental/superfluous-cascade-across-modules.swift @@ -0,0 +1,39 @@ +// ============================================================================= +// Without private dependencies +// ============================================================================= + +// First, build a submodule + +// RUN: %empty-directory(%t) +// RUN: cp %S/Inputs/superfluous-cascade-across-modules/*.swift %t +// RUN: cp %S/Inputs/superfluous-cascade-across-modules/*.json %t + +// RUN: %target-build-swift %S/Inputs/superfluous-cascade-across-modules/submodule/lib-before.swift -emit-module -emit-library -module-name Lib -module-link-name Lib -emit-module-path %t/Lib.swiftmodule -o %t/%target-library-name(Lib) + +// Build the main executable that depends on the submodule we just built + +// RUN: cd %t && %swiftc_driver -emit-module -enable-batch-mode -j2 -incremental -driver-show-incremental -I %t -L %t -lLib -module-name main \ +// RUN: -output-file-map ofm.json \ +// RUN: main.swift \ +// RUN: doesNotUseLib.swift \ +// RUN: usesLib.swift \ +// RUN: usesLibTransitively.swift >&output1 + +// Rebuild the submodule + +// RUN: %target-build-swift %S/Inputs/superfluous-cascade-across-modules/submodule/lib-after.swift -emit-module -emit-library -module-name Lib -module-link-name Lib -emit-module-path %t/Lib.swiftmodule -o %t/%target-library-name(Lib) + +// Rebuild the main executable + +// RUN: cd %t && %swiftc_driver -emit-module -enable-batch-mode -j2 -incremental -driver-show-incremental -I %t -L %t -lLib -module-name main \ +// RUN: -output-file-map ofm.json \ +// RUN: main.swift \ +// RUN: doesNotUseLib.swift \ +// RUN: usesLib.swift \ +// RUN: usesLibTransitively.swift >&output2 + +// RUN: %FileCheck -check-prefix=CHECK-STATUS-QUO-RECOMPILED %s < %t/output2 + +// CHECK-STATUS-QUO-RECOMPILED-DAG: Queuing because of external dependencies: {compile: main +// CHECK-STATUS-QUO-RECOMPILED-DAG: Queuing because of external dependencies: {compile: usesLib +// CHECK-STATUS-QUO-RECOMPILED-DAG: Queuing because of external dependencies: {compile: doesNotUseLib