Skip to content

[Constraint graph] Eliminate adjacency information in the graph nodes. #26347

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

Conversation

DougGregor
Copy link
Member

Each constraint graph node maintained adjacency information that was
fairly expensive---a vector of type variables and a dense map of extra
adjacency information---and that was continuously maintained. Remove
this adjacency information, instead recomputing it by walking the
constraints (to get their type variables) and having a separate
(smaller) list of type variables that are adjacent due to fixed
bindings. This simplifies the constraint graph code and reduces
per-node memory overhead.

The constraint graph maintains a fairly heavyweight list of
adjacencies that is only used in two operations: connected components
and gathering related constraints. Switch connected components over to
primarily use the set of constraints (which are necessary for many
reasons), reducing the need for the adjacencies list.
…adjacencies list.

Use the adjacencies implied by the constraints of a node rather than looking
at the "adjacency" list, and try to simplify this code path a bit. The
diagnostic change is because we are now uniformly recording the
members of the equivalence class.
Each constraint graph node maintained adjacency information that was
fairly expensive---a vector of type variables and a dense map of extra
adjacency information---and that was continuously maintained. Remove
this adjacency information, instead recomputing it by walking the
constraints (to get their type variables) and having a separate
(smaller) list of type variables that are adjacent due to fixed
bindings. This simplifies the constraint graph code and reduces
per-node memory overhead.
Simplify the interface to gatherConstraints() by performing the
uniquing within the function itself and returning only the resulting
(uniqued) vector of constraints.
@DougGregor
Copy link
Member Author

@swift-ci please smoke test

@DougGregor
Copy link
Member Author

@swift-ci please test compiler performance

@slavapestov
Copy link
Contributor

Awesome!

