From 9ec2bc7946c6618fa099a98c0708d0c349235aad Mon Sep 17 00:00:00 2001 From: satotake Date: Sat, 13 Nov 2021 06:03:18 +0000 Subject: [PATCH] Remove `takeFirst` and `takeLast` from backend --- compiler/builtins/bitcode/src/list.zig | 55 ------------------------ compiler/builtins/bitcode/src/main.zig | 2 - compiler/builtins/src/bitcode.rs | 2 - compiler/can/src/builtins.rs | 36 +++++++++++++++- compiler/gen_llvm/src/llvm/build.rs | 44 +------------------ compiler/gen_llvm/src/llvm/build_list.rs | 41 ------------------ compiler/gen_wasm/src/low_level.rs | 9 ++-- compiler/module/src/low_level.rs | 4 -- compiler/mono/src/borrow.rs | 2 - compiler/mono/src/low_level.rs | 2 - 10 files changed, 39 insertions(+), 158 deletions(-) diff --git a/compiler/builtins/bitcode/src/list.zig b/compiler/builtins/bitcode/src/list.zig index adf5f7f2bc..d284369a65 100644 --- a/compiler/builtins/bitcode/src/list.zig +++ b/compiler/builtins/bitcode/src/list.zig @@ -862,33 +862,6 @@ pub fn listSwap( return newList; } -pub fn listTakeFirst( - list: RocList, - alignment: u32, - element_width: usize, - take_count: usize, -) callconv(.C) RocList { - if (list.bytes) |source_ptr| { - if (take_count == 0) { - return RocList.empty(); - } - const in_len = list.len(); - const out_len = std.math.min(take_count, in_len); - - const output = RocList.allocate(alignment, out_len, element_width); - const target_ptr = output.bytes orelse unreachable; - - @memcpy(target_ptr, source_ptr, out_len * element_width); - - utils.decref(list.bytes, in_len * element_width, alignment); - - return output; - } else { - return RocList.empty(); - } -} - - pub fn listSublist( list: RocList, alignment: u32, @@ -926,34 +899,6 @@ pub fn listSublist( return RocList.empty(); } -pub fn listTakeLast( - list: RocList, - alignment: u32, - element_width: usize, - take_count: usize, - dec: Dec, -) callconv(.C) RocList { - if (take_count == 0) { - return RocList.empty(); - } - if (list.bytes) |source_ptr| { - const size = list.len(); - if (size <= take_count) { - return list; - } - const drop_count = size - take_count; - return listDrop( - list, - alignment, - element_width, - drop_count, - dec, - ); - } else { - return RocList.empty(); - } -} - pub fn listDrop( list: RocList, alignment: u32, diff --git a/compiler/builtins/bitcode/src/main.zig b/compiler/builtins/bitcode/src/main.zig index a3e3ffd19a..374aaa7bc5 100644 --- a/compiler/builtins/bitcode/src/main.zig +++ b/compiler/builtins/bitcode/src/main.zig @@ -45,8 +45,6 @@ comptime { exportListFn(list.listReverse, "reverse"); exportListFn(list.listSortWith, "sort_with"); exportListFn(list.listConcat, "concat"); - exportListFn(list.listTakeFirst, "take_first"); - exportListFn(list.listTakeLast, "take_last"); exportListFn(list.listSublist, "sublist"); exportListFn(list.listDrop, "drop"); exportListFn(list.listDropAt, "drop_at"); diff --git a/compiler/builtins/src/bitcode.rs b/compiler/builtins/src/bitcode.rs index 5aa5c4a526..f8ad6f920f 100644 --- a/compiler/builtins/src/bitcode.rs +++ b/compiler/builtins/src/bitcode.rs @@ -183,8 +183,6 @@ pub const LIST_CONTAINS: &str = "roc_builtins.list.contains"; pub const LIST_REPEAT: &str = "roc_builtins.list.repeat"; pub const LIST_APPEND: &str = "roc_builtins.list.append"; pub const LIST_PREPEND: &str = "roc_builtins.list.prepend"; -pub const LIST_TAKE_FIRST: &str = "roc_builtins.list.take_first"; -pub const LIST_TAKE_LAST: &str = "roc_builtins.list.take_last"; pub const LIST_SUBLIST: &str = "roc_builtins.list.sublist"; pub const LIST_DROP: &str = "roc_builtins.list.drop"; pub const LIST_DROP_AT: &str = "roc_builtins.list.drop_at"; diff --git a/compiler/can/src/builtins.rs b/compiler/can/src/builtins.rs index 27c1f38735..0c558f57cb 100644 --- a/compiler/can/src/builtins.rs +++ b/compiler/can/src/builtins.rs @@ -2020,11 +2020,13 @@ fn list_swap(symbol: Symbol, var_store: &mut VarStore) -> Def { fn list_take_first(symbol: Symbol, var_store: &mut VarStore) -> Def { let list_var = var_store.fresh(); let len_var = var_store.fresh(); + let zero = int(len_var, Variable::NATURAL, 0); let body = RunLowLevel { - op: LowLevel::ListTakeFirst, + op: LowLevel::ListSublist, args: vec![ (list_var, Var(Symbol::ARG_1)), + (len_var, zero), (len_var, Var(Symbol::ARG_2)), ], ret_var: list_var, @@ -2044,10 +2046,40 @@ fn list_take_last(symbol: Symbol, var_store: &mut VarStore) -> Def { let list_var = var_store.fresh(); let len_var = var_store.fresh(); + let zero = int(len_var, Variable::NATURAL, 0); + let bool_var = var_store.fresh(); + + let get_list_len = RunLowLevel { + op: LowLevel::ListLen, + args: vec![(list_var, Var(Symbol::ARG_1))], + ret_var: len_var, + }; + + let get_sub = RunLowLevel { + op: LowLevel::NumSubWrap, + args: vec![(len_var, get_list_len), (len_var, Var(Symbol::ARG_2))], + ret_var: len_var, + }; + + let get_start = If { + cond_var: bool_var, + branch_var: len_var, + branches: vec![( + no_region(RunLowLevel { + op: LowLevel::NumGt, + args: vec![(len_var, get_sub.clone()), (len_var, zero.clone())], + ret_var: bool_var, + }), + no_region(get_sub), + )], + final_else: Box::new(no_region(zero)), + }; + let body = RunLowLevel { - op: LowLevel::ListTakeLast, + op: LowLevel::ListSublist, args: vec![ (list_var, Var(Symbol::ARG_1)), + (len_var, get_start), (len_var, Var(Symbol::ARG_2)), ], ret_var: list_var, diff --git a/compiler/gen_llvm/src/llvm/build.rs b/compiler/gen_llvm/src/llvm/build.rs index e6a82e6ff6..dc0499ae67 100644 --- a/compiler/gen_llvm/src/llvm/build.rs +++ b/compiler/gen_llvm/src/llvm/build.rs @@ -12,8 +12,7 @@ use crate::llvm::build_list::{ list_contains, list_drop, list_drop_at, list_find_trivial_not_found, list_find_unsafe, list_get_unsafe, list_join, list_keep_errs, list_keep_if, list_keep_oks, list_len, list_map, list_map2, list_map3, list_map4, list_map_with_index, list_prepend, list_range, list_repeat, - list_reverse, list_set, list_single, list_sort_with, list_sublist, list_swap, list_take_first, - list_take_last, + list_reverse, list_set, list_single, list_sort_with, list_sublist, list_swap, }; use crate::llvm::build_str::{ empty_str, str_concat, str_count_graphemes, str_ends_with, str_from_float, str_from_int, @@ -5169,47 +5168,6 @@ fn run_low_level<'a, 'ctx, 'env>( _ => unreachable!("Invalid layout {:?} in List.swap", list_layout), } } - ListTakeFirst => { - // List.takeFirst : List elem, Nat -> List elem - debug_assert_eq!(args.len(), 2); - - let (list, list_layout) = load_symbol_and_layout(scope, &args[0]); - let original_wrapper = list.into_struct_value(); - - let count = load_symbol(scope, &args[1]); - - match list_layout { - Layout::Builtin(Builtin::EmptyList) => empty_list(env), - Layout::Builtin(Builtin::List(element_layout)) => list_take_first( - env, - original_wrapper, - count.into_int_value(), - element_layout, - ), - _ => unreachable!("Invalid layout {:?} in List.takeFirst", list_layout), - } - } - ListTakeLast => { - // List.takeLast : List elem, Nat -> List elem - debug_assert_eq!(args.len(), 2); - - let (list, list_layout) = load_symbol_and_layout(scope, &args[0]); - let original_wrapper = list.into_struct_value(); - - let count = load_symbol(scope, &args[1]); - - match list_layout { - Layout::Builtin(Builtin::EmptyList) => empty_list(env), - Layout::Builtin(Builtin::List(element_layout)) => list_take_last( - env, - layout_ids, - original_wrapper, - count.into_int_value(), - element_layout, - ), - _ => unreachable!("Invalid layout {:?} in List.takeLast", list_layout), - } - } ListSublist => { // List.sublist : List elem, { start : Nat, len : Nat } -> List elem // diff --git a/compiler/gen_llvm/src/llvm/build_list.rs b/compiler/gen_llvm/src/llvm/build_list.rs index 6695e93b83..e78fa2f765 100644 --- a/compiler/gen_llvm/src/llvm/build_list.rs +++ b/compiler/gen_llvm/src/llvm/build_list.rs @@ -297,47 +297,6 @@ pub fn list_swap<'a, 'ctx, 'env>( ) } -/// List.takeFirst : List elem, Nat -> List elem -pub fn list_take_first<'a, 'ctx, 'env>( - env: &Env<'a, 'ctx, 'env>, - original_wrapper: StructValue<'ctx>, - count: IntValue<'ctx>, - element_layout: &Layout<'a>, -) -> BasicValueEnum<'ctx> { - call_bitcode_fn_returns_list( - env, - &[ - pass_list_cc(env, original_wrapper.into()), - env.alignment_intvalue(element_layout), - layout_width(env, element_layout), - count.into(), - ], - bitcode::LIST_TAKE_FIRST, - ) -} - -/// List.takeLast : List elem, Nat -> List elem -pub fn list_take_last<'a, 'ctx, 'env>( - env: &Env<'a, 'ctx, 'env>, - layout_ids: &mut LayoutIds<'a>, - original_wrapper: StructValue<'ctx>, - count: IntValue<'ctx>, - element_layout: &Layout<'a>, -) -> BasicValueEnum<'ctx> { - let dec_element_fn = build_dec_wrapper(env, layout_ids, element_layout); - call_bitcode_fn_returns_list( - env, - &[ - pass_list_cc(env, original_wrapper.into()), - env.alignment_intvalue(element_layout), - layout_width(env, element_layout), - count.into(), - dec_element_fn.as_global_value().as_pointer_value().into(), - ], - bitcode::LIST_TAKE_LAST, - ) -} - /// List.sublist : List elem, { start : Nat, len : Nat } -> List elem pub fn list_sublist<'a, 'ctx, 'env>( env: &Env<'a, 'ctx, 'env>, diff --git a/compiler/gen_wasm/src/low_level.rs b/compiler/gen_wasm/src/low_level.rs index ffb8ce1af8..2cf05a7a08 100644 --- a/compiler/gen_wasm/src/low_level.rs +++ b/compiler/gen_wasm/src/low_level.rs @@ -33,11 +33,10 @@ pub fn build_call_low_level<'a>( | ListGetUnsafe | ListSet | ListSingle | ListRepeat | ListReverse | ListConcat | ListContains | ListAppend | ListPrepend | ListJoin | ListRange | ListMap | ListMap2 | ListMap3 | ListMap4 | ListMapWithIndex | ListKeepIf | ListWalk | ListWalkUntil - | ListWalkBackwards | ListKeepOks | ListKeepErrs | ListSortWith | ListTakeFirst - | ListTakeLast | ListSublist | ListDrop | ListDropAt | ListSwap | ListAny - | ListFindUnsafe | DictSize | DictEmpty | DictInsert | DictRemove | DictContains - | DictGetUnsafe | DictKeys | DictValues | DictUnion | DictIntersection | DictDifference - | DictWalk | SetFromList => { + | ListWalkBackwards | ListKeepOks | ListKeepErrs | ListSortWith | ListSublist + | ListDrop | ListDropAt | ListSwap | ListAny | ListFindUnsafe | DictSize | DictEmpty + | DictInsert | DictRemove | DictContains | DictGetUnsafe | DictKeys | DictValues + | DictUnion | DictIntersection | DictDifference | DictWalk | SetFromList => { return NotImplemented; } diff --git a/compiler/module/src/low_level.rs b/compiler/module/src/low_level.rs index 920e217fd9..dd9a4f020b 100644 --- a/compiler/module/src/low_level.rs +++ b/compiler/module/src/low_level.rs @@ -43,8 +43,6 @@ pub enum LowLevel { ListKeepOks, ListKeepErrs, ListSortWith, - ListTakeFirst, - ListTakeLast, ListSublist, ListDrop, ListDropAt, @@ -137,8 +135,6 @@ macro_rules! first_order { | ListLen | ListGetUnsafe | ListSet - | ListTakeFirst - | ListTakeLast | ListSublist | ListDrop | ListDropAt diff --git a/compiler/mono/src/borrow.rs b/compiler/mono/src/borrow.rs index f1724b10fa..045dfb38cb 100644 --- a/compiler/mono/src/borrow.rs +++ b/compiler/mono/src/borrow.rs @@ -966,8 +966,6 @@ pub fn lowlevel_borrow_signature(arena: &Bump, op: LowLevel) -> &[bool] { // TODO when we have lists with capacity (if ever) // List.append should own its first argument ListAppend => arena.alloc_slice_copy(&[owned, owned]), - ListTakeFirst => arena.alloc_slice_copy(&[owned, irrelevant]), - ListTakeLast => arena.alloc_slice_copy(&[owned, irrelevant]), ListSublist => arena.alloc_slice_copy(&[owned, irrelevant, irrelevant]), ListDrop => arena.alloc_slice_copy(&[owned, irrelevant]), ListDropAt => arena.alloc_slice_copy(&[owned, irrelevant]), diff --git a/compiler/mono/src/low_level.rs b/compiler/mono/src/low_level.rs index 8d26fb187f..2139ea59aa 100644 --- a/compiler/mono/src/low_level.rs +++ b/compiler/mono/src/low_level.rs @@ -100,8 +100,6 @@ enum FirstOrder { ListLen, ListGetUnsafe, ListSet, - ListTakeFirst, - ListTakeLast, ListSublist, ListDrop, ListDropAt,