Skip to content

Commit ecba023

Browse files
Dynamically generate new blocks with Builder.invoke.
* Updates Drop, Assert, and Call TerminatorKinds to do this. * Changes various code in these terminators to have more uniform completions and replaced non-end-of-block llblock and funclet_br with the code that they'd execute.
1 parent 938d024 commit ecba023

File tree

3 files changed

+51
-50
lines changed

3 files changed

+51
-50
lines changed

src/librustc_trans/mir/block.rs

Lines changed: 45 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -231,20 +231,23 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
231231
lvalue.project_index(&bcx, C_uint(bcx.ccx, 0u64)),
232232
ety,
233233
lvalue.len(bcx.ccx),
234-
|bcx, llval, loop_bb| {
234+
|mut bcx, llval, loop_bb| {
235235
self.set_debug_loc(&bcx, terminator.source_info);
236236
if let Some(unwind) = unwind {
237-
bcx.invoke(
237+
let old_bcx = bcx;
238+
bcx = old_bcx.build_sibling_block("drop-next");
239+
old_bcx.invoke(
238240
drop_fn,
239241
&[llval],
240-
loop_bb,
241-
llblock(self, unwind),
242+
bcx.llbb(),
243+
self.landing_pad_to(unwind),
242244
cleanup_bundle
243245
);
244246
} else {
245247
bcx.call(drop_fn, &[llval], cleanup_bundle);
246-
bcx.br(loop_bb);
247248
}
249+
bcx.br(loop_bb);
250+
bcx
248251
});
249252
funclet_br(self, bcx, target);
250253
return
@@ -253,17 +256,19 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
253256
};
254257
let args = &[lvalue.llval, lvalue.llextra][..1 + need_extra as usize];
255258
if let Some(unwind) = unwind {
256-
bcx.invoke(
259+
let old_bcx = bcx;
260+
bcx = old_bcx.build_sibling_block("drop-next");
261+
old_bcx.invoke(
257262
drop_fn,
258263
args,
259-
self.blocks[target],
260-
llblock(self, unwind),
264+
bcx.llbb(),
265+
self.landing_pad_to(unwind),
261266
cleanup_bundle
262267
);
263268
} else {
264269
bcx.call(drop_fn, args, cleanup_bundle);
265-
funclet_br(self, bcx, target);
266270
}
271+
funclet_br(self, bcx, target);
267272
}
268273

269274
mir::TerminatorKind::Assert { ref cond, expected, ref msg, target, cleanup } => {
@@ -297,12 +302,12 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
297302
let cond = bcx.call(expect, &[cond, C_bool(bcx.ccx, expected)], None);
298303

299304
// Create the failure block and the conditional branch to it.
300-
let lltarget = llblock(self, target);
305+
let success_block = self.new_block("success");
301306
let panic_block = self.new_block("panic");
302307
if expected {
303-
bcx.cond_br(cond, lltarget, panic_block.llbb());
308+
bcx.cond_br(cond, success_block.llbb(), panic_block.llbb());
304309
} else {
305-
bcx.cond_br(cond, panic_block.llbb(), lltarget);
310+
bcx.cond_br(cond, panic_block.llbb(), success_block.llbb());
306311
}
307312

308313
// After this point, bcx is the block for the call to panic.
@@ -377,12 +382,14 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
377382
bcx.invoke(llfn,
378383
&args,
379384
self.unreachable_block(),
380-
llblock(self, unwind),
385+
self.landing_pad_to(unwind),
381386
cleanup_bundle);
382387
} else {
383388
bcx.call(llfn, &args, cleanup_bundle);
384389
bcx.unreachable();
385390
}
391+
392+
success_block.br(self.blocks[target]);
386393
}
387394

388395
mir::TerminatorKind::DropAndReplace { .. } => {
@@ -552,42 +559,33 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
552559
_ => span_bug!(span, "no llfn for call"),
553560
};
554561

