@@ -24,11 +24,7 @@ impl<'tcx> crate::MirPass<'tcx> for MergeBranchSimplification {
2424        let  param_env = tcx. param_env_reveal_all_normalized ( def_id) ; 
2525
2626        let  borrowed_locals = borrowed_locals ( body) ; 
27-         let  mut  maybe_live:  ResultsCursor < ' _ ,  ' _ ,  MaybeTransitiveLiveLocals < ' _ > >  =
28-             MaybeTransitiveLiveLocals :: new ( & borrowed_locals) 
29-                 . into_engine ( tcx,  body) 
30-                 . iterate_to_fixpoint ( ) 
31-                 . into_results_cursor ( body) ; 
27+         let  mut  stmt_live_result = StatementLiveResult :: new ( tcx,  body,  & borrowed_locals) ; 
3228        for  i in  0 ..body. basic_blocks . len ( )  { 
3329            let  bbs = & * body. basic_blocks ; 
3430            let  switch_bb_idx = BasicBlock :: from_usize ( i) ; 
@@ -75,8 +71,7 @@ impl<'tcx> crate::MirPass<'tcx> for MergeBranchSimplification {
7571                targets, 
7672                src_place, 
7773                src_ty, 
78-                 & borrowed_locals, 
79-                 & mut  maybe_live, 
74+                 & mut  stmt_live_result, 
8075            )  { 
8176                let  statement_index = bbs[ switch_bb_idx] . statements . len ( ) ; 
8277                let  parent_end = Location  {  block :  switch_bb_idx,  statement_index } ; 
@@ -93,6 +88,33 @@ impl<'tcx> crate::MirPass<'tcx> for MergeBranchSimplification {
9388    } 
9489} 
9590
91+ struct  StatementLiveResult < ' tcx ,  ' mir ,  ' a >  { 
92+     tcx :  TyCtxt < ' tcx > , 
93+     body :  & ' mir  Body < ' tcx > , 
94+     result :  Option < ResultsCursor < ' mir ,  ' tcx ,  MaybeTransitiveLiveLocals < ' a > > > , 
95+     borrowed_locals :  & ' a  BitSet < Local > , 
96+ } 
97+ 
98+ impl < ' tcx ,  ' mir ,  ' a >  StatementLiveResult < ' tcx ,  ' mir ,  ' a >  { 
99+     fn  new ( tcx :  TyCtxt < ' tcx > ,  body :  & ' mir  Body < ' tcx > ,  borrowed_locals :  & ' a  BitSet < Local > )  -> Self  { 
100+         Self  {  tcx,  body,  result :  None ,  borrowed_locals } 
101+     } 
102+ 
103+     fn  is_live ( & mut  self ,  loc :  Location ,  local :  Local )  -> bool  { 
104+         if  self . borrowed_locals . contains ( local)  { 
105+             return  true ; 
106+         } 
107+         let  maybe_live = self . result . get_or_insert_with ( || { 
108+             MaybeTransitiveLiveLocals :: new ( & self . borrowed_locals ) 
109+                 . into_engine ( self . tcx ,  self . body ) 
110+                 . iterate_to_fixpoint ( ) 
111+                 . into_results_cursor ( self . body ) 
112+         } ) ; 
113+         maybe_live. seek_before_primary_effect ( loc) ; 
114+         maybe_live. get ( ) . contains ( local) 
115+     } 
116+ } 
117+ 
96118/// The GVN simplified 
97119/// ```ignore (syntax-highlighting-only) 
98120/// match a { 
@@ -116,22 +138,11 @@ fn can_simplify_to_copy<'tcx>(
116138    targets :  & SwitchTargets , 
117139    src_place :  Place < ' tcx > , 
118140    src_ty :  tcx:: PlaceTy < ' tcx > , 
119-     borrowed_locals :  & BitSet < Local > , 
120-     maybe_live :  & mut  ResultsCursor < ' _ ,  ' tcx ,  MaybeTransitiveLiveLocals < ' _ > > , 
141+     stmt_live_result :  & mut  StatementLiveResult < ' tcx ,  ' _ ,  ' _ > , 
121142)  -> Option < Place < ' tcx > >  { 
122143    let  mut  targets_iter = targets. iter ( ) ; 
123144    let  dest_place = targets_iter. next ( ) . and_then ( |( index,  target) | { 
124-         find_copy_assign ( 
125-             tcx, 
126-             param_env, 
127-             body, 
128-             index, 
129-             target, 
130-             src_place, 
131-             src_ty, 
132-             borrowed_locals, 
133-             maybe_live, 
134-         ) 
145+         find_copy_assign ( tcx,  param_env,  body,  index,  target,  src_place,  src_ty,  stmt_live_result) 
135146    } ) ?; 
136147    let  dest_ty = dest_place. ty ( body. local_decls ( ) ,  tcx) ; 
137148    if  dest_ty. ty  != src_ty. ty  || dest_ty. variant_index . is_some ( )  { 
@@ -147,8 +158,7 @@ fn can_simplify_to_copy<'tcx>(
147158                other_target, 
148159                src_place, 
149160                src_ty, 
150-                 borrowed_locals, 
151-                 maybe_live, 
161+                 stmt_live_result, 
152162            ) 
153163    } )  { 
154164        return  None ; 
@@ -164,8 +174,7 @@ fn find_copy_assign<'tcx>(
164174    target_block :  BasicBlock , 
165175    src_place :  Place < ' tcx > , 
166176    src_ty :  tcx:: PlaceTy < ' tcx > , 
167-     borrowed_locals :  & BitSet < Local > , 
168-     maybe_live :  & mut  ResultsCursor < ' _ ,  ' tcx ,  MaybeTransitiveLiveLocals < ' _ > > , 
177+     stmt_live_result :  & mut  StatementLiveResult < ' tcx ,  ' _ ,  ' _ > , 
169178)  -> Option < Place < ' tcx > >  { 
170179    let  statements = & body. basic_blocks [ target_block] . statements ; 
171180    if  statements. is_empty ( )  { 
@@ -190,11 +199,10 @@ fn find_copy_assign<'tcx>(
190199                StatementKind :: Assign ( box ( dest_place,  _) ) 
191200                | StatementKind :: SetDiscriminant  {  place :  box dest_place,  .. } 
192201                | StatementKind :: Deinit ( box dest_place)  => { 
193-                     if  dest_place. is_indirect ( )  || borrowed_locals . contains ( dest_place . local )   { 
202+                     if  dest_place. is_indirect ( )  { 
194203                        return  None ; 
195204                    } 
196-                     maybe_live. seek_before_primary_effect ( loc) ; 
197-                     if  !maybe_live. get ( ) . contains ( dest_place. local )  { 
205+                     if  !stmt_live_result. is_live ( loc,  dest_place. local )  { 
198206                        lived_stmts. remove ( statement_index) ; 
199207                    }  else  if  matches ! ( statement. kind,  StatementKind :: Assign ( _) ) 
200208                        && expected_assign_stmt. is_none ( ) 
0 commit comments