@@ -431,10 +431,7 @@ llvm::TinyPtrVector<Constraint *> ConstraintGraph::gatherConstraints(
431
431
// / Perform a depth-first search.
432
432
// /
433
433
// / \param cg The constraint graph.
434
- // / \param node The current constraint graph node.
435
- // / \param nodeIndex The index of the current constraint graph node.
436
- // / \param visitFixedBindings Whether to visit the nodes by following
437
- // / fixed bindings.
434
+ // / \param typeVar The type variable we're searching from.
438
435
// / \param preVisitNode Called before traversing a node. Must return \c
439
436
// / false when the node has already been visited.
440
437
// / \param visitConstraint Called before considering a constraint. If it
@@ -443,31 +440,28 @@ llvm::TinyPtrVector<Constraint *> ConstraintGraph::gatherConstraints(
443
440
// / internally to avoid duplicated work.
444
441
static void depthFirstSearch (
445
442
ConstraintGraph &cg,
446
- ConstraintGraphNode &node,
447
- unsigned nodeIndex,
448
- bool visitFixedBindings,
449
- llvm::function_ref<bool (unsigned )> preVisitNode,
443
+ TypeVariableType *typeVar,
444
+ llvm::function_ref<bool (TypeVariableType *)> preVisitNode,
450
445
llvm::function_ref<bool(Constraint *)> visitConstraint,
451
446
llvm::DenseSet<Constraint *> &visitedConstraints) {
452
447
// Visit this node. If we've already seen it, bail out.
453
- if (!preVisitNode (nodeIndex ))
448
+ if (!preVisitNode (typeVar ))
454
449
return ;
455
450
456
451
// Local function to visit adjacent type variables.
457
452
auto visitAdjacencies = [&](ArrayRef<TypeVariableType *> adjTypeVars) {
458
453
for (auto adj : adjTypeVars) {
459
- if (adj == node. getTypeVariable () )
454
+ if (adj == typeVar )
460
455
continue ;
461
456
462
- auto adjNodeAndIndex = cg.lookupNode (adj);
463
-
464
457
// Recurse into this node.
465
- depthFirstSearch (cg, adjNodeAndIndex.first , adjNodeAndIndex.second ,
466
- visitFixedBindings, preVisitNode, visitConstraint,
458
+ depthFirstSearch (cg, adj, preVisitNode, visitConstraint,
467
459
visitedConstraints);
468
460
}
469
461
};
470
462
463
+ auto &node = cg[typeVar];
464
+
471
465
// Walk all of the constraints associated with this node to find related
472
466
// nodes.
473
467
for (auto constraint : node.getConstraints ()) {
@@ -480,9 +474,8 @@ static void depthFirstSearch(
480
474
}
481
475
482
476
// Visit all of the other nodes in the equivalence class.
483
- auto nodeTypeVar = node.getTypeVariable ();
484
- auto repTypeVar = cg.getConstraintSystem ().getRepresentative (nodeTypeVar);
485
- if (nodeTypeVar == repTypeVar) {
477
+ auto repTypeVar = cg.getConstraintSystem ().getRepresentative (typeVar);
478
+ if (typeVar == repTypeVar) {
486
479
// We are the representative, so visit all of the other type variables
487
480
// in this equivalence class.
488
481
visitAdjacencies (node.getEquivalenceClass ());
@@ -491,80 +484,56 @@ static void depthFirstSearch(
491
484
visitAdjacencies (repTypeVar);
492
485
}
493
486
494
- if (visitFixedBindings) {
495
- // Walk any type variables related via fixed bindings.
496
- visitAdjacencies (node.getFixedBindings ());
497
- }
487
+ // Walk any type variables related via fixed bindings.
488
+ visitAdjacencies (node.getFixedBindings ());
498
489
}
499
490
500
491
// / Perform a depth-first search.
501
492
// /
502
493
// / \param cg The constraint graph.
503
- // / \param node The current constraint graph node.
504
- // / \param nodeIndex The index of the current constraint graph node.
505
- // / \param visitFixedBindings Whether to visit the nodes by following
506
- // / fixed bindings.
494
+ // / \param typeVar The type variable we're searching from.
507
495
// / \param preVisitNode Called before traversing a node. Must return \c
508
496
// / false when the node has already been visited.
509
497
// / \param visitConstraint Called before considering a constraint. If it
510
498
// / returns \c false, that constraint will be skipped.
511
499
static void depthFirstSearch (
512
500
ConstraintGraph &cg,
513
- ConstraintGraphNode &node,
514
- unsigned nodeIndex,
515
- bool visitFixedBindings,
516
- llvm::function_ref<bool (unsigned )> preVisitNode,
501
+ TypeVariableType *typeVar,
502
+ llvm::function_ref<bool (TypeVariableType *)> preVisitNode,
517
503
llvm::function_ref<bool(Constraint *)> visitConstraint) {
518
504
llvm::DenseSet<Constraint *> visitedConstraints;
519
- depthFirstSearch (cg, node, nodeIndex, visitFixedBindings, preVisitNode ,
520
- visitConstraint, visitedConstraints);
505
+ depthFirstSearch (cg, typeVar, preVisitNode, visitConstraint ,
506
+ visitedConstraints);
521
507
}
522
508
523
509
unsigned ConstraintGraph::computeConnectedComponents (
524
510
std::vector<TypeVariableType *> &typeVars,
525
511
std::vector<unsigned > &components) {
526
- // Track those type variables that the caller cares about.
527
- llvm::SmallPtrSet<TypeVariableType *, 4 > typeVarSubset (typeVars.begin (),
528
- typeVars.end ());
529
- typeVars.clear ();
530
-
531
- // Initialize the components with component == # of type variables,
532
- // a sentinel value indicating that we have yet to assign a component to
533
- // that particular type variable.
534
- unsigned numTypeVariables = TypeVariables.size ();
535
- components.assign (numTypeVariables, numTypeVariables);
512
+ llvm::SmallDenseMap<TypeVariableType *, unsigned > componentsMap;
536
513
537
514
// Perform a depth-first search from each type variable to identify
538
515
// what component it is in.
539
- llvm::DenseSet<Constraint *> visitedConstraints;
540
516
unsigned numComponents = 0 ;
541
- for (unsigned i = 0 ; i != numTypeVariables; ++i) {
542
- auto typeVar = TypeVariables[i];
543
-
544
- // Look up the node for this type variable.
545
- auto nodeAndIndex = lookupNode (typeVar);
546
-
547
- // If we're already assigned a component for this node, skip it.
548
- unsigned &curComponent = components[nodeAndIndex.second ];
549
- if (curComponent != numTypeVariables)
517
+ for (auto typeVar : typeVars) {
518
+ // If we've already assigned a component to this type variable, we're done.
519
+ if (componentsMap.count (typeVar) > 0 )
550
520
continue ;
551
521
552
522
// Record this component.
553
523
unsigned component = numComponents++;
554
524
555
- // Note that this node is part of this component, then visit it.
525
+ // Perform a depth-first search to mark those type variables that are
526
+ // in the same component as this type variable.
556
527
depthFirstSearch (
557
- *this , nodeAndIndex.first , nodeAndIndex.second ,
558
- /* visitFixedBindings=*/ true ,
559
- [&](unsigned nodeIndex) {
528
+ *this , typeVar,
529
+ [&](TypeVariableType *typeVar) {
560
530
// If we have already seen this node, we're done.
561
- unsigned &nodeComponent = components[nodeIndex];
562
- if (nodeComponent == component)
531
+ if (componentsMap. count (typeVar) > 0 ) {
532
+ assert (componentsMap[typeVar] == component && " Wrong component? " );
563
533
return false ;
534
+ }
564
535
565
- assert (nodeComponent == components.size () &&
566
- " Already in a component?" );
567
- nodeComponent = component;
536
+ componentsMap[typeVar] = component;
568
537
return true ;
569
538
},
570
539
[&](Constraint *constraint) {
@@ -575,43 +544,43 @@ unsigned ConstraintGraph::computeConnectedComponents(
575
544
// Figure out which components have unbound type variables; these
576
545
// are the only components and type variables we want to report.
577
546
SmallVector<bool , 4 > componentHasUnboundTypeVar (numComponents, false );
578
- for (unsigned i = 0 ; i != numTypeVariables; ++i ) {
547
+ for (auto typeVar : typeVars ) {
579
548
// If this type variable has a fixed type, skip it.
580
- if (CS.getFixedType (TypeVariables[i]))
581
- continue ;
582
-
583
- // If this type variable isn't in the subset of type variables we care
584
- // about, skip it.
585
- if (typeVarSubset.count (TypeVariables[i]) == 0 )
549
+ if (CS.getFixedType (typeVar))
586
550
continue ;
587
551
588
- componentHasUnboundTypeVar[components[i]] = true ;
552
+ assert (componentsMap.count (typeVar) > 0 );
553
+ componentHasUnboundTypeVar[componentsMap[typeVar]] = true ;
589
554
}
590
555
591
556
// Renumber the old components to the new components.
592
557
SmallVector<unsigned , 4 > componentRenumbering (numComponents, 0 );
593
558
numComponents = 0 ;
594
- for (unsigned i = 0 , n = componentHasUnboundTypeVar. size (); i != n; ++i ) {
559
+ for (unsigned i : indices (componentRenumbering) ) {
595
560
// Skip components that have no unbound type variables.
596
561
if (!componentHasUnboundTypeVar[i])
597
562
continue ;
598
563
599
564
componentRenumbering[i] = numComponents++;
600
565
}
601
566
602
- // Copy over the type variables in the live components and remap
603
- // component numbers.
604
- unsigned outIndex = 0 ;
605
- for (unsigned i = 0 , n = TypeVariables.size (); i != n; ++i) {
606
- // Skip type variables in dead components.
607
- if (!componentHasUnboundTypeVar[components[i]])
608
- continue ;
609
-
610
- typeVars.push_back (TypeVariables[i]);
611
- components[outIndex] = componentRenumbering[components[i]];
612
- ++outIndex;
613
- }
614
- components.erase (components.begin () + outIndex, components.end ());
567
+ // Remove type variables in dead components and provide component
568
+ // numbers for those that remain.
569
+ typeVars.erase (
570
+ std::remove_if (
571
+ typeVars.begin (), typeVars.end (),
572
+ [&](TypeVariableType *typeVar) {
573
+ assert (componentsMap.count (typeVar) > 0 );
574
+ unsigned component = componentsMap[typeVar];
575
+ // Remove type variables in dead components.
576
+ if (!componentHasUnboundTypeVar[component])
577
+ return true ;
578
+
579
+ // Record the (renumbered) component.
580
+ components.push_back (componentRenumbering[component]);
581
+ return false ;
582
+ }),
583
+ typeVars.end ());
615
584
616
585
return numComponents + getOrphanedConstraints ().size ();
617
586
}
0 commit comments