Skip to content

Commit c70bc3a

Browse files
committed
Don't build a map of predecessors, just count them instead
1 parent eee7f3c commit c70bc3a

File tree

1 file changed

+4
-88
lines changed

1 file changed

+4
-88
lines changed

src/librustc_mir/transform/break_critical_edges.rs

Lines changed: 4 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@
77
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
10-
use std::mem;
11-
12-
use rustc_back::slice;
1310
use rustc::mir::repr::*;
1411
use rustc::mir::mir_map::MirMap;
1512

@@ -43,95 +40,14 @@ pub fn break_critical_edges<'tcx>(mir_map: &mut MirMap<'tcx>) {
4340
}
4441
}
4542

46-
/*
47-
* Predecessor map for tracking the predecessors of a block
48-
*/
49-
struct PredMap {
50-
preds: Vec<BlockPredecessors>
51-
}
52-
53-
/**
54-
* Most blocks only have one predecessor, so we can cut down on
55-
* some allocation by not using Vec until we have more than one.
56-
*/
57-
#[derive(Clone)]
58-
enum BlockPredecessors {
59-
None,
60-
One(BasicBlock),
61-
Some(Vec<BasicBlock>)
62-
}
63-
64-
impl PredMap {
65-
pub fn new(n: usize) -> PredMap {
66-
let preds = vec![BlockPredecessors::None; n];
67-
68-
PredMap {
69-
preds: preds
70-
}
71-
}
72-
73-
fn ensure_len(&mut self, bb: BasicBlock) {
74-
let idx = bb.index();
75-
while self.preds.len() <= idx {
76-
self.preds.push(BlockPredecessors::None);
77-
}
78-
}
79-
80-
pub fn add_pred(&mut self, target: BasicBlock, pred: BasicBlock) {
81-
self.ensure_len(target);
82-
83-
let preds = mem::replace(&mut self.preds[target.index()], BlockPredecessors::None);
84-
match preds {
85-
BlockPredecessors::None => {
86-
self.preds[target.index()] = BlockPredecessors::One(pred);
87-
}
88-
BlockPredecessors::One(bb) => {
89-
self.preds[target.index()] = BlockPredecessors::Some(vec![bb, pred]);
90-
}
91-
BlockPredecessors::Some(mut preds) => {
92-
preds.push(pred);
93-
self.preds[target.index()] = BlockPredecessors::Some(preds);
94-
}
95-
}
96-
}
97-
98-
pub fn remove_pred(&mut self, target: BasicBlock, pred: BasicBlock) {
99-
self.ensure_len(target);
100-
101-
let preds = mem::replace(&mut self.preds[target.index()], BlockPredecessors::None);
102-
match preds {
103-
BlockPredecessors::None => {}
104-
BlockPredecessors::One(bb) if bb == pred => {}
105-
106-
BlockPredecessors::One(bb) => {
107-
self.preds[target.index()] = BlockPredecessors::One(bb);
108-
}
109-
110-
BlockPredecessors::Some(mut preds) => {
111-
preds.retain(|&bb| bb != pred);
112-
self.preds[target.index()] = BlockPredecessors::Some(preds);
113-
}
114-
}
115-
}
116-
117-
pub fn get_preds(&self, bb: BasicBlock) -> &[BasicBlock] {
118-
match self.preds[bb.index()] {
119-
BlockPredecessors::None => &[],
120-
BlockPredecessors::One(ref bb) => slice::ref_slice(bb),
121-
BlockPredecessors::Some(ref bbs) => &bbs[..]
122-
}
123-
}
124-
}
125-
126-
12743
fn break_critical_edges_fn(mir: &mut Mir) {
128-
let mut pred_map = PredMap::new(mir.basic_blocks.len());
44+
let mut pred_count = vec![0u32; mir.basic_blocks.len()];
12945

13046
// Build the precedecessor map for the MIR
131-
for (pred, data) in traversal::preorder(mir) {
47+
for (_, data) in traversal::preorder(mir) {
13248
if let Some(ref term) = data.terminator {
13349
for &tgt in term.successors().iter() {
134-
pred_map.add_pred(tgt, pred);
50+
pred_count[tgt.index()] += 1;
13551
}
13652
}
13753
}
@@ -150,7 +66,7 @@ fn break_critical_edges_fn(mir: &mut Mir) {
15066
let succs = term.successors_mut();
15167
if succs.len() > 1 || (succs.len() > 0 && is_invoke) {
15268
for tgt in succs {
153-
let num_preds = pred_map.get_preds(*tgt).len();
69+
let num_preds = pred_count[tgt.index()];
15470
if num_preds > 1 {
15571
// It's a critical edge, break it
15672
let goto = Terminator::Goto { target: *tgt };

0 commit comments

Comments
 (0)