diff --git a/compiler/gen_llvm/src/llvm/bitcode.rs b/compiler/gen_llvm/src/llvm/bitcode.rs index fa89ceacf9..0fad482fef 100644 --- a/compiler/gen_llvm/src/llvm/bitcode.rs +++ b/compiler/gen_llvm/src/llvm/bitcode.rs @@ -1,7 +1,7 @@ /// Helpers for interacting with the zig that generates bitcode use crate::debug_info_init; use crate::llvm::build::{struct_from_fields, Env, C_CALL_CONV, FAST_CALL_CONV, TAG_DATA_INDEX}; -use crate::llvm::convert::{basic_type_from_layout, basic_type_from_layout_1}; +use crate::llvm::convert::basic_type_from_layout; use crate::llvm::refcounting::{ decrement_refcount_layout, increment_n_refcount_layout, increment_refcount_layout, }; diff --git a/compiler/gen_llvm/src/llvm/build.rs b/compiler/gen_llvm/src/llvm/build.rs index 480a5ccdfe..66a2e0013b 100644 --- a/compiler/gen_llvm/src/llvm/build.rs +++ b/compiler/gen_llvm/src/llvm/build.rs @@ -1194,17 +1194,7 @@ pub fn build_exp_expr<'a, 'ctx, 'env>( .unwrap(); let field_layout = fields[*index as usize]; - if field_layout.is_passed_by_reference() { - let alloca = env.builder.build_alloca( - basic_type_from_layout(env, &field_layout), - "struct_field_tag", - ); - env.builder.build_store(alloca, field_value); - - alloca.into() - } else { - field_value - } + use_roc_value(env, field_layout, field_value, "struct_field_tag") } ( PointerValue(argument), @@ -1253,8 +1243,6 @@ pub fn build_exp_expr<'a, 'ctx, 'env>( index, union_layout, } => { - let builder = env.builder; - // cast the argument bytes into the desired shape for this tag let (argument, _structure_layout) = load_symbol_and_layout(scope, structure); @@ -2399,6 +2387,23 @@ pub fn load_roc_value<'a, 'ctx, 'env>( } } +pub fn use_roc_value<'a, 'ctx, 'env>( + env: &Env<'a, 'ctx, 'env>, + layout: Layout<'a>, + source: BasicValueEnum<'ctx>, + name: &str, +) -> BasicValueEnum<'ctx> { + if layout.is_passed_by_reference() { + let alloca = tag_alloca(env, basic_type_from_layout(env, &layout), name); + + env.builder.build_store(alloca, source); + + alloca.into() + } else { + source + } +} + pub fn store_roc_value_opaque<'a, 'ctx, 'env>( env: &Env<'a, 'ctx, 'env>, layout: Layout<'a>, @@ -2526,7 +2531,23 @@ pub fn build_exp_stmt<'a, 'ctx, 'env>( if align_bytes > 0 { let value_ptr = value.into_pointer_value(); - value_ptr.replace_all_uses_with(destination); + if true { + value_ptr.replace_all_uses_with(destination); + } else { + let size = env + .ptr_int() + .const_int(layout.stack_size(env.ptr_bytes) as u64, false); + + env.builder + .build_memcpy( + destination, + align_bytes, + value.into_pointer_value(), + align_bytes, + size, + ) + .unwrap(); + } } } else { env.builder.build_store(destination, value); @@ -2794,20 +2815,6 @@ pub fn load_symbol_and_lambda_set<'a, 'ctx, 'b>( } } -fn access_index_struct_value<'ctx>( - builder: &Builder<'ctx>, - from_value: StructValue<'ctx>, - to_type: StructType<'ctx>, -) -> StructValue<'ctx> { - complex_bitcast( - builder, - from_value.into(), - to_type.into(), - "access_index_struct_value", - ) - .into_struct_value() -} - /// Cast a value to another value of the same (or smaller?) size pub fn cast_basic_basic<'ctx>( builder: &Builder<'ctx>, @@ -4660,6 +4667,7 @@ pub struct RocFunctionCall<'ctx> { pub data_is_owned: IntValue<'ctx>, } +#[allow(clippy::too_many_arguments)] fn roc_function_call<'a, 'ctx, 'env>( env: &Env<'a, 'ctx, 'env>, layout_ids: &mut LayoutIds<'a>, diff --git a/compiler/gen_llvm/src/llvm/build_hash.rs b/compiler/gen_llvm/src/llvm/build_hash.rs index b73fe7bd4e..261af4e7d4 100644 --- a/compiler/gen_llvm/src/llvm/build_hash.rs +++ b/compiler/gen_llvm/src/llvm/build_hash.rs @@ -2,7 +2,7 @@ use crate::debug_info_init; use crate::llvm::bitcode::call_bitcode_fn; use crate::llvm::build::tag_pointer_clear_tag_id; use crate::llvm::build::Env; -use crate::llvm::build::{cast_block_of_memory_to_tag, get_tag_id, FAST_CALL_CONV, TAG_DATA_INDEX}; +use crate::llvm::build::{get_tag_id, FAST_CALL_CONV, TAG_DATA_INDEX}; use crate::llvm::build_str; use crate::llvm::convert::{basic_type_from_layout, basic_type_from_layout_1}; use bumpalo::collections::Vec; diff --git a/compiler/gen_llvm/src/llvm/compare.rs b/compiler/gen_llvm/src/llvm/compare.rs index 83c8887ce8..c624890616 100644 --- a/compiler/gen_llvm/src/llvm/compare.rs +++ b/compiler/gen_llvm/src/llvm/compare.rs @@ -884,8 +884,15 @@ fn build_tag_eq_help<'a, 'ctx, 'env>( let block = env.context.append_basic_block(parent, "tag_id_modify"); env.builder.position_at_end(block); - let answer = - eq_ptr_to_struct(env, layout_ids, union_layout, field_layouts, tag1, tag2); + let answer = eq_ptr_to_struct( + env, + layout_ids, + union_layout, + Some(when_recursive.clone()), + field_layouts, + tag1, + tag2, + ); env.builder.build_return(Some(&answer)); @@ -941,8 +948,15 @@ fn build_tag_eq_help<'a, 'ctx, 'env>( let block = env.context.append_basic_block(parent, "tag_id_modify"); env.builder.position_at_end(block); - let answer = - eq_ptr_to_struct(env, layout_ids, union_layout, field_layouts, tag1, tag2); + let answer = eq_ptr_to_struct( + env, + layout_ids, + union_layout, + None, + field_layouts, + tag1, + tag2, + ); env.builder.build_return(Some(&answer)); @@ -998,6 +1012,7 @@ fn build_tag_eq_help<'a, 'ctx, 'env>( env, layout_ids, union_layout, + None, other_fields, tag1.into_pointer_value(), tag2.into_pointer_value(), @@ -1088,8 +1103,15 @@ fn build_tag_eq_help<'a, 'ctx, 'env>( let block = env.context.append_basic_block(parent, "tag_id_modify"); env.builder.position_at_end(block); - let answer = - eq_ptr_to_struct(env, layout_ids, union_layout, field_layouts, tag1, tag2); + let answer = eq_ptr_to_struct( + env, + layout_ids, + union_layout, + None, + field_layouts, + tag1, + tag2, + ); env.builder.build_return(Some(&answer)); @@ -1123,6 +1145,7 @@ fn build_tag_eq_help<'a, 'ctx, 'env>( env, layout_ids, union_layout, + None, field_layouts, tag1.into_pointer_value(), tag2.into_pointer_value(), @@ -1137,6 +1160,7 @@ fn eq_ptr_to_struct<'a, 'ctx, 'env>( env: &Env<'a, 'ctx, 'env>, layout_ids: &mut LayoutIds<'a>, union_layout: &UnionLayout<'a>, + opt_when_recursive: Option>, field_layouts: &'a [Layout<'a>], tag1: PointerValue<'ctx>, tag2: PointerValue<'ctx>, @@ -1179,7 +1203,7 @@ fn eq_ptr_to_struct<'a, 'ctx, 'env>( env, layout_ids, field_layouts, - WhenRecursive::Loop(*union_layout), + opt_when_recursive.unwrap_or(WhenRecursive::Loop(*union_layout)), struct1, struct2, ) diff --git a/compiler/gen_llvm/src/llvm/refcounting.rs b/compiler/gen_llvm/src/llvm/refcounting.rs index 9c40a8d367..de55b101ff 100644 --- a/compiler/gen_llvm/src/llvm/refcounting.rs +++ b/compiler/gen_llvm/src/llvm/refcounting.rs @@ -1,8 +1,8 @@ use crate::debug_info_init; use crate::llvm::bitcode::call_void_bitcode_fn; use crate::llvm::build::{ - add_func, cast_basic_basic, get_tag_id, tag_pointer_clear_tag_id, Env, FAST_CALL_CONV, - TAG_DATA_INDEX, TAG_ID_INDEX, + add_func, cast_basic_basic, get_tag_id, tag_pointer_clear_tag_id, use_roc_value, Env, + FAST_CALL_CONV, TAG_DATA_INDEX, TAG_ID_INDEX, }; use crate::llvm::build_list::{incrementing_elem_loop, list_len, load_list}; use crate::llvm::convert::{basic_type_from_layout, basic_type_from_layout_1, ptr_int}; @@ -354,17 +354,12 @@ fn modify_refcount_struct_help<'a, 'ctx, 'env>( .build_extract_value(wrapper_struct, i as u32, "decrement_struct_field") .unwrap(); - let field_value = if field_layout.is_passed_by_reference() { - let field_type = basic_type_from_layout(env, field_layout); - let alloca = env - .builder - .build_alloca(field_type, "load_struct_tag_field_for_decrement"); - env.builder.build_store(alloca, raw_value); - - alloca.into() - } else { - raw_value - }; + let field_value = use_roc_value( + env, + *field_layout, + raw_value, + "load_struct_tag_field_for_decrement", + ); modify_refcount_layout_help( env, diff --git a/compiler/load/src/file.rs b/compiler/load/src/file.rs index 60e8d7a5f2..e0dfe8fd0a 100644 --- a/compiler/load/src/file.rs +++ b/compiler/load/src/file.rs @@ -2152,7 +2152,7 @@ fn update<'a>( println!("{}", result); } - Proc::insert_refcount_operations(arena, &mut state.procedures); + // Proc::insert_refcount_operations(arena, &mut state.procedures); // This is not safe with the new non-recursive RC updates that we do for tag unions // diff --git a/compiler/mono/src/alias_analysis.rs b/compiler/mono/src/alias_analysis.rs index e2f9bd582c..2a0d4b1c18 100644 --- a/compiler/mono/src/alias_analysis.rs +++ b/compiler/mono/src/alias_analysis.rs @@ -243,7 +243,7 @@ where match opt_level { OptLevel::Development | OptLevel::Normal => morphic_lib::solve_trivial(program), - OptLevel::Optimize => morphic_lib::solve_trivial(program), + OptLevel::Optimize => morphic_lib::solve(program), } } diff --git a/compiler/test_gen/src/gen_tags.rs b/compiler/test_gen/src/gen_tags.rs index 9c5989b174..c62140fd96 100644 --- a/compiler/test_gen/src/gen_tags.rs +++ b/compiler/test_gen/src/gen_tags.rs @@ -3,7 +3,6 @@ use crate::assert_evals_to; // use crate::assert_wasm_evals_to as assert_evals_to; use indoc::indoc; -use roc_mono::layout::LambdaSet; use roc_std::{RocList, RocStr}; #[test]