@@ -721,19 +721,9 @@ namespace {
721
721
ConstraintGraph &cg;
722
722
ArrayRef<TypeVariableType *> typeVars;
723
723
724
- // / A mapping from each type variable to its representative in a union-find
725
- // / data structure, excluding entries where the type variable is its own
726
- // / representative.
727
- mutable llvm::SmallDenseMap<TypeVariableType *, TypeVariableType *>
728
- representatives;
729
-
730
- // Figure out which components have unbound type variables and/or
731
- // constraints. These are the only components we want to report.
732
- llvm::SmallDenseSet<TypeVariableType *> validComponents;
733
-
734
- // / The complete set of constraints that were visited while computing
735
- // / connected components.
736
- llvm::SmallPtrSet<Constraint *, 8 > visitedConstraints;
724
+ // / The number of connected components discovered so far. Decremented when
725
+ // / we merge equivalence classes.
726
+ unsigned validComponentCount = 0 ;
737
727
738
728
// / Describes the one-way incoming and outcoming adjacencies of
739
729
// / a component within the directed graph of one-way constraints.
@@ -776,10 +766,9 @@ namespace {
776
766
// The final return value.
777
767
SmallVector<Component, 1 > flatComponents;
778
768
779
-
780
769
// We don't actually need to partition the graph into components if
781
770
// there are fewer than 2.
782
- if (validComponents. size () < 2 && cg.getOrphanedConstraints ().empty ())
771
+ if (validComponentCount < 2 && cg.getOrphanedConstraints ().empty ())
783
772
return flatComponents;
784
773
785
774
// Mapping from representatives to components.
@@ -790,8 +779,8 @@ namespace {
790
779
for (auto typeVar : typeVars) {
791
780
// Find the representative. If we aren't creating a type variable
792
781
// for this component, skip it.
793
- auto rep = findRepresentative ( typeVar);
794
- if (validComponents. count (rep) == 0 )
782
+ auto rep = typeVar-> getImpl (). getComponent ( );
783
+ if (!rep-> getImpl (). isValidComponent () )
795
784
continue ;
796
785
797
786
auto pair = components.insert ({rep, Component (components.size ())});
@@ -829,7 +818,7 @@ namespace {
829
818
typeVar = constraintTypeVars.front ();
830
819
}
831
820
832
- auto rep = findRepresentative ( typeVar);
821
+ auto rep = typeVar-> getImpl (). getComponent ( );
833
822
getComponent (rep).addConstraint (&constraint);
834
823
}
835
824
@@ -857,7 +846,7 @@ namespace {
857
846
auto &oneWayComponent = knownOneWayComponent->second ;
858
847
auto &component = getComponent (typeVar);
859
848
for (auto inAdj : oneWayComponent.inAdjacencies ) {
860
- if (validComponents. count (inAdj) == 0 )
849
+ if (!inAdj-> getImpl (). isValidComponent () )
861
850
continue ;
862
851
863
852
component.recordDependency (getComponent (inAdj));
@@ -899,44 +888,34 @@ namespace {
899
888
return flatComponents;
900
889
}
901
890
902
- // / Find the representative for the given type variable within the set
903
- // / of representatives in a union-find data structure.
904
- TypeVariableType *findRepresentative (TypeVariableType *typeVar) const {
905
- // If we don't have a record of this type variable, it is it's own
906
- // representative.
907
- auto known = representatives.find (typeVar);
908
- if (known == representatives.end () || known->second == typeVar)
909
- return typeVar;
910
-
911
- // Find the representative of the parent.
912
- auto parent = known->second ;
913
- auto rep = findRepresentative (parent);
914
- representatives[typeVar] = rep;
915
-
916
- return rep;
917
- }
918
-
919
891
private:
920
892
// / Perform the union of two type variables in a union-find data structure
921
893
// / used for connected components.
922
894
// /
923
895
// / \returns true if the two components were separate and have now been
924
896
// / joined, \c false if they were already in the same set.
925
897
bool unionSets (TypeVariableType *typeVar1, TypeVariableType *typeVar2) {
926
- auto rep1 = findRepresentative ( typeVar1);
927
- auto rep2 = findRepresentative ( typeVar2);
898
+ auto rep1 = typeVar1-> getImpl (). getComponent ( );
899
+ auto rep2 = typeVar2-> getImpl (). getComponent ( );
928
900
if (rep1 == rep2)
929
901
return false ;
930
902
931
903
// Reparent the type variable with the higher ID. The actual choice doesn't
932
904
// matter, but this makes debugging easier.
933
- if (rep1->getID () < rep2->getID ()) {
934
- validComponents.erase (rep2);
935
- representatives[rep2] = rep1;
936
- } else {
937
- validComponents.erase (rep1);
938
- representatives[rep1] = rep2;
905
+ if (rep1->getID () > rep2->getID ())
906
+ std::swap (rep1, rep2);
907
+
908
+ if (rep2->getImpl ().isValidComponent ()) {
909
+ // If both are valid components, decrement the valid component counter
910
+ // by one. Otherwise, propagate the valid component flag.
911
+ if (!rep1->getImpl ().markValidComponent ()) {
912
+ ASSERT (validComponentCount > 0 );
913
+ --validComponentCount;
914
+ }
939
915
}
916
+
917
+ rep2->getImpl ().setComponent (rep1);
918
+
940
919
return true ;
941
920
}
942
921
@@ -949,51 +928,49 @@ namespace {
949
928
950
929
auto &cs = cg.getConstraintSystem ();
951
930
952
- // Perform a depth-first search from each type variable to identify
953
- // what component it is in.
954
931
for (auto typeVar : typeVars) {
955
- // If we've already assigned a representative to this type variable,
956
- // we're done.
957
- if (representatives.count (typeVar) > 0 )
958
- continue ;
959
-
960
- // Perform a depth-first search to mark those type variables that are
961
- // in the same component as this type variable.
962
- depthFirstSearch (
963
- cg, typeVar,
964
- [&](TypeVariableType *found) {
965
- // If we have already seen this node, we're done.
966
- auto inserted = representatives.insert ({found, typeVar});
967
- assert ((inserted.second || inserted.first ->second == typeVar) &&
968
- " Wrong component?" );
969
-
970
- if (inserted.second )
971
- if (!cs.getFixedType (found))
972
- validComponents.insert (typeVar);
973
-
974
- return inserted.second ;
975
- },
976
- [&](Constraint *constraint) {
977
- // Record and skip one-way constraints.
978
- if (constraint->isOneWayConstraint ()) {
979
- oneWayConstraints.push_back (constraint);
980
- return false ;
981
- }
932
+ auto &impl = typeVar->getImpl ();
933
+ if (auto *rep = impl.getRepresentativeOrFixed ().dyn_cast <TypeVariableType *>()) {
934
+ impl.setComponent (rep);
935
+ if (typeVar == rep) {
936
+ if (impl.markValidComponent ())
937
+ ++validComponentCount;
938
+ }
939
+ } else {
940
+ impl.setComponent (typeVar);
941
+ }
942
+ }
982
943
983
- return true ;
984
- },
985
- visitedConstraints);
944
+ for (auto typeVar : typeVars) {
945
+ auto &impl = typeVar->getImpl ();
946
+ if (auto fixedType = impl.getRepresentativeOrFixed ().dyn_cast <TypeBase *>()) {
947
+ auto &node = cg[typeVar];
948
+ for (auto otherTypeVar : node.getReferencedVars ()) {
949
+ unionSets (typeVar, otherTypeVar);
950
+ }
951
+ }
986
952
}
987
953
988
954
for (auto &constraint : cs.getConstraints ()) {
989
- if (constraint.getKind () == ConstraintKind::Disjunction ||
990
- constraint. getKind () == ConstraintKind::Conjunction) {
991
- for ( auto typeVar : constraint.getTypeVariables ()) {
992
- auto rep = findRepresentative ( typeVar);
993
- if (validComponents. insert (rep). second )
994
- ASSERT (cs. getFixedType (typeVar)) ;
995
- }
955
+ if (constraint.isOneWayConstraint ()) {
956
+ oneWayConstraints. push_back (&constraint);
957
+ auto * typeVar = constraint.getFirstType ()-> castTo <TypeVariableType>();
958
+ typeVar = typeVar-> getImpl (). getComponent ( );
959
+ if (typeVar-> getImpl (). markValidComponent () )
960
+ ++validComponentCount ;
961
+ continue ;
996
962
}
963
+
964
+ auto typeVars = constraint.getTypeVariables ();
965
+ if (typeVars.empty ())
966
+ continue ;
967
+
968
+ auto *firstTypeVar = typeVars[0 ]->getImpl ().getComponent ();
969
+ if (firstTypeVar->getImpl ().markValidComponent ())
970
+ ++validComponentCount;
971
+
972
+ for (auto *otherTypeVar : typeVars.slice (1 ))
973
+ unionSets (firstTypeVar, otherTypeVar);
997
974
}
998
975
999
976
return oneWayConstraints;
@@ -1016,7 +993,7 @@ namespace {
1016
993
SmallPtrSet<TypeVariableType *, 2 > typeVars;
1017
994
type->getTypeVariables (typeVars);
1018
995
for (auto typeVar : typeVars) {
1019
- auto rep = findRepresentative ( typeVar);
996
+ auto rep = typeVar-> getImpl (). getComponent ( );
1020
997
insertIfUnique (results, rep);
1021
998
}
1022
999
@@ -1226,7 +1203,7 @@ namespace {
1226
1203
rep,
1227
1204
[&](TypeVariableType *typeVar) -> ArrayRef<TypeVariableType *> {
1228
1205
// Traverse the outgoing adjacencies for the subcomponent
1229
- assert (typeVar == findRepresentative ( typeVar));
1206
+ assert (typeVar == typeVar-> getImpl (). getComponent ( ));
1230
1207
auto oneWayComponent = oneWayDigraph.find (typeVar);
1231
1208
if (oneWayComponent == oneWayDigraph.end ()) {
1232
1209
return { };
@@ -1240,7 +1217,7 @@ namespace {
1240
1217
[&](TypeVariableType *typeVar) {
1241
1218
// Record this type variable, if it's one of the representative
1242
1219
// type variables.
1243
- if (validComponents. count (typeVar) > 0 )
1220
+ if (typeVar-> getImpl (). isValidComponent () )
1244
1221
orderedReps.push_back (typeVar);
1245
1222
});
1246
1223
}
0 commit comments