Commit Graph

195 Commits

Author SHA1 Message Date
Doug Gregor
c2a9286d1d [Constraint graph] Print only those type variables that are of interest now 2019-08-05 22:21:21 -07:00
Doug Gregor
0b61f86a4a [Constraint solver] No need to associate bound type variables everywhere.
When we are associating type variables with components in a “split” step,
there is no need to record already-bound type variables with every component.
2019-08-05 17:06:52 -07:00
Pavel Yaskevich
ded44b4919 [CSStep] Attempt all disabled disjunction choices in diagnostic mode 2019-07-25 00:36:00 -07:00
Pavel Yaskevich
731ec39c24 [CSStep] Properly finalize component step without follow-up steps
Currently finalization e.g. scope reset and solution minimization
is only done if component step had follow-up e.g. type variable or
disjunction step(s), but it should be done if `take` generated any
fixes as well, or component changed score in any way, otherwise
we might miss some solutions with fixes because "best score" haven't
been reset properly.
2019-07-17 18:04:11 -07:00
Suyash Srijan
aaacd29b68 [ConstraintSystem] Adds the new overload to FailureDiagnostic as well and remove other instances of 0 summary flags 2019-06-24 22:33:38 +01:00
Pavel Yaskevich
c30845fa74 [ConstraintSystem] Detect and diagnose missing generic arguments
Introduce a fix to detect and diagnose situations when omitted
generic arguments couldn't be deduced by the solver based on
the enclosing context.

Example:

```swift
struct S<T> {
}

_ = S() // There is not enough context to deduce `T`
```

Resolves: rdar://problem/51203824
2019-05-29 16:39:41 -07:00
Gwen Mittertreiner
e51b72b3e0 Reduce the Stack Size of ConstraintSystem
The ConstraintSystem class is on the order of 1000s of bytes in size on
the stacka nd is causing issues with dispatch's 64k stack limit.

