-
Notifications
You must be signed in to change notification settings - Fork 10.5k
[CSBindings] Cache already computed type variable bindings #19852
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
Conversation
@swift-ci please smoke test compiler performance |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some optional comments, but I don’t claim to understand this part of the type checker too well
@@ -1,4 +1,4 @@ | |||
// RUN: %scale-test --invert-result --begin 1 --end 5 --step 1 --select incrementScopeCounter %s --expected-exit-code 1 | |||
// RUN: %scale-test --invert-result --begin 1 --end 4 --step 1 --select incrementScopeCounter %s --expected-exit-code 1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why did you change this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because scale test can’t fit the curve with these changes unfortunately...
if (auto bindings = getPotentialBindings(typeVar)) | ||
cache.insert({typeVar, std::move(bindings)}); | ||
Bindings.insert({typeVar, std::move(bindings)}); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you want to assert that the insertion succeeded?
lib/Sema/CSSimplify.cpp
Outdated
@@ -1561,6 +1561,7 @@ ConstraintSystem::matchTypesBindTypeVar( | |||
} | |||
|
|||
assignFixedType(typeVar, type); | |||
invalidateBindings(typeVar); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are there any other callers of assignFixedType() that need to do this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am considering unifying both assign and merge paths, want to run perf test first before I spend more time on this...
lib/Sema/CSSimplify.cpp
Outdated
@@ -1688,6 +1689,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind, | |||
|
|||
// Merge the equivalence classes corresponding to these two variables. | |||
mergeEquivalenceClasses(rep1, rep2); | |||
invalidateBindings(rep1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe do this in mergeEquivalenceClasses()?
@swift-ci please test source compatibility |
Failure was:
Let's try again... |
@swift-ci please clean test source compatibility |
@swift-ci please test source compatibility |
Not sure what's up with this linker error, going to wait for a bit before running the suite again... |
@rudkx For problems with huge collections of literals, these changes cut type-check time significantly e.g. rdar://problem/26877601 (which used to be stack overflow) it reduced it from 6 minutes to 1:54 on my machine... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So is the assumption here that having more types as potential bindings than is strictly necessary always safe? (which seems on the surface to be true)
If so it’s not clear that you actually need to invalidate bindings when merging type variables, but could instead merge bindings.
@rudkx Yes, that’s an assumption. I am just trying to take it one step at a time, the problem with updating bindings in-place is that we don’t currently record bindings which bind two type variables directly, so that has to be fixed before update in-place is possible... |
@swift-ci please test |
@swift-ci please test source compatibility |
bd72fc6
to
cb887c8
Compare
@swift-ci please test |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
@rudkx If you don't have any objections I'm going to merge this soon... |
SGTM! |
cb887c8
to
6378923
Compare
To avoid re-computing same bindings over and over again, let's try to keep a cache of active bindings and invalidate them as needed. Invalidate bindings conservatively when new constraints are introduced (even if such constraints are not going to result in new type bindings), and when type variables are assigned fixed types or merged together. Invalidation also makes sure to erase bindings of all adjacent type variables related to equivalence class of the variables in question. This significantly speeds up use-cases that have a lot of type variables such as collection literals with arbitrary nesting.
6378923
to
18da183
Compare
@swift-ci please test |
@swift-ci please test source compatibility |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
@swift-ci please smoke test |
@swift-ci please test |
Build failed |
@swift-ci please test macOS platform |
@swift-ci please test source compatibility |
To avoid re-computing same bindings over and over again,
let's try to keep a cache of active bindings and invalidate
them as needed.
Invalidate bindings conservatively when new constraints are
introduced (even if such constraints are not going to result
in new type bindings), and when type variables are assigned
fixed types or merged together.
Invalidation also makes sure to erase bindings of all adjacent
type variables related to equivalence class of the variables
in question.
This significantly speeds up use-cases which have a lot of type
variables such as collection literals with arbitrary nesting.