Commit Graph

201 Commits

Author SHA1 Message Date
Doug Gregor
2d61bd31f8 Always use the constraint graph and worklist.
Since it takes the code in <rdar://problem/15476050> from > 10 minutes
to 4 seconds.


Swift SVN r11064
2013-12-10 01:25:56 +00:00
Doug Gregor
3040f2195b Factor our the selection of "alternative" literal type suggestions.
Swift SVN r11035
2013-12-09 19:19:21 +00:00
Doug Gregor
4ddd82cc89 As soon as a (partial) solution becomes worse than the best solution, stop.
This shaves about 10% off the number of solution states explored when
type-checking the standard library, although it doesn't improve
overall time by much. In a more targeted benchmark, 1 + 2.0 + 1, we
get a 21% speedup.


Swift SVN r11033
2013-12-09 18:13:37 +00:00
Doug Gregor
79f8175e0b Solver: Keep track of a solution's score as we're computing it.
No functionality change here; just staging for some future optimizations.


Swift SVN r11028
2013-12-09 17:12:07 +00:00
Doug Gregor
16c15ca3c5 Remove an unused typedef
Swift SVN r11022
2013-12-09 15:37:36 +00:00
Doug Gregor
a6bd190b7c Split the core implementation of ConstraintSystem into its own file.
Swift SVN r11014
2013-12-09 14:05:35 +00:00
Doug Gregor
72c1e8c88e Split constraint simplification into its own source file.
Swift SVN r11013
2013-12-09 13:55:34 +00:00
Doug Gregor
52d611a683 Add, use factory methods to create constraints.
Swift SVN r11011
2013-12-09 13:09:45 +00:00
Doug Gregor
117940958b Replace the type variable -> graph node dense map with an embedded pointer.
Provides a 4% speedup type-checking the standard library. This
optimization brings the global constraint graph within 2% of the prior
solution, and prevents us from creating multiple constraint graphs per
constraint system, so flip the switch to always use the global
constraint graph.


Swift SVN r11003
2013-12-09 04:53:33 +00:00
Doug Gregor
dfe6646d5a Micro-optimization: replace ActiveConstraints set with a bit on Constraint.
No functionality change.


Swift SVN r10940
2013-12-06 21:41:51 +00:00
Doug Gregor
30b6302b7c Introduce a basic worklist into the constraint solver.
Whenever we bind a type variable or merge two type variables, add
those constraints that could be affected to a worklist. Simplification
continues processing constraints in the worklist until the worklist is
empty.

This change reduces the number of constraints that we visit but can't
simplify by ~13x in the standard library, but this doesn't translate
into a performance win. More investigation is needed here.

Note that the worklist is only in use when we have a global constraint
graph, which isn't enabled by default yet.


Swift SVN r10936
2013-12-06 21:31:05 +00:00
Doug Gregor
680a5ba5e7 Introduce a per-constraint system constraint graph (optionally).
Make the constraint graph into a scoped data structure that tracks the
changes that occur within a given scope, undoing those changes when
the scope is popped off the scope stack. The constraint graph's scopes
align with the constraint solver's scopes. Synchronize the solver's
constraint addition/removal operations with the constraint graph, and
improve our verification to make sure these stay in sync.

This is still a work in progress. Type checking the standard library
is about 5% slower with the per-constraint-system constraint graph
rather than building a new constraint graph each iteration *after*
simplification, and there are two intruiging test failures that appear
to be the constraint solver breaking its own invariants. Therefore,
this feature is off by default. See the ConstraintSystem constructor
for the one-line change to turn it back on.



Swift SVN r10927
2013-12-06 19:07:46 +00:00
Doug Gregor
61eb9b1f11 (Optionally) Evolve the constraint graph during simplification.
Rather than building the constraint graph after simplification and
then never modifying it, build the constraint graph before
simplification and update it as simplification adds/removes
constraints. This is a step toward two separable performance goals:
(1) having a single constraint graph that evolves over the lifetime of
the constraint system, rather than building a new constraint graph at
each solver step, and (2) using the constraint graph to implement a
worklist traversal during simplification, so we only re-simplify those
constraints that might be affected by a choice the solver makes.

