@@ -2731,9 +2731,7 @@ fn trans_cast(cx: @block_ctxt, e: @ast::expr, id: ast::node_id,
2731
2731
}
2732
2732
2733
2733
fn trans_arg_expr ( cx : @block_ctxt , arg : ty:: arg , lldestty : TypeRef ,
2734
- & to_zero: [ { v : ValueRef , t : ty:: t } ] ,
2735
- & to_revoke: [ { v : ValueRef , t : ty:: t } ] , e : @ast:: expr ) ->
2736
- result {
2734
+ e : @ast:: expr ) -> result {
2737
2735
let ccx = bcx_ccx ( cx) ;
2738
2736
let e_ty = expr_ty ( cx, e) ;
2739
2737
let is_bot = ty:: type_is_bot ( e_ty) ;
@@ -2765,19 +2763,20 @@ fn trans_arg_expr(cx: @block_ctxt, arg: ty::arg, lldestty: TypeRef,
2765
2763
if arg_mode == ast:: by_val && ( lv. kind == owned || !imm) {
2766
2764
val = Load ( bcx, val) ;
2767
2765
}
2768
- } else if arg_mode == ast:: by_copy {
2766
+ } else if arg_mode == ast:: by_copy || arg_mode == ast :: by_move {
2769
2767
let { bcx: cx , val : alloc } = alloc_ty ( bcx, e_ty) ;
2770
- let last_use = ccx. last_uses . contains_key ( e. id ) ;
2768
+ let move_out = arg_mode == ast:: by_move ||
2769
+ ccx. last_uses . contains_key ( e. id ) ;
2771
2770
bcx = cx;
2772
2771
if lv. kind == temporary { revoke_clean ( bcx, val) ; }
2773
2772
if lv. kind == owned || !ty:: type_is_immediate ( e_ty) {
2774
2773
bcx = memmove_ty ( bcx, alloc, val, e_ty) ;
2775
- if last_use && ty:: type_needs_drop ( ccx. tcx , e_ty) {
2774
+ if move_out && ty:: type_needs_drop ( ccx. tcx , e_ty) {
2776
2775
bcx = zero_alloca ( bcx, val, e_ty) ;
2777
2776
}
2778
2777
} else { Store ( bcx, val, alloc) ; }
2779
2778
val = alloc;
2780
- if lv. kind != temporary && !last_use {
2779
+ if lv. kind != temporary && !move_out {
2781
2780
bcx = take_ty ( bcx, val, e_ty) ;
2782
2781
}
2783
2782
} else if ty:: type_is_immediate ( e_ty) && lv. kind != owned {
@@ -2789,15 +2788,6 @@ fn trans_arg_expr(cx: @block_ctxt, arg: ty::arg, lldestty: TypeRef,
2789
2788
if !is_bot && arg. ty != e_ty || ty:: type_has_params ( arg. ty ) {
2790
2789
val = PointerCast ( bcx, val, lldestty) ;
2791
2790
}
2792
-
2793
- // Collect arg for later if it happens to be one we've moving out.
2794
- if arg_mode == ast:: by_move {
2795
- if lv. kind == owned {
2796
- // Use actual ty, not declared ty -- anything else doesn't make
2797
- // sense if declared ty is a ty param
2798
- to_zero += [ { v: lv. val , t: e_ty} ] ;
2799
- } else { to_revoke += [ { v: lv. val , t: e_ty} ] ; }
2800
- }
2801
2791
ret rslt( bcx, val) ;
2802
2792
}
2803
2793
@@ -2813,15 +2803,11 @@ fn trans_args(cx: @block_ctxt, llenv: ValueRef,
2813
2803
dest : dest )
2814
2804
-> { bcx : @block_ctxt ,
2815
2805
args : [ ValueRef ] ,
2816
- retslot : ValueRef ,
2817
- to_zero : [ { v : ValueRef , t : ty:: t } ] ,
2818
- to_revoke : [ { v : ValueRef , t : ty:: t } ] } {
2806
+ retslot : ValueRef } {
2819
2807
2820
2808
let args = ty:: ty_fn_args ( fn_ty) ;
2821
2809
let llargs: [ ValueRef ] = [ ] ;
2822
2810
let lltydescs: [ ValueRef ] = [ ] ;
2823
- let to_zero = [ ] ;
2824
- let to_revoke = [ ] ;
2825
2811
2826
2812
let ccx = bcx_ccx ( cx) ;
2827
2813
let bcx = cx;
@@ -2899,17 +2885,14 @@ fn trans_args(cx: @block_ctxt, llenv: ValueRef,
2899
2885
let arg_tys = type_of_explicit_args ( ccx, args) ;
2900
2886
let i = 0 u;
2901
2887
for e: @ast:: expr in es {
2902
- let r = trans_arg_expr ( bcx, args[ i] , arg_tys[ i] , to_zero, to_revoke,
2903
- e) ;
2888
+ let r = trans_arg_expr ( bcx, args[ i] , arg_tys[ i] , e) ;
2904
2889
bcx = r. bcx ;
2905
2890
llargs += [ r. val ] ;
2906
2891
i += 1 u;
2907
2892
}
2908
2893
ret { bcx : bcx,
2909
2894
args : llargs,
2910
- retslot : llretslot,
2911
- to_zero : to_zero,
2912
- to_revoke : to_revoke} ;
2895
+ retslot : llretslot} ;
2913
2896
}
2914
2897
2915
2898
fn trans_call ( in_cx : @block_ctxt , f : @ast:: expr ,
@@ -2969,8 +2952,7 @@ fn trans_call_inner(in_cx: @block_ctxt, fn_expr_ty: ty::t,
2969
2952
then one or more of the args has
2970
2953
type _|_. Since that means it diverges, the code
2971
2954
for the call itself is unreachable. */
2972
- bcx = invoke_full ( bcx, faddr, llargs, args_res. to_zero ,
2973
- args_res. to_revoke ) ;
2955
+ bcx = invoke_full ( bcx, faddr, llargs) ;
2974
2956
alt dest {
2975
2957
ignore {
2976
2958
if llvm:: LLVMIsUndef ( llretslot) != lib:: llvm:: True {
@@ -2982,8 +2964,6 @@ fn trans_call_inner(in_cx: @block_ctxt, fn_expr_ty: ty::t,
2982
2964
* cell = Load ( bcx, llretslot) ;
2983
2965
}
2984
2966
}
2985
- // Forget about anything we moved out.
2986
- bcx = zero_and_revoke ( bcx, args_res. to_zero , args_res. to_revoke ) ;
2987
2967
2988
2968
bcx = trans_block_cleanups ( bcx, cx) ;
2989
2969
let next_cx = new_sub_block_ctxt ( in_cx, "next" ) ;
@@ -2994,65 +2974,43 @@ fn trans_call_inner(in_cx: @block_ctxt, fn_expr_ty: ty::t,
2994
2974
ret next_cx;
2995
2975
}
2996
2976
2997
- fn zero_and_revoke ( bcx : @block_ctxt ,
2998
- to_zero : [ { v : ValueRef , t : ty:: t } ] ,
2999
- to_revoke : [ { v : ValueRef , t : ty:: t } ] ) -> @block_ctxt {
3000
- let bcx = bcx;
3001
- for { v, t} in to_zero {
3002
- bcx = zero_alloca ( bcx, v, t) ;
3003
- }
3004
- for { v, _} in to_revoke { revoke_clean ( bcx, v) ; }
3005
- ret bcx;
3006
- }
3007
-
3008
2977
fn invoke ( bcx : @block_ctxt , llfn : ValueRef ,
3009
2978
llargs : [ ValueRef ] ) -> @block_ctxt {
3010
- ret invoke_ ( bcx, llfn, llargs, [ ] , [ ] , Invoke ) ;
2979
+ ret invoke_ ( bcx, llfn, llargs, Invoke ) ;
3011
2980
}
3012
2981
3013
- fn invoke_full ( bcx : @block_ctxt , llfn : ValueRef , llargs : [ ValueRef ] ,
3014
- to_zero : [ { v : ValueRef , t : ty:: t } ] ,
3015
- to_revoke : [ { v : ValueRef , t : ty:: t } ] ) -> @block_ctxt {
3016
- ret invoke_ ( bcx, llfn, llargs, to_zero, to_revoke, Invoke ) ;
2982
+ fn invoke_full ( bcx : @block_ctxt , llfn : ValueRef , llargs : [ ValueRef ] )
2983
+ -> @block_ctxt {
2984
+ ret invoke_ ( bcx, llfn, llargs, Invoke ) ;
3017
2985
}
3018
2986
3019
2987
fn invoke_ ( bcx : @block_ctxt , llfn : ValueRef , llargs : [ ValueRef ] ,
3020
- to_zero : [ { v : ValueRef , t : ty:: t } ] ,
3021
- to_revoke : [ { v : ValueRef , t : ty:: t } ] ,
3022
2988
invoker : fn ( @block_ctxt , ValueRef , [ ValueRef ] ,
3023
2989
BasicBlockRef , BasicBlockRef ) ) -> @block_ctxt {
3024
2990
// FIXME: May be worth turning this into a plain call when there are no
3025
2991
// cleanups to run
3026
2992
if bcx. unreachable { ret bcx; }
3027
2993
let normal_bcx = new_sub_block_ctxt ( bcx, "normal return" ) ;
3028
- invoker ( bcx, llfn, llargs, normal_bcx. llbb ,
3029
- get_landing_pad ( bcx, to_zero, to_revoke) ) ;
2994
+ invoker ( bcx, llfn, llargs, normal_bcx. llbb , get_landing_pad ( bcx) ) ;
3030
2995
ret normal_bcx;
3031
2996
}
3032
2997
3033
- fn get_landing_pad ( bcx : @block_ctxt ,
3034
- to_zero : [ { v : ValueRef , t : ty:: t } ] ,
3035
- to_revoke : [ { v : ValueRef , t : ty:: t } ]
3036
- ) -> BasicBlockRef {
3037
- let have_zero_or_revoke = vec:: is_not_empty ( to_zero)
3038
- || vec:: is_not_empty ( to_revoke) ;
3039
- let scope_bcx = find_scope_for_lpad ( bcx, have_zero_or_revoke) ;
3040
- if scope_bcx. lpad_dirty || have_zero_or_revoke {
2998
+ fn get_landing_pad ( bcx : @block_ctxt ) -> BasicBlockRef {
2999
+ let scope_bcx = find_scope_for_lpad ( bcx) ;
3000
+ if scope_bcx. lpad_dirty {
3041
3001
let unwind_bcx = new_sub_block_ctxt ( bcx, "unwind" ) ;
3042
- trans_landing_pad ( unwind_bcx, to_zero , to_revoke ) ;
3002
+ trans_landing_pad ( unwind_bcx) ;
3043
3003
scope_bcx. lpad = some ( unwind_bcx. llbb ) ;
3044
- scope_bcx. lpad_dirty = have_zero_or_revoke ;
3004
+ scope_bcx. lpad_dirty = false ;
3045
3005
}
3046
3006
assert option:: is_some ( scope_bcx. lpad ) ;
3047
3007
ret option:: get ( scope_bcx. lpad ) ;
3048
3008
3049
- fn find_scope_for_lpad ( bcx : @block_ctxt ,
3050
- have_zero_or_revoke : bool ) -> @block_ctxt {
3009
+ fn find_scope_for_lpad ( bcx : @block_ctxt ) -> @block_ctxt {
3051
3010
let scope_bcx = bcx;
3052
3011
while true {
3053
3012
scope_bcx = find_scope_cx ( scope_bcx) ;
3054
- if vec:: is_not_empty ( scope_bcx. cleanups )
3055
- || have_zero_or_revoke {
3013
+ if vec:: is_not_empty ( scope_bcx. cleanups ) {
3056
3014
ret scope_bcx;
3057
3015
} else {
3058
3016
scope_bcx = alt scope_bcx. parent {
@@ -3067,9 +3025,7 @@ fn get_landing_pad(bcx: @block_ctxt,
3067
3025
}
3068
3026
}
3069
3027
3070
- fn trans_landing_pad ( bcx : @block_ctxt ,
3071
- to_zero : [ { v : ValueRef , t : ty:: t } ] ,
3072
- to_revoke : [ { v : ValueRef , t : ty:: t } ] ) -> BasicBlockRef {
3028
+ fn trans_landing_pad ( bcx : @block_ctxt ) -> BasicBlockRef {
3073
3029
// The landing pad return type (the type being propagated). Not sure what
3074
3030
// this represents but it's determined by the personality function and
3075
3031
// this is what the EH proposal example uses.
@@ -3095,7 +3051,7 @@ fn trans_landing_pad(bcx: @block_ctxt,
3095
3051
// FIXME: This seems like a very naive and redundant way to generate the
3096
3052
// landing pads, as we're re-generating all in-scope cleanups for each
3097
3053
// function call. Probably good optimization opportunities here.
3098
- let bcx = zero_and_revoke ( bcx, to_zero , to_revoke ) ;
3054
+ let bcx = bcx;
3099
3055
let scope_cx = bcx;
3100
3056
while true {
3101
3057
scope_cx = find_scope_cx ( scope_cx) ;
0 commit comments