Commit Graph

92 Commits

Author SHA1 Message Date
Pavel Yaskevich
eb78e27a08 [CSOptimizer] Consider choices marked as @_disfavoredOverload
These choices could be better than some other non-disfavored ones
in certain situations i.e. when `async` overload is disfavored
but appears in async context it's preferrable to a non-async
overload choice.

Note that the code that mimic old hacks still needs to filter on
`@_disfavoredOverload` in few places to maintain source compatibility.
2025-06-27 23:43:12 -07:00
Pavel Yaskevich
ea47e3cc24 [CSOptimizer] NFC: Adopt new Constraint and ConstraintGraph APIs 2025-06-27 23:43:11 -07:00
Pavel Yaskevich
b90fc2b8c6 [CSOptimizer] Don't attempt to walk into literals while analyzing operator chains
Most of them don't have any children but string interpolation does
and that marks whole chain as unsupported.
2025-06-27 23:43:11 -07:00
Pavel Yaskevich
db0a9de996 [CSOptimizer] Account for the fact that sometimes all initializer choices are failable
If all of the viable initializer overloads are failable,
the only valid inference choice is an optional candidate type.
2025-06-27 23:43:11 -07:00
Pavel Yaskevich
e7b351d41d [CSOptimizer] NFC: Use builder pattern to construct DisjunctionInfo 2025-06-27 23:43:11 -07:00
Pavel Yaskevich
125abede66 [CSOptimizer] Detect when candidate comes from string interpolation
Instead of checking both protocols, check one that matches best
depending on where `String` literal candidate came from.
2025-06-27 23:43:11 -07:00
Pavel Yaskevich
5aa3859f17 [CSOptimizer] Disable unary argument hack if overload set has requirements or variadic overloads
This matches the behavior of the old hack where favoring choices
were rolled back if `mustConsider` produced `true` which happened
only for protocol requirements and variadic overload choice regardless
of their viability.
2025-06-27 23:43:11 -07:00
Pavel Yaskevich
e280569988 [CSOptimizer] Fix scoring while matching against partially resolved parameter types
When matching candidate like `[Int]` against `Array<Element>`
we need to conservatively assume that if the nominals match
the argument is a viable exact match because otherwise it's
possible to skip some of the valid matches when other overload
choice have generic parameters at the same parameter position.
2025-06-27 23:43:11 -07:00
Pavel Yaskevich
1dab584f29 [CSOptimizer] Account for speculative scores only when matching operators vs. non-operators
The problem this is trying to solve is eager selection of operators
over unsupported disjunctions, when matching operators let's take
speculative information into account because it helps to make better
choices in this case.
2025-06-27 23:43:11 -07:00
Pavel Yaskevich
073b48c43b [CSOptimizer] Restrict unary argument legacy favoring behavior to ApplyExprs
The original hack never applied to subscripts.
2025-06-27 23:43:11 -07:00
Pavel Yaskevich
617338f250 [CSOptimizer] Prevent candidate inference from unresolved generic parameters and ternary expressions
We need to have a notion of "complete" binding set before
we can allow inference from generic parameters and ternary,
otherwise we'd make a favoring decision that might not be
correct i.e. `v ?? (<<cond>> ? nil : o)` where `o` is `Int`.
`getBindingsFor` doesn't currently infer transitive bindings
which means that for a ternary we'd only have a single
binding - `Int` which could lead to favoring overload of
`??` and has non-optional parameter on the right-hand side.
2025-06-27 23:43:11 -07:00
Pavel Yaskevich
e2fe558956 [CSOptimizer] Introduce a way to preference disjunctions before scores are considered
Some of the disjunctions are not supported by the optimizers but
could still be a better choice than an operator. Using a non-score
based preference mechanism first allows us to make sure that
operator disjunctions are not selected too eagerly in some situations
when i.e. a member (supported or not) could be a better choice.

