Commit Graph

28 Commits

Author SHA1 Message Date
Pavel Yaskevich
f2a6677a6d [CSOptimizer] Infer argument candidates from calls to Double and CGFloat constructors
Helps situations like `1 + {Double, CGFloat}(...)` by inferring
a type for the second operand of `+` based on a type being constructed.

Currently limited to Double and CGFloat only since we need to
support implicit `Double<->CGFloat` conversion.

Helps situations like `1 + CGFloat(...)` by inferring a type for
the second operand of `+` based on a type being constructed.
Currently limited to known integer, floating-point and CGFloat types
since we know how they are structured.
2024-12-17 11:36:40 -08:00
Pavel Yaskevich
59109c2d60 [CSOptimizer] Score all of the overload choices matching on literals uniformly
Regardless of whether an overload choice matched on one or more
literal candidate types assign it a fixed score to make sure that
we always prefer outmost disjunction in cases like `test(1 + 2 + 3)`
since it gives us a better chance to prune once there is a contextual
type.
2024-12-17 11:36:40 -08:00
Pavel Yaskevich
6fb6d1cf90 [CSOptimizer] Enable ranking of Int*, Float{80} and Double initializers 2024-12-17 11:36:40 -08:00
Pavel Yaskevich
8818d399f9 [CSOptimizer] Rank disjunctions based on score only if both sides are supported 2024-12-17 11:36:40 -08:00
Pavel Yaskevich
3996b25fbd [CSOptimizer] Rank results of operators regardless of whether anything is known about parameters
When operators are chained it's possible that we don't know anything
about parameter(s) but result is known from the context, we should
use that information.
2024-12-17 11:36:40 -08:00
Pavel Yaskevich
23589add74 [CSOptimizer] Average score should reflect number of defaulted parameters 2024-12-17 11:36:40 -08:00
Pavel Yaskevich
8a918e2369 [CSOptimizer] Don't optimize (implicit) calls with code completion arguments
`containsIDEInspectionTarget` doesn't work for implicit argument
lists, but luckily implicit code completion expressions cannot
be injected into arguments, so we can check whether whether they
appear at an argument position and prevent optimization.
2024-12-17 11:36:40 -08:00
Pavel Yaskevich
deca9b61c5 [CSOptimizer] attempt to rank only standard/simd operators and fully concrete overload sets 2024-12-17 11:36:39 -08:00
Pavel Yaskevich
3819ddfb40 [CSOptimizer] Record best scores for each disjunction and use them in selectDisjunction
If there is no single best disjunction use best scores first
to determine minimum with fallback to favored and/or active
choice counts.
2024-12-17 11:36:39 -08:00
Pavel Yaskevich
cf05405eae [CSOptimizer] Let determineBestChoicesInContext return the best disjunction if one is available
If there is one overall best disjunction, let's attempt it first.
2024-12-17 11:36:39 -08:00
Pavel Yaskevich
527de22bec [CSOptimizer] Emulate old behavior related to favoring of unary calls to members
Preserves old behavior where for unary calls to members
the solver would not consider choices that didn't match on
the number of parameters (regardless of defaults) and only
exact matches were favored.
2024-12-17 11:36:39 -08:00
Pavel Yaskevich
d69b6a0594 [CSOptimizer] Prefer homogeneous arithmetic operator overloads when argument(s) or result match
This is an opportunistic optimization based on the operator
use patterns where homogeneous operators are the most
heavily used ones.
2024-12-17 11:36:39 -08:00
Pavel Yaskevich
1760bd1f1e [CSOptimizer] Remove an outdated optimization to compare resolved argument types with all else equal
This is already accounted for by `determineBestChoicesInContext`
and reflected in the overall score, which means that we no longer
need to use this in vacuum.
2024-12-17 11:36:39 -08:00
Pavel Yaskevich
c429f5b9ec [CSOptimizer] NFC: Switch from llvm::Optional to std::optional post-rebase 2024-12-17 11:36:39 -08:00
Pavel Yaskevich
2869dff995 [CSOptimizer] Increase score when type matches opaque type
Since erasure of a concrete type into an existential value yields
score of 1, we need to bump the score in cases where a type
passed to a generic parameter satisfies all of its protocol
conformance requirements and that parameter represents an
opaque type.
2024-12-17 11:36:39 -08:00
Pavel Yaskevich
0fc6806922 [CSOptimizer] NFC: Switch to llvm::Optional 2024-12-17 11:36:39 -08:00
Pavel Yaskevich
da65333d41 [CSOptimizer] NFC: Adjust conformance check to use ConstraintSystem::lookupConformance 2024-12-17 11:36:38 -08:00
Pavel Yaskevich
957a5f4270 [CSOptimizer] Treat all type parameters equally
Dependent members just like generic parameter types could
have associated protocol conformances which give us a glimpse
into whether arguments could possibly match.
2024-12-17 11:36:38 -08:00
Pavel Yaskevich
11b897b32f [CSOptimizer] Relax candidate type requirements from equality to set of no-impact conversions
Candidate is viable (with some score) if:

