@@ -472,6 +472,67 @@ void ConstraintGraph::unbindTypeVariable(TypeVariableType *typeVar, Type fixed){
472
472
}
473
473
}
474
474
475
+ #pragma mark Algorithms
476
+
477
+ // / Perform a depth-first search.
478
+ // /
479
+ // / \param cg The constraint graph.
480
+ // / \param typeVar The type variable we're searching from.
481
+ // / \param preVisitNode Called before traversing a node. Must return \c
482
+ // / false when the node has already been visited.
483
+ // / \param visitConstraint Called before considering a constraint. If it
484
+ // / returns \c false, that constraint will be skipped.
485
+ // / \param visitedConstraints Set of already-visited constraints, used
486
+ // / internally to avoid duplicated work.
487
+ static void depthFirstSearch (
488
+ ConstraintGraph &cg,
489
+ TypeVariableType *typeVar,
490
+ llvm::function_ref<bool (TypeVariableType *)> preVisitNode,
491
+ llvm::function_ref<bool(Constraint *)> visitConstraint,
492
+ llvm::SmallPtrSet<Constraint *, 8> &visitedConstraints) {
493
+ // Visit this node. If we've already seen it, bail out.
494
+ if (!preVisitNode (typeVar))
495
+ return ;
496
+
497
+ // Local function to visit adjacent type variables.
498
+ auto visitAdjacencies = [&](ArrayRef<TypeVariableType *> adjTypeVars) {
499
+ for (auto adj : adjTypeVars) {
500
+ if (adj == typeVar)
501
+ continue ;
502
+
503
+ // Recurse into this node.
504
+ depthFirstSearch (cg, adj, preVisitNode, visitConstraint,
505
+ visitedConstraints);
506
+ }
507
+ };
508
+
509
+ // Walk all of the constraints associated with this node to find related
510
+ // nodes.
511
+ auto &node = cg[typeVar];
512
+ for (auto constraint : node.getConstraints ()) {
513
+ // If we've already seen this constraint, skip it.
514
+ if (!visitedConstraints.insert (constraint).second )
515
+ continue ;
516
+
517
+ if (visitConstraint (constraint))
518
+ visitAdjacencies (constraint->getTypeVariables ());
519
+ }
520
+
521
+ // Visit all of the other nodes in the equivalence class.
522
+ auto repTypeVar = cg.getConstraintSystem ().getRepresentative (typeVar);
523
+ if (typeVar == repTypeVar) {
524
+ // We are the representative, so visit all of the other type variables
525
+ // in this equivalence class.
526
+ visitAdjacencies (node.getEquivalenceClass ());
527
+ } else {
528
+ // We are not the representative; visit the representative.
529
+ visitAdjacencies (repTypeVar);
530
+ }
531
+
532
+ // Walk any type variables related via fixed bindings.
533
+ visitAdjacencies (node.getFixedBindings ());
534
+ }
535
+
475
536
llvm::TinyPtrVector<Constraint *> ConstraintGraph::gatherConstraints (
476
537
TypeVariableType *typeVar, GatheringKind kind,
477
538
llvm::function_ref<bool (Constraint *)> acceptConstraintFn) {
@@ -571,67 +632,6 @@ llvm::TinyPtrVector<Constraint *> ConstraintGraph::gatherConstraints(
571
632
return constraints;
572
633
}
573
634
574
- #pragma mark Algorithms
575
-
576
- // / Perform a depth-first search.
577
- // /
578
- // / \param cg The constraint graph.
579
- // / \param typeVar The type variable we're searching from.
580
- // / \param preVisitNode Called before traversing a node. Must return \c
581
- // / false when the node has already been visited.
582
- // / \param visitConstraint Called before considering a constraint. If it
583
- // / returns \c false, that constraint will be skipped.
584
- // / \param visitedConstraints Set of already-visited constraints, used
585
- // / internally to avoid duplicated work.
586
- static void depthFirstSearch (
587
- ConstraintGraph &cg,
588
- TypeVariableType *typeVar,
589
- llvm::function_ref<bool (TypeVariableType *)> preVisitNode,
590
- llvm::function_ref<bool(Constraint *)> visitConstraint,
591
- llvm::SmallPtrSet<Constraint *, 8> &visitedConstraints) {
592
- // Visit this node. If we've already seen it, bail out.
593
- if (!preVisitNode (typeVar))
594
- return ;
595
-
596
- // Local function to visit adjacent type variables.
597
- auto visitAdjacencies = [&](ArrayRef<TypeVariableType *> adjTypeVars) {
598
- for (auto adj : adjTypeVars) {
599
- if (adj == typeVar)
600
- continue ;
601
-
602
- // Recurse into this node.
603
- depthFirstSearch (cg, adj, preVisitNode, visitConstraint,
604
- visitedConstraints);
605
- }
606
- };
607
-
608
- // Walk all of the constraints associated with this node to find related
609
- // nodes.
610
- auto &node = cg[typeVar];
611
- for (auto constraint : node.getConstraints ()) {
612
- // If we've already seen this constraint, skip it.
613
- if (!visitedConstraints.insert (constraint).second )
614
- continue ;
615
-
616
- if (visitConstraint (constraint))
617
- visitAdjacencies (constraint->getTypeVariables ());
618
- }
619
-
620
- // Visit all of the other nodes in the equivalence class.
621
- auto repTypeVar = cg.getConstraintSystem ().getRepresentative (typeVar);
622
- if (typeVar == repTypeVar) {
623
- // We are the representative, so visit all of the other type variables
624
- // in this equivalence class.
625
- visitAdjacencies (node.getEquivalenceClass ());
626
- } else {
627
- // We are not the representative; visit the representative.
628
- visitAdjacencies (repTypeVar);
629
- }
630
-
631
- // Walk any type variables related via fixed bindings.
632
- visitAdjacencies (node.getFixedBindings ());
633
- }
634
-
635
635
namespace {
636
636
// / A union-find connected components algorithm used to find the connected
637
637
// / components within a constraint graph.
0 commit comments