Skip to content

Commit be27d8b

Browse files
incr.comp.: Use a set implementation optimized for small item counts for deduplicating read-edges.
1 parent e0febe7 commit be27d8b

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
@@ -724,7 +724,7 @@ impl CurrentDepGraph {
724724
self.task_stack.push(OpenTask::Regular {
725725
node: key,
726726
reads: Vec::new(),
727-
read_set: FxHashSet(),
727+
read_set: DepNodeIndexSet::Zero,
728728
});
729729
}
730730

@@ -746,7 +746,7 @@ impl CurrentDepGraph {
746746
fn push_anon_task(&mut self) {
747747
self.task_stack.push(OpenTask::Anon {
748748
reads: Vec::new(),
749-
read_set: FxHashSet(),
749+
read_set: DepNodeIndexSet::Zero,
750750
});
751751
}
752752

@@ -839,16 +839,76 @@ impl CurrentDepGraph {
839839
}
840840
}
841841

842-
#[derive(Clone, Debug, PartialEq)]
842+
#[derive(Debug, PartialEq, Eq)]
843843
enum OpenTask {
844844
Regular {
845845
node: DepNode,
846846
reads: Vec<DepNodeIndex>,
847-
read_set: FxHashSet<DepNodeIndex>,
847+
read_set: DepNodeIndexSet,
848848
},
849849
Anon {
850850
reads: Vec<DepNodeIndex>,
851-
read_set: FxHashSet<DepNodeIndex>,
851+
read_set: DepNodeIndexSet,
852852
},
853853
Ignore,
854854
}
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

Comments
 (0)