555-
// Many different ways to call a function handled here
556-
if let &Some(cleanup) = cleanup {
557-
let ret_bcx = if let Some((_, target)) = *destination {
558-
self.blocks[target]
559-
} else {
560-
self.unreachable_block()
561-
};
562-
let invokeret = bcx.invoke(fn_ptr,
563-
&llargs,
564-
ret_bcx,
565-
llblock(self, cleanup),
566-
cleanup_bundle);
567-
fn_ty.apply_attrs_callsite(invokeret);
562+
let llret = if let &Some(cleanup) = cleanup {
563+
let old_bcx = bcx;
564+
bcx = old_bcx.build_sibling_block("call-next");
565+
self.set_debug_loc(&bcx, terminator.source_info);
566+
old_bcx.invoke(
567+
fn_ptr,
568+
&llargs,
569+
bcx.llbb(),
570+
self.landing_pad_to(cleanup),
571+
cleanup_bundle,
572+
)
573+
} else {
574+
bcx.call(fn_ptr, &llargs, cleanup_bundle)
575+
};
568576

569-
if let Some((_, target)) = *destination {
570-
let ret_bcx = self.get_builder(target);
571-
self.set_debug_loc(&ret_bcx, terminator.source_info);
572-
let op = OperandRef {
573-
val: Immediate(invokeret),
574-
ty: sig.output(),
575-
};
576-
self.store_return(&ret_bcx, ret_dest, fn_ty.ret, op);
577-
}
577+
fn_ty.apply_attrs_callsite(llret);
578+
579+
let op = OperandRef {
580+
val: Immediate(llret),
581+
ty: sig.output(),
582+
};
583+
self.store_return(&bcx, ret_dest, fn_ty.ret, op);
584+
585+
if let Some((_, target)) = *destination {
586+
funclet_br(self, bcx, target);
578587
} else {
579-
let llret = bcx.call(fn_ptr, &llargs, cleanup_bundle);
580-
fn_ty.apply_attrs_callsite(llret);
581-
if let Some((_, target)) = *destination {
582-
let op = OperandRef {
583-
val: Immediate(llret),
584-
ty: sig.output(),
585-
};
586-
self.store_return(&bcx, ret_dest, fn_ty.ret, op);
587-
funclet_br(self, bcx, target);
588-
} else {
589-
bcx.unreachable();
590-
}
588+
bcx.unreachable();
591589
}
592590
}
593591
}

src/librustc_trans/mir/rvalue.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,9 @@ impl<'a, 'tcx> MirContext<'a, 'tcx> {
9999
let size = C_uint(bcx.ccx, size);
100100
let base = base::get_dataptr(&bcx, dest.llval);
101101
tvec::slice_for_each(&bcx, base, tr_elem.ty, size, |bcx, llslot, loop_bb| {
102-
self.store_operand(bcx, llslot, dest.alignment.to_align(), tr_elem);
102+
self.store_operand(&bcx, llslot, dest.alignment.to_align(), tr_elem);
103103
bcx.br(loop_bb);
104+
bcx
104105
})
105106
}
106107

src/librustc_trans/tvec.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,9 @@ pub fn slice_for_each<'a, 'tcx, F>(
2020
unit_ty: Ty<'tcx>,
2121
len: ValueRef,
2222
f: F
23-
) -> Builder<'a, 'tcx> where F: FnOnce(&Builder<'a, 'tcx>, ValueRef, BasicBlockRef) {
23+
) -> Builder<'a, 'tcx>
24+
where F: FnOnce(Builder<'a, 'tcx>, ValueRef, BasicBlockRef) -> Builder<'a, 'tcx>
25+
{
2426
// Special-case vectors with elements of size 0 so they don't go out of bounds (#9890)
2527
let zst = type_is_zero_size(bcx.ccx, unit_ty);
2628
let add = |bcx: &Builder, a, b| if zst {
@@ -47,7 +49,7 @@ pub fn slice_for_each<'a, 'tcx, F>(
4749
header_bcx.cond_br(keep_going, body_bcx.llbb(), next_bcx.llbb());
4850

4951
let next = add(&body_bcx, current, C_uint(bcx.ccx, 1usize));
50-
f(&body_bcx, if zst { data_ptr } else { current }, header_bcx.llbb());
52+
let body_bcx = f(body_bcx, if zst { data_ptr } else { current }, header_bcx.llbb());
5153
header_bcx.add_incoming_to_phi(current, next, body_bcx.llbb());
5254
next_bcx
5355
}

0 commit comments

Comments
 (0)