core: Minor refactor allocate_list

This commit is contained in:
David Mak 2023-09-15 16:55:02 +08:00
parent 2e6a64a1de
commit 806f65815f
1 changed files with 45 additions and 15 deletions

View File

@ -765,32 +765,55 @@ pub fn destructure_range<'ctx, 'a>(
(start, end, step) (start, end, step)
} }
/// Allocates a List structure with the given [type][ty] and [length]. The name of the resulting
/// LLVM value is `{name}.addr`, or `list.addr` if [name] is not specified.
///
/// Returns an instance of [PointerValue] pointing to the List structure. The List structure is
/// defined as `type { ty*, size_t }` in LLVM, where the first element stores the pointer to the
/// data, and the second element stores the size of the List.
pub fn allocate_list<'ctx, 'a, G: CodeGenerator>( pub fn allocate_list<'ctx, 'a, G: CodeGenerator>(
generator: &mut G, generator: &mut G,
ctx: &mut CodeGenContext<'ctx, 'a>, ctx: &mut CodeGenContext<'ctx, 'a>,
ty: BasicTypeEnum<'ctx>, ty: BasicTypeEnum<'ctx>,
length: IntValue<'ctx>, length: IntValue<'ctx>,
name: Option<&str>,
) -> PointerValue<'ctx> { ) -> PointerValue<'ctx> {
let arr_ptr = ctx.builder.build_array_alloca(ty, length, "tmparr");
let size_t = generator.get_size_type(ctx.ctx); let size_t = generator.get_size_type(ctx.ctx);
let i32_t = ctx.ctx.i32_type(); let i32_t = ctx.ctx.i32_type();
let arr_ty = // List structure; type { ty*, size_t }
ctx.ctx.struct_type(&[ty.ptr_type(AddressSpace::default()).into(), size_t.into()], false); let arr_ty = ctx.ctx
.struct_type(&[ty.ptr_type(AddressSpace::default()).into(), size_t.into()], false);
let zero = ctx.ctx.i32_type().const_zero(); let zero = ctx.ctx.i32_type().const_zero();
let arr_str_ptr = ctx.builder.build_alloca(arr_ty, "tmparrstr");
let arr_str_ptr = ctx.builder.build_alloca(
arr_ty, format!("{}.addr", name.unwrap_or("list")).as_str()
);
unsafe { unsafe {
// Pointer to the `length` element of the list structure
let len_ptr = ctx.builder.build_in_bounds_gep( let len_ptr = ctx.builder.build_in_bounds_gep(
arr_str_ptr, arr_str_ptr,
&[zero, i32_t.const_int(1, false)], &[zero, i32_t.const_int(1, false)],
"len_ptr", ""
);
let length = ctx.builder.build_int_z_extend(
length,
size_t,
""
); );
let length = ctx.builder.build_int_z_extend(length, size_t, "zext");
ctx.builder.build_store(len_ptr, length); ctx.builder.build_store(len_ptr, length);
let ptr_to_arr =
ctx.builder.build_in_bounds_gep(arr_str_ptr, &[zero, i32_t.const_zero()], "ptr_to_arr"); // Pointer to the `data` element of the list structure
let arr_ptr = ctx.builder.build_array_alloca(ty, length, "");
let ptr_to_arr = ctx.builder.build_in_bounds_gep(
arr_str_ptr,
&[zero, i32_t.const_zero()],
""
);
ctx.builder.build_store(ptr_to_arr, arr_ptr); ctx.builder.build_store(ptr_to_arr, arr_ptr);
arr_str_ptr
} }
arr_str_ptr
} }
pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>( pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>(
@ -849,11 +872,18 @@ pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>(
ctx, ctx,
elem_ty, elem_ty,
ctx.builder.build_int_z_extend_or_bit_cast(length, size_t, "z_ext_len"), ctx.builder.build_int_z_extend_or_bit_cast(length, size_t, "z_ext_len"),
Some("listcomp"),
); );
ctx.builder.build_unconditional_branch(list_init); ctx.builder.build_unconditional_branch(list_init);
ctx.builder.position_at_end(empty); ctx.builder.position_at_end(empty);
let list_b = allocate_list(generator, ctx, elem_ty, zero_size_t); let list_b = allocate_list(
generator,
ctx,
elem_ty,
zero_size_t,
Some("list_b")
);
ctx.builder.build_unconditional_branch(list_init); ctx.builder.build_unconditional_branch(list_init);
ctx.builder.position_at_end(list_init); ctx.builder.position_at_end(list_init);
@ -898,7 +928,7 @@ pub fn gen_comprehension<'ctx, 'a, G: CodeGenerator>(
Some("length"), Some("length"),
) )
.into_int_value(); .into_int_value();
list = allocate_list(generator, ctx, elem_ty, length); list = allocate_list(generator, ctx, elem_ty, length, Some("listcomp"));
list_content = list_content =
ctx.build_gep_and_load(list, &[zero_size_t, zero_32], Some("list_content")).into_pointer_value(); ctx.build_gep_and_load(list, &[zero_size_t, zero_32], Some("list_content")).into_pointer_value();
let counter = generator.gen_var_alloc(ctx, size_t.into(), Some("counter.addr"))?; let counter = generator.gen_var_alloc(ctx, size_t.into(), Some("counter.addr"))?;
@ -1089,7 +1119,7 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
} }
} }
ExprKind::Name { id, .. } => match ctx.var_assignment.get(id) { ExprKind::Name { id, .. } => match ctx.var_assignment.get(id) {
Some((ptr, None, _)) => ctx.builder.build_load(*ptr, "load").into(), Some((ptr, None, _)) => ctx.builder.build_load(*ptr, id.to_string().as_str()).into(),
Some((_, Some(static_value), _)) => ValueEnum::Static(static_value.clone()), Some((_, Some(static_value), _)) => ValueEnum::Static(static_value.clone()),
None => { None => {
let resolver = ctx.resolver.clone(); let resolver = ctx.resolver.clone();
@ -1120,8 +1150,8 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
elements[0].get_type() elements[0].get_type()
}; };
let length = generator.get_size_type(ctx.ctx).const_int(elements.len() as u64, false); let length = generator.get_size_type(ctx.ctx).const_int(elements.len() as u64, false);
let arr_str_ptr = allocate_list(generator, ctx, ty, length); let arr_str_ptr = allocate_list(generator, ctx, ty, length, Some("list"));
let arr_ptr = ctx.build_gep_and_load(arr_str_ptr, &[zero, zero], Some("arr.addr")) let arr_ptr = ctx.build_gep_and_load(arr_str_ptr, &[zero, zero], Some("list.ptr.addr"))
.into_pointer_value(); .into_pointer_value();
unsafe { unsafe {
for (i, v) in elements.iter().enumerate() { for (i, v) in elements.iter().enumerate() {
@ -1558,7 +1588,7 @@ pub fn gen_expr<'ctx, 'a, G: CodeGenerator>(
.into_int_value(), .into_int_value(),
step, step,
); );
let res_array_ret = allocate_list(generator, ctx, ty, length); let res_array_ret = allocate_list(generator, ctx, ty, length, Some("ret"));
let res_ind = let res_ind =
handle_slice_indices(&None, &None, &None, ctx, generator, res_array_ret)?; handle_slice_indices(&None, &None, &None, ctx, generator, res_array_ret)?;
list_slice_assignment( list_slice_assignment(