Commit Graph

278 Commits

Author SHA1 Message Date
Artem Chikin
f09ab5c52f Add support for emitting parseable-outpuit "began" message from swift-frontend 2020-12-11 16:01:03 -08:00
Robert Widmann
859b87fd8c Move The Last Pieces for Cross-Module Incremental Builds
We're going to play a dirty, dirty trick - but it'll make our users'
lives better in the end so stick with me here.

In order to build up an incremental compilation, we need two sources of
dependency information:

1) "Priors" - Swiftdeps with dependency information from the past
   build(s)
2) "Posteriors" - Swiftdeps with dependencies from after we rebuild the
   file or module or whatever

With normal swift files built in incremental mode, the priors are given by the
swiftdeps files which are generated parallel to a swift file and usually
placed in the build directory alongside the object files. Because we
have entries in the output file map, we can always know where these
swiftdeps files are. The priors are integrated by the driver and then
the build is scheduled. As the build runs and jobs complete, their
swiftdeps are reloaded and re-integrated. The resulting changes are then
traversed and more jobs are scheduled if necessary. These give us the
posteriors we desire.

A module flips this on its head. The swiftdeps information serialized
in a module functions as the *posterior* since the driver consuming the
module has no way of knowing how to rebuild the module, and because its
dependencies are, for all intents and purposes, fixed in time. The
missing piece of the puzzle is the priors. That is, we need some way of
knowing what the "past" interface of the module looked like so we can
compare it to the "present" interface. Moreover, we need to always know
where to look for these priors.

We solve this problem by serializing a file alongside the build record:
the "external" build record. This is given by a... creative encoding
of multiple source file dependency graphs into a single source file
dependency graph. The rough structure of this is:

   SourceFile => interface <BUILD_RECORD>.external
   | - Incremental External Dependency => interface <MODULE_1>.swiftmodule
   | | - <dependency> ...
   | | - <dependency> ...
   | | - <dependency> ...
   | - Incremental External Dependency => interface <MODULE_2>.swiftmodule
   | | - <dependency> ...
   | | - <dependency> ...
   | - Incremental External Dependency => interface <MODULE_3>.swiftmodule
   | - ...

Sorta, `cat`'ing a bunch of source file dependency graphs together but
with incremental external dependency nodes acting as glue.

Now for the trick:

We have to unpack this structure and integrate it to get our priors.
This is easy. The tricky bit comes in integrate itself. Because the
top-level source file node points directly at the external build record,
not the original swift modules that defined these dependency nodes, we
swap the key it wants to use (the external build record) for the
incremental external dependency acting as the "parent" of the dependency
node. We do this by following the arc we carefully laid down in the
structure above.

For rdar://69595010
Goes a long way towards rdar://48955139, rdar://64238133
2020-12-10 18:45:21 -08:00
Robert Widmann
d4e76d0a47 [NFC] Use Result::code to Simplify Some Callsites 2020-12-09 19:28:50 -08:00
Robert Widmann
3ecb0b0b06 [NFC] Move "HadAbnormalExit" Flag Into Compilation::Result 2020-12-09 19:25:56 -08:00
Robert Widmann
d815e2724a [NFC] Add Compilation::Result
In order to extract the module dependency graph from the compilation the driver just ran, define a separate semantic type to hold a result code and the graph itself.
2020-12-09 19:25:56 -08:00
Robert Widmann
9075d32495 [NFC] Delete An Unused Entrypoint 2020-12-07 15:19:28 -08:00
Robert Widmann
e2e19dcf82 Add Compilation "Wave" Assertion in +Asserts Builds
The "wave" of a compilation job describes the number of indirections through other compile jobs the driver required to reach the decision to schedule a job. In incremental mode, it should always be the case that it takes no more than two complete waves to arrive at a fixpoint in the build. This is a natural consequence of the structure of the dependencies emitted by the Swift frontend - namely we rely on transitivity in dependency arcs.

A quick proof sketch: Suppose an arbitrary perturbation of the inputs to an incremental compilation session are made. In the first wave, dependency edges from the prior build's state (the "zeroeth wave") are loaded and the files corresponding to invalidated edges are scheduled into the first wave. Supposing the second wave is not the null set - the trivial case - there are additional arcs that were invalidated. Now suppose that there were a third wave. Take an arbitrary arc invalidated by this third wave. It must be the case that the file containing the use is not new - else it would be scheduled. Further it must be the case that its def was not invalidated by the zeroeth or first waves of compilation otherwise we would have scheduled it into the first or second waves. Finally, it must have a use that was discovered in the second wave. But in order for that use to have been included in the second wave, there must have been an invalidated arc created by the first wave. By transitivity of dependency arcs, there must therefore be a dependency arc from a definition invalidated in the first wave to our third wave job, which implies that the file would be scheduled into the second wave!

