Skip to content

Commit

Permalink
Auto merge of #45577 - michaelwoerister:small-set-opt, r=<try>
Browse files Browse the repository at this point in the history
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
  • Loading branch information
bors committed Oct 28, 2017
2 parents 7da9a5e + be27d8b commit 877833f
Showing 1 changed file with 65 additions and 5 deletions.
70 changes: 65 additions & 5 deletions src/librustc/dep_graph/graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -756,7 +756,7 @@ impl CurrentDepGraph {
self.task_stack.push(OpenTask::Regular {
node: key,
reads: Vec::new(),
read_set: FxHashSet(),
read_set: DepNodeIndexSet::Zero,
});
}

Expand All @@ -778,7 +778,7 @@ impl CurrentDepGraph {
fn push_anon_task(&mut self) {
self.task_stack.push(OpenTask::Anon {
reads: Vec::new(),
read_set: FxHashSet(),
read_set: DepNodeIndexSet::Zero,
});
}

Expand Down Expand Up @@ -890,19 +890,79 @@ impl CurrentDepGraph {
}
}

#[derive(Clone, Debug, PartialEq)]
#[derive(Debug, PartialEq, Eq)]
enum OpenTask {
Regular {
node: DepNode,
reads: Vec<DepNodeIndex>,
read_set: FxHashSet<DepNodeIndex>,
read_set: DepNodeIndexSet,
},
Anon {
reads: Vec<DepNodeIndex>,
read_set: FxHashSet<DepNodeIndex>,
read_set: DepNodeIndexSet,
},
Ignore,
EvalAlways {
node: DepNode,
},
}

// Many kinds of nodes often only have between 0 and 3 edges, so we provide a
// specialized set implementation that does not allocate for those some counts.
#[derive(Debug, PartialEq, Eq)]
enum DepNodeIndexSet {
Zero,
One(DepNodeIndex),
Two(DepNodeIndex, DepNodeIndex),
Three(DepNodeIndex, DepNodeIndex, DepNodeIndex),
Four(DepNodeIndex, DepNodeIndex, DepNodeIndex, DepNodeIndex),
Many(FxHashSet<DepNodeIndex>),
}

impl DepNodeIndexSet {
#[inline(always)]
fn insert(&mut self, x: DepNodeIndex) -> bool {
let new_state = match *self {
DepNodeIndexSet::Zero => {
DepNodeIndexSet::One(x)
}
DepNodeIndexSet::One(a) => {
if x == a {
return false
} else {
DepNodeIndexSet::Two(x, a)
}
}
DepNodeIndexSet::Two(a, b) => {
if x == a || x == b {
return false
} else {
DepNodeIndexSet::Three(x, a, b)
}
}
DepNodeIndexSet::Three(a, b, c) => {
if x == a || x == b || x == c {
return false
} else {
DepNodeIndexSet::Four(x, a, b, c)
}
}
DepNodeIndexSet::Four(a, b, c, d) => {
if x == a || x == b || x == c || x == d {
return false
} else {
let hash_set: FxHashSet<_> = [x, a, b, c, d].into_iter()
.cloned()
.collect();
DepNodeIndexSet::Many(hash_set)
}
}
DepNodeIndexSet::Many(ref mut set) => {
return set.insert(x)
}
};

*self = new_state;
true
}
}

0 comments on commit 877833f

Please sign in to comment.