@@ -1042,7 +1042,7 @@ pub fn with_cond<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, val: ValueRef, f: F) ->
10421042 next_cx
10431043}
10441044
1045- enum Lifetime { Start , End }
1045+ pub enum Lifetime { Start , End }
10461046
10471047// If LLVM lifetime intrinsic support is enabled (i.e. optimizations
10481048// on), and `ptr` is nonzero-sized, then extracts the size of `ptr`
@@ -1079,24 +1079,25 @@ fn core_lifetime_emit<'blk, 'tcx, F>(ccx: &'blk CrateContext<'blk, 'tcx>,
10791079 emit ( ccx, size, lifetime_intrinsic)
10801080}
10811081
1082- pub fn call_lifetime_start ( cx : Block , ptr : ValueRef ) {
1083- core_lifetime_emit ( cx. ccx ( ) , ptr, Lifetime :: Start , |ccx, size, lifetime_start| {
1084- let ptr = PointerCast ( cx, ptr, Type :: i8p ( ccx) ) ;
1085- Call ( cx,
1086- lifetime_start,
1087- & [ C_u64 ( ccx, size) , ptr] ,
1088- DebugLoc :: None ) ;
1089- } )
1082+ impl Lifetime {
1083+ pub fn call ( self , b : & Builder , ptr : ValueRef ) {
1084+ core_lifetime_emit ( b. ccx , ptr, self , |ccx, size, lifetime_intrinsic| {
1085+ let ptr = b. pointercast ( ptr, Type :: i8p ( ccx) ) ;
1086+ b. call ( lifetime_intrinsic, & [ C_u64 ( ccx, size) , ptr] , None ) ;
1087+ } ) ;
1088+ }
10901089}
10911090
1092- pub fn call_lifetime_end ( cx : Block , ptr : ValueRef ) {
1093- core_lifetime_emit ( cx. ccx ( ) , ptr, Lifetime :: End , |ccx, size, lifetime_end| {
1094- let ptr = PointerCast ( cx, ptr, Type :: i8p ( ccx) ) ;
1095- Call ( cx,
1096- lifetime_end,
1097- & [ C_u64 ( ccx, size) , ptr] ,
1098- DebugLoc :: None ) ;
1099- } )
1091+ pub fn call_lifetime_start ( bcx : Block , ptr : ValueRef ) {
1092+ if !bcx. unreachable . get ( ) {
1093+ Lifetime :: Start . call ( & bcx. build ( ) , ptr) ;
1094+ }
1095+ }
1096+
1097+ pub fn call_lifetime_end ( bcx : Block , ptr : ValueRef ) {
1098+ if !bcx. unreachable . get ( ) {
1099+ Lifetime :: End . call ( & bcx. build ( ) , ptr) ;
1100+ }
11001101}
11011102
11021103// Generates code for resumption of unwind at the end of a landing pad.
@@ -1663,29 +1664,21 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
16631664 arg_ty,
16641665 datum:: Lvalue :: new ( "FunctionContext::bind_args" ) )
16651666 } else {
1666- let lltmp = if common:: type_is_fat_ptr ( bcx. tcx ( ) , arg_ty) {
1667- let lltemp = alloc_ty ( bcx, arg_ty, "" ) ;
1668- let b = & bcx. build ( ) ;
1669- // we pass fat pointers as two words, but we want to
1670- // represent them internally as a pointer to two words,
1671- // so make an alloca to store them in.
1672- let meta = & self . fn_ty . args [ idx] ;
1673- idx += 1 ;
1674- arg. store_fn_arg ( b, & mut llarg_idx, expr:: get_dataptr ( bcx, lltemp) ) ;
1675- meta. store_fn_arg ( b, & mut llarg_idx, expr:: get_meta ( bcx, lltemp) ) ;
1676- lltemp
1677- } else {
1678- // otherwise, arg is passed by value, so store it into a temporary.
1679- let llarg_ty = arg. cast . unwrap_or ( arg. memory_ty ( bcx. ccx ( ) ) ) ;
1680- let lltemp = alloca ( bcx, llarg_ty, "" ) ;
1667+ unpack_datum ! ( bcx, datum:: lvalue_scratch_datum( bcx, arg_ty, "" ,
1668+ uninit_reason,
1669+ arg_scope_id, |bcx, dst| {
1670+ debug!( "FunctionContext::bind_args: {:?}: {:?}" , hir_arg, arg_ty) ;
16811671 let b = & bcx. build( ) ;
1682- arg. store_fn_arg ( b, & mut llarg_idx, lltemp) ;
1683- // And coerce the temporary into the type we expect.
1684- b. pointercast ( lltemp, arg. memory_ty ( bcx. ccx ( ) ) . ptr_to ( ) )
1685- } ;
1686- bcx. fcx . schedule_drop_mem ( arg_scope_id, lltmp, arg_ty, None ) ;
1687- datum:: Datum :: new ( lltmp, arg_ty,
1688- datum:: Lvalue :: new ( "bind_args" ) )
1672+ if common:: type_is_fat_ptr( bcx. tcx( ) , arg_ty) {
1673+ let meta = & self . fn_ty. args[ idx] ;
1674+ idx += 1 ;
1675+ arg. store_fn_arg( b, & mut llarg_idx, expr:: get_dataptr( bcx, dst) ) ;
1676+ meta. store_fn_arg( b, & mut llarg_idx, expr:: get_meta( bcx, dst) ) ;
1677+ } else {
1678+ arg. store_fn_arg( b, & mut llarg_idx, dst) ;
1679+ }
1680+ bcx
1681+ } ) )
16891682 }
16901683 } else {
16911684 // FIXME(pcwalton): Reduce the amount of code bloat this is responsible for.
@@ -1720,19 +1713,16 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
17201713 } ;
17211714
17221715 let pat = & hir_arg. pat ;
1723- bcx = match simple_name ( pat) {
1724- // The check for alloca is necessary because above for the immediate argument case
1725- // we had to cast. At this point arg_datum is not an alloca anymore and thus
1726- // breaks debuginfo if we allow this optimisation.
1727- Some ( name)
1728- if unsafe { llvm:: LLVMIsAAllocaInst ( arg_datum. val ) != :: std:: ptr:: null_mut ( ) } => {
1729- // Generate nicer LLVM for the common case of fn a pattern
1730- // like `x: T`
1731- set_value_name ( arg_datum. val , & bcx. name ( name) ) ;
1732- self . lllocals . borrow_mut ( ) . insert ( pat. id , arg_datum) ;
1733- bcx
1734- } ,
1735- _ => _match:: bind_irrefutable_pat ( bcx, pat, arg_datum. match_input ( ) , arg_scope_id)
1716+ bcx = if let Some ( name) = simple_name ( pat) {
1717+ // Generate nicer LLVM for the common case of fn a pattern
1718+ // like `x: T`
1719+ set_value_name ( arg_datum. val , & bcx. name ( name) ) ;
1720+ self . lllocals . borrow_mut ( ) . insert ( pat. id , arg_datum) ;
1721+ bcx
1722+ } else {
1723+ // General path. Copy out the values that are used in the
1724+ // pattern.
1725+ _match:: bind_irrefutable_pat ( bcx, pat, arg_datum. match_input ( ) , arg_scope_id)
17361726 } ;
17371727 debuginfo:: create_argument_metadata ( bcx, hir_arg) ;
17381728 }
0 commit comments