add in-place List.swap

This commit is contained in:
Folkert 2021-10-03 00:25:35 +02:00
parent 3d7b42deba
commit dbb8acbe67
3 changed files with 30 additions and 9 deletions

View file

@ -934,7 +934,9 @@ pub fn build_exp_call<'a, 'ctx, 'env>(
CallType::LowLevel { op, update_mode } => {
let bytes = update_mode.to_bytes();
let update_var = UpdateModeVar(&bytes);
let update_mode = func_spec_solutions.update_mode(update_var).ok();
let update_mode = func_spec_solutions
.update_mode(update_var)
.unwrap_or(UpdateMode::Immutable);
run_low_level(
env,
@ -2229,13 +2231,13 @@ fn list_literal<'a, 'ctx, 'env>(
}
ListLiteralElement::Symbol(symbol) => {
let val = load_symbol(scope, symbol);
let intval = val.into_int_value();
// here we'd like to furthermore check for intval.is_const().
// if all elements are const for LLVM, we could make the array a constant.
// BUT morphic does not know about this, and could allow us to modify that
// array in-place. That would cause a segfault. So, we'll have to find
// constants ourselves and cannot lean on LLVM here.
is_all_constant = false;
runtime_evaluated_elements.push((index, val));
@ -4790,7 +4792,7 @@ fn run_low_level<'a, 'ctx, 'env>(
layout: &Layout<'a>,
op: LowLevel,
args: &[Symbol],
update_mode: Option<UpdateMode>,
update_mode: UpdateMode,
// expect_failed: *const (),
) -> BasicValueEnum<'ctx> {
use LowLevel::*;
@ -4990,6 +4992,7 @@ fn run_low_level<'a, 'ctx, 'env>(
index_1.into_int_value(),
index_2.into_int_value(),
element_layout,
update_mode,
),
_ => unreachable!("Invalid layout {:?} in List.swap", list_layout),
}
@ -5317,7 +5320,7 @@ fn run_low_level<'a, 'ctx, 'env>(
index.into_int_value(),
element,
element_layout,
update_mode.unwrap(),
update_mode,
),
_ => unreachable!("invalid dict layout"),
}

View file

@ -17,6 +17,16 @@ use morphic_lib::UpdateMode;
use roc_builtins::bitcode;
use roc_mono::layout::{Builtin, Layout, LayoutIds};
fn pass_update_mode<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
update_mode: UpdateMode,
) -> BasicValueEnum<'ctx> {
match update_mode {
UpdateMode::Immutable => env.context.bool_type().const_zero().into(),
UpdateMode::InPlace => env.context.bool_type().const_int(1, false).into(),
}
}
fn list_returned_from_zig<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
output: BasicValueEnum<'ctx>,
@ -267,6 +277,7 @@ pub fn list_swap<'a, 'ctx, 'env>(
index_1: IntValue<'ctx>,
index_2: IntValue<'ctx>,
element_layout: &Layout<'a>,
update_mode: UpdateMode,
) -> BasicValueEnum<'ctx> {
call_bitcode_fn_returns_list(
env,
@ -276,6 +287,7 @@ pub fn list_swap<'a, 'ctx, 'env>(
layout_width(env, element_layout),
index_1.into(),
index_2.into(),
pass_update_mode(env, update_mode),
],
bitcode::LIST_SWAP,
)