[Insert contradiction pig image here]
2020-10-21 19:36:43 -07:00
Robert Widmann
d793878923 Schedule merge-modules When modulewrap Job is in the Queue
In order to unblock the SwiftWASM project, which relies on an
incremental build of the Swift driver that relies on the merge-modules
job always being run. The situation appears to be something like this:

1) An incremental build is run
2) Temporary swiftmodule outputs are laid down
3) merge-modules is skipped
4) modulewrap is run anyways and reads the empty temp file

We should fix this by skipping modulewrap if we can skip merge-modules.
But for now, be conservative and fall back to the status quo behavior of
always running merge-modules whenever we encounter a modulewrap job.
2020-10-13 15:28:12 -07:00
Robert Widmann
4f49b6ab81 Merge pull request #34231 from CodaFi/skippy
Skip Merge-Modules When We Can
2020-10-08 14:41:01 -07:00
Robert Widmann
164bd08623 Merge pull request #34219 from CodaFi/negative-externalities
Keep a Cache of Externally-Dependent Jobs
2020-10-07 19:40:30 -07:00
Robert Widmann
cecb7c8313 Schedule MergeModules Incrementally
Plumb the logic necessary to schedule merge-modules incrementally. This means that if any inputs jobs to merge-modules run, merge-modules is run. But, if they are all skipped, merge-modules will be skipped as well.

This requires some light special-casing of the legacy driver's incremental job handling because it assumes in a few places it can always extract a swiftdeps file. This invariant will be further broken when the precompile step for bridging headers is skipped as well.

rdar://65893400
2020-10-07 16:57:14 -07:00
Robert Widmann
84f9ba3004 Use ModuleInputs instead of a Vector to build MergeModules 2020-10-07 16:56:48 -07:00
Robert Widmann
d29dcf8901 [NFC] Upgrade CompileJobAction::InputInfo::Status to an enum class 2020-10-07 16:56:48 -07:00
Robert Widmann
8fbcdf392f [NFC] Use IncrementalJobAction to Supersede getFirstSwiftPrimaryInput()
This function was being used in a roundabout way to test for a compile job action. But the actual data itself was not being used.
2020-10-07 12:08:21 -07:00
Robert Widmann
b0f0587963 Keep a Cache of Externally-Dependent Jobs
A more durable form of #34218. Keep a side cache of externally-dependent
jobs for now. This ensures our pseudo-Jobs don't get prematurely
deallocated before the tracing machinery has had a chance to report the
structure of the Job graph.

rdar://70053563
2020-10-07 10:39:17 -07:00
Robert Widmann
d7cd605c31 Adjust the Registration of the Pseudo-Job for External Incremental Dependencies
Register the module the external dependencies ride in with the pseudo-job in the Driver. This is a hack.
2020-10-05 18:42:28 -07:00
Robert Widmann
964f640636 Drop "Private Deps" Flag
In order for type body fingerprints to work, these declarations must always be included. Drop the ability to turn this off.
2020-10-01 14:40:45 -07:00
Robert Widmann
74765a8ba8 Remove Type Body Fingerprints Flags
This infrastructure has more than proven itself. Drop the code paths and tests supporting the status quo.
2020-10-01 13:09:00 -07:00
Robert Widmann
e35f060144 Install Incremental External Dependency Integration Code
An incremental build involving incremental external dependencies behaves as a hybrid between an external dependency and a normal swiftdeps-laden Swift file.

In the simplest case, we will fall back to the behavior of a plain external dependency today. That is, we will check its timestamp, then schedule all jobs that involve these external dependencies if it is out of date.

Where things get interesting is when cross-module incremental builds are enabled. In such a case, we know that a previous compiler has already emitted serialized swiftdeps information inside of a swiftmodule file. Moreover, we know that that swiftmodule file was loaded by the build of the current swift module. Finally, thanks to the previous stack of commits, we now know exactly how to extract this information from the swiftmodule file. To bring this all home, we unpack incremental dependency information from external dependencies, then integrate them into the current dependency graph - as though they were any other swiftdeps file. This neatly extends the single-module incremental logic to the multi-module case.
2020-09-25 11:45:58 -06:00
Robert Widmann
3ba33b93eb Install Faux Cross-Module Incremental Infrastructure In Driver
Treat any incremental external depends like normal external depends. This will eventually become the fallback behavior for cross-module incremental builds.
2020-09-25 01:16:01 -06:00
Robert Widmann
48415ad228 [NFC] Stage in driver flags for experimental cross-module incremental builds 2020-09-24 17:10:57 -06:00
Robert Widmann
14188f4428 Remove ~moduleonly Duplicate of Compilation Record
We thought we would need this while exploring  certain pre-build optimizations a la rdar://problem/37725110. This information was never used.
2020-09-24 11:42:06 -06:00
David Ungar
6171c4105b Remove bogus assertion with explanation. 2020-07-14 15:09:04 -07:00
Anthony Latsis
9fd1aa5d59 [NFC] Pre- increment and decrement where possible 2020-06-01 15:39:29 +03:00
Saleem Abdulrasool
09975d1253 sprinkle llvm_unreachable for covered switches (NFC)
Annotate the covered switches with `llvm_unreachable` to avoid the MSVC
warning which does not recognise the covered switches.  This allows us
to avoid a spew of warnings.
2020-05-07 11:05:35 -07:00
Slava Pestov
368d47429d Frontend: Remove coarse-grained dependency graph implementation 2020-04-29 16:55:53 -04:00
David Ungar
6f65e0ec36 Change unfinished handling 2020-01-27 15:14:46 -08:00
David Ungar
d61f6f2f66 Changes to support per-type-body fingerprints. 2020-01-27 15:14:46 -08:00
David Ungar
7f4205e9dc grammar 2020-01-22 21:38:21 -08:00
David Ungar
0c776a4a86 Add a verb. 2020-01-22 21:31:46 -08:00
David Ungar
cbd458c968 Make tests more deterministic by sorting jobs before scheduling 2020-01-16 13:20:35 -08:00
David Ungar
8c2c4ab391 Fixes for fine-grained dependencies 2020-01-16 13:20:27 -08:00
David Ungar
cc89dad526 Fine-grained and driver fixes.
Restructure fine-grained-dependencies to enable unit testing

