@@ -1042,7 +1042,7 @@ pub fn with_cond<'blk, 'tcx, F>(bcx: Block<'blk, 'tcx>, val: ValueRef, f: F) ->
1042
1042
next_cx
1043
1043
}
1044
1044
1045
- enum Lifetime { Start , End }
1045
+ pub enum Lifetime { Start , End }
1046
1046
1047
1047
// If LLVM lifetime intrinsic support is enabled (i.e. optimizations
1048
1048
// 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>,
1079
1079
emit ( ccx, size, lifetime_intrinsic)
1080
1080
}
1081
1081
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
+ }
1090
1089
}
1091
1090
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
+ }
1100
1101
}
1101
1102
1102
1103
// Generates code for resumption of unwind at the end of a landing pad.
@@ -1663,29 +1664,21 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
1663
1664
arg_ty,
1664
1665
datum:: Lvalue :: new ( "FunctionContext::bind_args" ) )
1665
1666
} 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) ;
1681
1671
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
+ } ) )
1689
1682
}
1690
1683
} else {
1691
1684
// FIXME(pcwalton): Reduce the amount of code bloat this is responsible for.
@@ -1720,19 +1713,16 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
1720
1713
} ;
1721
1714
1722
1715
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)
1736
1726
} ;
1737
1727
debuginfo:: create_argument_metadata ( bcx, hir_arg) ;
1738
1728
}
0 commit comments