@@ -557,56 +557,14 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
557557 callsite : & CallSite < ' tcx > ,
558558 caller_mir : & mut Mir < ' tcx > ,
559559 ) -> Vec < Operand < ' tcx > > {
560- // FIXME: Analysis of the usage of the arguments to avoid
561- // unnecessary temporaries.
562-
563- fn create_temp_if_necessary < ' a , ' tcx : ' a > (
564- arg : Operand < ' tcx > ,
565- tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
566- callsite : & CallSite < ' tcx > ,
567- caller_mir : & mut Mir < ' tcx > ,
568- ) -> Operand < ' tcx > {
569- if let Operand :: Consume ( Lvalue :: Local ( local) ) = arg {
570- if caller_mir. local_kind ( local) == LocalKind :: Temp {
571- // Reuse the operand if it's a temporary already
572- return arg;
573- }
574- }
575-
576- debug ! ( "Creating temp for argument {:?}" , arg) ;
577- // Otherwise, create a temporary for the arg
578- let arg = Rvalue :: Use ( arg) ;
579-
580- let ty = arg. ty ( caller_mir, tcx) ;
581-
582- let arg_tmp = LocalDecl :: new_temp ( ty, callsite. location . span ) ;
583- let arg_tmp = caller_mir. local_decls . push ( arg_tmp) ;
584- let arg_tmp = Lvalue :: Local ( arg_tmp) ;
585-
586- let stmt = Statement {
587- source_info : callsite. location ,
588- kind : StatementKind :: Assign ( arg_tmp. clone ( ) , arg) ,
589- } ;
590- caller_mir[ callsite. bb ] . statements . push ( stmt) ;
591- Operand :: Consume ( arg_tmp)
592- }
593-
594560 let tcx = self . tcx ;
595561
596562 // A closure is passed its self-type and a tuple like `(arg1, arg2, ...)`,
597563 // hence mappings to tuple fields are needed.
598564 if tcx. def_key ( callsite. callee ) . disambiguated_data . data == DefPathData :: ClosureExpr {
599565 let mut args = args. into_iter ( ) ;
600-
601- let self_ = create_temp_if_necessary ( args. next ( ) . unwrap ( ) , tcx, callsite, caller_mir) ;
602-
603- let tuple = if let Operand :: Consume ( lvalue) =
604- create_temp_if_necessary ( args. next ( ) . unwrap ( ) , tcx, callsite, caller_mir)
605- {
606- lvalue
607- } else {
608- unreachable ! ( )
609- } ;
566+ let self_ = self . create_temp_if_necessary ( args. next ( ) . unwrap ( ) , callsite, caller_mir) ;
567+ let tuple = self . create_temp_if_necessary ( args. next ( ) . unwrap ( ) , callsite, caller_mir) ;
610568 assert ! ( args. next( ) . is_none( ) ) ;
611569
612570 let tuple_tys = if let ty:: TyTuple ( s, _) = tuple. ty ( caller_mir, tcx) . to_ty ( tcx) . sty {
@@ -616,17 +574,53 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
616574 } ;
617575
618576 let mut res = Vec :: with_capacity ( 1 + tuple_tys. len ( ) ) ;
619- res. push ( self_) ;
577+ res. push ( Operand :: Consume ( self_) ) ;
620578 res. extend ( tuple_tys. iter ( ) . enumerate ( ) . map ( |( i, ty) | {
621579 Operand :: Consume ( tuple. clone ( ) . field ( Field :: new ( i) , ty) )
622580 } ) ) ;
623581 res
624582 } else {
625583 args. into_iter ( )
626- . map ( |a| create_temp_if_necessary ( a, tcx , callsite, caller_mir) )
584+ . map ( |a| Operand :: Consume ( self . create_temp_if_necessary ( a, callsite, caller_mir) ) )
627585 . collect ( )
628586 }
629587 }
588+
589+ /// If `arg` is already a temporary, returns it. Otherwise, introduces a fresh
590+ /// temporary `T` and an instruction `T = arg`, and returns `T`.
591+ fn create_temp_if_necessary (
592+ & self ,
593+ arg : Operand < ' tcx > ,
594+ callsite : & CallSite < ' tcx > ,
595+ caller_mir : & mut Mir < ' tcx > ,
596+ ) -> Lvalue < ' tcx > {
597+ // FIXME: Analysis of the usage of the arguments to avoid
598+ // unnecessary temporaries.
599+
600+ if let Operand :: Consume ( Lvalue :: Local ( local) ) = arg {
601+ if caller_mir. local_kind ( local) == LocalKind :: Temp {
602+ // Reuse the operand if it's a temporary already
603+ return Lvalue :: Local ( local) ;
604+ }
605+ }
606+
607+ debug ! ( "Creating temp for argument {:?}" , arg) ;
608+ // Otherwise, create a temporary for the arg
609+ let arg = Rvalue :: Use ( arg) ;
610+
611+ let ty = arg. ty ( caller_mir, self . tcx ) ;
612+
613+ let arg_tmp = LocalDecl :: new_temp ( ty, callsite. location . span ) ;
614+ let arg_tmp = caller_mir. local_decls . push ( arg_tmp) ;
615+ let arg_tmp = Lvalue :: Local ( arg_tmp) ;
616+
617+ let stmt = Statement {
618+ source_info : callsite. location ,
619+ kind : StatementKind :: Assign ( arg_tmp. clone ( ) , arg) ,
620+ } ;
621+ caller_mir[ callsite. bb ] . statements . push ( stmt) ;
622+ arg_tmp
623+ }
630624}
631625
632626fn type_size_of < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
0 commit comments