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;
1310use rustc:: mir:: repr:: * ;
1411use 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-
12743fn 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