`isPreferable` currently targets only operators in result builder
contexts but it could be expanded to more uses in the future.
2025-06-27 23:43:11 -07:00
Pavel Yaskevich
bcc749fa1a [CSOptimizer] Reset the overall score of operator disjunctions that is based speculation
New ranking + selection algorithm suffered from over-eagerly selecting
operator disjunctions vs. unsupported non-operator ones even if the
ranking was based purely on literal candidates.

This change introduces a notion of a speculative candidate - one which
has a type inferred from a literal or an initializer call that has
failable overloads and/or implicit conversions (i.e. Double/CGFloat).

`determineBestChoicesInContext` would reset the score of an operator
disjunction which was computed based on speculative candidates alone
but would preserve favoring information. This way selection algorithm
would not be skewed towards operators and at the same time if there
is no no choice by to select one we'd still have favoring information
available which is important for operator chains that consist purely
of literals.
2025-06-27 23:43:11 -07:00
Pavel Yaskevich
df4ae0a546 [CSOptimizer] Update candidate selection to use arithmetic operator chain inference 2025-06-27 23:43:11 -07:00
Pavel Yaskevich
4eec3f6788 [CSOptimizer] Introduce a drop of inference to preserved unary argument behavior
Thanks to `LinkedExprAnalyzer` unary argument hack was able to
infer matching based on literals and arithmetic operator chains,
let's preserve that behavior in a more principled manner.
2025-06-27 23:43:10 -07:00
Pavel Yaskevich
0525818a33 [CSOptimizer] Allow matching candidates with optional types against generic paameter types
For example passing `Int?` to `T` should be considered a match
if `T` doesn't have any requirements that block it.
2025-06-27 23:43:10 -07:00
Pavel Yaskevich
ac24a8e251 [CSOptimizer] Introduce _OptionalNilComparisonType as candidate for nil while ranking == and != operators
`==` and `!=` operators have special overloads that allow matching
`nil` literal on either side even if wrapped type on the other side
doesn't conform to `Equatable`.
2025-06-27 23:43:10 -07:00
Pavel Yaskevich
aedc4fe25e [CSOptimizer] Remove selectBestBindingDisjunction hack 2025-06-27 23:43:10 -07:00
Pavel Yaskevich
b936900eb8 [CSOptimizer] Support non-operator generic choices with simple signatures
If there are no-same type requirements and parameters use
either concrete types or generic parameter types directly,
the optimizer should be able to handle ranking. Currently
candidate arguments are considered in isolation which makes
it impossible to deal with same-type requirements and
complex generic signatures.
2025-06-27 23:43:10 -07:00
Pavel Yaskevich
2646efac98 [CSOptimizer] Expand literal support to bools, strings and dictionaries
Optimizer now covers all of the most common ExpressibleBy*Literal
protocols.
2025-06-27 23:43:10 -07:00
Pavel Yaskevich
0e0b5f9a80 [CSOptimizer] Always prefer a disjunction with a single active choice
Disjunctions with a single element are sometimes introduced after
disfavoring, so we need to make sure that they are always preferred
during disjunction selection.
2025-06-27 23:43:10 -07:00
Pavel Yaskevich
b96139eb5b [CSOptimizer] Emulate old hack for unary argument matching more precisely
Having it be part of the other matching wasn't a good idea because
previous "favoring" happened only in a few situations - if argument
was a declaration reference, application or (dynamic) subscript that
had overload choice selected during constraint generation.
2025-06-27 23:43:10 -07:00
Pavel Yaskevich
666aa24224 [CSOptimizer] Add support for ?? operator 2025-06-27 23:43:10 -07:00
Pavel Yaskevich
84d034c388 [CSOptimizer] Don't reduce the ranking for non-default literal types
Since each candidate and overload choice are considered independenty
there is no way to judge whether non-default literal type is going
to result in a worse solution than non-default one.
2025-06-27 23:43:10 -07:00
Pavel Yaskevich
0dfb2044ef [CSOptimizer] Infer types from init calls used as arguments
This used to be limited to Double/CGFloat and operator arguments
but it's safe to do in general.
2025-06-27 23:43:10 -07:00
Pavel Yaskevich
899b2bc1e9 [CSOptimizer] Allow matching against CGFloat as a contextual result type 2025-06-27 23:43:10 -07:00
Pavel Yaskevich
6c28cdfb78 [CSOptimizer] Infer argument candidates through optionals
For example, `??` operator could produce an optional type
so `test(<<something>> ?? 0) could result in an optional
argument that wraps a type variable. It should be possible
to infer bindings from underlying type variable and restore
optionality.
2025-06-27 23:43:10 -07:00
Pavel Yaskevich
2f8a343aef [CSOptimizer] Infer result types through ternary expressions 2025-06-27 23:43:09 -07:00
Pavel Yaskevich
80e12b9dde [CSOptimizer] Improve contextual result type handling during overload matching
Result type should only be matched if there are matches on arguments
or there are no viable candidates.
2025-06-27 23:43:09 -07:00
Pavel Yaskevich
c04068db1c [ConstraintSystem] Initial implementation of disjunction optimizer
This brings back CSOptimizer from https://github.com/swiftlang/swift/pull/63585
2025-06-27 23:43:09 -07:00
Pavel Yaskevich
725bd910be [ConstraintSystem] Revert new disjunction favoring algorithm (#79128)
* Revert "[CSOptimizer] Look through `OptionalEvaluationExpr`s when dealing with unapplied disjunctions"

This reverts commit 72340f39b8.

* Revert "[CSOptimizer] Don't consider disabled overloads when checking whether disjunction is supported"

This reverts commit 6bc23b5057.

* Revert "[CSOptimizer] Disjunctions with IUO overload choices are unsupported"

This reverts commit 471ee21535.

* Revert "[CSOptimizer] MemberImportVisibility: Don't consider overloads that come from implicit imports"

This reverts commit aa4a2b9071.

* Revert "[CSOptimizer] Don't consider CGFloat widening when explicit initializer is used"

This reverts commit 3cc76eacdd.

* Revert "[CSOptimizer] Literal arguments should cause score reset only for operators"

This reverts commit e3987beffb.

* Revert "[CSOptimizer] NFC: check whether a choice is of operator instead of whole disjunction"

This reverts commit 6c82892c3c.

* Revert "[CSOptimizer/Tests] NFC: Add a perf test-case fixed by improved literal array handling"

This reverts commit cfd34e54c4.

* Revert "[CSOptimizer] Extend candidate/parameter matching to support array literals"

This reverts commit 8a304f88c6.

* Revert "[CSOptimizer] Favor choices that don't require application"

This reverts commit 0737542da8.

* Revert "[CSOptimizer] Disable CGFloat -> Double conversion for unary operators"

This reverts commit bc3a15fbe6.

* Revert "[CSOptimizer] Mark bitwise operators as supported"

This reverts commit 860ae08d1b.

* Revert "[CSOptimizer] Simplify handling of non-applied disjunctions"

This reverts commit 43ca7dfff9.

* Revert "[ConstraintSystem] Fix `getEffectiveOverloadType` handling of `mutating` methods"

This reverts commit c767f7aff7.

* Revert "[CSOptimizer] Reduce overload types before ranking"

This reverts commit 95b47aead6.

* Revert "[CSOptimizer] Implement special prioritization rules for result builder contexts"

This reverts commit 56d6635e46.

* Revert "[CSOptimizer] Allow only widening CGFloat->Double conversions while matching candidate arguments"

This reverts commit bf8ae3bc1b.

* Revert "[CSSimplify] CGFloat-Double: Rank narrowing correctly when result is injected into an optional"

This reverts commit cb876cbd9e.

* Revert "[CSBindings] Prevent `BindingSet::isViable` from dropping viable bindings (v2)"

This reverts commit b7e7493076.

* Revert "[CSOptimizer] Add support for chained members without arguments"

This reverts commit 87cd5f8733.

* Revert "[CSOptimizer] Mark compiler synthesized disjunctions as optimized"

This reverts commit 867e64182f.

* Revert "[CSOptimizer] Make a light-weight generic overload check if some requirements are unsatisfiable"

This reverts commit 15c773b9d7.

* Revert "[CSOptimizer] Fix `selectDisjunction` to use favored choices even if disjunction was not optimized"

This reverts commit c2a55886f0.

* Revert "[CSOptimizer] Limit "old" behavior compatibility to unlabeled unary arguments"

This reverts commit 9fb73143f6.

* Revert "[Tests] NFC: Update a couple of type-checker tests"

This reverts commit ff8663ff16.

* Revert "[Tests] NFC: Move simd related test-case from `slow` to `fast`"

This reverts commit 28396a6dce.

* Revert "[CSGen] NFC: Remove obsolete `ConstraintSystem::{get, set}FavoredType`"

This reverts commit 8bd288447f.

* Revert "[CSOptimizer] Allow literal arguments to match parameters that conform to `ExpressibleBy{Integer, Float}Literal`"

This reverts commit 2fdd4b6c35.

* Revert "[CSOptimizer] Adjust `scoreCandidateMatch` to indicate when match cannot be decided"

This reverts commit 9b62c84a4f.

* Revert "[CSOptimizer] Fix Double<->CGFloat implicit conversion support when arguments are literals"

This reverts commit 6caf1ccbb2.

* Revert "[CSOptimizer] A more comprehensive generic overload checking when candidates are fully resolved"

This reverts commit e30587bda4.

* Revert "[CSOptimizer] Restore old hack behavior which used to favor overloads based on arity matches"

This reverts commit a3a3ec4fe0.

* Revert "[CSOptimizer] Desugar types before checking for equality"

This reverts commit 802f5cd105.

* Revert "[ConstraintSystem] Narrowly disable `tryOptimizeGenericDisjunction` when some of the arguments are number literals"

This reverts commit 8d5cb112ef.

* Revert "[CSOptimizer] Infer argument candidates from calls to `Double` and CGFloat constructors"

This reverts commit f2a6677a6d.

* Revert "[CSOptimizer] Score all of the overload choices matching on literals uniformly"

This reverts commit 59109c2d60.

* Revert "[CSOptimizer] Enable ranking of `Int*`, `Float{80}` and `Double` initializers"

This reverts commit 6fb6d1cf90.

* Revert "[CSOptimizer] Rank disjunctions based on score only if both sides are supported"

This reverts commit 8818d399f9.

* Revert "[CSOptimizer] Rank results of operators regardless of whether anything is known about parameters"

This reverts commit 3996b25fbd.

* Revert "[Tests] NFC: Add more test-cases that were previously solved due to old hacks behavior"

This reverts commit d0ff6c81b8.

* Revert "[CSOptimizer] Average score should reflect number of defaulted parameters"

This reverts commit 23589add74.

* Revert "[Tests] NFC: Adjust a couple of improved tests"

This reverts commit 66981364fe.

* Revert "[CSOptimizer] Don't optimize (implicit) calls with code completion arguments"

This reverts commit 8a918e2369.

* Revert "[CSOptimizer] attempt to rank only standard/simd operators and fully concrete overload sets"

This reverts commit deca9b61c5.

* Revert "[CSOptimizer] Record best scores for each disjunction and use them in `selectDisjunction`"

This reverts commit 3819ddfb40.

* Revert "[CSOptimizer] Let `determineBestChoicesInContext` return the best disjunction if one is available"

This reverts commit cf05405eae.

* Revert "[CSOptimizer] Emulate old behavior related to favoring of unary calls to members"

This reverts commit 527de22bec.

* Revert "[Tests] NFC: Add a test-case for rdar://133340307 which is now fast"

This reverts commit 670127abd6.

* Revert "[CSOptimizer] Prefer homogeneous arithmetic operator overloads when argument(s) or result match"

This reverts commit d69b6a0594.

* Revert "[CSOptimizer] Remove an outdated optimization to compare resolved argument types with all else equal"

This reverts commit 1760bd1f1e.

* Revert "[CSOptimizer] NFC: Switch from llvm::Optional to std::optional post-rebase"

This reverts commit c429f5b9ec.

* Revert "[CSOptimizer] Increase score when type matches opaque type"

This reverts commit 2869dff995.

* Revert "[CSOptimizer] NFC: Switch to llvm::Optional"

This reverts commit 0fc6806922.

* Revert "[CSOptimizer] NFC: Adjust conformance check to use `ConstraintSystem::lookupConformance`"

This reverts commit da65333d41.

* Revert "[CSOptimizer] Treat all type parameters equally"

This reverts commit 957a5f4270.

* Revert "[CSStep] Remove disjunction pruning logic from DisjunctionStep"

This reverts commit 2c44e37948.

* Revert "[CSOptimizer] Relax candidate type requirements from equality to set of no-impact conversions"

This reverts commit 11b897b32f.

* Revert "[CSOptimizer] Use `matchCallArguments` to establish argument-to-parameter relationships"

This reverts commit cb1cb2018d.

* Revert "[CSOptimizer] Don't attempt to optimize calls with code completion token(s) in argument position"

This reverts commit 14e2a16fce.

* Revert "[CSOptimizer] Allow generic operator overloads without associated type parameters"

This reverts commit bc5f70a9a3.

* Revert "[CSOptimizer] Make sure that all parameters without arguments are defaulted"

This reverts commit 7c1c46d4e4.

* Revert "[CSStep] Don't favor choices until the disjunction is picked"

This reverts commit e404ed722a.

* Revert "[CSOptimizer] Keep track of mismatches while evaluating candidates"

This reverts commit a094c3ebb0.

* Revert "[CSOptimizer] Favor SIMD related arithmetic operator choices if argument is SIMD<N> type"

This reverts commit c2f7451c7b.

* Revert "[CSOptimizer] Initial implementation of disjunction choice favoring algorithm"

This reverts commit 672ae3d252.

* Revert "[ConstraintSystem] Add skeleton of constraint optimizer"

This reverts commit b5f08a4009.

* Revert "[CSGen] Remove ConstraintOptimizer and all favoring logic"

This reverts commit 4432c51f57.

* Revert "[ConstraintSystem] Remove `shrink`"

This reverts commit 757ca24e8a.

* [TypeChecker] NFC: Remove resurrected use of `SolverShrinkUnsolvedThreshold`

* [TypeChecker] Bring back `SolverDisableShrink`

* [Tests] NFC: Mark tests affected by solver-perf revert as slow

* [Tests] NFC: Adjust async tests that are affected by performance hacks
2025-02-13 08:06:24 -08:00
Slava Pestov
99595e615e Revert "Sema: Split up gatherConstraints() into gatherAllConstraints() and gatherNearbyConstraints()"
This reverts commit 2230c3a17e.
2025-02-02 00:43:15 -05:00
Pavel Yaskevich
d245dac784 Merge pull request #79086 from xedin/small-solver-perf-optimizations
[CSOptimizer] A few small performance optimizations
2025-01-31 21:20:50 -08:00
Pavel Yaskevich
72340f39b8 [CSOptimizer] Look through OptionalEvaluationExprs when dealing with unapplied disjunctions
This improves performance for situations like `a?.b + 2` by
giving a high score to `b` which prioritizes it over an operator.
2025-01-31 13:07:29 -08:00
Pavel Yaskevich
6bc23b5057 [CSOptimizer] Don't consider disabled overloads when checking whether disjunction is supported
Non-operator disjunctions are supported only if all of their _active_
choices are concrete.
2025-01-31 13:06:51 -08:00
Pavel Yaskevich
f5158f8427 Merge pull request #79023 from xedin/rdar-143799118
[CSOptimizer] Disjunctions with IUO overload choices are unsupported
2025-01-30 00:37:33 -08:00
Pavel Yaskevich
654d39b736 Merge pull request #79004 from xedin/rdar-143582881
[CSOptimizer] MemberImportVisibility: Don't consider overloads that c…
2025-01-29 14:23:47 -08:00
Pavel Yaskevich
471ee21535 [CSOptimizer] Disjunctions with IUO overload choices are unsupported
They form a follow-up disjunction to determine whether force unwrap
is necessary and `getEffectiveType` cannot handle that.

Resolves: rdar://143799118
2025-01-29 10:36:16 -08:00
Pavel Yaskevich
aa4a2b9071 [CSOptimizer] MemberImportVisibility: Don't consider overloads that come from implicit imports
Ignore declarations that come from implicitly imported modules
when `MemberImportVisibility` feature is enabled otherwise
we might end up favoring an overload that would be diagnosed
as unavailable later.

Resolves: rdar://143582881
2025-01-29 10:09:39 -08:00
Pavel Yaskevich
248c0260f0 Merge pull request #78949 from xedin/rdar-143475850-part-2
[CSOptimizer] Don't consider CGFloat widening when explicit initializ…
2025-01-28 00:04:18 -08:00
Pavel Yaskevich
3cc76eacdd [CSOptimizer] Don't consider CGFloat widening when explicit initializer is used
Disable implicit `CGFloat` -> `Double` widening conversion if
argument is an explicit call to `CGFloat` initializer.
2025-01-27 09:57:47 -08:00
Slava Pestov
2230c3a17e Sema: Split up gatherConstraints() into gatherAllConstraints() and gatherNearbyConstraints()
The two GatherKinds no longer share any implementation, so there's
no point keeping the logic together. Doing this also allows removing
the acceptConstraintFn from gatherAllConstraints(), which further
simplifies depthFirstSearch().
2025-01-27 10:27:00 -05:00
Slava Pestov
1aff26eaa6 Sema: Store BindingSet inside the ConstraintGraphNode
Building the DenseMap in determineBestBindings() is extremely
expensive.

Also rename getCurrentBindings() to getPotentialBindings().
2025-01-15 22:30:32 -05:00
Pavel Yaskevich
e3987beffb [CSOptimizer] Literal arguments should cause score reset only for operators
Resetting score to `0.1` is intended to make sure that the
solver picks the outermost disjunction in literal chains like
`1 + 2 + 3 ...` because that would provide context to the
inner choices.

Resolves: https://github.com/swiftlang/swift/issues/78371
Resolves: rdar://142105691
2025-01-09 11:28:24 -08:00
Pavel Yaskevich
6c82892c3c [CSOptimizer] NFC: check whether a choice is of operator instead of whole disjunction 2025-01-09 10:39:18 -08:00
Pavel Yaskevich
8a304f88c6 [CSOptimizer] Extend candidate/parameter matching to support array literals
Match `[...]` to Array<...> and/or `ExpressibleByArrayLiteral`
conforming types. This is very helpful for expressions like:
`[...] + [...]`.
2024-12-25 12:51:01 -08:00
Pavel Yaskevich
0737542da8 [CSOptimizer] Favor choices that don't require application
When disjunction is not applied, don't only bump its score
but also favor all of the choices that don't require application
because selection algorithm uses that for comparison.

This is important for situation when property is overload with
a method i.e. `Array.count`.
2024-12-24 17:12:36 -08:00
Pavel Yaskevich
bc3a15fbe6 [CSOptimizer] Disable CGFloat -> Double conversion for unary operators
Some of the unary operators, i.e. prefix `-`, don't have
CGFloat variants and expect generic `FloatingPoint` overload
to match CGFloat type. Let's not attempt `CGFloat` -> `Double`
conversion for unary operators because it always leads
to a worse solutions vs. generic overloads.
2024-12-18 00:22:49 -08:00
Pavel Yaskevich
860ae08d1b [CSOptimizer] Mark bitwise operators as supported 2024-12-17 16:44:18 -08:00
Pavel Yaskevich
43ca7dfff9 [CSOptimizer] Simplify handling of non-applied disjunctions
If a disjunction doesn't have an application, let's prefer
it if it's passed as an argument to an operator application
or involved in a member chain, in such situations attempting
a disjunction could provide context to parent call/member chain.

If disjunction is passed as an unapplied reference to some
parameter i.e. `<base>.map(String.init(describing:))` we don't
favor it for now because optimizer cannot do enough checking
to determine whether preferring such disjunction would help
make forward progress in solving by pruning some space or
providing additional context.
2024-12-17 16:44:06 -08:00