Compare commits

..

3 Commits

Author SHA1 Message Date
David Mak 6de0884dc1 core: Use anonymous name for variables if unspecified
The current default prefix is only derived from the instruction type,
which is not helpful during the comprehension of the IR. Changing to
anonymous names (e.g. %1) helps understand that the variable is only
needed as part of a larger (possibly named) expression.
2023-09-06 14:02:15 +08:00
David Mak f1b0e05b3d core: Rename IR variables
Because it is unclear which variables are expressions and
subexpressions, all variables which are previously anonymous are named
using (1) the control flow statement if available, (2) the possible name
of the variable as inferred from the variable name in Rust, and (3) the
"addr" prefix to indicate that the values are pointers. These three
strings are joint together using '.', forming "for.i.addr" for instance.
2023-09-06 14:02:15 +08:00
David Mak ff23968544 core: Add name parameter to gen_{var_alloc,store_target}
This allows variables in the IR to be assigned a custom name as opposed
to names with a default prefix.
2023-09-06 11:00:02 +08:00
4 changed files with 23 additions and 19 deletions

View File

@ -84,7 +84,7 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> {
.try_as_basic_value() .try_as_basic_value()
.left() .left()
.unwrap(); .unwrap();
let end_store = self.gen_store_target(ctx, &end)?; let end_store = self.gen_store_target(ctx, &end, Some("end_store.addr"))?;
ctx.builder.build_store(end_store, max); ctx.builder.build_store(end_store, max);
} }
if let Some(start) = self.start.clone() { if let Some(start) = self.start.clone() {
@ -140,7 +140,7 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> {
node: ExprKind::Name { id: start, ctx: name_ctx.clone() }, node: ExprKind::Name { id: start, ctx: name_ctx.clone() },
custom: Some(ctx.primitives.int64), custom: Some(ctx.primitives.int64),
}; };
let start = self.gen_store_target(ctx, &start_expr)?; let start = self.gen_store_target(ctx, &start_expr, Some("start.addr"))?;
ctx.builder.build_store(start, now); ctx.builder.build_store(start, now);
Ok(Some(start_expr)) as Result<_, String> Ok(Some(start_expr)) as Result<_, String>
}, },
@ -153,7 +153,7 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> {
node: ExprKind::Name { id: end, ctx: name_ctx.clone() }, node: ExprKind::Name { id: end, ctx: name_ctx.clone() },
custom: Some(ctx.primitives.int64), custom: Some(ctx.primitives.int64),
}; };
let end = self.gen_store_target(ctx, &end_expr)?; let end = self.gen_store_target(ctx, &end_expr, Some("end.addr"))?;
ctx.builder.build_store(end, now); ctx.builder.build_store(end, now);
self.end = Some(end_expr); self.end = Some(end_expr);
self.name_counter += 1; self.name_counter += 1;
@ -204,7 +204,7 @@ impl<'b> CodeGenerator for ArtiqCodeGenerator<'b> {
.try_as_basic_value() .try_as_basic_value()
.left() .left()
.unwrap(); .unwrap();
let outer_end = self.gen_store_target(ctx, old_end)?; let outer_end = self.gen_store_target(ctx, old_end, Some("outer_end.addr"))?;
ctx.builder.build_store(outer_end, max); ctx.builder.build_store(outer_end, max);
} }
self.start = old_start; self.start = old_start;

View File