This behavior is currently optional with an ugly in-source flag
because while it works, it's a rather painful performance regression
that I don't want to subject everyone to. I'll turn it on for everyone
once it's a win, which should be after either (1) or (2) above is
implemented.



Swift SVN r10924
2013-12-06 16:01:25 +00:00
Doug Gregor
80d0e03f61 Don't path-compress the fixed type for a type variable binding.
We still perform path compression for the representative of a type
variable, but the fixed type of a type variable is no longer
compressed: it either doesn't exist or is stored in the
representative. This preserves the equivalence-class structure of type
variables even after they've been bound to fixed types.


Swift SVN r10921
2013-12-06 15:04:37 +00:00
Doug Gregor
adb4fb0da4 Separately rank the partial solutions for each connected component.
This per-component ranking selects the best partial solution (or at
least minimizes the set of partial solutions) before composing the
results of the partial solutions into set of solutions. This way, we
don't end up creating a huge number of solutions (i.e., all
permutations of the partial solutions) that we'll then have to compare. 

27% improvement in type-checking time for the standard library.



Swift SVN r10865
2013-12-05 18:00:57 +00:00
Doug Gregor
0bbf7c92bc Give ConstraintSystem::findBestSolution() a more reasonable return type.
Swift SVN r10861
2013-12-05 17:22:02 +00:00
Jordan Rose
417b5d3982 Merge TranslationUnit into Module, and eliminate the term "translation unit".
This completes the FileUnit refactoring. A module consists of multiple
FileUnits, which provide decls from various file-like sources. I say
"file-like" because the Builtin module is implemented with a single
BuiltinUnit, and imported Clang modules are just a single FileUnit source
within a module.

Most modules, therefore, contain a single file unit; only the main module
will contain multiple source files (and eventually partial AST files).

The term "translation unit" has been scrubbed from the project. To refer
to the context of declarations outside of any other declarations, use
"top-level" or "module scope". To refer to a .swift file or its DeclContext,
use "source file". To refer to a single unit of compilation, use "module",
since the model is that an entire module will be compiled with a single
driver call. (It will still be possible to compile a single source file
through the direct-to-frontend interface, but only in the context of the
whole module.)

