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