11use crate :: MirPass ;
22
33use rustc_middle:: mir:: {
4- BasicBlock , BasicBlockData , Body , Statement , StatementKind , TerminatorKind ,
4+ BasicBlock , BasicBlockData , BasicBlocks , Body , Statement , StatementKind , TerminatorKind ,
55} ;
66use rustc_middle:: ty:: TyCtxt ;
77
@@ -10,29 +10,20 @@ pub struct CtfeLimit;
1010impl < ' tcx > MirPass < ' tcx > for CtfeLimit {
1111 #[ instrument( skip( self , _tcx, body) ) ]
1212 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 { .. } )
1918 // 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 ( ) ;
3627 for index in indices {
3728 insert_counter (
3829 body. basic_blocks_mut ( )
@@ -43,6 +34,20 @@ impl<'tcx> MirPass<'tcx> for CtfeLimit {
4334 }
4435}
4536
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+
4651fn insert_counter ( basic_block_data : & mut BasicBlockData < ' _ > ) {
4752 basic_block_data. statements . push ( Statement {
4853 source_info : basic_block_data. terminator ( ) . source_info ,
0 commit comments