- Candidate is exactly equal to a parameter type
- Candidate type differs from a parameter type only in optionality
- Parameter is a generic parameter type and all conformances are matched by a candidate type
- Candidate tuples matches a parameter tuple on arity
- Candidate is an `Array<T>` and parameter is an `Unsafe*Pointer`
- Candidate is a subclass of a parameter class type
- Candidate is a concrete type and parameter is its existential value (except Any)
2024-12-17 11:36:38 -08:00
Pavel Yaskevich
cb1cb2018d [CSOptimizer] Use matchCallArguments to establish argument-to-parameter relationships
This helps to find defaulted parameter positions as well.
2024-12-17 11:36:38 -08:00
Pavel Yaskevich
14e2a16fce [CSOptimizer] Don't attempt to optimize calls with code completion token(s) in argument position 2024-12-17 11:36:38 -08:00
Pavel Yaskevich
bc5f70a9a3 [CSOptimizer] Allow generic operator overloads without associated type parameters 2024-12-17 11:36:38 -08:00
Pavel Yaskevich
7c1c46d4e4 [CSOptimizer] Make sure that all parameters without arguments are defaulted 2024-12-17 11:36:38 -08:00
Pavel Yaskevich
e404ed722a [CSStep] Don't favor choices until the disjunction is picked 2024-12-17 11:36:38 -08:00
Pavel Yaskevich
a094c3ebb0 [CSOptimizer] Keep track of mismatches while evaluating candidates 2024-12-17 11:36:38 -08:00
Pavel Yaskevich
c2f7451c7b [CSOptimizer] Favor SIMD related arithmetic operator choices if argument is SIMD<N> type 2024-12-17 11:36:38 -08:00
Pavel Yaskevich
672ae3d252 [CSOptimizer] Initial implementation of disjunction choice favoring algorithm
This algorithm attempts to ensure that the solver always picks a disjunction
it knows the most about given the previously deduced type information.

For example in chains of operators like: `let _: (Double) -> Void = { 1 * 2 + $0 - 5 }`

The solver is going to start from `2 + $0` because `$0` is known to be `Double` and
then proceed to `1 * ...` and only after that to `... - 5`.

The algorithm is pretty simple:

- Collect "candidate" types for each argument
  - If argument is bound then the set going to be represented by just one type
  - Otherwise:
    - Collect all the possible bindings
    - Add default literal type (if any)

- Collect "candidate" types for result

- For each disjunction in the current scope:
  - Compute a favoring score for each viable* overload choice:
    - Compute score for each parameter:
      - Match parameter flags to argument flags
      - Match parameter types to a set of candidate argument types
        - If it's an exact match
          - Concrete type: score = 1.0
          - Literal default: score = 0.3
        - Highest scored candidate type wins.
      - If none of the candidates match and they are all non-literal
        remove overload choice from consideration.

    - Average the score by dividing it by the number of parameters
      to avoid disfavoring disjunctions with fewer arguments.

    - Match result type to a set of candidates; add 1 to the score
      if one of the candidate types matches exactly.

  - The best choice score becomes a disjunction score

- Compute disjunction scores for all of the disjunctions in scope.

- Pick disjunction with the best overall score and favor choices with
  the best local candidate scores (if some candidates have equal scores).

- Viable overloads include:
  - non-disfavored
  - non-disabled
  - available
  - non-generic (with current exception to SIMD)
2024-12-17 11:36:38 -08:00
Pavel Yaskevich
b5f08a4009 [ConstraintSystem] Add skeleton of constraint optimizer 2024-12-17 11:36:38 -08:00