@@ -362,10 +362,8 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
362362 let param_env = tcx. param_env_reveal_all_normalized ( def_id) ;
363363
364364 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) ;
369367 let mut only_propagate_inside_block_locals = BitSet :: new_empty ( can_const_prop. len ( ) ) ;
370368 for ( l, mode) in can_const_prop. iter_enumerated ( ) {
371369 if * mode == ConstPropMode :: OnlyInsideOwnBlock {
@@ -401,6 +399,14 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
401399 )
402400 . expect ( "failed to push initial stack frame" ) ;
403401
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+
404410 ConstPropagator {
405411 ecx,
406412 tcx,
@@ -837,12 +843,11 @@ struct CanConstProp {
837843}
838844
839845impl CanConstProp {
840- /// Returns true if `local` can be propagated
841846 fn check < ' tcx > (
842847 tcx : TyCtxt < ' tcx > ,
843848 param_env : ParamEnv < ' tcx > ,
844849 body : & Body < ' tcx > ,
845- ) -> IndexVec < Local , ConstPropMode > {
850+ ) -> ( IndexVec < Local , ConstPropMode > , IndexVec < Local , Option < TyAndLayout < ' tcx > > > ) {
846851 let mut cpv = CanConstProp {
847852 can_const_prop : IndexVec :: from_elem ( ConstPropMode :: FullConstProp , & body. local_decls ) ,
848853 found_assignment : BitSet :: new_empty ( body. local_decls . len ( ) ) ,
@@ -851,10 +856,13 @@ impl CanConstProp {
851856 body. local_decls . len ( ) ,
852857 ) ,
853858 } ;
859+ let mut local_layouts = IndexVec :: from_elem ( None , & body. local_decls ) ;
854860 for ( local, val) in cpv. can_const_prop . iter_enumerated_mut ( ) {
855861 let ty = body. local_decls [ local] . ty ;
856862 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+ }
858866 // Either the layout fails to compute, then we can't use this local anyway
859867 // or the local is too large, then we don't want to.
860868 _ => {
@@ -882,7 +890,7 @@ impl CanConstProp {
882890 }
883891 }
884892 cpv. visit_body ( & body) ;
885- cpv. can_const_prop
893+ ( cpv. can_const_prop , local_layouts )
886894 }
887895}
888896
0 commit comments