@@ -912,7 +912,6 @@ impl Optimizer<'_> {
912912 }
913913 }
914914
915- /// Actually inlines variables.
916915 pub ( super ) fn inline ( & mut self , e : & mut Expr ) {
917916 if self . ctx . bit_ctx . contains ( BitCtx :: IsExactLhsOfAssign ) {
918917 return ;
@@ -936,81 +935,89 @@ impl Optimizer<'_> {
936935 }
937936 }
938937 Expr :: Ident ( i) => {
939- let id = i. to_id ( ) ;
940- if let Some ( value) = self . vars . lits . get ( & id) . or_else ( || {
941- if self . ctx . bit_ctx . contains ( BitCtx :: IsCallee ) {
942- self . vars . simple_functions . get ( & id)
943- } else {
944- None
945- }
946- } ) {
947- if !matches ! ( * * value, Expr :: Ident ( ..) | Expr :: Member ( ..) )
948- && self . ctx . bit_ctx . contains ( BitCtx :: IsUpdateArg )
949- {
950- return ;
951- }
952-
953- // currently renamer relies on the fact no distinct var has same ctxt, we need
954- // to remap all new bindings.
955- let bindings: FxHashSet < Id > = collect_decls ( value) ;
956- let new_mark = Mark :: new ( ) ;
957- let mut cache = FxHashMap :: default ( ) ;
958- let mut remap = FxHashMap :: default ( ) ;
959-
960- for id in bindings {
961- let new_ctxt = cache
962- . entry ( id. 1 )
963- . or_insert_with ( || id. 1 . apply_mark ( new_mark) ) ;
938+ if let Some ( value) = self . inline_ident ( i) {
939+ * e = * value
940+ }
941+ }
942+ _ => ( ) ,
943+ }
944+ }
964945
965- let new_ctxt = * new_ctxt;
946+ /// Actually inlines variables.
947+ pub ( super ) fn inline_ident ( & mut self , ident : & Ident ) -> Option < Box < Expr > > {
948+ let id = ident. to_id ( ) ;
966949
967- if let Some ( usage) = self . data . vars . get ( & id) . cloned ( ) {
968- let new_id = ( id. 0 . clone ( ) , new_ctxt) ;
969- self . data . vars . insert ( new_id, usage) ;
970- }
950+ if let Some ( value) = self . vars . lits . get ( & id) . or_else ( || {
951+ if self . ctx . bit_ctx . contains ( BitCtx :: IsCallee ) {
952+ self . vars . simple_functions . get ( & id)
953+ } else {
954+ None
955+ }
956+ } ) {
957+ if !matches ! ( * * value, Expr :: Ident ( ..) | Expr :: Member ( ..) )
958+ && self . ctx . bit_ctx . contains ( BitCtx :: IsUpdateArg )
959+ {
960+ return None ;
961+ }
971962
972- remap. insert ( id, new_ctxt) ;
973- }
963+ // currently renamer relies on the fact no distinct var has same ctxt, we need
964+ // to remap all new bindings.
965+ let bindings: FxHashSet < Id > = collect_decls ( value) ;
966+ let new_mark = Mark :: new ( ) ;
967+ let mut cache = FxHashMap :: default ( ) ;
968+ let mut remap = FxHashMap :: default ( ) ;
974969
975- let mut value = value. clone ( ) ;
976- if !remap. is_empty ( ) {
977- let mut remapper = Remapper :: new ( & remap) ;
978- value. visit_mut_with ( & mut remapper) ;
979- }
970+ for id in bindings {
971+ let new_ctxt = cache
972+ . entry ( id. 1 )
973+ . or_insert_with ( || id. 1 . apply_mark ( new_mark) ) ;
980974
981- self . changed = true ;
982- report_change ! ( "inline: Replacing a variable `{}` with cheap expression" , i) ;
975+ let new_ctxt = * new_ctxt;
983976
984- * e = * value;
985- return ;
977+ if let Some ( usage) = self . data . vars . get ( & id) . cloned ( ) {
978+ let new_id = ( id. 0 . clone ( ) , new_ctxt) ;
979+ self . data . vars . insert ( new_id, usage) ;
986980 }
987981
988- // Check without cloning
989- if let Some ( value) = self . vars . vars_for_inlining . get ( & id) {
990- if self . ctx . bit_ctx . contains ( BitCtx :: IsExactLhsOfAssign )
991- && !is_valid_for_lhs ( value)
992- {
993- return ;
994- }
982+ remap. insert ( id, new_ctxt) ;
983+ }
995984
996- if let Expr :: Member ( ..) = & * * value {
997- if self . ctx . bit_ctx . contains ( BitCtx :: ExecutedMultipleTime ) {
998- return ;
999- }
1000- }
1001- }
985+ let mut value = value. clone ( ) ;
986+ if !remap. is_empty ( ) {
987+ let mut remapper = Remapper :: new ( & remap) ;
988+ value. visit_mut_with ( & mut remapper) ;
989+ }
1002990
1003- if let Some ( value) = self . vars . vars_for_inlining . remove ( & id) {
1004- self . changed = true ;
1005- report_change ! ( "inline: Replacing '{}' with an expression" , i) ;
991+ self . changed = true ;
992+ report_change ! (
993+ "inline: Replacing a variable `{}` with cheap expression" ,
994+ ident
995+ ) ;
1006996
1007- * e = * value;
997+ return Some ( value) ;
998+ }
999+
1000+ // Check without cloning
1001+ if let Some ( value) = self . vars . vars_for_inlining . get ( & id) {
1002+ if self . ctx . bit_ctx . contains ( BitCtx :: IsExactLhsOfAssign ) && !is_valid_for_lhs ( value) {
1003+ return None ;
1004+ }
10081005
1009- log_abort ! ( "inline: [Change] {}" , crate :: debug:: dump( & * e, false ) )
1006+ if let Expr :: Member ( ..) = & * * value {
1007+ if self . ctx . bit_ctx . contains ( BitCtx :: ExecutedMultipleTime ) {
1008+ return None ;
10101009 }
10111010 }
1012- _ => ( ) ,
10131011 }
1012+
1013+ if let Some ( value) = self . vars . vars_for_inlining . remove ( & id) {
1014+ self . changed = true ;
1015+ report_change ! ( "inline: Replacing '{}' with an expression" , ident) ;
1016+
1017+ return Some ( value) ;
1018+ }
1019+
1020+ None
10141021 }
10151022}
10161023
0 commit comments