@@ -756,7 +756,7 @@ impl CurrentDepGraph {
756
756
self . task_stack . push ( OpenTask :: Regular {
757
757
node : key,
758
758
reads : Vec :: new ( ) ,
759
- read_set : FxHashSet ( ) ,
759
+ read_set : DepNodeIndexSet :: Zero ,
760
760
} ) ;
761
761
}
762
762
@@ -778,7 +778,7 @@ impl CurrentDepGraph {
778
778
fn push_anon_task ( & mut self ) {
779
779
self . task_stack . push ( OpenTask :: Anon {
780
780
reads : Vec :: new ( ) ,
781
- read_set : FxHashSet ( ) ,
781
+ read_set : DepNodeIndexSet :: Zero ,
782
782
} ) ;
783
783
}
784
784
@@ -890,19 +890,79 @@ impl CurrentDepGraph {
890
890
}
891
891
}
892
892
893
- #[ derive( Clone , Debug , PartialEq ) ]
893
+ #[ derive( Debug , PartialEq , Eq ) ]
894
894
enum OpenTask {
895
895
Regular {
896
896
node : DepNode ,
897
897
reads : Vec < DepNodeIndex > ,
898
- read_set : FxHashSet < DepNodeIndex > ,
898
+ read_set : DepNodeIndexSet ,
899
899
} ,
900
900
Anon {
901
901
reads : Vec < DepNodeIndex > ,
902
- read_set : FxHashSet < DepNodeIndex > ,
902
+ read_set : DepNodeIndexSet ,
903
903
} ,
904
904
Ignore ,
905
905
EvalAlways {
906
906
node : DepNode ,
907
907
} ,
908
908
}
909
+
910
+ // Many kinds of nodes often only have between 0 and 3 edges, so we provide a
911
+ // specialized set implementation that does not allocate for those some counts.
912
+ #[ derive( Debug , PartialEq , Eq ) ]
913
+ enum DepNodeIndexSet {
914
+ Zero ,
915
+ One ( DepNodeIndex ) ,
916
+ Two ( DepNodeIndex , DepNodeIndex ) ,
917
+ Three ( DepNodeIndex , DepNodeIndex , DepNodeIndex ) ,
918
+ Four ( DepNodeIndex , DepNodeIndex , DepNodeIndex , DepNodeIndex ) ,
919
+ Many ( FxHashSet < DepNodeIndex > ) ,
920
+ }
921
+
922
+ impl DepNodeIndexSet {
923
+ #[ inline( always) ]
924
+ fn insert ( & mut self , x : DepNodeIndex ) -> bool {
925
+ let new_state = match * self {
926
+ DepNodeIndexSet :: Zero => {
927
+ DepNodeIndexSet :: One ( x)
928
+ }
929
+ DepNodeIndexSet :: One ( a) => {
930
+ if x == a {
931
+ return false
932
+ } else {
933
+ DepNodeIndexSet :: Two ( x, a)
934
+ }
935
+ }
936
+ DepNodeIndexSet :: Two ( a, b) => {
937
+ if x == a || x == b {
938
+ return false
939
+ } else {
940
+ DepNodeIndexSet :: Three ( x, a, b)
941
+ }
942
+ }
943
+ DepNodeIndexSet :: Three ( a, b, c) => {
944
+ if x == a || x == b || x == c {
945
+ return false
946
+ } else {
947
+ DepNodeIndexSet :: Four ( x, a, b, c)
948
+ }
949
+ }
950
+ DepNodeIndexSet :: Four ( a, b, c, d) => {
951
+ if x == a || x == b || x == c || x == d {
952
+ return false
953
+ } else {
954
+ let hash_set: FxHashSet < _ > = [ x, a, b, c, d] . into_iter ( )
955
+ . cloned ( )
956
+ . collect ( ) ;
957
+ DepNodeIndexSet :: Many ( hash_set)
958
+ }
959
+ }
960
+ DepNodeIndexSet :: Many ( ref mut set) => {
961
+ return set. insert ( x)
962
+ }
963
+ } ;
964
+
965
+ * self = new_state;
966
+ true
967
+ }
968
+ }
0 commit comments