Skip to content

Commit f730bd0

Browse files
committed
Track changed bitsets in CFG propagation
This reduces the amount of work done, especially in later iterations, by only processing nodes whose predecessors changed in the previous iteration, or earlier in the current iteration. This also has the side effect of completely ignoring all unreachable nodes.
1 parent 7d11b33 commit f730bd0

File tree

1 file changed

+26
-3
lines changed

1 file changed

+26
-3
lines changed

compiler/rustc_typeck/src/check/generator_interior/drop_ranges/cfg_propagate.rs

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,28 @@ impl DropRangesBuilder {
1010
trace!("predecessors: {:#?}", preds.iter_enumerated().collect::<BTreeMap<_, _>>());
1111

1212
let mut new_state = BitSet::new_empty(self.num_values());
13+
let mut changed_nodes = BitSet::new_empty(self.nodes.len());
14+
let mut unchanged_mask = BitSet::new_filled(self.nodes.len());
15+
changed_nodes.insert(0u32.into());
1316

1417
let mut propagate = || {
1518
let mut changed = false;
19+
unchanged_mask.insert_all();
1620
for id in self.nodes.indices() {
21+
trace!("processing {:?}, changed_nodes: {:?}", id, changed_nodes);
22+
// Check if any predecessor has changed, and if not then short-circuit.
23+
//
24+
// We handle the start node specially, since it doesn't have any predecessors,
25+
// but we need to start somewhere.
26+
if match id.index() {
27+
0 => !changed_nodes.contains(id),
28+
_ => !preds[id].iter().any(|pred| changed_nodes.contains(*pred)),
29+
} {
30+
trace!("short-circuiting because none of {:?} have changed", preds[id]);
31+
unchanged_mask.remove(id);
32+
continue;
33+
}
34+
1735
if id.index() == 0 {
1836
new_state.clear();
1937
} else {
@@ -23,8 +41,7 @@ impl DropRangesBuilder {
2341
};
2442

2543
for pred in &preds[id] {
26-
let state = &self.nodes[*pred].drop_state;
27-
new_state.intersect(state);
44+
new_state.intersect(&self.nodes[*pred].drop_state);
2845
}
2946

3047
for drop in &self.nodes[id].drops {
@@ -35,9 +52,15 @@ impl DropRangesBuilder {
3552
new_state.remove(*reinit);
3653
}
3754

38-
changed |= self.nodes[id].drop_state.intersect(&new_state);
55+
if self.nodes[id].drop_state.intersect(&new_state) {
56+
changed_nodes.insert(id);
57+
changed = true;
58+
} else {
59+
unchanged_mask.remove(id);
60+
}
3961
}
4062

63+
changed_nodes.intersect(&unchanged_mask);
4164
changed
4265
};
4366

0 commit comments

Comments
 (0)