standalone: Prepend statement type to basic block label names
This commit is contained in:
parent
91749bb01b
commit
1e27986864
|
@ -219,13 +219,13 @@ pub fn gen_for<'ctx, 'a, G: CodeGenerator>(
|
||||||
let int32 = ctx.ctx.i32_type();
|
let int32 = ctx.ctx.i32_type();
|
||||||
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().unwrap().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, "test");
|
let test_bb = ctx.ctx.append_basic_block(current, "for.cond");
|
||||||
let body_bb = ctx.ctx.append_basic_block(current, "body");
|
let body_bb = ctx.ctx.append_basic_block(current, "for.body");
|
||||||
let cont_bb = ctx.ctx.append_basic_block(current, "cont");
|
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
|
||||||
let orelse_bb =
|
let orelse_bb =
|
||||||
if orelse.is_empty() { cont_bb } else { ctx.ctx.append_basic_block(current, "orelse") };
|
if orelse.is_empty() { cont_bb } else { ctx.ctx.append_basic_block(current, "for.orelse") };
|
||||||
// store loop bb information and restore it later
|
// store loop bb information and restore it later
|
||||||
let loop_bb = ctx.loop_target.replace((test_bb, cont_bb));
|
let loop_bb = ctx.loop_target.replace((test_bb, cont_bb));
|
||||||
|
|
||||||
|
@ -239,9 +239,10 @@ pub fn gen_for<'ctx, 'a, G: CodeGenerator>(
|
||||||
let iter_val = iter_val.into_pointer_value();
|
let iter_val = iter_val.into_pointer_value();
|
||||||
let i = generator.gen_var_alloc(ctx, int32.into())?;
|
let i = generator.gen_var_alloc(ctx, int32.into())?;
|
||||||
let user_i = generator.gen_store_target(ctx, target)?;
|
let user_i = generator.gen_store_target(ctx, target)?;
|
||||||
let (start, end, step) = destructure_range(ctx, iter_val);
|
let (start, stop, step) = destructure_range(ctx, iter_val);
|
||||||
ctx.builder.build_store(i, ctx.builder.build_int_sub(start, step, "start_init"));
|
ctx.builder.build_store(i, ctx.builder.build_int_sub(start, step, "start_init"));
|
||||||
ctx.builder.build_unconditional_branch(test_bb);
|
ctx.builder.build_unconditional_branch(test_bb);
|
||||||
|
|
||||||
ctx.builder.position_at_end(test_bb);
|
ctx.builder.position_at_end(test_bb);
|
||||||
let sign = ctx.builder.build_int_compare(
|
let sign = ctx.builder.build_int_compare(
|
||||||
inkwell::IntPredicate::SGT,
|
inkwell::IntPredicate::SGT,
|
||||||
|
@ -258,9 +259,9 @@ pub fn gen_for<'ctx, 'a, G: CodeGenerator>(
|
||||||
ctx.builder.build_store(i, tmp);
|
ctx.builder.build_store(i, tmp);
|
||||||
ctx.builder.build_store(user_i, tmp);
|
ctx.builder.build_store(user_i, tmp);
|
||||||
// // if step > 0, continue when i < end
|
// // if step > 0, continue when i < end
|
||||||
let cmp1 = ctx.builder.build_int_compare(inkwell::IntPredicate::SLT, tmp, end, "cmp1");
|
let cmp1 = ctx.builder.build_int_compare(inkwell::IntPredicate::SLT, tmp, stop, "cmp1");
|
||||||
// if step < 0, continue when i > end
|
// if step < 0, continue when i > end
|
||||||
let cmp2 = ctx.builder.build_int_compare(inkwell::IntPredicate::SGT, tmp, end, "cmp2");
|
let cmp2 = ctx.builder.build_int_compare(inkwell::IntPredicate::SGT, tmp, stop, "cmp2");
|
||||||
let pos = ctx.builder.build_and(sign, cmp1, "pos");
|
let pos = ctx.builder.build_and(sign, cmp1, "pos");
|
||||||
let neg = ctx.builder.build_and(ctx.builder.build_not(sign, "inv"), cmp2, "neg");
|
let neg = ctx.builder.build_and(ctx.builder.build_not(sign, "inv"), cmp2, "neg");
|
||||||
ctx.builder.build_conditional_branch(
|
ctx.builder.build_conditional_branch(
|
||||||
|
@ -268,6 +269,7 @@ pub fn gen_for<'ctx, 'a, G: CodeGenerator>(
|
||||||
body_bb,
|
body_bb,
|
||||||
orelse_bb,
|
orelse_bb,
|
||||||
);
|
);
|
||||||
|
|
||||||
ctx.builder.position_at_end(body_bb);
|
ctx.builder.position_at_end(body_bb);
|
||||||
} else {
|
} else {
|
||||||
let counter = generator.gen_var_alloc(ctx, size_t.into())?;
|
let counter = generator.gen_var_alloc(ctx, size_t.into())?;
|
||||||
|
@ -280,12 +282,14 @@ pub fn gen_for<'ctx, 'a, G: CodeGenerator>(
|
||||||
)
|
)
|
||||||
.into_int_value();
|
.into_int_value();
|
||||||
ctx.builder.build_unconditional_branch(test_bb);
|
ctx.builder.build_unconditional_branch(test_bb);
|
||||||
|
|
||||||
ctx.builder.position_at_end(test_bb);
|
ctx.builder.position_at_end(test_bb);
|
||||||
let tmp = ctx.builder.build_load(counter, "i").into_int_value();
|
let tmp = ctx.builder.build_load(counter, "i").into_int_value();
|
||||||
let tmp = ctx.builder.build_int_add(tmp, size_t.const_int(1, false), "inc");
|
let tmp = ctx.builder.build_int_add(tmp, size_t.const_int(1, false), "inc");
|
||||||
ctx.builder.build_store(counter, tmp);
|
ctx.builder.build_store(counter, tmp);
|
||||||
let cmp = ctx.builder.build_int_compare(inkwell::IntPredicate::SLT, tmp, len, "cmp");
|
let cmp = ctx.builder.build_int_compare(inkwell::IntPredicate::SLT, tmp, len, "cmp");
|
||||||
ctx.builder.build_conditional_branch(cmp, body_bb, orelse_bb);
|
ctx.builder.build_conditional_branch(cmp, body_bb, orelse_bb);
|
||||||
|
|
||||||
ctx.builder.position_at_end(body_bb);
|
ctx.builder.position_at_end(body_bb);
|
||||||
let arr_ptr = ctx
|
let arr_ptr = ctx
|
||||||
.build_gep_and_load(iter_val.into_pointer_value(), &[zero, zero])
|
.build_gep_and_load(iter_val.into_pointer_value(), &[zero, zero])
|
||||||
|
@ -295,15 +299,18 @@ pub fn gen_for<'ctx, 'a, G: CodeGenerator>(
|
||||||
}
|
}
|
||||||
|
|
||||||
gen_block(generator, ctx, body.iter())?;
|
gen_block(generator, ctx, body.iter())?;
|
||||||
|
|
||||||
for (k, (_, _, counter)) in var_assignment.iter() {
|
for (k, (_, _, counter)) in var_assignment.iter() {
|
||||||
let (_, static_val, counter2) = ctx.var_assignment.get_mut(k).unwrap();
|
let (_, static_val, counter2) = ctx.var_assignment.get_mut(k).unwrap();
|
||||||
if counter != counter2 {
|
if counter != counter2 {
|
||||||
*static_val = None;
|
*static_val = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !ctx.is_terminated() {
|
if !ctx.is_terminated() {
|
||||||
ctx.builder.build_unconditional_branch(test_bb);
|
ctx.builder.build_unconditional_branch(test_bb);
|
||||||
}
|
}
|
||||||
|
|
||||||
if !orelse.is_empty() {
|
if !orelse.is_empty() {
|
||||||
ctx.builder.position_at_end(orelse_bb);
|
ctx.builder.position_at_end(orelse_bb);
|
||||||
gen_block(generator, ctx, orelse.iter())?;
|
gen_block(generator, ctx, orelse.iter())?;
|
||||||
|
@ -311,12 +318,14 @@ pub fn gen_for<'ctx, 'a, G: CodeGenerator>(
|
||||||
ctx.builder.build_unconditional_branch(cont_bb);
|
ctx.builder.build_unconditional_branch(cont_bb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (k, (_, _, counter)) in var_assignment.iter() {
|
for (k, (_, _, counter)) in var_assignment.iter() {
|
||||||
let (_, static_val, counter2) = ctx.var_assignment.get_mut(k).unwrap();
|
let (_, static_val, counter2) = ctx.var_assignment.get_mut(k).unwrap();
|
||||||
if counter != counter2 {
|
if counter != counter2 {
|
||||||
*static_val = None;
|
*static_val = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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 {
|
||||||
|
@ -336,12 +345,12 @@ pub fn gen_while<'ctx, 'a, G: CodeGenerator>(
|
||||||
let var_assignment = ctx.var_assignment.clone();
|
let var_assignment = ctx.var_assignment.clone();
|
||||||
|
|
||||||
let current = ctx.builder.get_insert_block().unwrap().get_parent().unwrap();
|
let current = ctx.builder.get_insert_block().unwrap().get_parent().unwrap();
|
||||||
let test_bb = ctx.ctx.append_basic_block(current, "test");
|
let test_bb = ctx.ctx.append_basic_block(current, "while.test");
|
||||||
let body_bb = ctx.ctx.append_basic_block(current, "body");
|
let body_bb = ctx.ctx.append_basic_block(current, "while.body");
|
||||||
let cont_bb = ctx.ctx.append_basic_block(current, "cont");
|
let cont_bb = ctx.ctx.append_basic_block(current, "while.cont");
|
||||||
// if there is no orelse, we just go to cont_bb
|
// if there is no orelse, we just go to cont_bb
|
||||||
let orelse_bb =
|
let orelse_bb =
|
||||||
if orelse.is_empty() { cont_bb } else { ctx.ctx.append_basic_block(current, "orelse") };
|
if orelse.is_empty() { cont_bb } else { ctx.ctx.append_basic_block(current, "while.orelse") };
|
||||||
// store loop bb information and restore it later
|
// store loop bb information and restore it later
|
||||||
let loop_bb = ctx.loop_target.replace((test_bb, cont_bb));
|
let loop_bb = ctx.loop_target.replace((test_bb, cont_bb));
|
||||||
ctx.builder.build_unconditional_branch(test_bb);
|
ctx.builder.build_unconditional_branch(test_bb);
|
||||||
|
@ -399,15 +408,15 @@ pub fn gen_if<'ctx, 'a, G: CodeGenerator>(
|
||||||
let var_assignment = ctx.var_assignment.clone();
|
let var_assignment = ctx.var_assignment.clone();
|
||||||
|
|
||||||
let current = ctx.builder.get_insert_block().unwrap().get_parent().unwrap();
|
let current = ctx.builder.get_insert_block().unwrap().get_parent().unwrap();
|
||||||
let test_bb = ctx.ctx.append_basic_block(current, "test");
|
let test_bb = ctx.ctx.append_basic_block(current, "if.test");
|
||||||
let body_bb = ctx.ctx.append_basic_block(current, "body");
|
let body_bb = ctx.ctx.append_basic_block(current, "if.body");
|
||||||
let mut cont_bb = None;
|
let mut cont_bb = None;
|
||||||
// if there is no orelse, we just go to cont_bb
|
// if there is no orelse, we just go to cont_bb
|
||||||
let orelse_bb = if orelse.is_empty() {
|
let orelse_bb = if orelse.is_empty() {
|
||||||
cont_bb = Some(ctx.ctx.append_basic_block(current, "cont"));
|
cont_bb = Some(ctx.ctx.append_basic_block(current, "if.cont"));
|
||||||
cont_bb.unwrap()
|
cont_bb.unwrap()
|
||||||
} else {
|
} else {
|
||||||
ctx.ctx.append_basic_block(current, "orelse")
|
ctx.ctx.append_basic_block(current, "if.orelse")
|
||||||
};
|
};
|
||||||
ctx.builder.build_unconditional_branch(test_bb);
|
ctx.builder.build_unconditional_branch(test_bb);
|
||||||
ctx.builder.position_at_end(test_bb);
|
ctx.builder.position_at_end(test_bb);
|
||||||
|
|
Loading…
Reference in New Issue