diff --git a/compiler/gen/src/llvm/build.rs b/compiler/gen/src/llvm/build.rs index cd9ec33426..c5bd67e0d2 100644 --- a/compiler/gen/src/llvm/build.rs +++ b/compiler/gen/src/llvm/build.rs @@ -1698,51 +1698,46 @@ fn list_join<'a, 'ctx, 'env>( // Inner Loop { let inner_list_len = load_list_len(builder, inner_list_wrapper); - let inner_list_ptr = - load_list_ptr(builder, inner_list_wrapper, elem_ptr_type); // inner_list_len > 0 - let inner_list_comparison = builder.build_int_compare( - IntPredicate::UGT, - inner_list_len, - ctx.i64_type().const_int(0, false), - "greaterthanzero", - ); - - 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 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_int_value() .into_pointer_value(), ) }; let build_non_empty = || { + 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], @@ -1759,16 +1754,37 @@ fn list_join<'a, 'ctx, 'env>( builder.build_store(curr_dest_elem_ptr, src_elem); - BasicValueEnum::PointerValue(unsafe { + 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 }; - let next_dest_elem_ptr = build_basic_phi2( + build_basic_phi2( env, parent, inner_list_comparison, @@ -1779,25 +1795,6 @@ fn list_join<'a, 'ctx, 'env>( AddressSpace::Generic, )), ); - - builder.build_store(dest_elem_ptr_alloca, next_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); } // #index < outer_list_len