forked from M-Labs/nac3
core: Remove redundant for.cond BB for iterable loops
Simplifies logic for creating basic blocks.
This commit is contained in:
parent
b4a9616648
commit
b4983526bd
|
@ -248,7 +248,6 @@ pub fn gen_for<'ctx, 'a, G: CodeGenerator>(
|
||||||
let size_t = generator.get_size_type(ctx.ctx);
|
let size_t = generator.get_size_type(ctx.ctx);
|
||||||
let zero = int32.const_zero();
|
let zero = int32.const_zero();
|
||||||
let current = ctx.builder.get_insert_block().and_then(|bb| bb.get_parent()).unwrap();
|
let current = ctx.builder.get_insert_block().and_then(|bb| bb.get_parent()).unwrap();
|
||||||
let test_bb = ctx.ctx.append_basic_block(current, "for.cond");
|
|
||||||
let body_bb = ctx.ctx.append_basic_block(current, "for.body");
|
let body_bb = ctx.ctx.append_basic_block(current, "for.body");
|
||||||
let cont_bb = ctx.ctx.append_basic_block(current, "for.end");
|
let cont_bb = ctx.ctx.append_basic_block(current, "for.end");
|
||||||
// if there is no orelse, we just go to cont_bb
|
// if there is no orelse, we just go to cont_bb
|
||||||
|
@ -258,13 +257,16 @@ pub fn gen_for<'ctx, 'a, G: CodeGenerator>(
|
||||||
// Whether the iterable is a range() expression
|
// Whether the iterable is a range() expression
|
||||||
let is_iterable_range_expr = ctx.unifier.unioned(iter.custom.unwrap(), ctx.primitives.range);
|
let is_iterable_range_expr = ctx.unifier.unioned(iter.custom.unwrap(), ctx.primitives.range);
|
||||||
|
|
||||||
// store loop bb information and restore it later
|
// The target BB of the loop backedge
|
||||||
let loop_bb = if is_iterable_range_expr {
|
let backedge_bb_target = if is_iterable_range_expr {
|
||||||
ctx.loop_target.replace((body_bb, cont_bb))
|
body_bb
|
||||||
} else {
|
} else {
|
||||||
ctx.loop_target.replace((test_bb, cont_bb))
|
ctx.ctx.append_basic_block(current, "for.cond")
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// store loop bb information and restore it later
|
||||||
|
let loop_bb = ctx.loop_target.replace((backedge_bb_target, cont_bb));
|
||||||
|
|
||||||
let iter_val = generator.gen_expr(ctx, iter)?.unwrap().to_basic_value_enum(
|
let iter_val = generator.gen_expr(ctx, iter)?.unwrap().to_basic_value_enum(
|
||||||
ctx,
|
ctx,
|
||||||
generator,
|
generator,
|
||||||
|
@ -317,6 +319,8 @@ pub fn gen_for<'ctx, 'a, G: CodeGenerator>(
|
||||||
ctx.builder.position_at_end(cond_cont_bb);
|
ctx.builder.position_at_end(cond_cont_bb);
|
||||||
ctx.builder.build_store(i, next_i);
|
ctx.builder.build_store(i, next_i);
|
||||||
} else {
|
} else {
|
||||||
|
let test_bb = backedge_bb_target;
|
||||||
|
|
||||||
let counter = generator.gen_var_alloc(ctx, size_t.into(), Some("for.counter.addr"))?;
|
let counter = generator.gen_var_alloc(ctx, size_t.into(), Some("for.counter.addr"))?;
|
||||||
// counter = -1
|
// counter = -1
|
||||||
ctx.builder.build_store(counter, size_t.const_int(u64::max_value(), true));
|
ctx.builder.build_store(counter, size_t.const_int(u64::max_value(), true));
|
||||||
|
@ -353,11 +357,7 @@ pub fn gen_for<'ctx, 'a, G: CodeGenerator>(
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ctx.is_terminated() {
|
if !ctx.is_terminated() {
|
||||||
if is_iterable_range_expr {
|
ctx.builder.build_unconditional_branch(backedge_bb_target);
|
||||||
ctx.builder.build_unconditional_branch(body_bb);
|
|
||||||
} else {
|
|
||||||
ctx.builder.build_unconditional_branch(test_bb);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !orelse.is_empty() {
|
if !orelse.is_empty() {
|
||||||
|
@ -375,12 +375,6 @@ pub fn gen_for<'ctx, 'a, G: CodeGenerator>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clear test_bb if unused
|
|
||||||
if is_iterable_range_expr {
|
|
||||||
ctx.builder.position_at_end(test_bb);
|
|
||||||
ctx.builder.build_unreachable();
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.builder.position_at_end(cont_bb);
|
ctx.builder.position_at_end(cont_bb);
|
||||||
ctx.loop_target = loop_bb;
|
ctx.loop_target = loop_bb;
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue