@@ -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
}
@@ -776,7 +776,7 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> {
776
776
777
777
let Some ( ( ) ) = self . check_rvalue ( rvalue, location) else { return } ;
778
778
779
- match self . ecx . machine . can_const_prop [ place. local ] {
779
+ match self . can_const_prop [ place. local ] {
780
780
// Do nothing if the place is indirect.
781
781
_ if place. is_indirect ( ) => { }
782
782
ConstPropMode :: NoPropagation => self . ensure_not_propagated ( place. local ) ,
@@ -812,7 +812,7 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> {
812
812
813
813
match statement. kind {
814
814
StatementKind :: SetDiscriminant { ref place, variant_index } => {
815
- match self . ecx . machine . can_const_prop [ place. local ] {
815
+ match self . can_const_prop [ place. local ] {
816
816
// Do nothing if the place is indirect.
817
817
_ if place. is_indirect ( ) => { }
818
818
ConstPropMode :: NoPropagation => self . ensure_not_propagated ( place. local ) ,
@@ -879,23 +879,19 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> {
879
879
// which were modified in the current block.
880
880
// Take it out of the ecx so we can get a mutable reference to the ecx for `remove_const`.
881
881
let mut written_only_inside_own_block_locals =
882
- std:: mem:: take ( & mut self . ecx . machine . written_only_inside_own_block_locals ) ;
882
+ std:: mem:: take ( & mut self . written_only_inside_own_block_locals ) ;
883
883
884
884
// This loop can get very hot for some bodies: it check each local in each bb.
885
885
// To avoid this quadratic behaviour, we only clear the locals that were modified inside
886
886
// the current block.
887
887
for local in written_only_inside_own_block_locals. drain ( ) {
888
- debug_assert_eq ! (
889
- self . ecx. machine. can_const_prop[ local] ,
890
- ConstPropMode :: OnlyInsideOwnBlock
891
- ) ;
888
+ debug_assert_eq ! ( self . can_const_prop[ local] , ConstPropMode :: OnlyInsideOwnBlock ) ;
892
889
self . remove_const ( local) ;
893
890
}
894
- self . ecx . machine . written_only_inside_own_block_locals =
895
- written_only_inside_own_block_locals;
891
+ self . written_only_inside_own_block_locals = written_only_inside_own_block_locals;
896
892
897
893
if cfg ! ( debug_assertions) {
898
- for ( local, & mode) in self . ecx . machine . can_const_prop . iter_enumerated ( ) {
894
+ for ( local, & mode) in self . can_const_prop . iter_enumerated ( ) {
899
895
match mode {
900
896
ConstPropMode :: FullConstProp => { }
901
897
ConstPropMode :: NoPropagation | ConstPropMode :: OnlyInsideOwnBlock => {
0 commit comments