2
2
//! (thus indicating there is a loop in the CFG), or whose terminator is a function call.
3
3
use crate :: MirPass ;
4
4
5
+ use rustc_data_structures:: graph:: dominators:: Dominators ;
5
6
use rustc_middle:: mir:: {
6
- BasicBlock , BasicBlockData , BasicBlocks , Body , Statement , StatementKind , TerminatorKind ,
7
+ BasicBlock , BasicBlockData , Body , Statement , StatementKind , TerminatorKind ,
7
8
} ;
8
9
use rustc_middle:: ty:: TyCtxt ;
9
10
@@ -12,13 +13,14 @@ pub struct CtfeLimit;
12
13
impl < ' tcx > MirPass < ' tcx > for CtfeLimit {
13
14
#[ instrument( skip( self , _tcx, body) ) ]
14
15
fn run_pass ( & self , _tcx : TyCtxt < ' tcx > , body : & mut Body < ' tcx > ) {
16
+ let doms = body. basic_blocks . dominators ( ) ;
15
17
let indices: Vec < BasicBlock > = body
16
18
. basic_blocks
17
19
. iter_enumerated ( )
18
20
. filter_map ( |( node, node_data) | {
19
21
if matches ! ( node_data. terminator( ) . kind, TerminatorKind :: Call { .. } )
20
22
// Back edges in a CFG indicate loops
21
- || has_back_edge ( & body . basic_blocks , node, & node_data)
23
+ || has_back_edge ( & doms , node, & node_data)
22
24
{
23
25
Some ( node)
24
26
} else {
@@ -37,17 +39,16 @@ impl<'tcx> MirPass<'tcx> for CtfeLimit {
37
39
}
38
40
39
41
fn has_back_edge (
40
- basic_blocks : & BasicBlocks < ' _ > ,
42
+ doms : & Dominators < BasicBlock > ,
41
43
node : BasicBlock ,
42
44
node_data : & BasicBlockData < ' _ > ,
43
45
) -> bool {
44
- let doms = basic_blocks. dominators ( ) ;
45
- basic_blocks. indices ( ) . any ( |potential_dom| {
46
- doms. is_reachable ( potential_dom)
47
- && doms. is_reachable ( node)
48
- && doms. is_dominated_by ( node, potential_dom)
49
- && node_data. terminator ( ) . successors ( ) . into_iter ( ) . any ( |succ| succ == potential_dom)
50
- } )
46
+ if !doms. is_reachable ( node) {
47
+ return false ;
48
+ }
49
+ // Check if any of the dominators of the node are also the node's successor.
50
+ doms. dominators ( node)
51
+ . any ( |dom| node_data. terminator ( ) . successors ( ) . into_iter ( ) . any ( |succ| succ == dom) )
51
52
}
52
53
53
54
fn insert_counter ( basic_block_data : & mut BasicBlockData < ' _ > ) {
0 commit comments