Skip to content

[Evaluator] Online Request-Based Incremental Dependency Tracking #30723

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 8 commits into from
Apr 1, 2020

Conversation

CodaFi
Copy link
Contributor

@CodaFi CodaFi commented Mar 30, 2020

This pull request grants the evaluator the ability to register incremental dependencies as a consequence of request evaluation. This also cuts the compiler over to using the evaluator's name tracker as the source of dependency information, and provides the staging flag -disable-request-based-incremental-dependencies should we require the old scheme once again.

The plan of attack is this:

  • Partition the total set of requests into "dependency-relevant" and "dependency-neutral" requests.
  • Further partition the "dependency-relevant" request into dependency sources and dependency sinks
  • For dependency source requests, have them tell the evaluator to switch the active context to their source file, and optionally provide a scope change to either cascading or non-cascading.
  • For dependency sink requests, have them use the active name tracker to write out the dependency-relevant information they produced as a consequence of request evaluation.

Sources

A request marked as a dependency source declares that its evaluation defines a scope under which dependency information should be registered. As request evaluation proceeds, additional source requests will push their scopes onto the evaluator's stack, and have those scopes removed when their execution terminates.

A dependency source under the request-based system is equivalent to a change of decl context under the manual scheme. As such, there are very few requests outside of the very high-level ones like TypeCheckSourceFileUntil that can claim to be valid dependency sources, but they do exist. For example, ModuleQualifiedLookupRequest switches its lookup context based on the decl context the lookup is performed from and writes into the referenced name tracker for the associated file (if any).

Sinks

A request marked as a dependency sink declares that any reads of the information computed by the request have dependency information to write into the active scope. That is, the act of "reading" the result of the request completes a dependency edge from the active scope to the name being looked up.

Note that it is insufficient to instrument the cache points or the evaluate method alone for dependency sinks, thus we have a separate write function to implement. This is because a request that populates the cache will not re-execute evaluate to register the edge, even if the active scope has changed. Imagine a frontend run with two primaries that each try to fire off a SuperclassTypeRequest if we did not instrument all reads. The evaluate kicked off by the first primary will warm the cache and register the edge, the second evaluate kicked off by the second primary will read the cache and skip evaluate. Instrumenting the cache-points manually is also right out since there are internally-cached requests that have nothing to instrument!

A dependency sink under the request-based system is associated one-to-one with a dependency-relevant use of a name. The ideal candidate for a dependency sink is therefore the lookup requests themselves - and indeed, lookup requests that register dependency edges manually have all been declared as sinks.

Exceptions

The tricky ones are the type checking requests that run in the primary file. Currently, redeclaration checking and protocol conformance checking register the bulk of provides edges in the file. They eventually bottom out in a lookup, but additional context is required to emulate the old scheme. So, to preserve compatibility, they are also declared as dependency sources to simulate the manual context change, and dependency sinks to write out the edges. We can and should scrap this in the future.

Effect on The Evaluator

This means that the model of request evaluation must be generalized to accommodate the source and sink points. For that, define a new dependency source stack in the evaluator and have request evaluation automatically push and pop scopes as needed (for dependency neutral requests, the template specialization ensures this operation is a no-op). For dependency sinks, all of the read-points of the evaluator (reading from the internal cache, external cache, and uncached evaluation) have been instrumented to call the dependency sink point (for dependency neutral requests, this is also a no-op because of template specialization).

Under this scheme, it should be the case that the only request that really flips the dependency scope from cascading to non-cascading is TypeCheckFunctionBodyUntilRequest. However, an attempt has been made at compatibility with the old manual scheme. Especially name lookup requests that use client-provided flags to register edges, will have those flags taken into consideration and so are also registered as dependency sources and sinks as appropriate.

There are two notable places where those compatibility guarantees fail:

  1. Extensions that do not also have associated protocol conformances are now registering dependencies on the type they extend. This is a pretty big hole in the manual system.
  2. Name lookups that use the "no known dependency" flag will register dependencies anyways. The callers cannot possibly be correct because that name may become defined in the module at any future point and we may potentially fail to rebuild dependents because of it.

rdar://59773704, rdar://60050653

@CodaFi
Copy link
Contributor Author

CodaFi commented Mar 30, 2020

Re-enabling the AnyObject test might sink us on Windows, but let's see

@swift-ci test

@CodaFi
Copy link
Contributor Author

CodaFi commented Mar 30, 2020

Hah, my assertion tripped an assertion.

@CodaFi CodaFi force-pushed the dependendable-dependencies branch from e11f54b to 3b9756f Compare March 30, 2020 19:37
@CodaFi
Copy link
Contributor Author

CodaFi commented Mar 30, 2020

@swift-ci please smoke test

@CodaFi
Copy link
Contributor Author