This changes most Small data types which store data on the stack to non
small heap based data types.
2019-05-13 11:40:43 -07:00
Pavel Yaskevich
8b5396bbac [CSSolver] Attempt disabled disjunction choices only if they have a fix
This draws a distinction between disabled choices with and without
fixes - former is disabled because it's unrelated, latter because
it only makes sense to attempt it during "salvage" mode while trying
to produce diagnostics.
2019-03-14 13:18:42 -07:00
Stephen Canon
6159ba810d Remove the (unused) SIMDOperators module. (#22530)
We originally planned to use this to hide some simd operators from the typechecker unless the user explicitly opted into having them but that scheme turned out to be ill-conceived, so we moved them
back into the stdlib. This change simply cleans up the empty vestigial module.
2019-02-14 16:37:41 -08:00
Doug Gregor
052d4c196c [Type checker] Pull the null check into swift::isSIMDOperator(). 2018-12-11 16:39:10 -08:00
Doug Gregor
88d34a1c7c [Constraint solver] De-priority SIMD operators.
The new SIMD proposal introduced a number of new operators, the presence of
which causes more "expression too complex" failures. Route around the
problem by de-prioritizing those operators, visiting them only if no
other operator could be chosen. This should limit the type checker
performance cost of said operators to only those expressions that need
them OR that already failed to type-check.

Fixes rdar://problem/46541800.
2018-12-11 16:34:37 -08:00
Pavel Yaskevich
7360cbcf9e [ComponentStep] NFC: Remove redundant numComponents check for debug output 2018-10-15 15:54:45 -07:00
Mark Lacey
6a3aa75932 [ConstraintSystem] Tweak -disable-constraint-solver-performance-hacks.
Allow a couple of the tests in shortCircuitDisjunctionAt() to run even
when hacks are disabled.

The first of these tests is imperfect since it assumes that "favored"
disjunction choices all come before the others (which may be the case
now but is pretty brittle).

Similarly, the second of these tests assumes that choices that are
fixes always come after ones that are not.

What we really want to do is skip these choices rather than stopping
at these points.
2018-10-04 17:09:19 -07:00
Mark Lacey
7e0c7040c0 [ConstraintSystem] Use shouldStopAt to limit disjunction choices.
Rather than using shouldStopAfter, use shouldStopAt, and check if
we're at the beginning of a disjunction (with an already successful
solution).
2018-09-26 13:42:40 -07:00
Pavel Yaskevich
091a757e5d [CSStep] Allocate component scopes only if siblings didn't fail
If sibling components failed, there is no reason to establish new
scope since remaining containers are not really going to be taken
but fail fast instead.
2018-09-20 11:04:26 -07:00
Pavel Yaskevich
f9452afa4f [CSStep] NFC: Unify type binding attempt logging
Instead of printing `trying` for type variable and `assuming`
for disjunction choices, unify it so `BindingStep` logs
`attempting {type variable, disjunction choice}`.
2018-09-19 18:37:36 -07:00
Pavel Yaskevich
8daaf905d6 [CSStep] Switch to use std::unique_ptr for work list
Instead of manually managing lifetime of the steps, let's just
use `std::unique_ptr` instead.
2018-09-19 11:19:15 -07:00
Pavel Yaskevich
de34d9fa6a [CSStep] Extract common type-var/disjunction functionality into BindingStep
Unify `take` implementation and API for type variable
and disjunction via `BindingStep` which accepts a producer.
2018-09-17 15:16:04 -07:00
Pavel Yaskevich
bec3d28407 [CSStep] Add isDebugMode and getDebugLogger methods and refactor logging
Instead of using `TypeChecker` and related APIs directly every time,
let's just abstract it all away to easily check if solver is running
in debug mode and to produce indented logger.
2018-09-15 20:56:47 -07:00
Pavel Yaskevich
c3a4434f3e [ConstraintSystem] Integrate emergency break into iterative solver loop
There are situations when solver goes exponential, before
(when solver was recursive) it would fail relatively quickly by running
out of stack space, now we really need to make sure that emergency
break is in place in main solver loop, otherwise we risk it running for
a really long time if doesn't consume too much memory since default
timeout is ~10 mins.
2018-09-15 20:56:47 -07:00
Pavel Yaskevich
f1a53c3f59 [ConstraintSystem] Remove unnecessary forward declarations of the steps
Also move `DisjunctionStep` from being a friend of `ConstraintSystem`
because it's not strictly necessary.
2018-09-15 20:56:47 -07:00
Pavel Yaskevich
6cf11b31f9 [CSStep/TypeVar] Check if loop should be stopped even if current binding has failed
Eagerly check if optimal solution has already been found even if
current binding attempt has failed, because otherwise it might
check too many bindings which would result in ambiguity.
2018-09-15 20:56:47 -07:00
Pavel Yaskevich
4f50710457 [CSStep] Use # of disjunctions directly to determine component ordering 2018-09-15 20:56:47 -07:00
Pavel Yaskevich
198003dd04 [CSStep] Record all of the type vars related to component while creating a split
Before this change some of the type variables, especially the ones
that have been previously bound haven't been associated with any
of the component steps, so it had to be done by scope once per step,
but now such recording is done once per split.
2018-09-15 20:56:47 -07:00
Pavel Yaskevich
58ad04d417 [CSStep] Filter solutions only if component is part of a large split 2018-09-15 20:56:47 -07:00
Pavel Yaskevich
b86aa22fca [CSStep] Try to simplify constraint system before performing split 2018-09-15 20:56:47 -07:00
Pavel Yaskevich
a2ba0021c3 [CSStep] Rework how orphaned constraints are handled by splitter/component steps
Orphaned constraints can be re-introduced to the system by `setup`
of the component, and all of them could be returned back by
`SplitterStep::resume` there so no need to use destructor for that.

Also, orphan constraints have to be registered as regular constraints
by components as well as marked as "orphaned".
2018-09-15 20:56:47 -07:00
Pavel Yaskevich
a6682ec5f2 [CSStep] Include related and bound type variables as "in scope"
Re-introduce all type variables which either belong to the given
component or are already bound.
2018-09-15 20:56:47 -07:00
Pavel Yaskevich
0d3c804c18 [DisjunctionStep] Start remembering choices when requested
Extract choice attempting logic into `DisjunctionStep::attemptChoice`
and start recording taken choices in constraint system when
requested by disjunction.
2018-09-15 20:56:47 -07:00
Pavel Yaskevich
0930cb9e37 [CSStep] If previous step before split failed don't do anything 2018-09-15 20:56:46 -07:00
Pavel Yaskevich
ac13752550 [CSStep] Restore original best score after component is done 2018-09-15 20:56:46 -07:00
Pavel Yaskevich
97b157f9fb [CSStep] Make sure that components are sorter before execution
Execute components with fewer disjunction constraints first,
to make sure that if one of the components fails we do the
smallest amount of work possible.
2018-09-15 20:56:46 -07:00
Pavel Yaskevich
f9fcd271e7 [CSStep] Rework how splitter handles component steps
First of all, let the splitter transfer constraints from inactive
work-list to associated components. Also start tracking components
to reinstate constraints back to constraint system when everything
is done, this allows to execute component steps in any desirable order.
2018-09-15 20:56:46 -07:00
Pavel Yaskevich
64c4d0e072 [CSStep] Fix a bug in DisjunctionStep::resume caused by was discarding active choice too early 2018-09-15 20:56:46 -07:00
Pavel Yaskevich
cdc9810f00 [CSStep] Split SolverStep::take(bool) into setup, take and resume
Introduce a notion of `StepState` with some valid transitions,
and split monolithic `take(bool)` into three phases - `setup`, `take`, and
`resume`.

