From 5aa29c4e8be4c7d7a4f6c4c56c6891dd662ea698 Mon Sep 17 00:00:00 2001 From: Folkert Date: Tue, 15 Nov 2022 22:02:11 +0100 Subject: [PATCH] morphic + reset/reuse --- crates/compiler/alias_analysis/src/lib.rs | 29 +++++++++++++++++++--- crates/compiler/gen_llvm/src/llvm/build.rs | 17 +++++++++++-- 2 files changed, 40 insertions(+), 6 deletions(-) diff --git a/crates/compiler/alias_analysis/src/lib.rs b/crates/compiler/alias_analysis/src/lib.rs index 01d9287320..d3f91bb538 100644 --- a/crates/compiler/alias_analysis/src/lib.rs +++ b/crates/compiler/alias_analysis/src/lib.rs @@ -1543,11 +1543,32 @@ fn expr_spec<'a>( } _ => unreachable!("empty array does not have a list layout"), }, - Reset { symbol, .. } => { - let type_id = layout_spec(env, builder, interner, layout, &WhenRecursive::Unreachable)?; - let value_id = env.symbols[symbol]; + Reset { + symbol, + update_mode, + } => { + let tag_value_id = env.symbols[symbol]; - builder.add_unknown_with(block, &[value_id], type_id) + let union_layout = match layout { + Layout::Union(ul) => ul, + _ => unreachable!(), + }; + + let type_name_bytes = recursive_tag_union_name_bytes(union_layout).as_bytes(); + let type_name = TypeName(&type_name_bytes); + + // unwrap the named wrapper + let union_id = builder.add_unwrap_named(block, MOD_APP, type_name, tag_value_id)?; + + let heap_cell = builder.add_get_tuple_field(block, union_id, TAG_CELL_INDEX)?; + let union_data = builder.add_get_tuple_field(block, union_id, TAG_DATA_INDEX)?; + + let mode = update_mode.to_bytes(); + let update_mode_var = UpdateModeVar(&mode); + + let _unit = builder.add_update(block, update_mode_var, heap_cell)?; + + with_new_heap_cell(builder, block, union_data) } RuntimeErrorFunction(_) => { let type_id = layout_spec(env, builder, interner, layout, &WhenRecursive::Unreachable)?; diff --git a/crates/compiler/gen_llvm/src/llvm/build.rs b/crates/compiler/gen_llvm/src/llvm/build.rs index 5335c0dbb3..bb2b0ec22d 100644 --- a/crates/compiler/gen_llvm/src/llvm/build.rs +++ b/crates/compiler/gen_llvm/src/llvm/build.rs @@ -1053,7 +1053,16 @@ pub fn build_exp_expr<'a, 'ctx, 'env>( load_roc_value(env, *layout, value.into_pointer_value(), "load_boxed_value") } - Reset { symbol, .. } => { + Reset { + symbol, + update_mode, + } => { + let bytes = update_mode.to_bytes(); + let update_var = UpdateModeVar(&bytes); + let update_mode = func_spec_solutions + .update_mode(update_var) + .unwrap_or(UpdateMode::Immutable); + let (tag_ptr, layout) = load_symbol_and_layout(scope, symbol); let tag_ptr = tag_ptr.into_pointer_value(); @@ -1070,7 +1079,11 @@ pub fn build_exp_expr<'a, 'ctx, 'env>( let refcount_ptr = PointerToRefcount::from_ptr_to_data(env, tag_pointer_clear_tag_id(env, tag_ptr)); - let is_unique = refcount_ptr.is_1(env); + + let is_unique = match update_mode { + UpdateMode::InPlace => env.context.bool_type().const_int(1, false), + UpdateMode::Immutable => refcount_ptr.is_1(env), + }; env.builder .build_conditional_branch(is_unique, then_block, else_block);