[3.1] [Constraint solver] Handle disjunctions as separate connected components#7658
Merged
tkremenek merged 1 commit intoswiftlang:swift-3.1-branchfrom Feb 21, 2017
Merged
Conversation
…nts. The constraint graph models type variables (as the nodes) and constraints (as the multi-edges connecting nodes). The connected components within this (multi-)graph are independent subproblems that are solved separately; the results from each subproblem are then combined. The approach helps curtail exponential behavior, because (e.g.) the disjunctions/type variables in one component won't ever be explored while solving for another component This approach assumes that all of the constraints that cannot be immediately solved are associated with one or more type variables. This is almost entirely true---constraints that don't involve type variables are immediately simplified. Except for disjunctions. A disjunction involving no type variables would not appear *at all* in the constraint graph. Worse, it's independence from other constraints could not be established, so the constraint solver would go exponential for every one of these constraints. This has always been an issue, but it got worse with the separation of type checking of "as" into the "coercion" case and the "bridging" case, which introduced more of these disjunctions. This led to counterintuitive behavior where adding "as Foo" would cause the type checking to take *more* time than leaving it off, if both sides of the "as" were known to be concrete. rdar://problem/30545483 captures a case (now in the new test case) where we saw such exponential blow-ups. Teach the constraint graph to keep track of "orphaned" constraints that don't reference any type variables, and treat each "orphaned" constraint as a separate connected component. That way, they're solved independently. Fixes rdar://problem/30545483 and will likely curtain other exponential behavior we're seeing in the solver.
Member
Author
|
@swift-ci please test |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The constraint graph models type variables (as the nodes) and
constraints (as the multi-edges connecting nodes). The connected
components within this (multi-)graph are independent subproblems that
are solved separately; the results from each subproblem are then
combined. The approach helps curtail exponential behavior, because
(e.g.) the disjunctions/type variables in one component won't ever be
explored while solving for another component
This approach assumes that all of the constraints that cannot be
immediately solved are associated with one or more type
variables. This is almost entirely true---constraints that don't
involve type variables are immediately simplified.
Except for disjunctions. A disjunction involving no type variables
would not appear at all in the constraint graph. Worse, it's
independence from other constraints could not be established, so the
constraint solver would go exponential for every one of these
constraints. This has always been an issue, but it got worse with the
separation of type checking of "as" into the "coercion" case and the
"bridging" case, which introduced more of these disjunctions. This led
to counterintuitive behavior where adding "as Foo" would cause the
type checking to take more time than leaving it off, if both sides
of the "as" were known to be concrete. rdar://problem/30545483
captures a case (now in the new test case) where we saw such
exponential blow-ups.
Teach the constraint graph to keep track of "orphaned" constraints
that don't reference any type variables, and treat each "orphaned"
constraint as a separate connected component. That way, they're solved
independently.
Fixes rdar://problem/30545483 and will likely curtain other
exponential behavior we're seeing in the solver.