close
Skip to content

[3.1] [Constraint solver] Handle disjunctions as separate connected components#7658

Merged
tkremenek merged 1 commit intoswiftlang:swift-3.1-branchfrom
DougGregor:orphaned-constraints-3.1
Feb 21, 2017
Merged

[3.1] [Constraint solver] Handle disjunctions as separate connected components#7658
tkremenek merged 1 commit intoswiftlang:swift-3.1-branchfrom
DougGregor:orphaned-constraints-3.1

Conversation

@DougGregor
Copy link
Copy Markdown
Member

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.

…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.
@DougGregor
Copy link
Copy Markdown
Member Author

@swift-ci please test

@DougGregor DougGregor changed the title [Constraint solver] Handle disjunctions as separate connected components [3.1] [Constraint solver] Handle disjunctions as separate connected components Feb 21, 2017
@DougGregor DougGregor added this to the Swift 3.1 milestone Feb 21, 2017
@DougGregor DougGregor requested a review from rudkx February 21, 2017 04:36
Copy link
Copy Markdown
Contributor

@rudkx rudkx left a comment

Choose a reason for hiding this comment

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

LGTM!

@tkremenek tkremenek merged commit 51795d3 into swiftlang:swift-3.1-branch Feb 21, 2017
@DougGregor DougGregor deleted the orphaned-constraints-3.1 branch February 21, 2017 07:06
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.

3 participants