@@ -557,56 +557,14 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
557
557
callsite : & CallSite < ' tcx > ,
558
558
caller_mir : & mut Mir < ' tcx > ,
559
559
) -> 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
-
594
560
let tcx = self . tcx ;
595
561
596
562
// A closure is passed its self-type and a tuple like `(arg1, arg2, ...)`,
597
563
// hence mappings to tuple fields are needed.
598
564
if tcx. def_key ( callsite. callee ) . disambiguated_data . data == DefPathData :: ClosureExpr {
599
565
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) ;
610
568
assert ! ( args. next( ) . is_none( ) ) ;
611
569
612
570
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> {
616
574
} ;
617
575
618
576
let mut res = Vec :: with_capacity ( 1 + tuple_tys. len ( ) ) ;
619
- res. push ( self_) ;
577
+ res. push ( Operand :: Consume ( self_) ) ;
620
578
res. extend ( tuple_tys. iter ( ) . enumerate ( ) . map ( |( i, ty) | {
621
579
Operand :: Consume ( tuple. clone ( ) . field ( Field :: new ( i) , ty) )
622
580
} ) ) ;
623
581
res
624
582
} else {
625
583
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) ) )
627
585
. collect ( )
628
586
}
629
587
}
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
+ }
630
624
}
631
625
632
626
fn type_size_of < ' a , ' tcx > ( tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
0 commit comments