CodaFi commented Mar 30, 2020

@swift-ci test Windows

@davidungar
Copy link
Contributor

@CodaFi Just read the description, prior to reviewing it. It would really help me to follow it if you could add an explanation of the terms "dependency source" and "dependency sink". Thanks!

@CodaFi
Copy link
Contributor Author

CodaFi commented Mar 30, 2020

No description provided.

@swiftlang swiftlang deleted a comment from swift-ci Mar 30, 2020
@swiftlang swiftlang deleted a comment from swift-ci Mar 30, 2020
@CodaFi
Copy link
Contributor Author

CodaFi commented Mar 30, 2020

@swift-ci test

@swiftlang swiftlang deleted a comment from swift-ci Mar 30, 2020
@swiftlang swiftlang deleted a comment from swift-ci Mar 30, 2020
@CodaFi CodaFi force-pushed the dependendable-dependencies branch from 3b9756f to 3a333f5 Compare March 31, 2020 01:05
@CodaFi
Copy link
Contributor Author

CodaFi commented Mar 31, 2020

@swift-ci test compiler performance

@CodaFi
Copy link
Contributor Author

CodaFi commented Mar 31, 2020

@swift-ci smoke test

Copy link
Contributor

@slavapestov slavapestov left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need a top-level requests for SIL optimization as well, otherwise we might miss dependency edges when optimizing code (it's tricky to come up with them, but, eg, conformance checks)

auto *unit = desc.context.dyn_cast<FileUnit *>();
return {
dyn_cast_or_null<SourceFile>(unit),
evaluator::DependencyScope::Cascading
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should similarly flip over to private dependencies when we SILGen or IRGen a function body.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I wonder if all dependencies recorded during SILGen and IRGen can be non-cascading. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That sounds like a fine idea, but we need to get more tests up for dependencies discovered during those later phases. In fact, we need to get any tests for this since we currently emit reference dependencies after Sema.

// UNSUPPORTED: CPU=armv7k && OS=ios
// Exclude iOS-based 32-bit platforms because the Foundation overlays introduce
// an extra dependency on _KeyValueCodingAndObservingPublishing only for 64-bit
// platforms.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you instead add --check-prefix=CHECK-%target-ptrsize to the RUN: line, and use CHECK-32/CHECK-64 to conditionalize this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll get it in a follow-up. This test has been historically difficult to gate on our more exotic configurations.

@davidungar
Copy link
Contributor

Wow! I'm very excited by the payoff of this work!

Thank you very much for adding the source and sink explanation. Now I understand. I have two thoughts, just about this text:

  1. It would be easier for others, reading this PR someday, if the source and sink discussion were prepended to the main description. Failing that, the main description could forward-reference the source/sink discussion.

  2. When I have tried to follow this work before, every time I read "dependency source", I thought you meant something that supplied a "provides", because that is what I think of as the source of a dependency. In other words, some entity is defined, and some other one uses it. The first is the "source", and the second, the "sink". And these terms seem to be natural in the context I've been working in. I now understand why, in your context "source" and "sink" make sense. I wonder how we can make it easier for future maintainers to deal with this conflicting terminology. Were I trying to name them from scratch--and I'm not necessarily proposing this--I would probably use "dependency scope/context source" and "dependency use source", since one kind of request provides the scope or context, and the other provides use information.

I'm not sure what the best way forward is... the easiest thing would be adding something to clarify the two terminologies somewhere, maybe? Anyway, submitted for your consideration...

Thanks!

Comment on lines 55 to 59
## Incremental Dependency Tracking
Request evaluation naturally captures the dependency structure of any given invocation of the compiler frontend. In fact, it captures it so well that the request graph trace generated by a select kind of lookup request can be used to completely recover the information relevant to the Swift compiler's incremental compilation subsystem. For these select *dependency-relevant* requests, we can further subdivide them into so-called *dependency sources* and *dependency sinks*. A dependency source is any (usually high-level) request that introduces a new context under which dependencies can be registered. Currently, these are the requests that operate that the level of individual source files. A dependency sink is any (usually lower-level) request that executes as a sub-computation of a depenendecy source. Any names that are dependency-relevant, such as the result of a lookup in a particular context, are then registered against trackers in the active dependency source (file). Using this, the evaluator pushes and pops sources and sinks automatically as request evaluation proceeds, and sink requests pair automatically to source requests to write out dependency information.

To define a request as a dependency source, it must implement an accessor for the new active scope (`readDependencySource`). To define a request as a dependency sink, it must implement a function that writes the result of evaluating the request into the current active source (`writeDependencySink`).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah!! I hadn't looked at the diffs before I wrote the comment on the conversation page. This is great! Maybe just add something like: "These terms apply when considering how the frontend finds and records uses for the dependency graph." In the wider context of the graph, a source could be considered to be a definition of an entity, and a sink could be a use, such that when the source changes, the use must be recompiled."

Comment on lines 467 to 489
template <typename Request,
typename std::enable_if<!Request::isDependencySink>::type * = nullptr>
void reportEvaluatedResult(const Request &r,
const typename Request::OutputType &o) const {}

template <typename Request,
typename std::enable_if<Request::isDependencySink>::type * = nullptr>
void reportEvaluatedResult(const Request &r,
const typename Request::OutputType &o) {
r.writeDependencySink(*this, o);
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have just read both of these over about four times, and I finally spotted the "const" difference. Sigh... C++. But now I'm wondering why it's OK to not write the sink if the receiver happens to be const. Would it be possible to put in a comment explaining this? Is there a possibility of creating a bug by calling the first one when a write is really needed because of a bogus "const" on the receiver of the message?

Copy link
Contributor

@davidungar davidungar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very nice solution to a tricky problem overall! Clearly took lots of careful thought.

Two items stick in my mind:

  1. To help future maintainers, add some verbiage in the documentation file explaining the different meanings of Dependency source and -sink.

  2. I don't like passing a pointer to the ReferencedNameTracker into the dependency-graph-creation systems (e.g. emitReferenceDependencies, etc.). I want to preserve the restriction that the tracker used goes with the source file.

At first, I thought, well, just in a boolean instead of a pointer. But, after reading through all the diffs, would the following work?

If you can get from a SourceFile, through the ASTContext, to the LangOpts, you could just have a get member function on the source file to get the right tracker. Then, just use that member wherever the old code used to get the tracker pointer out of the source file.

Copy link
Contributor

@hamishknight hamishknight left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great!

Formalize DependencyScope, DependencySource, and the incremental dependency stack.

Also specialize SimpleRequest to formalize dependency sources and dependency sinks. This allows the evaluator's internal entrypoints to specalize away the incremental dependency tracking infrastructure if a request is not actually dependency-relevant.
@CodaFi CodaFi force-pushed the dependendable-dependencies branch from 3806b6a to 205a2b4 Compare March 31, 2020 23:15
CodaFi added 6 commits March 31, 2020 16:16
Request-based incremental dependencies are enabled by default. For the time being, add a flag that will turn them off and switch back to manual dependency tracking.
Plug high-level requests that define dependency sources into the evaluator's incremental infrastructure.
Convert most of the name lookup requests and a few other ancillary typechecking requests into dependency sinks.

Some requests are also combined sinks and sources in order to emulate the current scheme, which performs scope changes based on lookup flags. This is generally undesirable, since it means those requests cannot immediately be generalized to a purely context-based scheme because they depend on some client-provided entropy source. In particular, the few callers that are providing the "known private" name lookup flag need to be converted to perform lookups in the appropriate private context.

Clients that are passing "no known dependency" are currently considered universally incorrect and are outside the scope of the compatibility guarantees. This means that request-based dependency tracking registers strictly more edges than manual dependency tracking. It also means that once we fixup the clients that are passing "known private", we can completely remove these name lookup flags.

Finally, some tests had to change to accomodate the new scheme. Currently, we go out of our way to register a dependency edge for extensions that declare protocol conformances. However, we were also asserting in at least one test that extensions without protocol conformances weren't registering dependency edges. This is blatantly incorrect and has been undone now that the request-based scheme is automatically registering this edge.
@CodaFi CodaFi force-pushed the dependendable-dependencies branch from 205a2b4 to 0879962 Compare March 31, 2020 23:17
* Document a number of legacy conditions and edge cases

* Add lexicon definitions for "dependency source", "dependency sink",
"cascading dependency" and "private dependency"
@CodaFi CodaFi force-pushed the dependendable-dependencies branch from 0879962 to ee723cd Compare March 31, 2020 23:19
@CodaFi
Copy link
Contributor Author

CodaFi commented Mar 31, 2020

I believe that's everything resolved.

@swift-ci please smoke test

@swift-ci
Copy link
Contributor

swift-ci commented Apr 1, 2020

Summary for master full

Unexpected test results, excluded stats for RxCocoa, SwifterSwift, Base64CoderSwiftUI

Regressions found (see below)

Debug-batch

debug-batch brief

Regressed (0)
name old new delta delta_pct
Improved (0)
name old new delta delta_pct
Unchanged (delta < 1.0% or delta < 100.0ms) (3)
name old new delta delta_pct
Frontend.NumInstructionsExecuted 70,276,537,143,799 70,792,614,872,552 516,077,728,753 0.73%
LLVM.NumLLVMBytesOutput 1,882,701,556 1,882,699,692 -1,864 -0.0%
time.swift-driver.wall 6384.0s 6393.2s 9.2s 0.14%

debug-batch detailed

Regressed (11)
name old new delta delta_pct
AST.NumASTBytesAllocated 62,625,833,688 63,334,920,275 709,086,587 1.13% ⛔
AST.NumReferencedMemberNames 6,702,052 7,686,519 984,467 14.69% ⛔
AST.NumReferencedTopLevelNames 574,342 608,289 33,947 5.91% ⛔
Driver.NumDriverPipePolls 69,765 70,658 893 1.28% ⛔
Driver.NumDriverPipeReads 56,936 57,780 844 1.48% ⛔
Sema.AccessLevelRequest 12,342,884 12,562,739 219,855 1.78% ⛔
Sema.CollectOverriddenDeclsRequest 7,612,330 7,758,800 146,470 1.92% ⛔
Sema.GenericParamListRequest 9,784,425 9,923,097 138,672 1.42% ⛔
Sema.ProvideDefaultImplForRequest 7,612,330 7,758,800 146,470 1.92% ⛔
Sema.SPIGroupsRequest 15,378,879 15,552,021 173,142 1.13% ⛔
Sema.USRGenerationRequest 9,128,999 9,278,266 149,267 1.64% ⛔
Improved (0)
name old new delta delta_pct
Unchanged (delta < 1.0% or delta < 100.0ms) (221)
name old new delta delta_pct
AST.ImportSetCacheHit 2,226,620 2,225,992 -628 -0.03%
AST.ImportSetCacheMiss 1,015,444 1,015,522 78 0.01%
AST.ImportSetFoldHit 536,250 536,268 18 0.0%
AST.ImportSetFoldMiss 479,193 479,254 61 0.01%
AST.ModuleShadowCacheHit 3,739 3,739 0 0.0%
AST.ModuleShadowCacheMiss 1,984 1,984 0 0.0%
AST.ModuleVisibilityCacheHit 35,037 35,034 -3 -0.01%
AST.ModuleVisibilityCacheMiss 9,091 9,088 -3 -0.03%
AST.NumASTScopeLookups 4,445,978 4,444,814 -1,164 -0.03%
AST.NumBraceStmtASTScopeExpansions 647,690 647,690 0 0.0%
AST.NumBraceStmtASTScopes 647,690 647,690 0 0.0%
AST.NumDecls 145,427 145,427 0 0.0%
AST.NumDependencies 445,207 445,263 56 0.01%
AST.NumIterableTypeBodyASTScopeExpansions 287,145 287,103 -42 -0.01%
AST.NumIterableTypeBodyASTScopes 369,057 369,137 80 0.02%
AST.NumLinkLibraries 0 0 0 0.0%
AST.NumLoadedModules 422,911 422,911 0 0.0%
AST.NumLocalTypeDecls 255 255 0 0.0%
AST.NumModuleLookupClassMember 6,993 6,993 0 0.0%
AST.NumModuleLookupValue 56,230,263 56,216,042 -14,221 -0.03%
AST.NumObjCMethods 25,253 25,253 0 0.0%
AST.NumOperators 589 589 0 0.0%
AST.NumPrecedenceGroups 93 93 0 0.0%
AST.NumReferencedDynamicNames 191 191 0 0.0%
AST.NumSourceBuffers 601,829 601,829 0 0.0%
AST.NumSourceLines 4,836,322 4,836,322 0 0.0%
AST.NumSourceLinesPerSecond 2,672,269 2,663,598 -8,671 -0.32%
AST.NumTotalClangImportedEntities 2,232,684 2,242,415 9,731 0.44%
Driver.ChildrenMaxRSS 274,675,009,536 274,835,734,528 160,724,992 0.06%
Driver.DriverDepCascadingDynamic 0 0 0 0.0%
Driver.DriverDepCascadingExternal 0 0 0 0.0%
Driver.DriverDepCascadingMember 0 0 0 0.0%
Driver.DriverDepCascadingNominal 0 0 0 0.0%
Driver.DriverDepCascadingTopLevel 0 0 0 0.0%
Driver.DriverDepDynamic 0 0 0 0.0%
Driver.DriverDepExternal 0 0 0 0.0%
Driver.DriverDepMember 0 0 0 0.0%
Driver.DriverDepNominal 0 0 0 0.0%
Driver.DriverDepTopLevel 0 0 0 0.0%
Driver.NumDriverJobsRun 28,924 28,924 0 0.0%
Driver.NumDriverJobsSkipped 0 0 0 0.0%
Driver.NumProcessFailures 0 0 0 0.0%
Frontend.MaxMallocUsage 1,624,481,932,040 1,629,109,575,272 4,627,643,232 0.28%
Frontend.NumInstructionsExecuted 70,276,537,143,799 70,792,614,872,552 516,077,728,753 0.73%
Frontend.NumProcessFailures 0 0 0 0.0%
IRGen.IRGenSourceFileRequest 27,616 27,616 0 0.0%
IRGen.IRGenWholeModuleRequest 20 20 0 0.0%
IRModule.NumGOTEntries 252,060 252,060 0 0.0%
IRModule.NumIRAliases 202,383 202,383 0 0.0%
IRModule.NumIRBasicBlocks 8,231,559 8,231,559 0 0.0%
IRModule.NumIRComdatSymbols 0 0 0 0.0%
IRModule.NumIRFunctions 3,447,071 3,447,071 0 0.0%
IRModule.NumIRGlobals 3,856,629 3,856,629 0 0.0%
IRModule.NumIRIFuncs 0 0 0 0.0%
IRModule.NumIRInsts 94,640,702 94,640,702 0 0.0%
IRModule.NumIRNamedMetaData 139,680 139,680 0 0.0%
IRModule.NumIRValueSymbols 6,628,771 6,628,771 0 0.0%
LLVM.NumLLVMBytesOutput 1,882,701,556 1,882,699,692 -1,864 -0.0%
Parse.CodeCompletionSecondPassRequest 0 0 0 0.0%
Parse.NumFunctionsParsed 276,302 276,302 0 0.0%
Parse.NumIterableDeclContextParsed 960,526 960,414 -112 -0.01%
Parse.ParseAbstractFunctionBodyRequest 253,815 253,815 0 0.0%
Parse.ParseMembersRequest 790,969 790,857 -112 -0.01%
Parse.ParseSourceFileRequest 591,231 591,231 0 0.0%
SILGen.SILGenSourceFileRequest 27,616 27,616 0 0.0%
SILGen.SILGenWholeModuleRequest 1,296 1,296 0 0.0%
SILModule.NumSILGenDefaultWitnessTables 0 0 0 0.0%
SILModule.NumSILGenFunctions 1,763,853 1,763,853 0 0.0%
SILModule.NumSILGenGlobalVariables 54,998 54,998 0 0.0%
SILModule.NumSILGenVtables 19,079 19,079 0 0.0%
SILModule.NumSILGenWitnessTables 75,526 75,526 0 0.0%
SILModule.NumSILOptDefaultWitnessTables 0 0 0 0.0%
SILModule.NumSILOptFunctions 2,599,029 2,599,029 0 0.0%
SILModule.NumSILOptGlobalVariables 56,693 56,693 0 0.0%
SILModule.NumSILOptVtables 32,320 32,320 0 0.0%
SILModule.NumSILOptWitnessTables 174,852 174,852 0 0.0%
SILOptimizer.ExecuteSILPipelineRequest 111,825 111,825 0 0.0%
Sema.AbstractGenericSignatureRequest 39,606 39,606 0 0.0%
Sema.AnyObjectLookupRequest 283 283 0 0.0%
Sema.AreAllStoredPropertiesDefaultInitableRequest 24,524 24,524 0 0.0%
Sema.AttachedFunctionBuilderRequest 181 181 0 0.0%
Sema.AttachedPropertyWrapperTypeRequest 588,987 588,987 0 0.0%
Sema.AttachedPropertyWrappersRequest 2,548,171 2,548,166 -5 -0.0%
Sema.CallerSideDefaultArgExprRequest 79,290 79,290 0 0.0%
Sema.CheckRedeclarationRequest 1,009,408 1,009,408 0 0.0%
Sema.ClassAncestryFlagsRequest 118,837 118,837 0 0.0%
Sema.ClosureHasExplicitResultRequest 93,055 93,055 0 0.0%
Sema.CompareDeclSpecializationRequest 486,687 487,737 1,050 0.22%
Sema.CursorInfoRequest 0 0 0 0.0%
Sema.CustomAttrNominalRequest 476 476 0 0.0%
Sema.DefaultAndMaxAccessLevelRequest 60,441 60,445 4 0.01%
Sema.DefaultArgumentExprRequest 39,606 39,606 0 0.0%
Sema.DefaultArgumentInitContextRequest 486 486 0 0.0%
Sema.DefaultDefinitionTypeRequest 8,684 8,684 0 0.0%
Sema.DefaultTypeRequest 498,906 498,906 0 0.0%
Sema.DifferentiableAttributeTypeCheckRequest 0 0 0 0.0%
Sema.DirectLookupRequest 34,793,523 34,889,426 95,903 0.28%
Sema.DirectOperatorLookupRequest 587,090 586,469 -621 -0.11%
Sema.DirectPrecedenceGroupLookupRequest 146,523 146,523 0 0.0%
Sema.DynamicallyReplacedDeclRequest 1,103,147 1,103,147 0 0.0%
Sema.EmittedMembersRequest 28,921 28,921 0 0.0%
Sema.EnumRawTypeRequest 27,057 27,057 0 0.0%
Sema.EnumRawValuesRequest 10,902 10,902 0 0.0%
Sema.ExistentialConformsToSelfRequest 13,340 13,385 45 0.34%
Sema.ExistentialTypeSupportedRequest 18,434 18,434 0 0.0%
Sema.ExpandASTScopeRequest 8,058,568 8,058,414 -154 -0.0%
Sema.ExtendedNominalRequest 919,398 919,398 0 0.0%
Sema.ExtendedTypeRequest 86,983 86,970 -13 -0.01%
Sema.FunctionBuilderTypeRequest 181 181 0 0.0%
Sema.FunctionOperatorRequest 74,244 74,244 0 0.0%
Sema.GenericSignatureRequest 2,799,349 2,802,713 3,364 0.12%
Sema.GetDestructorRequest 29,390 29,390 0 0.0%
Sema.HasCircularInheritanceRequest 24,492 24,492 0 0.0%
Sema.HasCircularInheritedProtocolsRequest 10,630 10,630 0 0.0%
Sema.HasCircularRawValueRequest 9,234 9,234 0 0.0%
Sema.HasDefaultInitRequest 59,499 59,499 0 0.0%
Sema.HasDynamicCallableAttributeRequest 0 0 0 0.0%
Sema.HasDynamicMemberLookupAttributeRequest 680,553 681,204 651 0.1%
Sema.HasMemberwiseInitRequest 21,590 21,590 0 0.0%
Sema.HasMissingDesignatedInitializersRequest 27,438 27,438 0 0.0%
Sema.HasUserDefinedDesignatedInitRequest 59,510 59,510 0 0.0%
Sema.InferredGenericSignatureRequest 192,447 192,391 -56 -0.03%
Sema.InheritedDeclsReferencedRequest 6,175,358 6,206,777 31,419 0.51%
Sema.InheritedProtocolsRequest 692,448 693,185 737 0.11%
Sema.InheritedTypeRequest 324,257 324,099 -158 -0.05%
Sema.InheritsSuperclassInitializersRequest 30,191 30,191 0 0.0%
Sema.InitKindRequest 102,201 102,201 0 0.0%
Sema.InterfaceTypeRequest 14,697,203 14,825,528 128,325 0.87%
Sema.IsABICompatibleOverrideRequest 140,453 140,453 0 0.0%
Sema.IsAccessorTransparentRequest 329,007 329,007 0 0.0%
Sema.IsCallableNominalTypeRequest 2,174 2,174 0 0.0%
Sema.IsDeclApplicableRequest 0 0 0 0.0%
Sema.IsDynamicRequest 1,810,588 1,810,588 0 0.0%
Sema.IsFinalRequest 2,788,941 2,804,782 15,841 0.57%
Sema.IsGetterMutatingRequest 451,227 451,227 0 0.0%
Sema.IsImplicitlyUnwrappedOptionalRequest 2,544,975 2,544,377 -598 -0.02%
Sema.IsObjCRequest 1,636,364 1,639,033 2,669 0.16%
Sema.IsSetterMutatingRequest 354,875 354,875 0 0.0%
Sema.IsStaticRequest 975,898 976,649 751 0.08%
Sema.LazyStoragePropertyRequest 3,001 3,001 0 0.0%
Sema.LookupAllConformancesInContextRequest 85,014 85,014 0 0.0%
Sema.LookupConformanceInModuleRequest 38,624,587 38,701,702 77,115 0.2%
Sema.LookupInModuleRequest 7,613,167 7,610,759 -2,408 -0.03%
Sema.LookupInfixOperatorRequest 97,928 97,928 0 0.0%
Sema.LookupPostfixOperatorRequest 215 215 0 0.0%
Sema.LookupPrecedenceGroupRequest 32,514 32,514 0 0.0%
Sema.LookupPrefixOperatorRequest 716 716 0 0.0%
Sema.MangleLocalTypeDeclRequest 510 510 0 0.0%
Sema.ModuleQualifiedLookupRequest 3,462,795 3,461,503 -1,292 -0.04%
Sema.NamedLazyMemberLoadSuccessCount 23,371,124 23,368,283 -2,841 -0.01%
Sema.NamingPatternRequest 243,336 243,331 -5 -0.0%
Sema.NeedsNewVTableEntryRequest 718,742 718,742 0 0.0%
Sema.NumAccessorBodiesSynthesized 194,705 194,705 0 0.0%
Sema.NumAccessorsSynthesized 306,956 306,956 0 0.0%
Sema.NumConformancesDeserialized 10,040,002 10,124,899 84,897 0.85%
Sema.NumConstraintScopes 32,787,868 32,798,124 10,256 0.03%
Sema.NumConstraintsConsideredForEdgeContraction 114,543,173 114,544,183 1,010 0.0%
Sema.NumCrossImportsChecked 0 0 0 0.0%
Sema.NumCrossImportsFound 0 0 0 0.0%
Sema.NumCyclicOneWayComponentsCollapsed 269 269 0 0.0%
Sema.NumDeclsDeserialized 81,121,090 81,784,686 663,596 0.82%
Sema.NumDeclsTypechecked 1,455,701 1,455,701 0 0.0%
Sema.NumGenericSignatureBuilders 1,531,875 1,534,325 2,450 0.16%
Sema.NumLazyIterableDeclContexts 10,389,930 10,423,818 33,888 0.33%
Sema.NumLazyRequirementSignatures 1,086,894 1,088,179 1,285 0.12%
Sema.NumLazyRequirementSignaturesLoaded 775,798 776,687 889 0.11%
Sema.NumLeafScopes 20,718,995 20,728,169 9,174 0.04%
Sema.NumTypesDeserialized 26,022,063 26,126,522 104,459 0.4%
Sema.NumTypesValidated 1,597,399 1,597,381 -18 -0.0%
Sema.NumUnloadedLazyIterableDeclContexts 7,050,119 7,042,521 -7,598 -0.11%
Sema.OpaqueReadOwnershipRequest 292,887 292,887 0 0.0%
Sema.OpaqueResultTypeRequest 182 182 0 0.0%
Sema.OperatorPrecedenceGroupRequest 749 749 0 0.0%
Sema.OverriddenDeclsRequest 2,619,356 2,631,177 11,821 0.45%
Sema.ParamSpecifierRequest 1,344,908 1,344,900 -8 -0.0%
Sema.PatternBindingEntryRequest 507,999 507,994 -5 -0.0%
Sema.PatternTypeRequest 582,615 582,610 -5 -0.0%
Sema.PreCheckFunctionBuilderRequest 296 296 0 0.0%
Sema.PropertyWrapperBackingPropertyInfoRequest 582,232 582,232 0 0.0%
Sema.PropertyWrapperBackingPropertyTypeRequest 588,987 588,987 0 0.0%
Sema.PropertyWrapperMutabilityRequest 655,010 655,010 0 0.0%
Sema.PropertyWrapperTypeInfoRequest 109 109 0 0.0%
Sema.ProtocolRequiresClassRequest 45,179 45,105 -74 -0.16%
Sema.QualifiedLookupRequest 5,809,462 5,824,311 14,849 0.26%
Sema.RangeInfoRequest 0 0 0 0.0%
Sema.RequirementRequest 120,618 120,610 -8 -0.01%
Sema.RequirementSignatureRequest 843,889 844,705 816 0.1%
Sema.RequiresOpaqueAccessorsRequest 1,369,039 1,369,039 0 0.0%
Sema.RequiresOpaqueModifyCoroutineRequest 282,851 282,851 0 0.0%
Sema.ResilienceExpansionRequest 1,945,474 1,945,397 -77 -0.0%
Sema.ResolveEffectiveMemberwiseInitRequest 0 0 0 0.0%
Sema.ResolveImplicitMemberRequest 395,045 396,840 1,795 0.45%
Sema.ResolveProtocolNameRequest 0 0 0 0.0%
Sema.ResultTypeRequest 714,698 714,660 -38 -0.01%
Sema.RootAndResultTypeOfKeypathDynamicMemberRequest 0 0 0 0.0%
Sema.RootTypeOfKeypathDynamicMemberRequest 0 0 0 0.0%
Sema.ScopedImportLookupRequest 1,076 1,076 0 0.0%
Sema.SelfAccessKindRequest 683,416 684,053 637 0.09%
Sema.SelfBoundsFromWhereClauseRequest 1,945,066 1,946,557 1,491 0.08%
Sema.SetterAccessLevelRequest 151,520 151,520 0 0.0%
Sema.StorageImplInfoRequest 1,511,078 1,511,078 0 0.0%
Sema.StoredPropertiesAndMissingMembersRequest 34,665 34,665 0 0.0%
Sema.StoredPropertiesRequest 395,814 395,814 0 0.0%
Sema.StructuralTypeRequest 2,348 2,348 0 0.0%
Sema.SuperclassDeclRequest 521,091 521,862 771 0.15%
Sema.SuperclassTypeRequest 62,828 62,828 0 0.0%
Sema.SynthesizeAccessorRequest 306,956 306,956 0 0.0%
Sema.SynthesizeDefaultInitRequest 5,649 5,649 0 0.0%
Sema.SynthesizeMemberwiseInitRequest 3,739 3,739 0 0.0%
Sema.TypeCheckFunctionBodyUntilRequest 545,413 545,413 0 0.0%
Sema.TypeCheckSourceFileRequest 27,936 27,936 0 0.0%
Sema.TypeDeclsFromWhereClauseRequest 31,746 31,750 4 0.01%
Sema.TypeEraserHasViableInitRequest 0 0 0 0.0%
Sema.TypeRelationCheckRequest 0 0 0 0.0%
Sema.TypeWitnessRequest 10,221 10,208 -13 -0.13%
Sema.UnderlyingTypeDeclsReferencedRequest 316,993 315,331 -1,662 -0.52%
Sema.UnderlyingTypeRequest 40,147 40,143 -4 -0.01%
Sema.UnqualifiedLookupRequest 4,598,531 4,597,367 -1,164 -0.03%
Sema.ValidatePrecedenceGroupRequest 183,202 183,202 0 0.0%
Sema.ValueWitnessRequest 71,461 71,461 0 0.0%
TBDGen.GenerateTBDRequest 27,636 27,636 0 0.0%

Release

release brief

Regressed (0)
name old new delta delta_pct
Improved (0)
name old new delta delta_pct
Unchanged (delta < 1.0% or delta < 100.0ms) (3)
name old new delta delta_pct
Frontend.NumInstructionsExecuted 55,829,942,842,626 55,837,515,221,850 7,572,379,224 0.01%
LLVM.NumLLVMBytesOutput 1,866,065,852 1,866,076,928 11,076 0.0%
time.swift-driver.wall 10240.5s 10223.6s -16.9s -0.17%

release detailed

Regressed (0)
name old new delta delta_pct
Improved (0)
name old new delta delta_pct
Unchanged (delta < 1.0% or delta < 100.0ms) (17)
name old new delta delta_pct
AST.NumLoadedModules 31,947 31,947 0 0.0%
AST.NumTotalClangImportedEntities 468,456 468,456 0 0.0%
IRModule.NumIRBasicBlocks 4,940,416 4,940,416 0 0.0%
IRModule.NumIRFunctions 2,841,916 2,841,916 0 0.0%
IRModule.NumIRGlobals 3,343,375 3,343,375 0 0.0%
IRModule.NumIRInsts 50,000,387 50,000,387 0 0.0%
IRModule.NumIRValueSymbols 5,816,728 5,816,728 0 0.0%
LLVM.NumLLVMBytesOutput 1,866,065,852 1,866,076,928 11,076 0.0%
SILModule.NumSILGenFunctions 1,232,369 1,232,369 0 0.0%
SILModule.NumSILOptFunctions 1,037,034 1,037,034 0 0.0%
Sema.NumConformancesDeserialized 3,567,782 3,567,782 0 0.0%
Sema.NumConstraintScopes 32,431,640 32,431,640 0 0.0%
Sema.NumDeclsDeserialized 11,131,893 11,131,893 0 0.0%
Sema.NumGenericSignatureBuilders 278,159 278,159 0 0.0%
Sema.NumLazyIterableDeclContexts 1,382,628 1,382,628 0 0.0%
Sema.NumTypesDeserialized 5,409,179 5,409,179 0 0.0%
Sema.NumTypesValidated 850,045 850,045 0 0.0%

@CodaFi
Copy link
Contributor Author

CodaFi commented Apr 1, 2020

⛵️

@CodaFi CodaFi merged commit aa0bf50 into swiftlang:master Apr 1, 2020
@CodaFi CodaFi deleted the dependendable-dependencies branch April 1, 2020 01:13
@CodaFi CodaFi mentioned this pull request May 20, 2020
CodaFi added a commit to CodaFi/swift that referenced this pull request May 20, 2020
Split off the notion of "recording" dependencies from the notion of
"collecting" dependencies. This corrects an oversight in the previous
design where dependency replay and recording were actually not "free" in
WMO where we actually never track dependencies. This architecture also
lays the groundwork for the removal of the referenced name trackers.

The algorithm builds upon the infrastructure for dependency sources and
sinks laid down during the cut over to request-based dependency tracking
in swiftlang#30723.

The idea of the naive algorithm is this:

For a chain of requests A -> B* -> C -> D* -> ... -> L where L is a lookup
request and all starred requests are cached, once L writes into the
dependency collector, the active stack is walked and at each cache-point
the results of dependency collection are associated with the request
itself (in this example, B* and D* have all the names L found associated
with them). Subsequent evaluations of these cached requests (B* and D*
et al) will then *replay* the previous lookup results from L into the
active referenced name tracker. One complication is, suppose the
evaluation of a cached request involves multiple downstream name
lookups. More concretely, suppose we have the following request trace:

A* -> B -> L
      |
       -> C -> L
          |
           -> D -> L
              |
               -> ...

Then A* must see the union of the results of each L. If this reminds
anyone of a union-find, that is no accident! A persistent union-find
a la Conchon and Filliatre is probably in order to help bring down peak
heap usage...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants