@@ -5,6 +5,7 @@ use std::fmt::Debug;
5
5
6
6
use rustc_const_eval:: interpret:: { ImmTy , Projectable } ;
7
7
use rustc_const_eval:: interpret:: { InterpCx , InterpResult , OpTy , Scalar } ;
8
+ use rustc_data_structures:: fx:: FxHashSet ;
8
9
use rustc_hir:: def:: DefKind ;
9
10
use rustc_hir:: HirId ;
10
11
use rustc_index:: bit_set:: BitSet ;
@@ -76,6 +77,8 @@ struct ConstPropagator<'mir, 'tcx> {
76
77
visited_blocks : BitSet < BasicBlock > ,
77
78
locals : IndexVec < Local , Value < ' tcx > > ,
78
79
body : & ' mir Body < ' tcx > ,
80
+ written_only_inside_own_block_locals : FxHashSet < Local > ,
81
+ can_const_prop : IndexVec < Local , ConstPropMode > ,
79
82
}
80
83
81
84
#[ derive( Debug , Clone ) ]
@@ -181,12 +184,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
181
184
let param_env = tcx. param_env_reveal_all_normalized ( def_id) ;
182
185
183
186
let can_const_prop = CanConstProp :: check ( tcx, param_env, body) ;
184
- let ecx = InterpCx :: new (
185
- tcx,
186
- tcx. def_span ( def_id) ,
187
- param_env,
188
- ConstPropMachine :: new ( can_const_prop) ,
189
- ) ;
187
+ let ecx = InterpCx :: new ( tcx, tcx. def_span ( def_id) , param_env, ConstPropMachine ) ;
190
188
191
189
ConstPropagator {
192
190
ecx,
@@ -196,6 +194,8 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
196
194
visited_blocks : BitSet :: new_empty ( body. basic_blocks . len ( ) ) ,
197
195
locals : IndexVec :: from_elem_n ( Value :: Uninit , body. local_decls . len ( ) ) ,
198
196
body,
197
+ can_const_prop,
198
+ written_only_inside_own_block_locals : Default :: default ( ) ,
199
199
}
200
200
}
201
201
@@ -212,14 +212,14 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
212
212
/// but not reading from them anymore.
213
213
fn remove_const ( & mut self , local : Local ) {
214
214
self . locals [ local] = Value :: Uninit ;
215
- self . ecx . machine . written_only_inside_own_block_locals . remove ( & local) ;
215
+ self . written_only_inside_own_block_locals . remove ( & local) ;
216
216
}
217
217
218
218
fn access_mut ( & mut self , place : & Place < ' _ > ) -> Option < & mut Value < ' tcx > > {
219
- match self . ecx . machine . can_const_prop [ place. local ] {
219
+ match self . can_const_prop [ place. local ] {
220
220
ConstPropMode :: NoPropagation => return None ,
221
221
ConstPropMode :: OnlyInsideOwnBlock => {
222
- self . ecx . machine . written_only_inside_own_block_locals . insert ( place. local ) ;
222
+ self . written_only_inside_own_block_locals . insert ( place. local ) ;
223
223
}
224
224
ConstPropMode :: FullConstProp => { }
225
225
}
@@ -775,7 +775,7 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> {
775
775
776
776
let Some ( ( ) ) = self . check_rvalue ( rvalue, location) else { return } ;
777
777
778
- match self . ecx . machine . can_const_prop [ place. local ] {
778
+ match self . can_const_prop [ place. local ] {
779
779
// Do nothing if the place is indirect.
780
780
_ if place. is_indirect ( ) => { }
781
781
ConstPropMode :: NoPropagation => self . ensure_not_propagated ( place. local ) ,
@@ -811,7 +811,7 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> {
811
811
812
812
match statement. kind {
813
813
StatementKind :: SetDiscriminant { ref place, variant_index } => {
814
- match self . ecx . machine . can_const_prop [ place. local ] {
814
+ match self . can_const_prop [ place. local ] {
815
815
// Do nothing if the place is indirect.
816
816
_ if place. is_indirect ( ) => { }
817
817
ConstPropMode :: NoPropagation => self . ensure_not_propagated ( place. local ) ,
@@ -878,25 +878,21 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> {
878
878
// which were modified in the current block.
879
879
// Take it out of the ecx so we can get a mutable reference to the ecx for `remove_const`.
880
880
let mut written_only_inside_own_block_locals =
881
- std:: mem:: take ( & mut self . ecx . machine . written_only_inside_own_block_locals ) ;
881
+ std:: mem:: take ( & mut self . written_only_inside_own_block_locals ) ;
882
882
883
883
// This loop can get very hot for some bodies: it check each local in each bb.
884
884
// To avoid this quadratic behaviour, we only clear the locals that were modified inside
885
885
// the current block.
886
886
// The order in which we remove consts does not matter.
887
887
#[ allow( rustc:: potential_query_instability) ]
888
888
for local in written_only_inside_own_block_locals. drain ( ) {
889
- debug_assert_eq ! (
890
- self . ecx. machine. can_const_prop[ local] ,
891
- ConstPropMode :: OnlyInsideOwnBlock
892
- ) ;
889
+ debug_assert_eq ! ( self . can_const_prop[ local] , ConstPropMode :: OnlyInsideOwnBlock ) ;
893
890
self . remove_const ( local) ;
894
891
}
895
- self . ecx . machine . written_only_inside_own_block_locals =
896
- written_only_inside_own_block_locals;
892
+ self . written_only_inside_own_block_locals = written_only_inside_own_block_locals;
897
893
898
894
if cfg ! ( debug_assertions) {
899
- for ( local, & mode) in self . ecx . machine . can_const_prop . iter_enumerated ( ) {
895
+ for ( local, & mode) in self . can_const_prop . iter_enumerated ( ) {
900
896
match mode {
901
897
ConstPropMode :: FullConstProp => { }
902
898
ConstPropMode :: NoPropagation | ConstPropMode :: OnlyInsideOwnBlock => {
0 commit comments