1
1
use crate :: MirPass ;
2
2
3
3
use rustc_middle:: mir:: {
4
- BasicBlock , BasicBlockData , Body , Statement , StatementKind , TerminatorKind ,
4
+ BasicBlock , BasicBlockData , BasicBlocks , Body , Statement , StatementKind , TerminatorKind ,
5
5
} ;
6
6
use rustc_middle:: ty:: TyCtxt ;
7
7
@@ -10,29 +10,20 @@ pub struct CtfeLimit;
10
10
impl < ' tcx > MirPass < ' tcx > for CtfeLimit {
11
11
#[ instrument( skip( self , _tcx, body) ) ]
12
12
fn run_pass ( & self , _tcx : TyCtxt < ' tcx > , body : & mut Body < ' tcx > ) {
13
- let doms = body. basic_blocks . dominators ( ) ;
14
- let indices: Vec < BasicBlock > =
15
- body. basic_blocks
16
- . iter_enumerated ( )
17
- . filter_map ( |( node, node_data) | {
18
- if matches ! ( node_data. terminator( ) . kind, TerminatorKind :: Call { .. } ) ||
13
+ let indices: Vec < BasicBlock > = body
14
+ . basic_blocks
15
+ . iter_enumerated ( )
16
+ . filter_map ( |( node, node_data) | {
17
+ if matches ! ( node_data. terminator( ) . kind, TerminatorKind :: Call { .. } )
19
18
// Back edges in a CFG indicate loops
20
- body. basic_blocks . iter_enumerated ( ) . any ( |( potential_dom, _) | {
21
- doms. is_reachable ( potential_dom)
22
- && doms. is_reachable ( node)
23
- && doms. is_dominated_by ( node, potential_dom)
24
- && node_data
25
- . terminator ( )
26
- . successors ( )
27
- . into_iter ( )
28
- . any ( |succ| succ == potential_dom)
29
- } ) {
30
- Some ( node)
31
- } else {
32
- None
33
- }
34
- } )
35
- . collect ( ) ;
19
+ || has_back_edge ( & body. basic_blocks , node, & node_data)
20
+ {
21
+ Some ( node)
22
+ } else {
23
+ None
24
+ }
25
+ } )
26
+ . collect ( ) ;
36
27
for index in indices {
37
28
insert_counter (
38
29
body. basic_blocks_mut ( )
@@ -43,6 +34,20 @@ impl<'tcx> MirPass<'tcx> for CtfeLimit {
43
34
}
44
35
}
45
36
37
+ fn has_back_edge (
38
+ basic_blocks : & BasicBlocks < ' _ > ,
39
+ node : BasicBlock ,
40
+ node_data : & BasicBlockData < ' _ > ,
41
+ ) -> bool {
42
+ let doms = basic_blocks. dominators ( ) ;
43
+ basic_blocks. indices ( ) . any ( |potential_dom| {
44
+ doms. is_reachable ( potential_dom)
45
+ && doms. is_reachable ( node)
46
+ && doms. is_dominated_by ( node, potential_dom)
47
+ && node_data. terminator ( ) . successors ( ) . into_iter ( ) . any ( |succ| succ == potential_dom)
48
+ } )
49
+ }
50
+
46
51
fn insert_counter ( basic_block_data : & mut BasicBlockData < ' _ > ) {
47
52
basic_block_data. statements . push ( Statement {
48
53
source_info : basic_block_data. terminator ( ) . source_info ,
0 commit comments