@@ -17,8 +17,8 @@ use rustc_middle::mir::*;
1717use rustc_middle:: ty:: layout:: TyAndLayout ;
1818use rustc_middle:: ty:: { self , ParamEnv , Ty , TyCtxt } ;
1919use rustc_mir_dataflow:: lattice:: FlatSet ;
20- use rustc_mir_dataflow:: value_analysis:: { Map , ValueAnalysis } ;
21- use rustc_mir_dataflow:: { Analysis , AnalysisDomain } ;
20+ use rustc_mir_dataflow:: value_analysis:: { Map , ValueAnalysis , ValueOrPlace } ;
21+ use rustc_mir_dataflow:: AnalysisDomain ;
2222use rustc_span:: def_id:: DefId ;
2323use rustc_target:: abi:: { Align , Size } ;
2424use rustc_target:: spec:: abi:: Abi as CallAbi ;
@@ -105,7 +105,7 @@ impl<'tcx> MirPass<'tcx> for ConstProp {
105105 let map = Map :: from_filter ( tcx, body, |local| ssa. is_ssa ( local) , place_limit) ;
106106
107107 // Perform the actual dataflow analysis.
108- let mut analysis = ConstAnalysis :: new ( tcx, body, & map) . wrap ( ) ;
108+ let analysis = ConstAnalysis :: new ( tcx, body, & map) . wrap ( ) ;
109109 let mut state = analysis. bottom_value ( body) ;
110110 analysis. initialize_start_block ( body, & mut state) ;
111111
@@ -120,23 +120,24 @@ impl<'tcx> MirPass<'tcx> for ConstProp {
120120 OperandCollector { state : & state, visitor : & mut collector, map : & map }
121121 . visit_statement ( statement, location) ;
122122
123- if let Some ( ( place, _) ) = statement. kind . as_assign ( )
124- && !place. has_deref ( )
125- && ssa. is_ssa ( place. local )
126- {
127- analysis. apply_statement_effect ( & mut state, statement, location) ;
128- }
129-
130- match statement. kind {
131- StatementKind :: Assign ( box ( _, Rvalue :: Use ( Operand :: Constant ( _) ) ) ) => {
132- // Don't overwrite the assignment if it already uses a constant (to keep the span).
133- }
134- StatementKind :: Assign ( box ( place, _) ) => {
135- if let FlatSet :: Elem ( value) = state. get ( place. as_ref ( ) , & map) {
136- collector. assignments . insert ( location, value) ;
123+ if let Some ( ( place, rvalue) ) = statement. kind . as_assign ( ) {
124+ let value = if !place. has_deref ( ) && ssa. is_ssa ( place. local ) {
125+ // Use `handle_assign` here to handle the case where `place` is not scalar.
126+ analysis. 0 . handle_assign ( * place, rvalue, & mut state) ;
127+ state. get ( place. as_ref ( ) , & map)
128+ } else if place. ty ( & body. local_decls , tcx) . ty . is_scalar ( ) {
129+ let value = analysis. 0 . handle_rvalue ( rvalue, & mut state) ;
130+ match value {
131+ ValueOrPlace :: Value ( value) => value,
132+ ValueOrPlace :: Place ( place) => state. get_idx ( place, & map) ,
137133 }
134+ } else {
135+ FlatSet :: Top
136+ } ;
137+
138+ if let FlatSet :: Elem ( value) = value {
139+ collector. assignments . insert ( location, value) ;
138140 }
139- _ => ( ) ,
140141 }
141142 }
142143
0 commit comments