@@ -276,7 +276,7 @@ fn alloca_zeroed(cx: block, t: TypeRef) -> ValueRef {
276
276
fn alloca_maybe_zeroed ( cx : block , t : TypeRef , zero : bool ) -> ValueRef {
277
277
let _icx = cx. insn_ctxt ( ~"alloca") ;
278
278
if cx. unreachable { ret llvm:: LLVMGetUndef ( t) ; }
279
- let initcx = raw_block ( cx. fcx , cx. fcx . llstaticallocas ) ;
279
+ let initcx = raw_block ( cx. fcx , false , cx. fcx . llstaticallocas ) ;
280
280
let p = Alloca ( initcx, t) ;
281
281
if zero { Store ( initcx, C_null ( t) , p) ; }
282
282
ret p;
@@ -294,7 +294,7 @@ fn zero_mem(cx: block, llptr: ValueRef, t: ty::t) -> block {
294
294
fn arrayalloca ( cx : block , t : TypeRef , v : ValueRef ) -> ValueRef {
295
295
let _icx = cx. insn_ctxt ( ~"arrayalloca") ;
296
296
if cx. unreachable { ret llvm:: LLVMGetUndef ( t) ; }
297
- ret ArrayAlloca ( raw_block ( cx. fcx , cx. fcx . llstaticallocas ) , t, v) ;
297
+ ret ArrayAlloca ( raw_block ( cx. fcx , false , cx. fcx . llstaticallocas ) , t, v) ;
298
298
}
299
299
300
300
// Given a pointer p, returns a pointer sz(p) (i.e., inc'd by sz bytes).
@@ -3228,6 +3228,11 @@ fn need_invoke(bcx: block) -> bool {
3228
3228
ret false ;
3229
3229
}
3230
3230
3231
+ // Avoid using invoke if we are already inside a landing pad.
3232
+ if bcx. is_lpad {
3233
+ ret false ;
3234
+ }
3235
+
3231
3236
if have_cached_lpad ( bcx) {
3232
3237
ret true ;
3233
3238
}
@@ -3291,7 +3296,7 @@ fn get_landing_pad(bcx: block) -> BasicBlockRef {
3291
3296
alt copy inf. landing_pad {
3292
3297
some ( target) { cached = some ( target) ; }
3293
3298
none {
3294
- pad_bcx = sub_block ( bcx, ~"unwind") ;
3299
+ pad_bcx = lpad_block ( bcx, ~"unwind") ;
3295
3300
inf. landing_pad = some ( pad_bcx. llbb ) ;
3296
3301
}
3297
3302
}
@@ -4107,15 +4112,16 @@ fn trans_stmt(cx: block, s: ast::stmt) -> block {
4107
4112
// You probably don't want to use this one. See the
4108
4113
// next three functions instead.
4109
4114
fn new_block ( cx : fn_ctxt , parent : option < block > , +kind : block_kind ,
4110
- name : ~str , opt_node_info : option < node_info > ) -> block {
4115
+ is_lpad : bool , name : ~str , opt_node_info : option < node_info > )
4116
+ -> block {
4111
4117
4112
4118
let s = if cx. ccx . sess . opts . save_temps || cx. ccx . sess . opts . debuginfo {
4113
4119
cx. ccx . names ( name)
4114
4120
} else { ~"" } ;
4115
4121
let llbb: BasicBlockRef = str:: as_c_str ( s, |buf| {
4116
4122
llvm:: LLVMAppendBasicBlock ( cx. llfn , buf)
4117
4123
} ) ;
4118
- let bcx = mk_block ( llbb, parent, kind, opt_node_info, cx) ;
4124
+ let bcx = mk_block ( llbb, parent, kind, is_lpad , opt_node_info, cx) ;
4119
4125
do option:: iter ( parent) |cx| {
4120
4126
if cx. unreachable { Unreachable ( bcx) ; }
4121
4127
} ;
@@ -4129,14 +4135,14 @@ fn simple_block_scope() -> block_kind {
4129
4135
4130
4136
// Use this when you're at the top block of a function or the like.
4131
4137
fn top_scope_block ( fcx : fn_ctxt , opt_node_info : option < node_info > ) -> block {
4132
- ret new_block ( fcx, none, simple_block_scope ( ) ,
4138
+ ret new_block ( fcx, none, simple_block_scope ( ) , false ,
4133
4139
~"function top level", opt_node_info) ;
4134
4140
}
4135
4141
4136
4142
fn scope_block ( bcx : block ,
4137
4143
opt_node_info : option < node_info > ,
4138
4144
n : ~str ) -> block {
4139
- ret new_block ( bcx. fcx , some ( bcx) , simple_block_scope ( ) ,
4145
+ ret new_block ( bcx. fcx , some ( bcx) , simple_block_scope ( ) , bcx . is_lpad ,
4140
4146
n, opt_node_info) ;
4141
4147
}
4142
4148
@@ -4147,17 +4153,21 @@ fn loop_scope_block(bcx: block, loop_break: block, n: ~str,
4147
4153
mut cleanups: ~[ ] ,
4148
4154
mut cleanup_paths: ~[ ] ,
4149
4155
mut landing_pad: none
4150
- } ) , n, opt_node_info) ;
4156
+ } ) , bcx . is_lpad , n, opt_node_info) ;
4151
4157
}
4152
4158
4159
+ // Use this when creating a block for the inside of a landing pad.
4160
+ fn lpad_block ( bcx : block , n : ~str ) -> block {
4161
+ new_block ( bcx. fcx , some ( bcx) , block_non_scope, true , n, none)
4162
+ }
4153
4163
4154
4164
// Use this when you're making a general CFG BB within a scope.
4155
4165
fn sub_block ( bcx : block , n : ~str ) -> block {
4156
- new_block ( bcx. fcx , some ( bcx) , block_non_scope, n, none)
4166
+ new_block ( bcx. fcx , some ( bcx) , block_non_scope, bcx . is_lpad , n, none)
4157
4167
}
4158
4168
4159
- fn raw_block ( fcx : fn_ctxt , llbb : BasicBlockRef ) -> block {
4160
- mk_block ( llbb, none, block_non_scope, none, fcx)
4169
+ fn raw_block ( fcx : fn_ctxt , is_lpad : bool , llbb : BasicBlockRef ) -> block {
4170
+ mk_block ( llbb, none, block_non_scope, is_lpad , none, fcx)
4161
4171
}
4162
4172
4163
4173
@@ -4475,14 +4485,14 @@ fn copy_args_to_allocas(fcx: fn_ctxt, bcx: block, args: ~[ast::arg],
4475
4485
fn finish_fn(fcx: fn_ctxt, lltop: BasicBlockRef) {
4476
4486
let _icx = fcx.insn_ctxt(~" finish_fn") ;
4477
4487
tie_up_header_blocks ( fcx, lltop) ;
4478
- let ret_cx = raw_block ( fcx, fcx. llreturn ) ;
4488
+ let ret_cx = raw_block ( fcx, false , fcx. llreturn ) ;
4479
4489
RetVoid ( ret_cx) ;
4480
4490
}
4481
4491
4482
4492
fn tie_up_header_blocks ( fcx : fn_ctxt , lltop : BasicBlockRef ) {
4483
4493
let _icx = fcx. insn_ctxt ( ~"tie_up_header_blocks") ;
4484
- Br ( raw_block ( fcx, fcx. llstaticallocas ) , fcx. llloadenv ) ;
4485
- Br ( raw_block ( fcx, fcx. llloadenv ) , lltop) ;
4494
+ Br ( raw_block ( fcx, false , fcx. llstaticallocas ) , fcx. llloadenv ) ;
4495
+ Br ( raw_block ( fcx, false , fcx. llloadenv ) , lltop) ;
4486
4496
}
4487
4497
4488
4498
enum self_arg { impl_self( ty:: t ) , no_self, }
0 commit comments