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