* `setup` - is preliminary state before the step has been taken
            for the first time.

* `take` - represents actual logic of the step, results in either
           step being done or suspended.

* `resume` - `take` might split steps into smaller ones to make
             incremental progress towards the target, which means
             that the main step has to be suspended. `resume` is
             triggered when all of the "follow-up" steps have been
             executed and are "done".
2018-09-15 20:56:46 -07:00
Pavel Yaskevich
f66592e0a7 [CSStep] Don't allocate scope if there is only one component
If "split" step produced a single component, there is no reason
to allocate a scope for it and modify constraint system,
because all of the existing type variables and constraints
are related to it anyway, so scope would just end up doing
useless work.
2018-09-15 20:56:46 -07:00
Pavel Yaskevich
da4871d476 [CSStep] Implement TypeVariable step
Similar to `DisjunctionStep` `TypeVariableStep` attempts
its choices one-by-one, and if any of the choices match
it makes type variable as a whole successfully solved.

Since type variable attempts choices it means that it
can only produce "split" steps as a follow-up.
2018-09-15 20:56:46 -07:00
Pavel Yaskevich
d50a3e804e [CSStep] Add License header to CSStep.cpp 2018-09-15 20:56:46 -07:00
Pavel Yaskevich
c9bf47cb39 [CSStep] Add Disjunction step
`DisjunctionStep` attempts all of the viable choices,
at least one of the choices has to succeed for disjunction
to be considered a success.

`DisjunctionStep` attempts each choice and generates followup
`SplitterStep` to see if applying choice to constraint system
resulted in any simplification.
2018-09-15 20:56:46 -07:00
Pavel Yaskevich
64415c81ff [CSStep] Rename advance to take(bool) and propagate failures
Failure propagation is crucial for splitter and component steps
because that's the only signal for them to figure out if they
could be completely solved or have to fail.

For example, if one of the component steps created by "split"
fails it would cascade to the rest of the pending component steps
receiving "fail" signal and ultimately result in failure of the
"split" when it's re-taken.
2018-09-15 20:56:46 -07:00
Pavel Yaskevich
7723487b18 [CSStep] Add StepResult container 2018-09-15 20:56:46 -07:00
Pavel Yaskevich
60581da15e [ConstraintSystem] Add Splitter, Component and binding steps
* `SplitterStep` is responsible for running connected components
  algorithm to determine how many independent sub-systems there are.
  Once that's done it would create one `ComponentStep` per such
  sub-system, and move to try to solve each and then merge partial
  solutions produced by components into complete solution(s).

* `ComponentStep` represents a set of type variables and related
  constraints which could be solved independently. It's further
  simplified into "binding" steps which attempt type variable and
  disjunction choices.

* "Binding" steps such as `TypeVariableStep` and `DisjunctionStep`
  are responsible for trying type binding choices in attempt to
  simplify the system and produce a solution. After attempting each
  choice they introduce a new "split" step to compute more work.
2018-09-15 20:56:46 -07:00
Pavel Yaskevich
0dda1af94d [CSStep] Implement computeFollowupSteps 2018-09-15 20:56:46 -07:00
Pavel Yaskevich
86c442cc39 [CSStep] Implement mergePartialSolutions 2018-09-15 20:56:46 -07:00
Pavel Yaskevich
daf4c2f3b5 [CSSolver] Add skeleton of iterative solve
The idea so to split solving into non-recursive steps,
represented by `SolverStep`, each of the steps is resposible
for a unit of work e.g. attempting type variable or
disjunction bindings/choices.

Each step could produce more work via "follow-up" steps,
complete "partial" solution when it's done, or error which
terminates solver loop.
2018-09-15 20:56:46 -07:00