mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 14:54:47 +00:00
remove list sum and product lowlevel ops
This commit is contained in:
parent
5cfc9c1d85
commit
e3293f1ba9
4 changed files with 3 additions and 170 deletions
|
@ -7,8 +7,8 @@ use crate::llvm::build_hash::generic_hash;
|
||||||
use crate::llvm::build_list::{
|
use crate::llvm::build_list::{
|
||||||
allocate_list, empty_list, empty_polymorphic_list, list_append, list_concat, list_contains,
|
allocate_list, empty_list, empty_polymorphic_list, list_append, list_concat, list_contains,
|
||||||
list_get_unsafe, list_join, list_keep_errs, list_keep_if, list_keep_oks, list_len, list_map,
|
list_get_unsafe, list_join, list_keep_errs, list_keep_if, list_keep_oks, list_len, list_map,
|
||||||
list_map2, list_map3, list_map_with_index, list_prepend, list_product, list_repeat,
|
list_map2, list_map3, list_map_with_index, list_prepend, list_repeat, list_reverse, list_set,
|
||||||
list_reverse, list_set, list_single, list_sum, list_walk, list_walk_backwards,
|
list_single, list_walk, list_walk_backwards,
|
||||||
};
|
};
|
||||||
use crate::llvm::build_str::{
|
use crate::llvm::build_str::{
|
||||||
str_concat, str_count_graphemes, str_ends_with, str_from_float, str_from_int, str_from_utf8,
|
str_concat, str_count_graphemes, str_ends_with, str_from_float, str_from_int, str_from_utf8,
|
||||||
|
@ -3930,20 +3930,6 @@ fn run_low_level<'a, 'ctx, 'env>(
|
||||||
_ => unreachable!("invalid list layout"),
|
_ => unreachable!("invalid list layout"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ListSum => {
|
|
||||||
debug_assert_eq!(args.len(), 1);
|
|
||||||
|
|
||||||
let list = load_symbol(scope, &args[0]);
|
|
||||||
|
|
||||||
list_sum(env, parent, list, layout)
|
|
||||||
}
|
|
||||||
ListProduct => {
|
|
||||||
debug_assert_eq!(args.len(), 1);
|
|
||||||
|
|
||||||
let list = load_symbol(scope, &args[0]);
|
|
||||||
|
|
||||||
list_product(env, parent, list, layout)
|
|
||||||
}
|
|
||||||
ListAppend => {
|
ListAppend => {
|
||||||
// List.append : List elem, elem -> List elem
|
// List.append : List elem, elem -> List elem
|
||||||
debug_assert_eq!(args.len(), 2);
|
debug_assert_eq!(args.len(), 2);
|
||||||
|
|
|
@ -4,7 +4,7 @@ use crate::llvm::bitcode::{
|
||||||
call_bitcode_fn, call_void_bitcode_fn,
|
call_bitcode_fn, call_void_bitcode_fn,
|
||||||
};
|
};
|
||||||
use crate::llvm::build::{
|
use crate::llvm::build::{
|
||||||
allocate_with_refcount_help, build_num_binop, cast_basic_basic, complex_bitcast, Env, InPlace,
|
allocate_with_refcount_help, cast_basic_basic, complex_bitcast, Env, InPlace,
|
||||||
};
|
};
|
||||||
use crate::llvm::convert::{basic_type_from_layout, collection, get_ptr_type};
|
use crate::llvm::convert::{basic_type_from_layout, collection, get_ptr_type};
|
||||||
use crate::llvm::refcounting::{
|
use crate::llvm::refcounting::{
|
||||||
|
@ -713,156 +713,6 @@ pub fn list_len<'ctx>(
|
||||||
.into_int_value()
|
.into_int_value()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// List.sum : List (Num a) -> Num a
|
|
||||||
pub fn list_sum<'a, 'ctx, 'env>(
|
|
||||||
env: &Env<'a, 'ctx, 'env>,
|
|
||||||
parent: FunctionValue<'ctx>,
|
|
||||||
list: BasicValueEnum<'ctx>,
|
|
||||||
default_layout: &Layout<'a>,
|
|
||||||
) -> BasicValueEnum<'ctx> {
|
|
||||||
let ctx = env.context;
|
|
||||||
let builder = env.builder;
|
|
||||||
|
|
||||||
let list_wrapper = list.into_struct_value();
|
|
||||||
let len = list_len(env.builder, list_wrapper);
|
|
||||||
|
|
||||||
let accum_type = basic_type_from_layout(env.arena, ctx, default_layout, env.ptr_bytes);
|
|
||||||
let accum_alloca = builder.build_alloca(accum_type, "alloca_walk_right_accum");
|
|
||||||
|
|
||||||
let default: BasicValueEnum = match accum_type {
|
|
||||||
BasicTypeEnum::IntType(int_type) => int_type.const_zero().into(),
|
|
||||||
BasicTypeEnum::FloatType(float_type) => float_type.const_zero().into(),
|
|
||||||
_ => unreachable!(""),
|
|
||||||
};
|
|
||||||
|
|
||||||
builder.build_store(accum_alloca, default);
|
|
||||||
|
|
||||||
let then_block = ctx.append_basic_block(parent, "then");
|
|
||||||
let cont_block = ctx.append_basic_block(parent, "branchcont");
|
|
||||||
|
|
||||||
let condition = builder.build_int_compare(
|
|
||||||
IntPredicate::UGT,
|
|
||||||
len,
|
|
||||||
ctx.i64_type().const_zero(),
|
|
||||||
"list_non_empty",
|
|
||||||
);
|
|
||||||
|
|
||||||
builder.build_conditional_branch(condition, then_block, cont_block);
|
|
||||||
|
|
||||||
builder.position_at_end(then_block);
|
|
||||||
|
|
||||||
let elem_ptr_type = get_ptr_type(&accum_type, AddressSpace::Generic);
|
|
||||||
let list_ptr = load_list_ptr(builder, list_wrapper, elem_ptr_type);
|
|
||||||
|
|
||||||
let walk_right_loop = |_, elem: BasicValueEnum<'ctx>| {
|
|
||||||
// load current accumulator
|
|
||||||
let current = builder.build_load(accum_alloca, "retrieve_accum");
|
|
||||||
|
|
||||||
let new_current = build_num_binop(
|
|
||||||
env,
|
|
||||||
parent,
|
|
||||||
current,
|
|
||||||
default_layout,
|
|
||||||
elem,
|
|
||||||
default_layout,
|
|
||||||
roc_module::low_level::LowLevel::NumAdd,
|
|
||||||
);
|
|
||||||
|
|
||||||
builder.build_store(accum_alloca, new_current);
|
|
||||||
};
|
|
||||||
|
|
||||||
incrementing_elem_loop(
|
|
||||||
builder,
|
|
||||||
ctx,
|
|
||||||
parent,
|
|
||||||
list_ptr,
|
|
||||||
len,
|
|
||||||
"#index",
|
|
||||||
walk_right_loop,
|
|
||||||
);
|
|
||||||
|
|
||||||
builder.build_unconditional_branch(cont_block);
|
|
||||||
|
|
||||||
builder.position_at_end(cont_block);
|
|
||||||
|
|
||||||
builder.build_load(accum_alloca, "load_final_acum")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// List.product : List (Num a) -> Num a
|
|
||||||
pub fn list_product<'a, 'ctx, 'env>(
|
|
||||||
env: &Env<'a, 'ctx, 'env>,
|
|
||||||
parent: FunctionValue<'ctx>,
|
|
||||||
list: BasicValueEnum<'ctx>,
|
|
||||||
default_layout: &Layout<'a>,
|
|
||||||
) -> BasicValueEnum<'ctx> {
|
|
||||||
let ctx = env.context;
|
|
||||||
let builder = env.builder;
|
|
||||||
|
|
||||||
let list_wrapper = list.into_struct_value();
|
|
||||||
let len = list_len(env.builder, list_wrapper);
|
|
||||||
|
|
||||||
let accum_type = basic_type_from_layout(env.arena, ctx, default_layout, env.ptr_bytes);
|
|
||||||
let accum_alloca = builder.build_alloca(accum_type, "alloca_walk_right_accum");
|
|
||||||
|
|
||||||
let default: BasicValueEnum = match accum_type {
|
|
||||||
BasicTypeEnum::IntType(int_type) => int_type.const_int(1, false).into(),
|
|
||||||
BasicTypeEnum::FloatType(float_type) => float_type.const_float(1.0).into(),
|
|
||||||
_ => unreachable!(""),
|
|
||||||
};
|
|
||||||
|
|
||||||
builder.build_store(accum_alloca, default);
|
|
||||||
|
|
||||||
let then_block = ctx.append_basic_block(parent, "then");
|
|
||||||
let cont_block = ctx.append_basic_block(parent, "branchcont");
|
|
||||||
|
|
||||||
let condition = builder.build_int_compare(
|
|
||||||
IntPredicate::UGT,
|
|
||||||
len,
|
|
||||||
ctx.i64_type().const_zero(),
|
|
||||||
"list_non_empty",
|
|
||||||
);
|
|
||||||
|
|
||||||
builder.build_conditional_branch(condition, then_block, cont_block);
|
|
||||||
|
|
||||||
builder.position_at_end(then_block);
|
|
||||||
|
|
||||||
let elem_ptr_type = get_ptr_type(&accum_type, AddressSpace::Generic);
|
|
||||||
let list_ptr = load_list_ptr(builder, list_wrapper, elem_ptr_type);
|
|
||||||
|
|
||||||
let walk_right_loop = |_, elem: BasicValueEnum<'ctx>| {
|
|
||||||
// load current accumulator
|
|
||||||
let current = builder.build_load(accum_alloca, "retrieve_accum");
|
|
||||||
|
|
||||||
let new_current = build_num_binop(
|
|
||||||
env,
|
|
||||||
parent,
|
|
||||||
current,
|
|
||||||
default_layout,
|
|
||||||
elem,
|
|
||||||
default_layout,
|
|
||||||
roc_module::low_level::LowLevel::NumMul,
|
|
||||||
);
|
|
||||||
|
|
||||||
builder.build_store(accum_alloca, new_current);
|
|
||||||
};
|
|
||||||
|
|
||||||
incrementing_elem_loop(
|
|
||||||
builder,
|
|
||||||
ctx,
|
|
||||||
parent,
|
|
||||||
list_ptr,
|
|
||||||
len,
|
|
||||||
"#index",
|
|
||||||
walk_right_loop,
|
|
||||||
);
|
|
||||||
|
|
||||||
builder.build_unconditional_branch(cont_block);
|
|
||||||
|
|
||||||
builder.position_at_end(cont_block);
|
|
||||||
|
|
||||||
builder.build_load(accum_alloca, "load_final_acum")
|
|
||||||
}
|
|
||||||
|
|
||||||
/// List.walk : List elem, (elem -> accum -> accum), accum -> accum
|
/// List.walk : List elem, (elem -> accum -> accum), accum -> accum
|
||||||
pub fn list_walk<'a, 'ctx, 'env>(
|
pub fn list_walk<'a, 'ctx, 'env>(
|
||||||
env: &Env<'a, 'ctx, 'env>,
|
env: &Env<'a, 'ctx, 'env>,
|
||||||
|
|
|
@ -33,8 +33,6 @@ pub enum LowLevel {
|
||||||
ListKeepIf,
|
ListKeepIf,
|
||||||
ListWalk,
|
ListWalk,
|
||||||
ListWalkBackwards,
|
ListWalkBackwards,
|
||||||
ListSum,
|
|
||||||
ListProduct,
|
|
||||||
ListKeepOks,
|
ListKeepOks,
|
||||||
ListKeepErrs,
|
ListKeepErrs,
|
||||||
DictSize,
|
DictSize,
|
||||||
|
|
|
@ -657,7 +657,6 @@ pub fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[bool] {
|
||||||
ListContains => arena.alloc_slice_copy(&[borrowed, irrelevant]),
|
ListContains => arena.alloc_slice_copy(&[borrowed, irrelevant]),
|
||||||
ListWalk => arena.alloc_slice_copy(&[owned, irrelevant, owned]),
|
ListWalk => arena.alloc_slice_copy(&[owned, irrelevant, owned]),
|
||||||
ListWalkBackwards => arena.alloc_slice_copy(&[owned, irrelevant, owned]),
|
ListWalkBackwards => arena.alloc_slice_copy(&[owned, irrelevant, owned]),
|
||||||
ListSum | ListProduct => arena.alloc_slice_copy(&[borrowed]),
|
|
||||||
|
|
||||||
// TODO when we have lists with capacity (if ever)
|
// TODO when we have lists with capacity (if ever)
|
||||||
// List.append should own its first argument
|
// List.append should own its first argument
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue