Skip to content

Commit 877833f

Browse files
committed
Auto merge of #45577 - michaelwoerister:small-set-opt, r=<try>
incr.comp.: Use a set implementation optimized for small item counts for deduplicating read-edges. Many kinds of `DepNodes` will only ever have between zero and three edges originating from them (see e.g. #45063 (comment)) so let's try to avoid allocating a `HashSet` in those cases. r? @nikomatsakis
2 parents 7da9a5e + be27d8b commit 877833f

File tree

1 file changed

+65
-5
lines changed

1 file changed

+65
-5
lines changed

src/librustc/dep_graph/graph.rs

+65-5
Original file line numberDiff line numberDiff line change
@@ -756,7 +756,7 @@ impl CurrentDepGraph {
756756
self.task_stack.push(OpenTask::Regular {
757757
node: key,
758758
reads: Vec::new(),
759-
read_set: FxHashSet(),
759+
read_set: DepNodeIndexSet::Zero,
760760
});
761761
}
762762

@@ -778,7 +778,7 @@ impl CurrentDepGraph {
778778
fn push_anon_task(&mut self) {
779779
self.task_stack.push(OpenTask::Anon {
780780
reads: Vec::new(),
781-
read_set: FxHashSet(),
781+
read_set: DepNodeIndexSet::Zero,
782782
});
783783
}
784784

@@ -890,19 +890,79 @@ impl CurrentDepGraph {
890890
}
891891
}
892892

893-
#[derive(Clone, Debug, PartialEq)]
893+
#[derive(Debug, PartialEq, Eq)]
894894
enum OpenTask {
895895
Regular {
896896
node: DepNode,
897897
reads: Vec<DepNodeIndex>,
898-
read_set: FxHashSet<DepNodeIndex>,
898+
read_set: DepNodeIndexSet,
899899
},
900900
Anon {
901901
reads: Vec<DepNodeIndex>,
902-
read_set: FxHashSet<DepNodeIndex>,
902+
read_set: DepNodeIndexSet,
903903
},
904904
Ignore,
905905
EvalAlways {
906906
node: DepNode,
907907
},
908908
}
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

Comments
 (0)