mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-21 15:59:20 +03:00
Passed down inplace to everything that uses allocate_list
This commit is contained in:
parent
0a1e297b0f
commit
3112025b0c
@ -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);
|
||||
|
@ -17,7 +17,7 @@ fn get_list_element_type<'a, 'b>(layout: &'b Layout<'a>) -> Option<&'b Layout<'a
|
||||
/// List.single : a -> List a
|
||||
pub fn list_single<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
layout: &Layout<'a>,
|
||||
inplace: InPlace,
|
||||
elem: BasicValueEnum<'ctx>,
|
||||
elem_layout: &Layout<'a>,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
@ -26,7 +26,8 @@ pub fn list_single<'a, 'ctx, 'env>(
|
||||
|
||||
// allocate a list of size 1 on the heap
|
||||
let size = ctx.i64_type().const_int(1, false);
|
||||
let ptr = allocate_list(env, elem_layout, size);
|
||||
|
||||
let ptr = allocate_list(env, inplace, elem_layout, size);
|
||||
|
||||
// Put the element into the list
|
||||
let elem_ptr = unsafe {
|
||||
@ -48,6 +49,7 @@ pub fn list_single<'a, 'ctx, 'env>(
|
||||
/// List.repeat : Int, elem -> List elem
|
||||
pub fn list_repeat<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
inplace: InPlace,
|
||||
parent: FunctionValue<'ctx>,
|
||||
list_len: IntValue<'ctx>,
|
||||
elem: BasicValueEnum<'ctx>,
|
||||
@ -72,7 +74,7 @@ pub fn list_repeat<'a, 'ctx, 'env>(
|
||||
|
||||
let build_then = || {
|
||||
// Allocate space for the new array that we'll copy into.
|
||||
let list_ptr = allocate_list(env, elem_layout, list_len);
|
||||
let list_ptr = allocate_list(env, inplace, elem_layout, list_len);
|
||||
// TODO check if malloc returned null; if so, runtime error for OOM!
|
||||
|
||||
let index_name = "#index";
|
||||
@ -137,6 +139,7 @@ pub fn list_repeat<'a, 'ctx, 'env>(
|
||||
/// List.prepend List elem, elem -> List elem
|
||||
pub fn list_prepend<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
inplace: InPlace,
|
||||
original_wrapper: StructValue<'ctx>,
|
||||
elem: BasicValueEnum<'ctx>,
|
||||
elem_layout: &Layout<'a>,
|
||||
@ -158,7 +161,7 @@ pub fn list_prepend<'a, 'ctx, 'env>(
|
||||
);
|
||||
|
||||
// Allocate space for the new array that we'll copy into.
|
||||
let clone_ptr = allocate_list(env, elem_layout, new_list_len);
|
||||
let clone_ptr = allocate_list(env, inplace, elem_layout, new_list_len);
|
||||
|
||||
builder.build_store(clone_ptr, elem);
|
||||
|
||||
@ -199,6 +202,7 @@ pub fn list_prepend<'a, 'ctx, 'env>(
|
||||
/// List.join : List (List elem) -> List elem
|
||||
pub fn list_join<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
inplace: InPlace,
|
||||
parent: FunctionValue<'ctx>,
|
||||
outer_list: BasicValueEnum<'ctx>,
|
||||
outer_list_layout: &Layout<'a>,
|
||||
@ -276,7 +280,7 @@ pub fn list_join<'a, 'ctx, 'env>(
|
||||
.build_load(list_len_sum_alloca, list_len_sum_name)
|
||||
.into_int_value();
|
||||
|
||||
let final_list_ptr = allocate_list(env, elem_layout, final_list_sum);
|
||||
let final_list_ptr = allocate_list(env, inplace, elem_layout, final_list_sum);
|
||||
|
||||
let dest_elem_ptr_alloca = builder.build_alloca(elem_ptr_type, "dest_elem");
|
||||
|
||||
@ -377,7 +381,7 @@ pub fn list_join<'a, 'ctx, 'env>(
|
||||
pub fn list_reverse_help<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
parent: FunctionValue<'ctx>,
|
||||
in_place: InPlace,
|
||||
inplace: InPlace,
|
||||
length: IntValue<'ctx>,
|
||||
source_ptr: PointerValue<'ctx>,
|
||||
dest_ptr: PointerValue<'ctx>,
|
||||
@ -406,7 +410,7 @@ pub fn list_reverse_help<'a, 'ctx, 'env>(
|
||||
|
||||
// if updating in-place, then the "middle element" can be left untouched
|
||||
// otherwise, the middle element needs to be copied over from the source to the target
|
||||
let predicate = match in_place {
|
||||
let predicate = match inplace {
|
||||
InPlace::InPlace => IntPredicate::SGT,
|
||||
InPlace::Clone => IntPredicate::SGE,
|
||||
};
|
||||
@ -430,7 +434,7 @@ pub fn list_reverse_help<'a, 'ctx, 'env>(
|
||||
let high_value = builder.build_load(high_ptr, "load_high");
|
||||
|
||||
// swap the two values
|
||||
if let InPlace::Clone = in_place {
|
||||
if let InPlace::Clone = inplace {
|
||||
low_ptr = unsafe { builder.build_in_bounds_gep(dest_ptr, &[low], "low_ptr") };
|
||||
high_ptr = unsafe { builder.build_in_bounds_gep(dest_ptr, &[high], "high_ptr") };
|
||||
}
|
||||
@ -451,7 +455,7 @@ pub fn list_reverse_help<'a, 'ctx, 'env>(
|
||||
pub fn list_reverse<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
parent: FunctionValue<'ctx>,
|
||||
in_place: InPlace,
|
||||
output_inplace: InPlace,
|
||||
list: BasicValueEnum<'ctx>,
|
||||
list_layout: &Layout<'a>,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
@ -461,12 +465,21 @@ pub fn list_reverse<'a, 'ctx, 'env>(
|
||||
let ctx = env.context;
|
||||
|
||||
let wrapper_struct = list.into_struct_value();
|
||||
let element_layout = match get_list_element_type(list_layout) {
|
||||
Some(element_layout) => element_layout.clone(),
|
||||
None => {
|
||||
let (input_inplace, element_layout) = match list_layout.clone() {
|
||||
Layout::Builtin(Builtin::EmptyList) => (
|
||||
InPlace::InPlace,
|
||||
// this pointer will never actually be dereferenced
|
||||
Layout::Builtin(Builtin::Int64)
|
||||
}
|
||||
Layout::Builtin(Builtin::Int64),
|
||||
),
|
||||
Layout::Builtin(Builtin::List(memory_mode, elem_layout)) => (
|
||||
match memory_mode {
|
||||
MemoryMode::Unique => InPlace::InPlace,
|
||||
MemoryMode::Refcounted => InPlace::Clone,
|
||||
},
|
||||
elem_layout.clone(),
|
||||
),
|
||||
|
||||
_ => unreachable!("Invalid layout {:?} in List.reverse", list_layout),
|
||||
};
|
||||
|
||||
let list_type = basic_type_from_layout(env.arena, env.context, &element_layout, env.ptr_bytes);
|
||||
@ -475,9 +488,9 @@ pub fn list_reverse<'a, 'ctx, 'env>(
|
||||
let list_ptr = load_list_ptr(builder, wrapper_struct, ptr_type);
|
||||
let length = list_len(builder, list.into_struct_value());
|
||||
|
||||
match in_place {
|
||||
match input_inplace {
|
||||
InPlace::InPlace => {
|
||||
list_reverse_help(env, parent, in_place, length, list_ptr, list_ptr);
|
||||
list_reverse_help(env, parent, input_inplace, length, list_ptr, list_ptr);
|
||||
|
||||
list
|
||||
}
|
||||
@ -512,7 +525,7 @@ pub fn list_reverse<'a, 'ctx, 'env>(
|
||||
{
|
||||
builder.position_at_end(len_1_block);
|
||||
|
||||
let new_list_ptr = clone_list(env, &element_layout, one, list_ptr);
|
||||
let new_list_ptr = clone_list(env, output_inplace, &element_layout, one, list_ptr);
|
||||
|
||||
builder.build_store(result, new_list_ptr);
|
||||
builder.build_unconditional_branch(cont_block);
|
||||
@ -522,7 +535,7 @@ pub fn list_reverse<'a, 'ctx, 'env>(
|
||||
{
|
||||
builder.position_at_end(len_n_block);
|
||||
|
||||
let new_list_ptr = allocate_list(env, &element_layout, length);
|
||||
let new_list_ptr = allocate_list(env, output_inplace, &element_layout, length);
|
||||
|
||||
list_reverse_help(env, parent, InPlace::Clone, length, list_ptr, new_list_ptr);
|
||||
|
||||
@ -574,6 +587,7 @@ pub fn list_get_unsafe<'a, 'ctx, 'env>(
|
||||
/// List.append : List elem, elem -> List elem
|
||||
pub fn list_append<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
inplace: InPlace,
|
||||
original_wrapper: StructValue<'ctx>,
|
||||
elem: BasicValueEnum<'ctx>,
|
||||
elem_layout: &Layout<'a>,
|
||||
@ -609,7 +623,7 @@ pub fn list_append<'a, 'ctx, 'env>(
|
||||
.build_int_mul(elem_bytes, list_len, "mul_old_len_by_elem_bytes");
|
||||
|
||||
// Allocate space for the new array that we'll copy into.
|
||||
let clone_ptr = allocate_list(env, elem_layout, new_list_len);
|
||||
let clone_ptr = allocate_list(env, inplace, elem_layout, new_list_len);
|
||||
|
||||
// TODO check if malloc returned null; if so, runtime error for OOM!
|
||||
|
||||
@ -635,7 +649,7 @@ pub fn list_set<'a, 'ctx, 'env>(
|
||||
parent: FunctionValue<'ctx>,
|
||||
args: &[(BasicValueEnum<'ctx>, &'a Layout<'a>)],
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
in_place: InPlace,
|
||||
inplace: InPlace,
|
||||
) -> BasicValueEnum<'ctx> {
|
||||
let builder = env.builder;
|
||||
|
||||
@ -657,13 +671,14 @@ pub fn list_set<'a, 'ctx, 'env>(
|
||||
let ctx = env.context;
|
||||
let elem_type = basic_type_from_layout(env.arena, ctx, elem_layout, env.ptr_bytes);
|
||||
let ptr_type = get_ptr_type(&elem_type, AddressSpace::Generic);
|
||||
let (new_wrapper, array_data_ptr) = match in_place {
|
||||
let (new_wrapper, array_data_ptr) = match inplace {
|
||||
InPlace::InPlace => (
|
||||
original_wrapper,
|
||||
load_list_ptr(builder, original_wrapper, ptr_type),
|
||||
),
|
||||
InPlace::Clone => clone_nonempty_list(
|
||||
env,
|
||||
inplace,
|
||||
list_len,
|
||||
load_list_ptr(builder, original_wrapper, ptr_type),
|
||||
elem_layout,
|
||||
@ -813,6 +828,7 @@ pub fn list_walk_right<'a, 'ctx, 'env>(
|
||||
/// List.keepIf : List elem, (elem -> Bool) -> List elem
|
||||
pub fn list_keep_if<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
inplace: InPlace,
|
||||
parent: FunctionValue<'ctx>,
|
||||
func: BasicValueEnum<'ctx>,
|
||||
func_layout: &Layout<'a>,
|
||||
@ -903,7 +919,7 @@ pub fn list_keep_if<'a, 'ctx, 'env>(
|
||||
|
||||
// Make a new list, with a length equal to the number
|
||||
// of `elem` that passed the `elem -> Bool` function.
|
||||
let ret_list_ptr = allocate_list(env, elem_layout, final_ret_list_len);
|
||||
let ret_list_ptr = allocate_list(env, inplace, elem_layout, final_ret_list_len);
|
||||
|
||||
// Make a pointer into the return list. This pointer is used
|
||||
// below to store elements into return list.
|
||||
@ -993,6 +1009,7 @@ pub fn list_keep_if<'a, 'ctx, 'env>(
|
||||
/// List.map : List before, (before -> after) -> List after
|
||||
pub fn list_map<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
inplace: InPlace,
|
||||
parent: FunctionValue<'ctx>,
|
||||
func: BasicValueEnum<'ctx>,
|
||||
func_layout: &Layout<'a>,
|
||||
@ -1007,7 +1024,7 @@ pub fn list_map<'a, 'ctx, 'env>(
|
||||
let ctx = env.context;
|
||||
let builder = env.builder;
|
||||
|
||||
let ret_list_ptr = allocate_list(env, ret_elem_layout, len);
|
||||
let ret_list_ptr = allocate_list(env, inplace, ret_elem_layout, len);
|
||||
|
||||
let elem_type = basic_type_from_layout(env.arena, ctx, elem_layout, env.ptr_bytes);
|
||||
let ptr_type = get_ptr_type(&elem_type, AddressSpace::Generic);
|
||||
@ -1054,6 +1071,7 @@ pub fn list_map<'a, 'ctx, 'env>(
|
||||
/// List.concat : List elem, List elem -> List elem
|
||||
pub fn list_concat<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
inplace: InPlace,
|
||||
parent: FunctionValue<'ctx>,
|
||||
first_list: BasicValueEnum<'ctx>,
|
||||
second_list: BasicValueEnum<'ctx>,
|
||||
@ -1095,6 +1113,7 @@ pub fn list_concat<'a, 'ctx, 'env>(
|
||||
|
||||
let (new_wrapper, _) = clone_nonempty_list(
|
||||
env,
|
||||
inplace,
|
||||
second_list_len,
|
||||
load_list_ptr(builder, second_list_wrapper, ptr_type),
|
||||
elem_layout,
|
||||
@ -1122,6 +1141,7 @@ pub fn list_concat<'a, 'ctx, 'env>(
|
||||
let if_second_list_is_empty = || {
|
||||
let (new_wrapper, _) = clone_nonempty_list(
|
||||
env,
|
||||
inplace,
|
||||
first_list_len,
|
||||
load_list_ptr(builder, first_list_wrapper, ptr_type),
|
||||
elem_layout,
|
||||
@ -1140,7 +1160,8 @@ pub fn list_concat<'a, 'ctx, 'env>(
|
||||
let combined_list_len =
|
||||
builder.build_int_add(first_list_len, second_list_len, "add_list_lengths");
|
||||
|
||||
let combined_list_ptr = allocate_list(env, elem_layout, combined_list_len);
|
||||
let combined_list_ptr =
|
||||
allocate_list(env, inplace, elem_layout, combined_list_len);
|
||||
|
||||
let first_list_ptr = load_list_ptr(builder, first_list_wrapper, ptr_type);
|
||||
|
||||
@ -1540,6 +1561,7 @@ pub fn load_list_ptr<'ctx>(
|
||||
|
||||
pub fn clone_nonempty_list<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
inplace: InPlace,
|
||||
list_len: IntValue<'ctx>,
|
||||
elems_ptr: PointerValue<'ctx>,
|
||||
elem_layout: &Layout<'_>,
|
||||
@ -1557,7 +1579,7 @@ pub fn clone_nonempty_list<'a, 'ctx, 'env>(
|
||||
.build_int_mul(elem_bytes, list_len, "clone_mul_len_by_elem_bytes");
|
||||
|
||||
// Allocate space for the new array that we'll copy into.
|
||||
let clone_ptr = allocate_list(env, elem_layout, list_len);
|
||||
let clone_ptr = allocate_list(env, inplace, elem_layout, list_len);
|
||||
|
||||
let int_type = ptr_int(ctx, ptr_bytes);
|
||||
let ptr_as_int = builder.build_ptr_to_int(clone_ptr, int_type, "list_cast_ptr");
|
||||
@ -1607,6 +1629,7 @@ pub fn clone_nonempty_list<'a, 'ctx, 'env>(
|
||||
|
||||
pub fn clone_list<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
output_inplace: InPlace,
|
||||
elem_layout: &Layout<'a>,
|
||||
length: IntValue<'ctx>,
|
||||
old_ptr: PointerValue<'ctx>,
|
||||
@ -1615,7 +1638,7 @@ pub fn clone_list<'a, 'ctx, 'env>(
|
||||
let ptr_bytes = env.ptr_bytes;
|
||||
|
||||
// allocate new empty list (with refcount 1)
|
||||
let new_ptr = allocate_list(env, elem_layout, length);
|
||||
let new_ptr = allocate_list(env, output_inplace, elem_layout, length);
|
||||
|
||||
let stack_size = elem_layout.stack_size(env.ptr_bytes);
|
||||
let bytes = builder.build_int_mul(
|
||||
@ -1632,7 +1655,7 @@ pub fn clone_list<'a, 'ctx, 'env>(
|
||||
|
||||
pub fn allocate_list<'a, 'ctx, 'env>(
|
||||
env: &Env<'a, 'ctx, 'env>,
|
||||
// in_place: InPlace,
|
||||
inplace: InPlace,
|
||||
elem_layout: &Layout<'a>,
|
||||
length: IntValue<'ctx>,
|
||||
) -> PointerValue<'ctx> {
|
||||
|
Loading…
Reference in New Issue
Block a user