@ -810,7 +810,7 @@ pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>(
let zero_size_t = size_t.const_zero(); let zero_size_t = size_t.const_zero();
let zero_32 = int32.const_zero(); let zero_32 = int32.const_zero();
let index = generator.gen_var_alloc(ctx, size_t.into())?; let index = generator.gen_var_alloc(ctx, size_t.into(), Some("index.addr"))?;
ctx.builder.build_store(index, zero_size_t); ctx.builder.build_store(index, zero_size_t);
let elem_ty = ctx.get_llvm_type(generator, elt.custom.unwrap()); let elem_ty = ctx.get_llvm_type(generator, elt.custom.unwrap());
@ -853,7 +853,7 @@ pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>(
list_content = list_content =
ctx.build_gep_and_load(list, &[zero_size_t, zero_32]).into_pointer_value(); ctx.build_gep_and_load(list, &[zero_size_t, zero_32]).into_pointer_value();
let i = generator.gen_store_target(ctx, target)?; let i = generator.gen_store_target(ctx, target, Some("i.addr"))?;
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);
@ -888,7 +888,7 @@ pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>(
list = allocate_list(generator, ctx, elem_ty, length); list = allocate_list(generator, ctx, elem_ty, length);
list_content = list_content =
ctx.build_gep_and_load(list, &[zero_size_t, zero_32]).into_pointer_value(); ctx.build_gep_and_load(list, &[zero_size_t, zero_32]).into_pointer_value();
let counter = generator.gen_var_alloc(ctx, size_t.into())?; let counter = generator.gen_var_alloc(ctx, size_t.into(), Some("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));
ctx.builder.build_unconditional_branch(test_bb); ctx.builder.build_unconditional_branch(test_bb);

View File

@ -87,8 +87,9 @@ pub trait CodeGenerator {
&mut self, &mut self,
ctx: &mut CodeGenContext<'ctx, 'a>, ctx: &mut CodeGenContext<'ctx, 'a>,
ty: BasicTypeEnum<'ctx>, ty: BasicTypeEnum<'ctx>,
name: Option<&str>,
) -> Result<PointerValue<'ctx>, String> { ) -> Result<PointerValue<'ctx>, String> {
gen_var(ctx, ty) gen_var(ctx, ty, name)
} }
/// Return a pointer pointing to the target of the expression. /// Return a pointer pointing to the target of the expression.
@ -96,11 +97,12 @@ pub trait CodeGenerator {
&mut self, &mut self,
ctx: &mut CodeGenContext<'ctx, 'a>, ctx: &mut CodeGenContext<'ctx, 'a>,
pattern: &Expr<Option<Type>>, pattern: &Expr<Option<Type>>,
name: Option<&str>,
) -> Result<PointerValue<'ctx>, String> ) -> Result<PointerValue<'ctx>, String>
where where
Self: Sized, Self: Sized,
{ {
gen_store_target(self, ctx, pattern) gen_store_target(self, ctx, pattern, name)
} }
/// Generate code for an assignment expression. /// Generate code for an assignment expression.

View File

@ -24,12 +24,13 @@ use std::convert::TryFrom;
pub fn gen_var<'ctx, 'a>( pub fn gen_var<'ctx, 'a>(
ctx: &mut CodeGenContext<'ctx, 'a>, ctx: &mut CodeGenContext<'ctx, 'a>,
ty: BasicTypeEnum<'ctx>, ty: BasicTypeEnum<'ctx>,
name: Option<&str>,
) -> Result<PointerValue<'ctx>, String> { ) -> Result<PointerValue<'ctx>, String> {
// put the alloca in init block // put the alloca in init block
let current = ctx.builder.get_insert_block().unwrap(); let current = ctx.builder.get_insert_block().unwrap();
// position before the last branching instruction... // position before the last branching instruction...
ctx.builder.position_before(&ctx.init_bb.get_last_instruction().unwrap()); ctx.builder.position_before(&ctx.init_bb.get_last_instruction().unwrap());
let ptr = ctx.builder.build_alloca(ty, "tmp"); let ptr = ctx.builder.build_alloca(ty, name.unwrap_or(""));
ctx.builder.position_at_end(current); ctx.builder.position_at_end(current);
Ok(ptr) Ok(ptr)
} }
@ -38,6 +39,7 @@ pub fn gen_store_target<'ctx, 'a, G: CodeGenerator>(
generator: &mut G, generator: &mut G,
ctx: &mut CodeGenContext<'ctx, 'a>, ctx: &mut CodeGenContext<'ctx, 'a>,
pattern: &Expr<Option<Type>>, pattern: &Expr<Option<Type>>,
name: Option<&str>,
) -> Result<PointerValue<'ctx>, String> { ) -> Result<PointerValue<'ctx>, String> {
// very similar to gen_expr, but we don't do an extra load at the end // very similar to gen_expr, but we don't do an extra load at the end
// and we flatten nested tuples // and we flatten nested tuples
@ -45,7 +47,7 @@ pub fn gen_store_target<'ctx, 'a, G: CodeGenerator>(
ExprKind::Name { id, .. } => match ctx.var_assignment.get(id) { ExprKind::Name { id, .. } => match ctx.var_assignment.get(id) {
None => { None => {
let ptr_ty = ctx.get_llvm_type(generator, pattern.custom.unwrap()); let ptr_ty = ctx.get_llvm_type(generator, pattern.custom.unwrap());
let ptr = generator.gen_var_alloc(ctx, ptr_ty)?; let ptr = generator.gen_var_alloc(ctx, ptr_ty, name)?;
ctx.var_assignment.insert(*id, (ptr, None, 0)); ctx.var_assignment.insert(*id, (ptr, None, 0));
ptr ptr
} }
@ -74,7 +76,7 @@ pub fn gen_store_target<'ctx, 'a, G: CodeGenerator>(
ctx.ctx.i32_type().const_zero(), ctx.ctx.i32_type().const_zero(),
ctx.ctx.i32_type().const_int(index as u64, false), ctx.ctx.i32_type().const_int(index as u64, false),
], ],
"attr", name.unwrap_or(""),
) )
} }
} }
@ -135,7 +137,7 @@ pub fn gen_store_target<'ctx, 'a, G: CodeGenerator>(
let arr_ptr = ctx let arr_ptr = ctx
.build_gep_and_load(v, &[i32_type.const_zero(), i32_type.const_zero()]) .build_gep_and_load(v, &[i32_type.const_zero(), i32_type.const_zero()])
.into_pointer_value(); .into_pointer_value();
ctx.builder.build_gep(arr_ptr, &[index], "loadarrgep") ctx.builder.build_gep(arr_ptr, &[index], name.unwrap_or(""))
} }
} }
_ => unreachable!(), _ => unreachable!(),
@ -191,7 +193,7 @@ pub fn gen_assign<'ctx, 'a, G: CodeGenerator>(
} }
} }
_ => { _ => {
let ptr = generator.gen_store_target(ctx, target)?; let ptr = generator.gen_store_target(ctx, target, Some("target.addr"))?;
if let ExprKind::Name { id, .. } = &target.node { if let ExprKind::Name { id, .. } = &target.node {
let (_, static_value, counter) = ctx.var_assignment.get_mut(id).unwrap(); let (_, static_value, counter) = ctx.var_assignment.get_mut(id).unwrap();
*counter += 1; *counter += 1;
@ -237,8 +239,8 @@ pub fn gen_for<'ctx, 'a, G: CodeGenerator>(
if ctx.unifier.unioned(iter.custom.unwrap(), ctx.primitives.range) { if ctx.unifier.unioned(iter.custom.unwrap(), ctx.primitives.range) {
// setup // setup
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(), Some("for.i.addr"))?;
let user_i = generator.gen_store_target(ctx, target)?; let user_i = generator.gen_store_target(ctx, target, Some("for.user_i.addr"))?;
let (start, end, step) = destructure_range(ctx, iter_val); let (start, end, 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);
@ -270,7 +272,7 @@ pub fn gen_for<'ctx, 'a, G: CodeGenerator>(
); );
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(), 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));
let len = ctx let len = ctx
@ -655,7 +657,7 @@ pub fn gen_try<'ctx, 'a, G: CodeGenerator>(
let mut final_data = None; let mut final_data = None;
let has_cleanup = !finalbody.is_empty(); let has_cleanup = !finalbody.is_empty();
if has_cleanup { if has_cleanup {
let final_state = generator.gen_var_alloc(ctx, ptr_type.into())?; let final_state = generator.gen_var_alloc(ctx, ptr_type.into(), Some("try.final_state.addr"))?;
final_data = Some((final_state, Vec::new(), Vec::new())); final_data = Some((final_state, Vec::new(), Vec::new()));
if let Some((continue_target, break_target)) = ctx.loop_target { if let Some((continue_target, break_target)) = ctx.loop_target {
let break_proxy = ctx.ctx.append_basic_block(current_fun, "try.break"); let break_proxy = ctx.ctx.append_basic_block(current_fun, "try.break");
@ -821,7 +823,7 @@ pub fn gen_try<'ctx, 'a, G: CodeGenerator>(
ctx.builder.position_at_end(handler_bb); ctx.builder.position_at_end(handler_bb);
if let Some(name) = name { if let Some(name) = name {
let exn_ty = ctx.get_llvm_type(generator, type_.as_ref().unwrap().custom.unwrap()); let exn_ty = ctx.get_llvm_type(generator, type_.as_ref().unwrap().custom.unwrap());
let exn_store = generator.gen_var_alloc(ctx, exn_ty)?; let exn_store = generator.gen_var_alloc(ctx, exn_ty, Some("try.exn_store.addr"))?;
ctx.var_assignment.insert(*name, (exn_store, None, 0)); ctx.var_assignment.insert(*name, (exn_store, None, 0));
ctx.builder.build_store(exn_store, exn.as_basic_value()); ctx.builder.build_store(exn_store, exn.as_basic_value());
} }