// If we want all mentions, visit type variables within each of our
// constraints.
if (kind == GatheringKind::AllMentions) {
for (auto adjTypeVar : constraint->getTypeVariables()) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the idea behind caching adjacency is based on the observation that we add constraints a lot less often than we gather them (e.g. to determine bindings), this algorithm is going to be less efficient (maybe not really reflecting in the wall time) because it would iterate over the same equivalence class N times based on the number of unique constraints in each node because equivalence class always includes "self".

Copy link
Contributor

Choose a reason for hiding this comment

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

On the other hand, DenseMap in particular is quite heavyweight in terms of memory usage, even when empty, IIRC

Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if that size is justified vs. having to allocate/grow and destruct sets of constraints every time we gather which is very often... I'm not saying that I'm against this, just thought that this is worse mentioning.

Copy link
Member Author

Choose a reason for hiding this comment

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

I was looking at gatherConstraints, and it was a pretty expensive operation both before and after this change, because it is grabbing constraints from a number of different adjacent type variables and uniquing them along the way. This new implementation is doing basically the same work, but instead of getting the type variables from the stored "adjacencies", we get them from the constraints we are already walking. We do the same uniquing of constraints and of type variables.

This simplification has another purpose, which is to make it easier to ignore specific constraints when performing connected components, so that we can handle one-way constraints specially (#25983).

@swift-ci
Copy link
Contributor

Summary for master full

Unexpected test results, excluded stats for RxCocoa, Deferred, Wordy

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 43,616,165,192,612 43,826,689,072,030 210,523,879,418 0.48%
LLVM.NumLLVMBytesOutput 1,755,817,728 1,755,812,284 -5,444 -0.0%
time.swift-driver.wall 4371.4s 4351.2s -20.3s -0.46%

debug-batch detailed

Regressed (4)
name old new delta delta_pct
Sema.AccessLevelRequest 10,990,478 11,187,595 197,117 1.79% ⛔
Sema.CollectOverriddenDeclsRequest 6,589,772 6,731,524 141,752 2.15% ⛔
Sema.ProvideDefaultImplForRequest 6,589,772 6,731,524 141,752 2.15% ⛔
Sema.USRGenerationRequest 7,762,556 7,904,284 141,728 1.83% ⛔
Improved (5)
name old new delta delta_pct
Driver.NumDriverPipePolls 82,939 81,824 -1,115 -1.34% ✅
Driver.NumDriverPipeReads 77,265 76,373 -892 -1.15% ✅
Sema.NumConstraintScopes 25,885,812 24,910,242 -975,570 -3.77% ✅
Sema.NumConstraintsConsideredForEdgeContraction 76,995,883 74,874,238 -2,121,645 -2.76% ✅
Sema.NumLeafScopes 16,674,118 16,107,767 -566,351 -3.4% ✅
Unchanged (delta < 1.0% or delta < 100.0ms) (123)
name old new delta delta_pct
AST.NumASTBytesAllocated 64,470,201,558 65,006,234,024 536,032,466 0.83%
AST.NumDecls 138,061 138,061 0 0.0%
AST.NumDependencies 314,366 314,370 4 0.0%
AST.NumInfixOperators 53,208 53,208 0 0.0%
AST.NumLinkLibraries 0 0 0 0.0%
AST.NumLoadedModules 389,794 389,794 0 0.0%
AST.NumLocalTypeDecls 246 246 0 0.0%
AST.NumObjCMethods 24,686 24,686 0 0.0%
AST.NumPostfixOperators 23 23 0 0.0%
AST.NumPrecedenceGroups 25,153 25,153 0 0.0%
AST.NumPrefixOperators 164 164 0 0.0%
AST.NumReferencedDynamicNames 189 189 0 0.0%
AST.NumReferencedMemberNames 6,301,632 6,301,702 70 0.0%
AST.NumReferencedTopLevelNames 467,699 467,699 0 0.0%
AST.NumSourceBuffers 552,727 552,727 0 0.0%
AST.NumSourceLines 4,663,328 4,663,328 0 0.0%
AST.NumSourceLinesPerSecond 3,574,260 3,577,677 3,417 0.1%
AST.NumTotalClangImportedEntities 6,711,857 6,720,591 8,734 0.13%
Driver.ChildrenMaxRSS 212,549,445,632 212,835,282,944 285,837,312 0.13%
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 26,758 26,758 0 0.0%
Driver.NumDriverJobsSkipped 0 0 0 0.0%
Driver.NumProcessFailures 0 0 0 0.0%
Frontend.MaxMallocUsage 1,265,554,853,080 1,270,323,890,552 4,769,037,472 0.38%
Frontend.NumInstructionsExecuted 43,616,165,192,612 43,826,689,072,030 210,523,879,418 0.48%
Frontend.NumProcessFailures 0 0 0 0.0%
IRModule.NumIRAliases 194,005 194,005 0 0.0%
IRModule.NumIRBasicBlocks 7,014,185 7,014,185 0 0.0%
IRModule.NumIRComdatSymbols 0 0 0 0.0%
IRModule.NumIRFunctions 3,278,774 3,278,774 0 0.0%
IRModule.NumIRGlobals 3,358,590 3,358,590 0 0.0%
IRModule.NumIRIFuncs 0 0 0 0.0%
IRModule.NumIRInsts 85,574,383 85,574,383 0 0.0%
IRModule.NumIRNamedMetaData 129,435 129,435 0 0.0%
IRModule.NumIRValueSymbols 5,997,658 5,997,658 0 0.0%
LLVM.NumLLVMBytesOutput 1,755,817,728 1,755,812,284 -5,444 -0.0%
Parse.NumFunctionsParsed 264,509 264,509 0 0.0%
Parse.NumIterableDeclContextParsed 1,808,927 1,808,927 0 0.0%
SILModule.NumSILGenDefaultWitnessTables 0 0 0 0.0%
SILModule.NumSILGenFunctions 1,697,275 1,697,275 0 0.0%
SILModule.NumSILGenGlobalVariables 62,988 62,988 0 0.0%
SILModule.NumSILGenVtables 17,421 17,421 0 0.0%
SILModule.NumSILGenWitnessTables 71,193 71,193 0 0.0%
SILModule.NumSILOptDefaultWitnessTables 0 0 0 0.0%
SILModule.NumSILOptFunctions 2,383,947 2,383,947 0 0.0%
SILModule.NumSILOptGlobalVariables 64,608 64,608 0 0.0%
SILModule.NumSILOptVtables 29,738 29,738 0 0.0%
SILModule.NumSILOptWitnessTables 156,149 156,149 0 0.0%
Sema.AttachedFunctionBuilderRequest 4 4 0 0.0%
Sema.AttachedPropertyWrapperTypeRequest 510,712 510,712 0 0.0%
Sema.AttachedPropertyWrappersRequest 2,417,290 2,417,290 0 0.0%
Sema.CursorInfoRequest 0 0 0 0.0%
Sema.CustomAttrNominalRequest 14 14 0 0.0%
Sema.DefaultAndMaxAccessLevelRequest 95,558 95,562 4 0.0%
Sema.DefaultDefinitionTypeRequest 8,076 8,076 0 0.0%
Sema.DefaultTypeRequest 501,413 501,393 -20 -0.0%
Sema.EnumRawTypeRequest 25,284 25,284 0 0.0%
Sema.ExistentialConformsToSelfRequest 22,790 22,880 90 0.39%
Sema.ExistentialTypeSupportedRequest 17,169 17,169 0 0.0%
Sema.ExtendedNominalRequest 5,298,228 5,317,875 19,647 0.37%
Sema.FunctionBuilderTypeRequest 4 4 0 0.0%
Sema.InheritedDeclsReferencedRequest 6,137,387 6,161,302 23,915 0.39%
Sema.InheritedTypeRequest 333,584 333,772 188 0.06%
Sema.IsDeclApplicableRequest 0 0 0 0.0%
Sema.IsDynamicRequest 1,691,900 1,691,900 0 0.0%
Sema.IsFinalRequest 4,441,211 4,459,608 18,397 0.41%
Sema.IsGetterMutatingRequest 498,577 498,577 0 0.0%
Sema.IsObjCRequest 1,669,323 1,671,534 2,211 0.13%
Sema.IsSetterMutatingRequest 378,879 378,879 0 0.0%
Sema.LazyStoragePropertyRequest 3,205 3,205 0 0.0%
Sema.MangleLocalTypeDeclRequest 492 492 0 0.0%
Sema.NamedLazyMemberLoadFailureCount 34,732 34,723 -9 -0.03%
Sema.NamedLazyMemberLoadSuccessCount 31,357,880 31,352,389 -5,491 -0.02%
Sema.NominalTypeLookupDirectCount 37,627,520 37,708,640 81,120 0.22%
Sema.NumAccessorBodiesSynthesized 186,104 186,104 0 0.0%
Sema.NumAccessorsSynthesized 403,144 403,144 0 0.0%
Sema.NumConformancesDeserialized 9,333,163 9,412,657 79,494 0.85%
Sema.NumDeclsDeserialized 71,536,500 72,108,787 572,287 0.8%
Sema.NumDeclsFinalized 717,993 717,993 0 0.0%
Sema.NumDeclsTypechecked 1,390,990 1,390,990 0 0.0%
Sema.NumDeclsValidated 2,776,104 2,776,127 23 0.0%
Sema.NumFunctionsTypechecked 519,305 519,305 0 0.0%
Sema.NumGenericSignatureBuilders 1,450,381 1,456,440 6,059 0.42%
Sema.NumLazyGenericEnvironments 12,930,022 13,037,408 107,386 0.83%
Sema.NumLazyGenericEnvironmentsLoaded 312,954 313,173 219 0.07%
Sema.NumLazyIterableDeclContexts 9,462,972 9,487,621 24,649 0.26%
Sema.NumLazyRequirementSignatures 990,662 991,609 947 0.1%
Sema.NumLazyRequirementSignaturesLoaded 643,279 644,103 824 0.13%
Sema.NumTypesDeserialized 21,455,865 21,570,678 114,813 0.54%
Sema.NumTypesValidated 2,421,261 2,421,297 36 0.0%
Sema.NumUnloadedLazyIterableDeclContexts 6,226,697 6,216,274 -10,423 -0.17%
Sema.OpaqueReadOwnershipRequest 531,878 531,878 0 0.0%
Sema.OverriddenDeclsRequest 2,375,589 2,394,894 19,305 0.81%
Sema.PropertyWrapperBackingPropertyInfoRequest 505,408 505,408 0 0.0%
Sema.PropertyWrapperBackingPropertyTypeRequest 510,712 510,712 0 0.0%
Sema.PropertyWrapperTypeInfoRequest 4 4 0 0.0%
Sema.ProtocolRequiresClassRequest 92,760 92,929 169 0.18%
Sema.RangeInfoRequest 0 0 0 0.0%
Sema.RequirementRequest 109,444 109,451 7 0.01%
Sema.RequirementSignatureRequest 745,901 746,882 981 0.13%
Sema.ResolveProtocolNameRequest 0 0 0 0.0%
Sema.SelfAccessKindRequest 6,643,891 6,641,960 -1,931 -0.03%
Sema.SelfBoundsFromWhereClauseRequest 7,855,839 7,893,637 37,798 0.48%
Sema.SetterAccessLevelRequest 149,277 149,277 0 0.0%
Sema.StorageImplInfoRequest 932,490 932,490 0 0.0%
Sema.StoredPropertiesAndMissingMembersRequest 31,962 31,962 0 0.0%
Sema.StoredPropertiesRequest 399,620 399,620 0 0.0%
Sema.StructuralTypeRequest 0 0 0 0.0%
Sema.SuperclassDeclRequest 496,439 497,491 1,052 0.21%
Sema.SuperclassTypeRequest 62,030 62,030 0 0.0%
Sema.TypeCheckFunctionBodyUntilRequest 519,305 519,305 0 0.0%
Sema.TypeDeclsFromWhereClauseRequest 50,115 50,119 4 0.01%
Sema.TypeRelationCheckRequest 0 0 0 0.0%
Sema.UnderlyingTypeDeclsReferencedRequest 275,536 276,488 952 0.35%

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 46,446,499,558,062 46,349,519,539,314 -96,980,018,748 -0.21%
LLVM.NumLLVMBytesOutput 1,549,394,280 1,549,394,068 -212 -0.0%
time.swift-driver.wall 8011.5s 7973.2s -38.3s -0.48%

release detailed

Regressed (0)
name old new delta delta_pct
Improved (1)
name old new delta delta_pct
Sema.NumConstraintScopes 25,431,352 24,446,326 -985,026 -3.87% ✅
Unchanged (delta < 1.0% or delta < 100.0ms) (20)
name old new delta delta_pct
AST.NumLoadedModules 27,679 27,679 0 0.0%
AST.NumTotalClangImportedEntities 1,235,106 1,235,106 0 0.0%
IRModule.NumIRBasicBlocks 6,367,333 6,367,333 0 0.0%
IRModule.NumIRFunctions 2,800,642 2,800,642 0 0.0%
IRModule.NumIRGlobals 2,975,004 2,975,004 0 0.0%
IRModule.NumIRInsts 55,881,078 55,881,078 0 0.0%
IRModule.NumIRValueSymbols 5,428,489 5,428,489 0 0.0%
LLVM.NumLLVMBytesOutput 1,549,394,280 1,549,394,068 -212 -0.0%
SILModule.NumSILGenFunctions 1,188,845 1,188,845 0 0.0%
SILModule.NumSILOptFunctions 1,593,141 1,593,141 0 0.0%
Sema.NumConformancesDeserialized 3,674,193 3,674,193 0 0.0%
Sema.NumDeclsDeserialized 9,765,777 9,765,777 0 0.0%
Sema.NumDeclsValidated 1,834,428 1,834,428 0 0.0%
Sema.NumFunctionsTypechecked 523,119 523,119 0 0.0%
Sema.NumGenericSignatureBuilders 285,049 285,049 0 0.0%
Sema.NumLazyGenericEnvironments 1,892,072 1,892,072 0 0.0%
Sema.NumLazyGenericEnvironmentsLoaded 34,557 34,557 0 0.0%
Sema.NumLazyIterableDeclContexts 1,212,898 1,212,898 0 0.0%
Sema.NumTypesDeserialized 5,049,378 5,049,378 0 0.0%
Sema.NumTypesValidated 1,117,659 1,117,659 0 0.0%

@xedin
Copy link
Contributor

xedin commented Jul 26, 2019

Hm, this is interesting, I wouldn't expect number of scopes to go down with these changes...

@DougGregor
Copy link
Member Author

Hm, this is interesting, I wouldn't expect number of scopes to go down with these changes...

There was one small behavioral change in this rewrite, which is that we weren't looking at constraints for type variables in the equivalence class of adjacent type variables, which could be responsible for the reduction in the number of scores... I think that behavioral change is properly captured by a separate PR I just put up at #26368.

@xedin
Copy link
Contributor

xedin commented Jul 26, 2019

My worry about that is related to how we determine bindings based on these constraints, if we are not getting as many constraints as before, it might mean we’ll not be able to find some solutions we do today.

@DougGregor DougGregor merged commit e6e6307 into swiftlang:master Jul 26, 2019
@DougGregor DougGregor deleted the constraint-graph-remove-adjacencies branch July 26, 2019 03:41
@DougGregor
Copy link
Member Author

We are getting more constraints, not fewer, because we were artificially skipping related constraints.

@xedin
Copy link
Contributor

xedin commented Jul 26, 2019

Ah, I misread your previous comment. I see what you mean now, hopefully that doesn't cause any source compatibility regressions.

case .init(opt: 0): break // expected-error{{value of optional type 'StaticMembers?' must be unwrapped to a value of type 'StaticMembers'}}
// expected-note@-1{{force-unwrap using '!' to abort execution if the optional value contains 'nil'}}
// expected-note@-2{{coalesce using '??' to provide a default when the optional value contains 'nil'}}
case .init(opt: 0): break // expected-error{{pattern cannot match values of type 'StaticMembers'}}
Copy link
Contributor

Choose a reason for hiding this comment

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

Looks like removing UR_LabelingMismatch and related changes fixed this diagnostic back to diagnose as missing force unwrap.

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.

4 participants