Skip to content

Commit 3996b25

Browse files
committed
[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.
1 parent d0ff6c8 commit 3996b25

File tree

2 files changed

+17
-12
lines changed

2 files changed

+17
-12
lines changed

lib/Sema/CSOptimizer.cpp

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,15 @@ static bool isSupportedOperator(Constraint *disjunction) {
5757
return false;
5858
}
5959

60+
static bool isStandardComparisonOperator(ValueDecl *decl) {
61+
return decl->isOperator() &&
62+
decl->getBaseIdentifier().isStandardComparisonOperator();
63+
}
64+
65+
static bool isArithmeticOperator(ValueDecl *decl) {
66+
return decl->isOperator() && decl->getBaseIdentifier().isArithmeticOperator();
67+
}
68+
6069
static bool isSupportedDisjunction(Constraint *disjunction) {
6170
auto choices = disjunction->getNestedConstraints();
6271

@@ -561,9 +570,7 @@ static Constraint *determineBestChoicesInContext(
561570
// ones that all have the same result type), regular
562571
// functions/methods and especially initializers could end up
563572
// with a lot of favored overloads because on the result type alone.
564-
if (score > 0 ||
565-
(decl->isOperator() &&
566-
!decl->getBaseIdentifier().isStandardComparisonOperator())) {
573+
if (decl->isOperator() && !isStandardComparisonOperator(decl)) {
567574
if (llvm::any_of(resultTypes, [&](const Type candidateResultTy) {
568575
return scoreCandidateMatch(genericSig,
569576
overloadType->getResult(),
@@ -575,15 +582,14 @@ static Constraint *determineBestChoicesInContext(
575582
}
576583

577584
if (score > 0) {
578-
if (decl->isOperator() &&
579-
decl->getBaseIdentifier().isArithmeticOperator() &&
585+
// Nudge the score slightly to prefer concrete homogeneous
586+
// arithmetic operators.
587+
//
588+
// This is an opportunistic optimization based on the operator
589+
// use patterns where homogeneous operators are the most
590+
// heavily used ones.
591+
if (isArithmeticOperator(decl) &&
580592
overloadType->getNumParams() == 2) {
581-
// Nudge the score slightly to prefer concrete homogeneous
582-
// operators.
583-
//
584-
// This is an opportunistic optimization based on the operator
585-
// use patterns where homogeneous operators are the most
586-
// heavily used ones.
587593
auto resultTy = overloadType->getResult();
588594
if (!resultTy->hasTypeParameter() &&
589595
llvm::all_of(overloadType->getParams(),

validation-test/Sema/type_checker_perf/slow/operator_chain_with_hetergeneous_arguments.swift renamed to validation-test/Sema/type_checker_perf/fast/operator_chain_with_hetergeneous_arguments.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,4 @@
55
func test(bytes: Int, length: UInt32) {
66
// left-hand side of `>=` is `Int` and right-hand side is a chain of `UInt32` inferred from `length`
77
_ = bytes >= 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + length
8-
// expected-error@-1 {{reasonable time}}
98
}

0 commit comments

Comments
 (0)