mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-28 22:34:45 +00:00
Passed down inplace to everything that uses allocate_list
This commit is contained in:
parent
0a1e297b0f
commit
3112025b0c
2 changed files with 104 additions and 41 deletions
|
@ -212,6 +212,17 @@ pub fn construct_optimization_passes<'a>(
|
|||
(mpm, fpm)
|
||||
}
|
||||
|
||||
fn get_inplace_from_layout<'a, 'b>(layout: &'b Layout<'a>) -> InPlace {
|
||||
match layout {
|
||||
Layout::Builtin(Builtin::EmptyList) => InPlace::InPlace,
|
||||
Layout::Builtin(Builtin::List(memory_mode, _)) => match memory_mode {
|
||||
MemoryMode::Unique => InPlace::InPlace,
|
||||
MemoryMode::Refcounted => InPlace::Clone,
|
||||
},
|
||||
_ => unreachable!("Layout {:?} does not have an inplace", layout),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build_exp_literal<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
literal: &roc_mono::ir::Literal<'a>,
|
||||
|
@ -239,7 +250,7 @@ pub fn build_exp_literal<'a, 'ctx, 'env>(
|
|||
let len_type = env.ptr_int();
|
||||
let len = len_type.const_int(bytes_len, false);
|
||||
|
||||
allocate_list(env, &CHAR_LAYOUT, len)
|
||||
allocate_list(env, InPlace::Clone, &CHAR_LAYOUT, len)
|
||||
|
||||
// TODO check if malloc returned null; if so, runtime error for OOM!
|
||||
};
|
||||
|
@ -671,7 +682,11 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
|
|||
}
|
||||
}
|
||||
EmptyArray => empty_polymorphic_list(env),
|
||||
Array { elem_layout, elems } => list_literal(env, scope, elem_layout, elems),
|
||||
Array { elem_layout, elems } => {
|
||||
let inplace = get_inplace_from_layout(layout);
|
||||
|
||||
list_literal(env, inplace, scope, elem_layout, elems)
|
||||
}
|
||||
FunctionPointer(symbol, layout) => {
|
||||
let fn_name = layout_ids
|
||||
.get(*symbol, layout)
|
||||
|
@ -760,6 +775,7 @@ pub fn allocate_with_refcount<'a, 'ctx, 'env>(
|
|||
|
||||
fn list_literal<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
inplace: InPlace,
|
||||
scope: &Scope<'a, 'ctx>,
|
||||
elem_layout: &Layout<'a>,
|
||||
elems: &&[Symbol],
|
||||
|
@ -775,7 +791,7 @@ fn list_literal<'a, 'ctx, 'env>(
|
|||
let len_type = env.ptr_int();
|
||||
let len = len_type.const_int(bytes_len, false);
|
||||
|
||||
allocate_list(env, elem_layout, len)
|
||||
allocate_list(env, inplace, elem_layout, len)
|
||||
|
||||
// TODO check if malloc returned null; if so, runtime error for OOM!
|
||||
};
|
||||
|
@ -1469,6 +1485,7 @@ fn call_intrinsic<'a, 'ctx, 'env>(
|
|||
})
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub enum InPlace {
|
||||
InPlace,
|
||||
Clone,
|
||||
|
@ -1512,7 +1529,9 @@ fn run_low_level<'a, 'ctx, 'env>(
|
|||
|
||||
let second_str = load_symbol(env, scope, &args[1]);
|
||||
|
||||
str_concat(env, parent, first_str, second_str)
|
||||
let inplace = get_inplace_from_layout(layout);
|
||||
|
||||
str_concat(env, inplace, parent, first_str, second_str)
|
||||
}
|
||||
ListLen => {
|
||||
// List.len : List * -> Int
|
||||
|
@ -1528,7 +1547,9 @@ fn run_low_level<'a, 'ctx, 'env>(
|
|||
|
||||
let (arg, arg_layout) = load_symbol_and_layout(env, scope, &args[0]);
|
||||
|
||||
list_single(env, layout, arg, arg_layout)
|
||||
let inplace = get_inplace_from_layout(layout);
|
||||
|
||||
list_single(env, inplace, arg, arg_layout)
|
||||
}
|
||||
ListRepeat => {
|
||||
// List.repeat : Int, elem -> List elem
|
||||
|
@ -1537,7 +1558,9 @@ fn run_low_level<'a, 'ctx, 'env>(
|
|||
let list_len = load_symbol(env, scope, &args[0]).into_int_value();
|
||||
let (elem, elem_layout) = load_symbol_and_layout(env, scope, &args[1]);
|
||||
|
||||
list_repeat(env, parent, list_len, elem, elem_layout)
|
||||
let inplace = get_inplace_from_layout(layout);
|
||||
|
||||
list_repeat(env, inplace, parent, list_len, elem, elem_layout)
|
||||
}
|
||||
ListReverse => {
|
||||
// List.reverse : List elem -> List elem
|
||||
|
@ -1545,7 +1568,9 @@ fn run_low_level<'a, 'ctx, 'env>(
|
|||
|
||||
let (list, list_layout) = load_symbol_and_layout(env, scope, &args[0]);
|
||||
|
||||
list_reverse(env, parent, InPlace::Clone, list, list_layout)
|
||||
let inplace = get_inplace_from_layout(layout);
|
||||
|
||||
list_reverse(env, parent, inplace, list, list_layout)
|
||||
}
|
||||
ListConcat => {
|
||||
debug_assert_eq!(args.len(), 2);
|
||||
|
@ -1554,7 +1579,9 @@ fn run_low_level<'a, 'ctx, 'env>(
|
|||
|
||||
let second_list = load_symbol(env, scope, &args[1]);
|
||||
|
||||
list_concat(env, parent, first_list, second_list, list_layout)
|
||||
let inplace = get_inplace_from_layout(layout);
|
||||
|
||||
list_concat(env, inplace, parent, first_list, second_list, list_layout)
|
||||
}
|
||||
ListMap => {
|
||||
// List.map : List before, (before -> after) -> List after
|
||||
|
@ -1564,7 +1591,9 @@ fn run_low_level<'a, 'ctx, 'env>(
|
|||
|
||||
let (func, func_layout) = load_symbol_and_layout(env, scope, &args[1]);
|
||||
|
||||
list_map(env, parent, func, func_layout, list, list_layout)
|
||||
let inplace = get_inplace_from_layout(layout);
|
||||
|
||||
list_map(env, inplace, parent, func, func_layout, list, list_layout)
|
||||
}
|
||||
ListKeepIf => {
|
||||
// List.keepIf : List elem, (elem -> Bool) -> List elem
|
||||
|
@ -1574,7 +1603,9 @@ fn run_low_level<'a, 'ctx, 'env>(
|
|||
|
||||
let (func, func_layout) = load_symbol_and_layout(env, scope, &args[1]);
|
||||
|
||||
list_keep_if(env, parent, func, func_layout, list, list_layout)
|
||||
let inplace = get_inplace_from_layout(layout);
|
||||
|
||||
list_keep_if(env, inplace, parent, func, func_layout, list, list_layout)
|
||||
}
|
||||
ListWalkRight => {
|
||||
// List.walkRight : List elem, (elem -> accum -> accum), accum -> accum
|
||||
|
@ -1604,7 +1635,9 @@ fn run_low_level<'a, 'ctx, 'env>(
|
|||
let original_wrapper = load_symbol(env, scope, &args[0]).into_struct_value();
|
||||
let (elem, elem_layout) = load_symbol_and_layout(env, scope, &args[1]);
|
||||
|
||||
list_append(env, original_wrapper, elem, elem_layout)
|
||||
let inplace = get_inplace_from_layout(layout);
|
||||
|
||||
list_append(env, inplace, original_wrapper, elem, elem_layout)
|
||||
}
|
||||
ListPrepend => {
|
||||
// List.prepend : List elem, elem -> List elem
|
||||
|
@ -1613,7 +1646,9 @@ fn run_low_level<'a, 'ctx, 'env>(
|
|||
let original_wrapper = load_symbol(env, scope, &args[0]).into_struct_value();
|
||||
let (elem, elem_layout) = load_symbol_and_layout(env, scope, &args[1]);
|
||||
|
||||
list_prepend(env, original_wrapper, elem, elem_layout)
|
||||
let inplace = get_inplace_from_layout(layout);
|
||||
|
||||
list_prepend(env, inplace, original_wrapper, elem, elem_layout)
|
||||
}
|
||||
ListJoin => {
|
||||
// List.join : List (List elem) -> List elem
|
||||
|
@ -1621,7 +1656,9 @@ fn run_low_level<'a, 'ctx, 'env>(
|
|||
|
||||
let (list, outer_list_layout) = load_symbol_and_layout(env, scope, &args[0]);
|
||||
|
||||
list_join(env, parent, list, outer_list_layout)
|
||||
let inplace = get_inplace_from_layout(layout);
|
||||
|
||||
list_join(env, inplace, parent, list, outer_list_layout)
|
||||
}
|
||||
NumAbs | NumNeg | NumRound | NumSqrtUnchecked | NumSin | NumCos | NumToFloat => {
|
||||
debug_assert_eq!(args.len(), 1);
|
||||
|
@ -1925,6 +1962,7 @@ where
|
|||
/// Str.concat : Str, Str -> Str
|
||||
fn str_concat<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
inplace: InPlace,
|
||||
parent: FunctionValue<'ctx>,
|
||||
first_str: BasicValueEnum<'ctx>,
|
||||
second_str: BasicValueEnum<'ctx>,
|
||||
|
@ -1955,6 +1993,7 @@ fn str_concat<'a, 'ctx, 'env>(
|
|||
|
||||
let (new_wrapper, _) = clone_nonempty_list(
|
||||
env,
|
||||
inplace,
|
||||
second_str_len,
|
||||
load_list_ptr(builder, second_str_wrapper, ptr_type),
|
||||
&CHAR_LAYOUT,
|
||||
|
@ -1982,6 +2021,7 @@ fn str_concat<'a, 'ctx, 'env>(
|
|||
let if_second_str_is_empty = || {
|
||||
let (new_wrapper, _) = clone_nonempty_list(
|
||||
env,
|
||||
inplace,
|
||||
first_str_len,
|
||||
load_list_ptr(builder, first_str_wrapper, ptr_type),
|
||||
&CHAR_LAYOUT,
|
||||
|
@ -1999,7 +2039,7 @@ fn str_concat<'a, 'ctx, 'env>(
|
|||
let combined_str_len =
|
||||
builder.build_int_add(first_str_len, second_str_len, "add_list_lengths");
|
||||
|
||||
let combined_str_ptr = allocate_list(env, &CHAR_LAYOUT, combined_str_len);
|
||||
let combined_str_ptr = allocate_list(env, inplace, &CHAR_LAYOUT, combined_str_len);
|
||||
|
||||
// FIRST LOOP
|
||||
let first_str_ptr = load_list_ptr(builder, first_str_wrapper, ptr_type);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue