forked from M-Labs/nac3
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.
This commit is contained in:
parent
049908044a
commit
ff23968544
|
@ -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, None)?;
|
||||||
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, None)?;
|
||||||
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, None)?;
|
||||||
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, None)?;
|
||||||
ctx.builder.build_store(outer_end, max);
|
ctx.builder.build_store(outer_end, max);
|
||||||
}
|
}
|
||||||
self.start = old_start;
|
self.start = old_start;
|
||||||
|
|
|
@ -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(), None)?;
|
||||||
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, None)?;
|
||||||
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(), None)?;
|
||||||
// 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);
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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("tmp"));
|
||||||
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("attr"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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("loadarrgep"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => 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, None)?;
|
||||||
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(), None)?;
|
||||||
let user_i = generator.gen_store_target(ctx, target)?;
|
let user_i = generator.gen_store_target(ctx, target, None)?;
|
||||||
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(), None)?;
|
||||||
// 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(), None)?;
|
||||||
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, None)?;
|
||||||
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());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue