@@ -2077,27 +2077,28 @@ static void existingOperatorBindingsForDisjunction(ConstraintSystem &CS,
2077
2077
}
2078
2078
}
2079
2079
2080
- // / Populates the \c found vector with the indices of the given constraints
2081
- // / that are arithmetic operator choices in the best order to attempt based on
2082
- // / the argument function type that the operator is applied to.
2083
- static void takeArithmeticOperators (ConstraintSystem &CS, const FunctionType *argFnType,
2084
- ArrayRef<Constraint *> constraints,
2085
- SmallVectorImpl<unsigned > &found,
2086
- ConstraintSystem::ConstraintMatchLoop forEachChoice) {
2080
+ void ConstraintSystem::partitionGenericOperators (ArrayRef<Constraint *> constraints,
2081
+ SmallVectorImpl<unsigned >::iterator first,
2082
+ SmallVectorImpl<unsigned >::iterator last,
2083
+ ConstraintLocator *locator) {
2084
+ auto *argFnType = AppliedDisjunctions[locator];
2085
+ if (!isOperatorBindOverload (constraints[0 ]) || !argFnType)
2086
+ return ;
2087
+
2087
2088
auto operatorName = constraints[0 ]->getOverloadChoice ().getName ();
2088
2089
if (!operatorName.getBaseIdentifier ().isArithmeticOperator ())
2089
2090
return ;
2090
2091
2092
+ SmallVector<unsigned , 4 > concreteOverloads;
2091
2093
SmallVector<unsigned , 4 > numericOverloads;
2092
2094
SmallVector<unsigned , 4 > sequenceOverloads;
2093
- SmallVector<unsigned , 4 > simdOverloads;
2094
2095
SmallVector<unsigned , 4 > otherGenericOverloads;
2095
2096
2096
2097
auto refinesOrConformsTo = [&](NominalTypeDecl *nominal, KnownProtocolKind kind) -> bool {
2097
2098
if (!nominal)
2098
2099
return false ;
2099
2100
2100
- auto *protocol = TypeChecker::getProtocol (CS. getASTContext (), SourceLoc (), kind);
2101
+ auto *protocol = TypeChecker::getProtocol (getASTContext (), SourceLoc (), kind);
2101
2102
2102
2103
if (auto *refined = dyn_cast<ProtocolDecl>(nominal))
2103
2104
return refined->inheritsFrom (protocol);
@@ -2106,29 +2107,21 @@ static void takeArithmeticOperators(ConstraintSystem &CS, const FunctionType *ar
2106
2107
nominal->getDeclContext ());
2107
2108
};
2108
2109
2109
- // Gather concrete, Numeric, Sequence, and SIMD overloads into separate buckets.
2110
- forEachChoice (constraints, [&](unsigned index, Constraint *constraint) -> bool {
2111
- auto *decl = constraint->getOverloadChoice ().getDecl ();
2112
-
2113
- if (isSIMDOperator (decl)) {
2114
- simdOverloads.push_back (index);
2115
- return true ;
2116
- }
2117
-
2110
+ // Gather Numeric and Sequence overloads into separate buckets.
2111
+ for (auto iter = first; iter != last; ++iter) {
2112
+ unsigned index = *iter;
2113
+ auto *decl = constraints[index]->getOverloadChoice ().getDecl ();
2118
2114
auto *nominal = decl->getDeclContext ()->getSelfNominalTypeDecl ();
2119
2115
if (!decl->getInterfaceType ()->is <GenericFunctionType>()) {
2120
- // Concrete overloads should always be attempted first.
2121
- found.push_back (index);
2116
+ concreteOverloads.push_back (index);
2122
2117
} else if (refinesOrConformsTo (nominal, KnownProtocolKind::AdditiveArithmetic)) {
2123
2118
numericOverloads.push_back (index);
2124
2119
} else if (refinesOrConformsTo (nominal, KnownProtocolKind::Sequence)) {
2125
2120
sequenceOverloads.push_back (index);
2126
2121
} else {
2127
2122
otherGenericOverloads.push_back (index);
2128
2123
}
2129
-
2130
- return true ;
2131
- });
2124
+ }
2132
2125
2133
2126
auto sortPartition = [&](SmallVectorImpl<unsigned > &partition) {
2134
2127
llvm::sort (partition, [&](unsigned lhs, unsigned rhs) -> bool {
@@ -2144,6 +2137,9 @@ static void takeArithmeticOperators(ConstraintSystem &CS, const FunctionType *ar
2144
2137
// subsequent choices that the successful choice is a refinement of.
2145
2138
sortPartition (sequenceOverloads);
2146
2139
2140
+ // Attempt concrete overloads first.
2141
+ first = std::copy (concreteOverloads.begin (), concreteOverloads.end (), first);
2142
+
2147
2143
// Check if any of the known argument types conform to one of the standard
2148
2144
// arithmetic protocols. If so, the sovler should attempt the corresponding
2149
2145
// overload choices first.
@@ -2152,34 +2148,27 @@ static void takeArithmeticOperators(ConstraintSystem &CS, const FunctionType *ar
2152
2148
if (!argType || argType->hasTypeVariable ())
2153
2149
continue ;
2154
2150
2155
- if (conformsToKnownProtocol (CS. DC , argType, KnownProtocolKind::AdditiveArithmetic)) {
2156
- found. append (numericOverloads.begin (), numericOverloads.end ());
2151
+ if (conformsToKnownProtocol (DC, argType, KnownProtocolKind::AdditiveArithmetic)) {
2152
+ first = std::copy (numericOverloads.begin (), numericOverloads.end (), first );
2157
2153
numericOverloads.clear ();
2158
2154
break ;
2159
2155
}
2160
2156
2161
- if (conformsToKnownProtocol (CS. DC , argType, KnownProtocolKind::Sequence)) {
2162
- found. append (sequenceOverloads.begin (), sequenceOverloads.end ());
2157
+ if (conformsToKnownProtocol (DC, argType, KnownProtocolKind::Sequence)) {
2158
+ first = std::copy (sequenceOverloads.begin (), sequenceOverloads.end (), first );
2163
2159
sequenceOverloads.clear ();
2164
2160
break ;
2165
2161
}
2166
-
2167
- if (conformsToKnownProtocol (CS.DC , argType, KnownProtocolKind::SIMD)) {
2168
- found.append (simdOverloads.begin (), simdOverloads.end ());
2169
- simdOverloads.clear ();
2170
- break ;
2171
- }
2172
2162
}
2173
2163
2174
- found.append (otherGenericOverloads.begin (), otherGenericOverloads.end ());
2175
- found.append (numericOverloads.begin (), numericOverloads.end ());
2176
- found.append (sequenceOverloads.begin (), sequenceOverloads.end ());
2177
- found.append (simdOverloads.begin (), simdOverloads.end ());
2164
+ first = std::copy (otherGenericOverloads.begin (), otherGenericOverloads.end (), first);
2165
+ first = std::copy (numericOverloads.begin (), numericOverloads.end (), first);
2166
+ first = std::copy (sequenceOverloads.begin (), sequenceOverloads.end (), first);
2178
2167
}
2179
2168
2180
2169
void ConstraintSystem::partitionDisjunction (
2181
2170
ArrayRef<Constraint *> Choices, SmallVectorImpl<unsigned > &Ordering,
2182
- SmallVectorImpl<unsigned > &PartitionBeginning, ConstraintLocator *locator ) {
2171
+ SmallVectorImpl<unsigned > &PartitionBeginning) {
2183
2172
// Apply a special-case rule for favoring one generic function over
2184
2173
// another.
2185
2174
if (auto favored = tryOptimizeGenericDisjunction (DC, Choices)) {
@@ -2252,11 +2241,8 @@ void ConstraintSystem::partitionDisjunction(
2252
2241
});
2253
2242
}
2254
2243
2255
- // Gather arithmetic and SIMD operators.
2244
+ // Partition SIMD operators.
2256
2245
if (isOperatorBindOverload (Choices[0 ])) {
2257
- if (auto *argFnType = AppliedDisjunctions[locator])
2258
- takeArithmeticOperators (*this , argFnType, Choices, everythingElse, forEachChoice);
2259
-
2260
2246
forEachChoice (Choices, [&](unsigned index, Constraint *constraint) -> bool {
2261
2247
if (!isOperatorBindOverload (constraint))
2262
2248
return false ;
0 commit comments