@@ -30,26 +30,28 @@ fn propagate_operand<'tcx>(
3030 Operand :: Copy ( place) | Operand :: Move ( place) => place,
3131 _ => return false ,
3232 } ;
33- if place. local != local {
34- return false ;
35- }
36- if place. projection . is_empty ( ) {
33+ if place. local == local && place. projection . is_empty ( ) {
3734 * operand = local_replacement. clone ( ) ;
38- return true ;
35+ true
36+ } else {
37+ false
3938 }
40- return false ;
4139}
4240impl < ' tcx > crate :: MirPass < ' tcx > for PropTrivialLocals {
4341 fn is_enabled ( & self , sess : & rustc_session:: Session ) -> bool {
4442 sess. mir_opt_level ( ) > 1
4543 }
4644 fn run_pass ( & self , tcx : TyCtxt < ' tcx > , body : & mut Body < ' tcx > ) {
45+ use std:: fs:: OpenOptions ;
46+ use std:: io:: Write ;
47+ use std:: time:: Instant ;
4748 trace ! ( "Running PropTrivialLocals on {:?}" , body. source) ;
48- loop {
49+ // Cap the number of check iterations.
50+ for _ in 0 ..2 {
4951 let mut dead_candidates = false ;
5052 for ( bid, block) in body. basic_blocks . as_mut ( ) . iter_enumerated_mut ( ) {
5153 let mut iter = StatementPairIterator :: new ( bid, & mut block. statements ) ;
52- while let Some ( StatementPair ( ( a_idx , a ) , ( b_idx , b ) ) ) = iter. next ( ) {
54+ while let Some ( StatementPair ( a , b ) ) = iter. next ( ) {
5355 let ( StatementKind :: Assign ( tmp_a) , StatementKind :: Assign ( tmp_b) ) =
5456 ( & a. kind , & mut b. kind )
5557 else {
@@ -58,7 +60,7 @@ impl<'tcx> crate::MirPass<'tcx> for PropTrivialLocals {
5860 let Some ( loc_a) = tmp_a. 0 . as_local ( ) else {
5961 continue ;
6062 } ;
61- let Rvalue :: Use ( ref src_a) = tmp_a. 1 else {
63+ let Rvalue :: Use ( src_a) = & tmp_a. 1 else {
6264 continue ;
6365 } ;
6466 match & mut tmp_b. 1 {
@@ -93,13 +95,7 @@ impl<'tcx> crate::MirPass<'tcx> for PropTrivialLocals {
9395 false
9496 }
9597}
96- struct DeadLocalCandidates {
97- dead : Local ,
98- }
99- struct StatementPair < ' a , ' tcx > (
100- ( StatmentPos , & ' a mut Statement < ' tcx > ) ,
101- ( StatmentPos , & ' a mut Statement < ' tcx > ) ,
102- ) ;
98+ struct StatementPair < ' a , ' tcx > ( & ' a mut Statement < ' tcx > , & ' a mut Statement < ' tcx > ) ;
10399struct StatementPairIterator < ' a , ' tcx > {
104100 curr_block : BasicBlock ,
105101 curr_idx : usize ,
@@ -114,13 +110,10 @@ impl<'a, 'tcx> StatementPairIterator<'a, 'tcx> {
114110 assert ! ( idx_a < idx_b) ;
115111 assert ! ( idx_b < self . statements. len( ) ) ;
116112 let ( part_a, reminder) = self . statements . split_at_mut ( idx_a + 1 ) ;
117- let ( part_b , reminder ) = reminder . split_at_mut ( ( idx_b - part_a. len ( ) ) + 1 ) ;
113+ let b_rel_idx = idx_b - part_a. len ( ) ;
118114 let a = & mut part_a[ part_a. len ( ) - 1 ] ;
119- let b = & mut part_b[ part_b. len ( ) - 1 ] ;
120- StatementPair (
121- ( StatmentPos ( self . curr_block , idx_a) , a) ,
122- ( StatmentPos ( self . curr_block , idx_b) , b) ,
123- )
115+ let b = & mut reminder[ b_rel_idx] ;
116+ StatementPair ( a, b)
124117 }
125118 fn is_statement_irrelevant ( statement : & Statement < ' _ > ) -> bool {
126119 match statement. kind {
@@ -141,19 +134,19 @@ impl<'a, 'tcx> StatementPairIterator<'a, 'tcx> {
141134 }
142135 }
143136 fn next < ' s > ( & ' s mut self ) -> Option < StatementPair < ' s , ' tcx > > {
144- // Skip irrelevant statements
137+ // If iter exchausted, quit.
145138 if self . curr_idx >= self . statements . len ( ) {
146139 return None ;
147140 }
148- while Self :: is_statement_irrelevant ( & self . statements [ self . curr_idx ] ) {
141+ // 1st Try finding the start point
142+ while !matches ! ( & self . statements[ self . curr_idx] . kind, StatementKind :: Assign ( ..) ) {
149143 self . curr_idx += 1 ;
150144 if self . curr_idx >= self . statements . len ( ) {
151145 return None ;
152146 }
153147 }
154148 let curr = self . curr_idx ;
155- self . curr_idx += 1 ;
156- let mut next_idx = self . curr_idx ;
149+ let mut next_idx = curr + 1 ;
157150 if next_idx >= self . statements . len ( ) {
158151 return None ;
159152 }
@@ -163,6 +156,8 @@ impl<'a, 'tcx> StatementPairIterator<'a, 'tcx> {
163156 return None ;
164157 }
165158 }
159+ // We known all statments in range self.curr_idx..next_idx will not benefit from this optimization. Skip them next time.
160+ self . curr_idx = next_idx;
166161 Some ( self . get_at ( curr, next_idx) )
167162 }
168163}
0 commit comments