Get frontend to emit correct swiftdeps file (fine-grained when needed) and only emit dot file for -emit-fine-grained-dependency-sourcefile-dot-files

Use deterministic order for more information outputs.

Set EnableFineGrainedDependencies consistently in frontend.

Tolerate errors that result in null getExtendedNominal()

Fix memory issue by removing node everywhere.

Break up print routine

Be more verbose so it will compile on Linux.

Sort batchable jobs, too.
2020-01-11 21:57:14 -08:00
Saleem Abdulrasool
b483047afe Revert "[Incremental] Dependency fixes in preparation for fine-grained dependencies" 2020-01-09 19:14:47 -08:00
David Ungar
939034a4bb Merge pull request #29009 from davidungar/fine-grained-fixes-post-rb
[Incremental] Dependency fixes in preparation for fine-grained dependencies
2020-01-09 00:57:31 -08:00
Doug Gregor
51bbaebd08 Merge pull request #28972 from kastiglione/dl/correct-batch-mode-partitiion-count-calculation
Adjust batch mode partition count calculation
2020-01-05 21:05:00 -08:00
David Ungar
6fffe724f2 Fine-grained and driver fixes.
Restructure fine-grained-dependencies to enable unit testing

Get frontend to emit correct swiftdeps file (fine-grained when needed) and only emit dot file for -emit-fine-grained-dependency-sourcefile-dot-files

Use deterministic order for more information outputs.

Set EnableFineGrainedDependencies consistently in frontend.

Tolerate errors that result in null getExtendedNominal()

Fix memory issue by removing node everywhere.

Break up print routine

Be more verbose so it will compile on Linux.

Sort batchable jobs, too.
2020-01-04 14:37:06 -08:00
Dave Lee
477763e7ed DivideRoundingUp 2020-01-04 06:53:37 -08:00
Dave Lee
d06d0394ed Remove incomplete bit about properties 2020-01-01 23:39:21 -08:00
Dave Lee
8a6f44da6b Extract DivideUp lambda 2020-01-01 23:35:12 -08:00
Dave Lee
17655b7c3e Correct batch mode partitiion count calculation 2019-12-31 07:32:15 -08:00
Saleem Abdulrasool
7d8aac60ca disambiguate some type shadowing (NFCI)
Adjust the type shadowing identified by GCC 7.  The declaration shadows
a type which changes the meaning of the identifier subsequently.
2019-12-23 15:34:55 -08:00
David Ungar
419240f4c3 Make path suitable for Windows 2019-12-20 10:47:12 -08:00
David Ungar
2a79331ac3 add -enable/disable-only-one-dependency-file flag, on by default 2019-12-18 16:07:51 -08:00
David Ungar
73a46ce57e Revert "[Incremental, Driver] Only emit a real make-style dependency file for one frontend job." 2019-12-12 22:26:25 -08:00
David Ungar
4c365a7735 Merge pull request #28702 from davidungar/only-one-dependency-file
[Incremental, Driver] Only emit a real make-style dependency file for one frontend job.
2019-12-11 21:21:41 -08:00
David Ungar
46687189a7 -only-one-dependency-file causes only the first frontend job to emit a real dependency file. 2019-12-10 22:52:57 -08:00
David Ungar
9bfed89e8c markTransitive & markExternal return the jobs, unfmt 2019-12-08 11:15:51 -08:00
David Ungar
0771d96986 Format 2019-12-08 10:14:24 -08:00
David Ungar
ebb77e8ee8 ExpDepGraph -> FineGrainedDepGraph 2019-12-08 09:44:47 -08:00