7
7
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8
8
// option. This file may not be copied, modified, or distributed
9
9
// except according to those terms.
10
- use std:: mem;
11
-
12
- use rustc_back:: slice;
13
10
use rustc:: mir:: repr:: * ;
14
11
use rustc:: mir:: mir_map:: MirMap ;
15
12
@@ -43,95 +40,14 @@ pub fn break_critical_edges<'tcx>(mir_map: &mut MirMap<'tcx>) {
43
40
}
44
41
}
45
42
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
-
127
43
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( ) ] ;
129
45
130
46
// Build the precedecessor map for the MIR
131
- for ( pred , data) in traversal:: preorder ( mir) {
47
+ for ( _ , data) in traversal:: preorder ( mir) {
132
48
if let Some ( ref term) = data. terminator {
133
49
for & tgt in term. successors ( ) . iter ( ) {
134
- pred_map . add_pred ( tgt , pred ) ;
50
+ pred_count [ tgt . index ( ) ] += 1 ;
135
51
}
136
52
}
137
53
}
@@ -150,7 +66,7 @@ fn break_critical_edges_fn(mir: &mut Mir) {
150
66
let succs = term. successors_mut ( ) ;
151
67
if succs. len ( ) > 1 || ( succs. len ( ) > 0 && is_invoke) {
152
68
for tgt in succs {
153
- let num_preds = pred_map . get_preds ( * tgt) . len ( ) ;
69
+ let num_preds = pred_count [ tgt. index ( ) ] ;
154
70
if num_preds > 1 {
155
71
// It's a critical edge, break it
156
72
let goto = Terminator :: Goto { target : * tgt } ;
0 commit comments