@@ -362,10 +362,8 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
362
362
let param_env = tcx. param_env_reveal_all_normalized ( def_id) ;
363
363
364
364
let span = tcx. def_span ( def_id) ;
365
- // FIXME: `CanConstProp::check` computes the layout of all locals, return those layouts
366
- // so we can write them to `ecx.frame_mut().locals.layout, reducing the duplication in
367
- // `layout_of` query invocations.
368
- let can_const_prop = CanConstProp :: check ( tcx, param_env, body) ;
365
+
366
+ let ( can_const_prop, local_layouts) = CanConstProp :: check ( tcx, param_env, body) ;
369
367
let mut only_propagate_inside_block_locals = BitSet :: new_empty ( can_const_prop. len ( ) ) ;
370
368
for ( l, mode) in can_const_prop. iter_enumerated ( ) {
371
369
if * mode == ConstPropMode :: OnlyInsideOwnBlock {
@@ -401,6 +399,14 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
401
399
)
402
400
. expect ( "failed to push initial stack frame" ) ;
403
401
402
+ // write layouts of locals to ecx, which can reduce the duplication on
403
+ // `layout_of` query invocations.
404
+ local_layouts. into_iter ( ) . zip ( ecx. frame ( ) . locals . iter ( ) ) . for_each ( |( layout, state) | {
405
+ if layout. is_some ( ) {
406
+ state. layout . set ( layout)
407
+ }
408
+ } ) ;
409
+
404
410
ConstPropagator {
405
411
ecx,
406
412
tcx,
@@ -837,12 +843,11 @@ struct CanConstProp {
837
843
}
838
844
839
845
impl CanConstProp {
840
- /// Returns true if `local` can be propagated
841
846
fn check < ' tcx > (
842
847
tcx : TyCtxt < ' tcx > ,
843
848
param_env : ParamEnv < ' tcx > ,
844
849
body : & Body < ' tcx > ,
845
- ) -> IndexVec < Local , ConstPropMode > {
850
+ ) -> ( IndexVec < Local , ConstPropMode > , IndexVec < Local , Option < TyAndLayout < ' tcx > > > ) {
846
851
let mut cpv = CanConstProp {
847
852
can_const_prop : IndexVec :: from_elem ( ConstPropMode :: FullConstProp , & body. local_decls ) ,
848
853
found_assignment : BitSet :: new_empty ( body. local_decls . len ( ) ) ,
@@ -851,10 +856,13 @@ impl CanConstProp {
851
856
body. local_decls . len ( ) ,
852
857
) ,
853
858
} ;
859
+ let mut local_layouts = IndexVec :: from_elem ( None , & body. local_decls ) ;
854
860
for ( local, val) in cpv. can_const_prop . iter_enumerated_mut ( ) {
855
861
let ty = body. local_decls [ local] . ty ;
856
862
match tcx. layout_of ( param_env. and ( ty) ) {
857
- Ok ( layout) if layout. size < Size :: from_bytes ( MAX_ALLOC_LIMIT ) => { }
863
+ Ok ( layout) if layout. size < Size :: from_bytes ( MAX_ALLOC_LIMIT ) => {
864
+ local_layouts[ local] = Some ( layout) ;
865
+ }
858
866
// Either the layout fails to compute, then we can't use this local anyway
859
867
// or the local is too large, then we don't want to.
860
868
_ => {
@@ -882,7 +890,7 @@ impl CanConstProp {
882
890
}
883
891
}
884
892
cpv. visit_body ( & body) ;
885
- cpv. can_const_prop
893
+ ( cpv. can_const_prop , local_layouts )
886
894
}
887
895
}
888
896
0 commit comments