@@ -724,7 +724,7 @@ impl CurrentDepGraph {
724
724
self . task_stack . push ( OpenTask :: Regular {
725
725
node : key,
726
726
reads : Vec :: new ( ) ,
727
- read_set : FxHashSet ( ) ,
727
+ read_set : DepNodeIndexSet :: Zero ,
728
728
} ) ;
729
729
}
730
730
@@ -746,7 +746,7 @@ impl CurrentDepGraph {
746
746
fn push_anon_task ( & mut self ) {
747
747
self . task_stack . push ( OpenTask :: Anon {
748
748
reads : Vec :: new ( ) ,
749
- read_set : FxHashSet ( ) ,
749
+ read_set : DepNodeIndexSet :: Zero ,
750
750
} ) ;
751
751
}
752
752
@@ -839,16 +839,76 @@ impl CurrentDepGraph {
839
839
}
840
840
}
841
841
842
- #[ derive( Clone , Debug , PartialEq ) ]
842
+ #[ derive( Debug , PartialEq , Eq ) ]
843
843
enum OpenTask {
844
844
Regular {
845
845
node : DepNode ,
846
846
reads : Vec < DepNodeIndex > ,
847
- read_set : FxHashSet < DepNodeIndex > ,
847
+ read_set : DepNodeIndexSet ,
848
848
} ,
849
849
Anon {
850
850
reads : Vec < DepNodeIndex > ,
851
- read_set : FxHashSet < DepNodeIndex > ,
851
+ read_set : DepNodeIndexSet ,
852
852
} ,
853
853
Ignore ,
854
854
}
855
+
856
+ // Many kinds of nodes often only have between 0 and 3 edges, so we provide a
857
+ // specialized set implementation that does not allocate for those some counts.
858
+ #[ derive( Debug , PartialEq , Eq ) ]
859
+ enum DepNodeIndexSet {
860
+ Zero ,
861
+ One ( DepNodeIndex ) ,
862
+ Two ( DepNodeIndex , DepNodeIndex ) ,
863
+ Three ( DepNodeIndex , DepNodeIndex , DepNodeIndex ) ,
864
+ Four ( DepNodeIndex , DepNodeIndex , DepNodeIndex , DepNodeIndex ) ,
865
+ Many ( FxHashSet < DepNodeIndex > ) ,
866
+ }
867
+
868
+ impl DepNodeIndexSet {
869
+ #[ inline( always) ]
870
+ fn insert ( & mut self , x : DepNodeIndex ) -> bool {
871
+ let new_state = match * self {
872
+ DepNodeIndexSet :: Zero => {
873
+ DepNodeIndexSet :: One ( x)
874
+ }
875
+ DepNodeIndexSet :: One ( a) => {
876
+ if x == a {
877
+ return false
878
+ } else {
879
+ DepNodeIndexSet :: Two ( x, a)
880
+ }
881
+ }
882
+ DepNodeIndexSet :: Two ( a, b) => {
883
+ if x == a || x == b {
884
+ return false
885
+ } else {
886
+ DepNodeIndexSet :: Three ( x, a, b)
887
+ }
888
+ }
889
+ DepNodeIndexSet :: Three ( a, b, c) => {
890
+ if x == a || x == b || x == c {
891
+ return false
892
+ } else {
893
+ DepNodeIndexSet :: Four ( x, a, b, c)
894
+ }
895
+ }
896
+ DepNodeIndexSet :: Four ( a, b, c, d) => {
897
+ if x == a || x == b || x == c || x == d {
898
+ return false
899
+ } else {
900
+ let hash_set: FxHashSet < _ > = [ x, a, b, c, d] . into_iter ( )
901
+ . cloned ( )
902
+ . collect ( ) ;
903
+ DepNodeIndexSet :: Many ( hash_set)
904
+ }
905
+ }
906
+ DepNodeIndexSet :: Many ( ref mut set) => {
907
+ return set. insert ( x)
908
+ }
909
+ } ;
910
+
911
+ * self = new_state;
912
+ true
913
+ }
914
+ }
0 commit comments