Swift SVN r10837
2013-12-05 01:51:15 +00:00
Doug Gregor
3d4da69b08 In "x as T", type-check the subexpression "x" using "T" as the context type.
Using "T" as the contextual type, either for an implicit conversion
(in the coercion case) or as a downcast (for the checked-cast case),
opens up more type-inference opportunities. Most importantly, it
allows coercions such as "1 as UInt32" (important for
<rdar://problem/15283100>). Additionally, it allows one to omit
generic arguments within the type we're casting to.

Some additional cleanup to follow.


Swift SVN r10799
2013-12-04 22:32:28 +00:00
Doug Gregor
dac8624bc0 Don't merge the TVO_PrefersSubtypeBinding bit; it doesn't affect solving.
Swift SVN r10717
2013-12-01 17:53:48 +00:00
Doug Gregor
3e290f4471 Use a intrusive doubly-linked lists for active/retired constraints.
Constraints move between the active and retired lists fairly often, so
use a doubly-linked list to eliminate memory traffic and O(n) copies
of constraint pointers between the lists by using splicing instead.


Swift SVN r10715
2013-12-01 16:31:49 +00:00
Doug Gregor
06ec5fff8f Remove debugging-only vector of solved constraints. It doesn't help.
Swift SVN r10677
2013-11-26 19:29:26 +00:00
Doug Gregor
3a71c8538b Remove the notion of a cutpoint from the solver; we no longer need it
Swift SVN r10675
2013-11-24 02:00:46 +00:00
Doug Gregor
cc75981ac6 Solve different connected components in isolation, then combine the results.
Reduces type checking time for the standard library by ~13%, the
number of solver states visited by ~25%, and the number of pointlessly
visited constraints by ~30%. There are only 2175 separable
connected components in the standard library, likely because our
heuristics for picking type variables/constraints to solve bias
against connected components.



Swift SVN r10674
2013-11-24 01:57:47 +00:00
Doug Gregor
c8523f32ec Solver step: separate "what constraints to solve" from "how to solve it".
No functionality change.


Swift SVN r10673
2013-11-23 21:35:54 +00:00
Doug Gregor
8cd63c9b8d Use the constraint graph to isolate and solve the smallest connected component.
At each solution phase, construct a constraint graph and identify the
smallest connected component. Only solve for the variables in that
connected component, and restrict simplification to the constraints
within that connected component. This reduces the number of
visited-but-not-simplified constraints by ~2x when type-checking the
standard library.

Performance-wise, this is actually a regression (0.25s/8% when parsing
the standard library), because the time spent building the constraint
graph exceeds the time saved by the optimization above.

The hackaround in the standard library is due to
<rdar://problem/15168483>. Essentially, this commit changes the order
in which we visit type variables, causing the type checker to make
some very poor deduction choices.

The point of actually committing this is that it validates the
constraint graph construction and sets the stage for an actual
optimization based on isolating the solving work for the different
components.



Swift SVN r10672
2013-11-23 03:44:40 +00:00
Doug Gregor
0428eeaebf Introduce --debug-constraints-attempt=N to debug a specific constraint system.
The constraint solver statistics now tell us which of the constraint
systems we are solving were the largest. This lets us look at what the
solver does with that constraint system without piling on the
debugging spew.


Swift SVN r10638
2013-11-21 18:53:00 +00:00
Doug Gregor
516fc3a9ac Track constraint solver statistics for the largest system.
Swift SVN r10633
2013-11-21 18:05:32 +00:00
Doug Gregor
cf074011b1 Stop creating type variables for archetypes.
Swift SVN r9918
2013-11-04 16:14:26 +00:00
Doug Gregor
b1a8e30b16 Teach witness matching to use interface types appropriately.
This is one of the last few type checker clients of
PolymorphicFunctionType, where we were relying on opening archetypes
rather than generic parameters.


Swift SVN r9870
2013-11-01 17:09:51 +00:00
Doug Gregor
5555e6043d Kill off the member-reference path that opens based on archetypes.
This eliminates another pile of mostly-duplicated code that was
dependent on archetypes.


Swift SVN r9823
2013-10-30 23:15:15 +00:00
Doug Gregor
1a9545f5c0 Open references to types within generic contexts via the "new" path.
Swift SVN r9782
2013-10-30 04:56:40 +00:00
Doug Gregor
3b63fac07e Handle dynamic lookup through the "new" generic type path.
No functionality change; just another step in subsuming the
archetype-based path.


Swift SVN r9772
2013-10-30 00:08:35 +00:00
Doug Gregor
769ed07a6d Use the opened type of a subscript reference to compute substitutions.
This eliminates the need to separately reconstruct all of the
substitutions for the base type of the subscript; our solution already
has all of that information.


Swift SVN r9771
2013-10-29 23:49:39 +00:00
Doug Gregor
45d840edfe Factor out the opening of generic function types.
No functionality change.


Swift SVN r9763
2013-10-29 21:11:09 +00:00
Doug Gregor
eecac1fd9c Eliminate the last few sources of SpecializeExprs.
All of these are dead code anyway, made redundant by ConcreteDeclRef's
elsewhere.


Swift SVN r9715
2013-10-28 18:42:24 +00:00
Doug Gregor
a000a25776 Open EnumElementDecl references via their generic function types.
Eliminates another use of SpecializeExpr.


Swift SVN r9711
2013-10-28 17:45:01 +00:00
Doug Gregor
37a803a314 For type checking, open constructor references based on their interface types.
Eliminates another use of SpecializeExpr.


Swift SVN r9690
2013-10-26 03:46:24 +00:00
Doug Gregor
a8aef7a10f Open references to protocol methods via their interface type.
Swift SVN r9641
2013-10-24 17:56:53 +00:00
Doug Gregor
e45254857a Tighten the constraint on the base of a '.' expression for protocol members.
The "conversion" constraint was far too loose, because we don't want
to permit arbitrary conversions on the left-hand side of the
'.'. Conformance constraints aren't correct either, because an
existential that does not conform to itself can still be used on the
left-hand side of a '.', so we introduce a new kind of constraint for
this.


Swift SVN r9630
2013-10-23 21:25:00 +00:00
Doug Gregor
8681e0abf9 Open operators in protocols with their interface types.
Rather than jumping through special hoops to deal with operators in
protocols, just open those methods via their interface types (which
are generic function types). This eliminates a number of special cases
for protocol methods.



Swift SVN r9626
2013-10-23 17:36:15 +00:00
Doug Gregor
905078a278 Open method references via the interface type rather than the polymorphic type.
Once we've opened method references via the interface type, we then
fold all levels of generic argument specialization into the
DeclRefExpr, rather than using SpecializeExpr. For reference, the call
to x.f in this example:

struct X<T> {
  func f<U>(u : U) { }
}

func honk(x: X<Int>) {
  x.f("hello")
}

goes from this double-specialized AST:

        (specialize_expr implicit type='(u: String) -> ()'
          (with U = String)
          (dot_syntax_call_expr type='<U> (u: U) -> ()'
            (specialize_expr implicit 
               type='(@inout X<Int>) -> <U> (u: U) -> ()'
              (with T = Int)
              (declref_expr type='<T> @inout X<T> -> <U> (u: U) -> ()'
        decl=t.X.f@t.swift:2:8 specialized=no))

to the cleaner, SpecalizeExpr-free:

        (dot_syntax_call_expr type='(u: String) -> ()'
          (declref_expr type='(@inout X<Int>) -> (u: String) -> ()'
            decl=t.X.f@t.swift:2:8 [with T=Int, U=String]
            specialized=no)

which handles substitutions at both levels together. The minor SILGen
tweak 

Note that there are numerous other places where we are still generated
SpecializeExprs.


Swift SVN r9614
2013-10-23 05:35:16 +00:00
Doug Gregor
1eebdc9025 Replace the free type variables in a solution with generic type parameters.
This is a cleaner approach to handling solutions with free type
variables than in r9513.


Swift SVN r9613
2013-10-23 05:21:53 +00:00
Doug Gregor
9def310d89 Give a real struct name SelectedOverload to (OverloadChoice, Type) pairs.
Swift SVN r9566
2013-10-21 23:06:37 +00:00
Doug Gregor
61a0958616 Open method references to methods using their interface type.
Rely on opening the GenericFunctionType of a method, rather than its
PolymorphicFunctionType. Alas, constraint application still falls back to
the PolymorphicFunctionType.


Swift SVN r9564
2013-10-21 22:28:46 +00:00
Dmitri Hrybenko
acdd5b120a Make type checker debug output redirectable
Introduce a replaceable TypeCheckerDebugConsumer for this.


Swift SVN r9555
2013-10-21 20:26:32 +00:00
Doug Gregor
5269d99d0c Store substitutions within a DeclRefExpr.
Replace DeclRefExpr's stored ValueDecl* with a ConcreteDeclRef,
allowing it to store the complete set of substitutions applied to
the declaration. Start storing those substitutions (without using them
yet).


Swift SVN r9535
2013-10-21 14:36:23 +00:00
Doug Gregor
50cfd44b37 Separate the computation of substitutions from the creation of SpecializeExpr.
No functionality change.


Swift SVN r9534
2013-10-21 14:08:26 +00:00
Doug Gregor
26c6659298 Introduce a Solution::specialize() for generic function types.
This variant of specialize() uses the requirements list of the generic
function type to form the substitution list, rather than relying on
the polymorphic function type and all-archetypes lists.


Swift SVN r9518
2013-10-20 02:52:00 +00:00
Dmitri Hrybenko
4d03f74a9a Code completion / type checker: while type checking a base expression for code
completion, don't fail if we have unsolved type variables.  Type variables are
replaced with GenericTypeParamType types.


Swift SVN r9515
2013-10-19 02:06:51 +00:00
Doug Gregor
e3ebb03c28 Start opening GenericFunctionTypes for references to non-member functions.
When the type checker sees a reference to a generic non-member
function, open its interface type, which is expressed as a
GenericFunctionType, rather than its PolymorphicFunctionType. This is
a tiny step toward weaning the type checker off archetypes within the
interface.




Swift SVN r9504
2013-10-18 23:04:16 +00:00