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
+
11
+ use rustc:: ty:: TyCtxt ;
10
12
use rustc:: mir:: repr:: * ;
11
- use rustc:: mir:: mir_map:: MirMap ;
13
+ use rustc:: mir:: transform:: { MirPass , Pass } ;
14
+ use syntax:: ast:: NodeId ;
12
15
13
16
use traversal;
14
17
18
+ pub struct BreakCriticalEdges ;
19
+
15
20
/**
16
21
* Breaks critical edges in the MIR.
17
22
*
@@ -34,13 +39,16 @@ use traversal;
34
39
* NOTE: Simplify CFG will happily undo most of the work this pass does.
35
40
*
36
41
*/
37
- pub fn break_critical_edges < ' tcx > ( mir_map : & mut MirMap < ' tcx > ) {
38
- for ( _, mir) in & mut mir_map. map {
39
- break_critical_edges_fn ( mir) ;
42
+
43
+ impl < ' tcx > MirPass < ' tcx > for BreakCriticalEdges {
44
+ fn run_pass ( & mut self , _: & TyCtxt < ' tcx > , _: NodeId , mir : & mut Mir < ' tcx > ) {
45
+ break_critical_edges ( mir) ;
40
46
}
41
47
}
42
48
43
- fn break_critical_edges_fn ( mir : & mut Mir ) {
49
+ impl Pass for BreakCriticalEdges { }
50
+
51
+ fn break_critical_edges ( mir : & mut Mir ) {
44
52
let mut pred_count = vec ! [ 0u32 ; mir. basic_blocks. len( ) ] ;
45
53
46
54
// Build the precedecessor map for the MIR
@@ -63,13 +71,19 @@ fn break_critical_edges_fn(mir: &mut Mir) {
63
71
64
72
if let Some ( ref mut term) = data. terminator {
65
73
let is_invoke = term_is_invoke ( term) ;
74
+ let term_span = term. span ;
75
+ let term_scope = term. scope ;
66
76
let succs = term. successors_mut ( ) ;
67
77
if succs. len ( ) > 1 || ( succs. len ( ) > 0 && is_invoke) {
68
78
for tgt in succs {
69
79
let num_preds = pred_count[ tgt. index ( ) ] ;
70
80
if num_preds > 1 {
71
81
// It's a critical edge, break it
72
- let goto = Terminator :: Goto { target : * tgt } ;
82
+ let goto = Terminator {
83
+ span : term_span,
84
+ scope : term_scope,
85
+ kind : TerminatorKind :: Goto { target : * tgt }
86
+ } ;
73
87
let data = BasicBlockData :: new ( Some ( goto) ) ;
74
88
// Get the index it will be when inserted into the MIR
75
89
let idx = cur_len + new_blocks. len ( ) ;
@@ -88,9 +102,9 @@ fn break_critical_edges_fn(mir: &mut Mir) {
88
102
89
103
// Returns true if the terminator would use an invoke in LLVM.
90
104
fn term_is_invoke ( term : & Terminator ) -> bool {
91
- match * term {
92
- Terminator :: Call { cleanup : Some ( _) , .. } |
93
- Terminator :: Drop { unwind : Some ( _) , .. } => true ,
105
+ match term. kind {
106
+ TerminatorKind :: Call { cleanup : Some ( _) , .. } |
107
+ TerminatorKind :: Drop { unwind : Some ( _) , .. } => true ,
94
108
_ => false
95
109
}
96
110
}
0 commit comments