@@ -2761,30 +2761,76 @@ fn trans_call_inner(in_cx: block, fn_expr_ty: ty::t, ret_ty: ty::t,
2761
2761
2762
2762
fn invoke ( bcx : block , llfn : ValueRef , llargs : [ ValueRef ] ) -> block {
2763
2763
let _icx = bcx. insn_ctxt ( "invoke_" ) ;
2764
- // FIXME: May be worth turning this into a plain call when there are no
2765
- // cleanups to run
2766
2764
if bcx. unreachable { ret bcx; }
2767
- let normal_bcx = sub_block ( bcx, "normal return" ) ;
2768
- Invoke ( bcx, llfn, llargs, normal_bcx. llbb , get_landing_pad ( bcx) ) ;
2769
- ret normal_bcx;
2765
+ if need_invoke ( bcx) {
2766
+ log ( error, "invoking" ) ;
2767
+ let normal_bcx = sub_block ( bcx, "normal return" ) ;
2768
+ Invoke ( bcx, llfn, llargs, normal_bcx. llbb , get_landing_pad ( bcx) ) ;
2769
+ ret normal_bcx;
2770
+ } else {
2771
+ log ( error, "calling" ) ;
2772
+ Call ( bcx, llfn, llargs) ;
2773
+ ret bcx;
2774
+ }
2770
2775
}
2771
2776
2772
- fn get_landing_pad ( bcx : block ) -> BasicBlockRef {
2773
- let _icx = bcx. insn_ctxt ( "get_landing_pad" ) ;
2774
- fn in_lpad_scope_cx ( bcx : block , f : fn ( scope_info ) ) {
2775
- let mut bcx = bcx;
2776
- loop {
2777
- alt bcx. kind {
2778
- block_scope ( info) {
2779
- if info. cleanups . len ( ) > 0 u || bcx. parent == parent_none {
2780
- f ( info) ; ret;
2777
+ fn need_invoke ( bcx : block ) -> bool {
2778
+ if have_cached_lpad ( bcx) {
2779
+ ret true ;
2780
+ }
2781
+
2782
+ // Walk the scopes to look for cleanups
2783
+ let mut cur = bcx;
2784
+ loop {
2785
+ alt cur. kind {
2786
+ block_scope ( info) {
2787
+ for cleanup in info. cleanups {
2788
+ alt cleanup {
2789
+ clean( _, cleanup_type) | clean_temp ( _, _, cleanup_type) {
2790
+ if cleanup_type == normal_exit_and_unwind {
2791
+ ret true ;
2792
+ }
2793
+ }
2781
2794
}
2782
- }
2783
- _ { }
2784
2795
}
2785
- bcx = block_parent ( bcx) ;
2796
+ }
2797
+ _ { }
2798
+ }
2799
+ cur = alt cur. parent {
2800
+ parent_some ( next) { next }
2801
+ parent_none { ret false; }
2802
+ }
2803
+ }
2804
+ }
2805
+
2806
+ fn have_cached_lpad ( bcx : block ) -> bool {
2807
+ let mut res = false ;
2808
+ in_lpad_scope_cx ( bcx) { |info|
2809
+ alt info. landing_pad {
2810
+ some ( _) { res = true ; }
2811
+ none { res = false ; }
2812
+ }
2813
+ }
2814
+ ret res;
2815
+ }
2816
+
2817
+ fn in_lpad_scope_cx ( bcx : block , f : fn ( scope_info ) ) {
2818
+ let mut bcx = bcx;
2819
+ loop {
2820
+ alt bcx. kind {
2821
+ block_scope ( info) {
2822
+ if info. cleanups . len ( ) > 0 u || bcx. parent == parent_none {
2823
+ f ( info) ; ret;
2824
+ }
2825
+ }
2826
+ _ { }
2786
2827
}
2828
+ bcx = block_parent ( bcx) ;
2787
2829
}
2830
+ }
2831
+
2832
+ fn get_landing_pad ( bcx : block ) -> BasicBlockRef {
2833
+ let _icx = bcx. insn_ctxt ( "get_landing_pad" ) ;
2788
2834
2789
2835
let mut cached = none, pad_bcx = bcx; // Guaranteed to be set below
2790
2836
in_lpad_scope_cx ( bcx) { |info|
0 commit comments