diff --git a/compiler/gen/src/llvm/build.rs b/compiler/gen/src/llvm/build.rs index c5bd67e0d2..13eff5351e 100644 --- a/compiler/gen/src/llvm/build.rs +++ b/compiler/gen/src/llvm/build.rs @@ -1702,99 +1702,91 @@ fn list_join<'a, 'ctx, 'env>( // inner_list_len > 0 let inner_list_comparison = list_is_not_empty(builder, ctx, inner_list_len); - let build_empty = || { - BasicValueEnum::PointerValue( - builder - .build_load(dest_elem_ptr_alloca, "load_dest_elem_ptr") - .into_pointer_value(), + let inner_list_non_empty_block = + ctx.append_basic_block(parent, "inner_list_non_empty"); + + let after_inner_list_non_empty_block = + ctx.append_basic_block(parent, "branchcont"); + + builder.build_conditional_branch( + inner_list_comparison, + inner_list_non_empty_block, + after_inner_list_non_empty_block, + ); + builder.position_at_end(inner_list_non_empty_block); + + let inner_index_name = "#inner_index"; + let inner_index_alloca = + builder.build_alloca(ctx.i64_type(), inner_index_name); + + let inner_list_index = ctx.i64_type().const_int(0, false); + builder.build_store(inner_index_alloca, inner_list_index); + + let inner_loop_bb = ctx.append_basic_block(parent, "loop"); + builder.build_unconditional_branch(inner_loop_bb); + builder.position_at_end(inner_loop_bb); + + // #index = #index + 1 + let curr_inner_index = builder + .build_load(inner_index_alloca, inner_index_name) + .into_int_value(); + let next_inner_index = builder.build_int_add( + curr_inner_index, + ctx.i64_type().const_int(1, false), + "nextindex", + ); + + builder.build_store(inner_index_alloca, next_inner_index); + + let src_elem_ptr = unsafe { + let inner_list_ptr = + load_list_ptr(builder, inner_list_wrapper, elem_ptr_type); + + builder.build_in_bounds_gep( + inner_list_ptr, + &[curr_inner_index], + "load_index", ) }; - let build_non_empty = || { - let inner_index_name = "#inner_index"; - let inner_index_alloca = - builder.build_alloca(ctx.i64_type(), inner_index_name); + let src_elem = builder.build_load(src_elem_ptr, "get_elem"); + // TODO clone src_elem - let inner_list_index = ctx.i64_type().const_int(0, false); - builder.build_store(inner_index_alloca, inner_list_index); + let curr_dest_elem_ptr = builder + .build_load(dest_elem_ptr_alloca, "load_dest_elem_ptr") + .into_pointer_value(); - let inner_loop_bb = ctx.append_basic_block(parent, "loop"); - builder.build_unconditional_branch(inner_loop_bb); - builder.position_at_end(inner_loop_bb); + builder.build_store(curr_dest_elem_ptr, src_elem); - // #index = #index + 1 - let curr_inner_index = builder - .build_load(inner_index_alloca, inner_index_name) - .into_int_value(); - let next_inner_index = builder.build_int_add( - curr_inner_index, - ctx.i64_type().const_int(1, false), - "nextindex", - ); + let inc_dest_elem_ptr = BasicValueEnum::PointerValue(unsafe { + builder.build_in_bounds_gep( + curr_dest_elem_ptr, + &[env.ptr_int().const_int(1 as u64, false)], + "increment_dest_elem", + ) + }); - builder.build_store(inner_index_alloca, next_inner_index); + builder.build_store(dest_elem_ptr_alloca, inc_dest_elem_ptr); - let src_elem_ptr = unsafe { - let inner_list_ptr = - load_list_ptr(builder, inner_list_wrapper, elem_ptr_type); - - builder.build_in_bounds_gep( - inner_list_ptr, - &[curr_inner_index], - "load_index", - ) - }; - - let src_elem = builder.build_load(src_elem_ptr, "get_elem"); - // TODO clone src_elem - - let curr_dest_elem_ptr = builder - .build_load(dest_elem_ptr_alloca, "load_dest_elem_ptr") - .into_pointer_value(); - - builder.build_store(curr_dest_elem_ptr, src_elem); - - let inc_dest_elem_ptr = BasicValueEnum::PointerValue(unsafe { - builder.build_in_bounds_gep( - curr_dest_elem_ptr, - &[env.ptr_int().const_int(1 as u64, false)], - "increment_dest_elem", - ) - }); - - builder.build_store(dest_elem_ptr_alloca, inc_dest_elem_ptr); - - let inner_loop_end_cond = builder.build_int_compare( - IntPredicate::ULT, - next_inner_index, - inner_list_len, - "loopcond", - ); - - let after_inner_loop_bb = - ctx.append_basic_block(parent, "after_inner_loop"); - - builder.build_conditional_branch( - inner_loop_end_cond, - inner_loop_bb, - after_inner_loop_bb, - ); - builder.position_at_end(after_inner_loop_bb); - - inc_dest_elem_ptr - }; - - build_basic_phi2( - env, - parent, - inner_list_comparison, - build_non_empty, - build_empty, - BasicTypeEnum::PointerType(get_ptr_type( - &elem_type, - AddressSpace::Generic, - )), + let inner_loop_end_cond = builder.build_int_compare( + IntPredicate::ULT, + next_inner_index, + inner_list_len, + "loopcond", ); + + let after_inner_loop_bb = + ctx.append_basic_block(parent, "after_inner_loop"); + + builder.build_conditional_branch( + inner_loop_end_cond, + inner_loop_bb, + after_inner_loop_bb, + ); + builder.position_at_end(after_inner_loop_bb); + + builder.build_unconditional_branch(after_inner_list_non_empty_block); + builder.position_at_end(after_inner_list_non_empty_block); } // #index < outer_list_len