@@ -145,20 +145,16 @@ void ConstraintSystem::mapImplicitConversions(Solution *solution)
145145 }
146146}
147147
148- bool ConstraintSystem::solveConstraints ( )
148+ bool ConstraintSystem::solveLocalConstraints (SolutionResult &result )
149149{
150150 // / The initial system state used to begin constraint solving.
151151 std::vector<SystemState> worklist;
152152 worklist.emplace_back (_context); // Start from an empty state
153153
154- SolutionResult result; // Local solution result
155-
156154 while (!worklist.empty ()) {
157155 SystemState current = std::move (worklist.back ());
158156 worklist.pop_back ();
159157
160- bool failed = false ;
161-
162158 // / Apply non-defaultable constraints first
163159 for (Constraint *constraint : _constraints) {
164160 // Skip disabled constraints
@@ -176,15 +172,11 @@ bool ConstraintSystem::solveConstraints()
176172 ConstraintResult result = apply (constraint, current, worklist);
177173 markConstraint (result, constraint);
178174 if (result == ConstraintResult::Failed) {
179- failed = true ;
180- break ;
175+ goto failed;
181176 }
182177 // Continue if Satisfied or Applied
183178 }
184179
185- if (failed)
186- continue ;
187-
188180 for (Constraint *constraint : _constraints) {
189181 if (constraint->isDisabled ())
190182 continue ;
@@ -194,8 +186,7 @@ bool ConstraintSystem::solveConstraints()
194186 ConstraintResult result = apply (constraint, current, worklist);
195187 markConstraint (result, constraint);
196188 if (result == ConstraintResult::Failed) {
197- failed = true ;
198- break ;
189+ goto failed;
199190 }
200191 }
201192
@@ -214,8 +205,7 @@ bool ConstraintSystem::solveConstraints()
214205 ConstraintResult result = apply (constraint, current, worklist);
215206 markConstraint (result, constraint);
216207 if (result == ConstraintResult::Failed) {
217- failed = true ;
218- break ;
208+ goto failed;
219209 }
220210 // Continue if Satisfied or Applied
221211 }
@@ -235,17 +225,16 @@ bool ConstraintSystem::solveConstraints()
235225 ConstraintResult result = apply (constraint, current, worklist);
236226 markConstraint (result, constraint);
237227 if (result == ConstraintResult::Failed) {
238- failed = true ;
239- break ;
228+ goto failed;
240229 }
241230 // Continue if Satisfied or Applied
242231 }
243232
244- if (failed)
245- continue ;
246-
247233 // / All constraints are satisfied -- record the solution.
248234 result.tryAddSolution (current);
235+
236+ failed:
237+ continue ;
249238 }
250239
251240 if (result.isAmbiguous ()) {
@@ -259,9 +248,68 @@ bool ConstraintSystem::solveConstraints()
259248 reportNoSolutionError ();
260249 return false ;
261250 }
262- mapTypeVariables (solution);
263- mapOverloadChoices (solution);
264- mapImplicitConversions (solution);
251+ return true ;
252+ }
253+
254+ bool ConstraintSystem::solveConstraints ()
255+ {
256+ // color the constraints based on which type variables they contain
257+ // map of color => set of used type variables
258+ std::vector<llvm::DenseSet<glu::types::TypeVariableTy *>> colors;
259+ // map of color => set of constraints
260+ std::vector<llvm::DenseSet<Constraint *>> colorConstraints;
261+ for (auto *constraint : _constraints) {
262+ llvm::DenseSet<glu::types::TypeVariableTy *> typeVars;
263+ collectTypeVariables (constraint, typeVars);
264+ colors.push_back (std::move (typeVars));
265+ colorConstraints.push_back ({ constraint });
266+ }
267+ // merge colors that share type variables
268+ bool changed;
269+ do {
270+ changed = false ;
271+ for (std::size_t i = 0 ; i < colors.size (); ++i) {
272+ for (std::size_t j = i + 1 ; j < colors.size (); ++j) {
273+ llvm::DenseSet<glu::types::TypeVariableTy *> intersection;
274+ for (auto *typeVar : colors[j]) {
275+ if (colors[i].count (typeVar)) {
276+ intersection.insert (typeVar);
277+ }
278+ }
279+ if (!intersection.empty ()) {
280+ // merge j into i
281+ for (auto *typeVar : colors[j]) {
282+ colors[i].insert (typeVar);
283+ }
284+ for (auto *constraint : colorConstraints[j]) {
285+ colorConstraints[i].insert (constraint);
286+ }
287+ changed = true ;
288+ // Erase the merged color
289+ colors.erase (colors.begin () + j);
290+ colorConstraints.erase (colorConstraints.begin () + j);
291+ --j;
292+ }
293+ }
294+ }
295+ } while (changed);
296+ // solve each color separately
297+ SystemState finalSolution (_context);
298+ for (std::size_t i = 0 ; i < colors.size (); ++i) {
299+ // Disable all constraints not in this color
300+ for (auto *constraint : _constraints) {
301+ constraint->setEnabled (colorConstraints[i].count (constraint));
302+ }
303+ SolutionResult result;
304+ if (!solveLocalConstraints (result)) {
305+ return false ;
306+ }
307+ result.getBestSolution ()->mergeInto (finalSolution);
308+ }
309+
310+ mapTypeVariables (&finalSolution);
311+ mapOverloadChoices (&finalSolution);
312+ mapImplicitConversions (&finalSolution);
265313 return true ;
266314}
267315
0 commit comments