@@ -2015,7 +2015,9 @@ static Constraint *tryOptimizeGenericDisjunction(
20152015
20162016// Performance hack: favor operator overloads with decl or type we're already
20172017// binding elsewhere in this expression.
2018- static void existingOperatorBindingsForDisjunction (ConstraintSystem &CS, ArrayRef<Constraint *> constraints, SmallVectorImpl<Constraint *> &found) {
2018+ static void existingOperatorBindingsForDisjunction (ConstraintSystem &CS,
2019+ ArrayRef<Constraint *> constraints,
2020+ SmallVectorImpl<unsigned > &found) {
20192021 auto *choice = constraints.front ();
20202022 if (choice->getKind () != ConstraintKind::BindOverload)
20212023 return ;
@@ -2026,59 +2028,35 @@ static void existingOperatorBindingsForDisjunction(ConstraintSystem &CS, ArrayRe
20262028 auto decl = overload.getDecl ();
20272029 if (!decl->isOperator ())
20282030 return ;
2029- auto baseName = decl->getBaseName ();
2030-
2031- SmallSet<TypeBase *, 8 > typesFound;
20322031
2032+ SmallSet<CanType, 8 > typesFound;
20332033 for (auto overload : CS.getResolvedOverloads ()) {
20342034 auto resolved = overload.second ;
20352035 if (!resolved.choice .isDecl ())
20362036 continue ;
2037- auto representativeDecl = resolved.choice .getDecl ();
20382037
2038+ auto representativeDecl = resolved.choice .getDecl ();
20392039 if (!representativeDecl->isOperator ())
20402040 continue ;
20412041
2042- if (representativeDecl->getBaseName () == baseName) {
2043- // Favor exactly the same decl, if we have a binding to the same name.
2044- for (auto *constraint : constraints) {
2045- if (constraint->isFavored ())
2046- continue ;
2047- auto choice = constraint->getOverloadChoice ();
2048- if (choice.getDecl () == representativeDecl) {
2049- found.push_back (constraint);
2050- break ;
2051- }
2052- }
2053- } else {
2054- // Favor the same type, if we have a binding to an operator of that type.
2055- auto representativeType = representativeDecl->getInterfaceType ();
2056- if (typesFound.count (representativeType.getPointer ()))
2057- continue ;
2058- typesFound.insert (representativeType.getPointer ());
2042+ typesFound.insert (representativeDecl->getInterfaceType ()->getCanonicalType ());
2043+ }
20592044
2060- for (auto *constraint : constraints) {
2061- if (constraint->isFavored ())
2062- continue ;
2063- auto choice = constraint->getOverloadChoice ();
2064- if (choice.getDecl ()->getInterfaceType ()->isEqual (representativeType)) {
2065- found.push_back (constraint);
2066- break ;
2067- }
2068- }
2069- }
2045+ for (auto index : indices (constraints)) {
2046+ auto *constraint = constraints[index];
2047+ if (constraint->isFavored ())
2048+ continue ;
2049+
2050+ auto *decl = constraint->getOverloadChoice ().getDecl ();
2051+ if (typesFound.count (decl->getInterfaceType ()->getCanonicalType ()))
2052+ found.push_back (index);
20702053 }
20712054}
20722055
20732056void ConstraintSystem::partitionDisjunction (
20742057 ArrayRef<Constraint *> Choices, SmallVectorImpl<unsigned > &Ordering,
20752058 SmallVectorImpl<unsigned > &PartitionBeginning) {
20762059
2077- SmallVector<Constraint *, 4 > existing;
2078- existingOperatorBindingsForDisjunction (*this , Choices, existing);
2079- for (auto constraint : existing)
2080- favorConstraint (constraint);
2081-
20822060 // Apply a special-case rule for favoring one generic function over
20832061 // another.
20842062 if (auto favored = tryOptimizeGenericDisjunction (DC, Choices)) {
@@ -2105,12 +2083,18 @@ void ConstraintSystem::partitionDisjunction(
21052083
21062084 // First collect some things that we'll generally put near the beginning or
21072085 // end of the partitioning.
2108-
21092086 SmallVector<unsigned , 4 > favored;
2087+ SmallVector<unsigned , 4 > everythingElse;
21102088 SmallVector<unsigned , 4 > simdOperators;
21112089 SmallVector<unsigned , 4 > disabled;
21122090 SmallVector<unsigned , 4 > unavailable;
21132091
2092+ // Add existing operator bindings to the main partition first. This often
2093+ // helps the solver find a solution fast.
2094+ existingOperatorBindingsForDisjunction (*this , Choices, everythingElse);
2095+ for (auto index : everythingElse)
2096+ taken.insert (Choices[index]);
2097+
21142098 // First collect disabled and favored constraints.
21152099 forEachChoice (Choices, [&](unsigned index, Constraint *constraint) -> bool {
21162100 if (constraint->isDisabled ()) {
@@ -2170,7 +2154,6 @@ void ConstraintSystem::partitionDisjunction(
21702154 }
21712155 };
21722156
2173- SmallVector<unsigned , 4 > everythingElse;
21742157 // Gather the remaining options.
21752158 forEachChoice (Choices, [&](unsigned index, Constraint *constraint) -> bool {
21762159 everythingElse.push_back (index);
@@ -2206,8 +2189,8 @@ Constraint *ConstraintSystem::selectDisjunction() {
22062189
22072190 if (firstFavored == secondFavored) {
22082191 // Look for additional choices to favor
2209- SmallVector<Constraint * , 4 > firstExisting;
2210- SmallVector<Constraint * , 4 > secondExisting;
2192+ SmallVector<unsigned , 4 > firstExisting;
2193+ SmallVector<unsigned , 4 > secondExisting;
22112194
22122195 existingOperatorBindingsForDisjunction (*cs, first->getNestedConstraints (), firstExisting);
22132196 firstFavored = firstExisting.size () ? firstExisting.size () : first->countActiveNestedConstraints ();
0 commit comments