diff --git a/compiler/gen_dev/src/lib.rs b/compiler/gen_dev/src/lib.rs index d11fb50dc4..5ef03a3a42 100644 --- a/compiler/gen_dev/src/lib.rs +++ b/compiler/gen_dev/src/lib.rs @@ -786,7 +786,6 @@ where CallType::ByName { .. } => {} CallType::LowLevel { .. } => {} CallType::HigherOrderLowLevel { .. } => {} - CallType::NewHigherOrderLowLevel { .. } => {} CallType::Foreign { .. } => {} } } diff --git a/compiler/gen_llvm/src/llvm/build.rs b/compiler/gen_llvm/src/llvm/build.rs index 48c4c71eea..eada14eeb7 100644 --- a/compiler/gen_llvm/src/llvm/build.rs +++ b/compiler/gen_llvm/src/llvm/build.rs @@ -952,32 +952,6 @@ pub fn build_exp_call<'a, 'ctx, 'env>( } CallType::HigherOrderLowLevel { - op, - function_owns_closure_data, - specialization_id, - arg_layouts, - ret_layout, - .. - } => { - let bytes = specialization_id.to_bytes(); - let callee_var = CalleeSpecVar(&bytes); - let func_spec = func_spec_solutions.callee_spec(callee_var).unwrap(); - - run_higher_order_low_level( - env, - layout_ids, - scope, - layout, - *op, - func_spec, - arg_layouts, - ret_layout, - *function_owns_closure_data, - arguments, - ) - } - - CallType::NewHigherOrderLowLevel { op, function_owns_closure_data, specialization_id, @@ -4895,451 +4869,6 @@ fn run_new_higher_order_low_level<'a, 'ctx, 'env>( } } -#[allow(clippy::too_many_arguments)] -fn run_higher_order_low_level<'a, 'ctx, 'env>( - env: &Env<'a, 'ctx, 'env>, - layout_ids: &mut LayoutIds<'a>, - scope: &Scope<'a, 'ctx>, - return_layout: &Layout<'a>, - op: LowLevel, - func_spec: FuncSpec, - argument_layouts: &[Layout<'a>], - result_layout: &Layout<'a>, - function_owns_closure_data: bool, - args: &[Symbol], -) -> BasicValueEnum<'ctx> { - use LowLevel::*; - - debug_assert!(op.is_higher_order()); - - // macros because functions cause lifetime issues related to the `env` or `layout_ids` - macro_rules! passed_function_at_index { - ($index:expr) => {{ - let function_symbol = args[$index]; - - function_value_by_func_spec( - env, - func_spec, - function_symbol, - argument_layouts, - return_layout, - ) - }}; - } - - macro_rules! list_walk { - ($variant:expr) => {{ - let (list, list_layout) = load_symbol_and_layout(scope, &args[0]); - - let (default, default_layout) = load_symbol_and_layout(scope, &args[1]); - - let function = passed_function_at_index!(2); - - let (closure, closure_layout) = load_symbol_and_lambda_set(scope, &args[3]); - - match list_layout { - Layout::Builtin(Builtin::EmptyList) => default, - Layout::Builtin(Builtin::List(element_layout)) => { - let argument_layouts = &[*default_layout, **element_layout]; - - let roc_function_call = roc_function_call( - env, - layout_ids, - function, - closure, - closure_layout, - function_owns_closure_data, - argument_layouts, - ); - - crate::llvm::build_list::list_walk_generic( - env, - layout_ids, - roc_function_call, - result_layout, - list, - element_layout, - default, - default_layout, - $variant, - ) - } - _ => unreachable!("invalid list layout"), - } - }}; - } - match op { - ListMap => { - // List.map : List before, (before -> after) -> List after - debug_assert_eq!(args.len(), 3); - - let (list, list_layout) = load_symbol_and_layout(scope, &args[0]); - - let function = passed_function_at_index!(1); - - let (closure, closure_layout) = load_symbol_and_lambda_set(scope, &args[2]); - - match (list_layout, return_layout) { - (Layout::Builtin(Builtin::EmptyList), _) => empty_list(env), - ( - Layout::Builtin(Builtin::List(element_layout)), - Layout::Builtin(Builtin::List(result_layout)), - ) => { - let argument_layouts = &[**element_layout]; - - let roc_function_call = roc_function_call( - env, - layout_ids, - function, - closure, - closure_layout, - function_owns_closure_data, - argument_layouts, - ); - - list_map(env, roc_function_call, list, element_layout, result_layout) - } - _ => unreachable!("invalid list layout"), - } - } - ListMap2 => { - debug_assert_eq!(args.len(), 4); - - let (list1, list1_layout) = load_symbol_and_layout(scope, &args[0]); - let (list2, list2_layout) = load_symbol_and_layout(scope, &args[1]); - - let function = passed_function_at_index!(2); - let (closure, closure_layout) = load_symbol_and_lambda_set(scope, &args[3]); - - match (list1_layout, list2_layout, return_layout) { - ( - Layout::Builtin(Builtin::List(element1_layout)), - Layout::Builtin(Builtin::List(element2_layout)), - Layout::Builtin(Builtin::List(result_layout)), - ) => { - let argument_layouts = &[**element1_layout, **element2_layout]; - - let roc_function_call = roc_function_call( - env, - layout_ids, - function, - closure, - closure_layout, - function_owns_closure_data, - argument_layouts, - ); - - list_map2( - env, - layout_ids, - roc_function_call, - list1, - list2, - element1_layout, - element2_layout, - result_layout, - ) - } - (Layout::Builtin(Builtin::EmptyList), _, _) - | (_, Layout::Builtin(Builtin::EmptyList), _) => empty_list(env), - _ => unreachable!("invalid list layout"), - } - } - ListMap3 => { - debug_assert_eq!(args.len(), 5); - - let (list1, list1_layout) = load_symbol_and_layout(scope, &args[0]); - let (list2, list2_layout) = load_symbol_and_layout(scope, &args[1]); - let (list3, list3_layout) = load_symbol_and_layout(scope, &args[2]); - - let function = passed_function_at_index!(3); - let (closure, closure_layout) = load_symbol_and_lambda_set(scope, &args[4]); - - match (list1_layout, list2_layout, list3_layout, return_layout) { - ( - Layout::Builtin(Builtin::List(element1_layout)), - Layout::Builtin(Builtin::List(element2_layout)), - Layout::Builtin(Builtin::List(element3_layout)), - Layout::Builtin(Builtin::List(result_layout)), - ) => { - let argument_layouts = - &[**element1_layout, **element2_layout, **element3_layout]; - - let roc_function_call = roc_function_call( - env, - layout_ids, - function, - closure, - closure_layout, - function_owns_closure_data, - argument_layouts, - ); - - list_map3( - env, - layout_ids, - roc_function_call, - list1, - list2, - list3, - element1_layout, - element2_layout, - element3_layout, - result_layout, - ) - } - (Layout::Builtin(Builtin::EmptyList), _, _, _) - | (_, Layout::Builtin(Builtin::EmptyList), _, _) - | (_, _, Layout::Builtin(Builtin::EmptyList), _) => empty_list(env), - _ => unreachable!("invalid list layout"), - } - } - ListMapWithIndex => { - // List.mapWithIndex : List before, (Nat, before -> after) -> List after - debug_assert_eq!(args.len(), 3); - - let (list, list_layout) = load_symbol_and_layout(scope, &args[0]); - - let function = passed_function_at_index!(1); - - let (closure, closure_layout) = load_symbol_and_lambda_set(scope, &args[2]); - - match (list_layout, return_layout) { - (Layout::Builtin(Builtin::EmptyList), _) => empty_list(env), - ( - Layout::Builtin(Builtin::List(element_layout)), - Layout::Builtin(Builtin::List(result_layout)), - ) => { - let argument_layouts = &[Layout::Builtin(Builtin::Usize), **element_layout]; - - let roc_function_call = roc_function_call( - env, - layout_ids, - function, - closure, - closure_layout, - function_owns_closure_data, - argument_layouts, - ); - - list_map_with_index(env, roc_function_call, list, element_layout, result_layout) - } - _ => unreachable!("invalid list layout"), - } - } - ListKeepIf => { - // List.keepIf : List elem, (elem -> Bool) -> List elem - debug_assert_eq!(args.len(), 3); - - let (list, list_layout) = load_symbol_and_layout(scope, &args[0]); - - let function = passed_function_at_index!(1); - - let (closure, closure_layout) = load_symbol_and_lambda_set(scope, &args[2]); - - match list_layout { - Layout::Builtin(Builtin::EmptyList) => empty_list(env), - Layout::Builtin(Builtin::List(element_layout)) => { - let argument_layouts = &[**element_layout]; - - let roc_function_call = roc_function_call( - env, - layout_ids, - function, - closure, - closure_layout, - function_owns_closure_data, - argument_layouts, - ); - - list_keep_if(env, layout_ids, roc_function_call, list, element_layout) - } - _ => unreachable!("invalid list layout"), - } - } - ListKeepOks => { - // List.keepOks : List before, (before -> Result after *) -> List after - debug_assert_eq!(args.len(), 3); - - let (list, list_layout) = load_symbol_and_layout(scope, &args[0]); - - let function = passed_function_at_index!(1); - - let (closure, closure_layout) = load_symbol_and_lambda_set(scope, &args[2]); - - match (list_layout, return_layout) { - (_, Layout::Builtin(Builtin::EmptyList)) - | (Layout::Builtin(Builtin::EmptyList), _) => empty_list(env), - ( - Layout::Builtin(Builtin::List(before_layout)), - Layout::Builtin(Builtin::List(after_layout)), - ) => { - let argument_layouts = &[**before_layout]; - - let roc_function_call = roc_function_call( - env, - layout_ids, - function, - closure, - closure_layout, - function_owns_closure_data, - argument_layouts, - ); - - list_keep_oks( - env, - layout_ids, - roc_function_call, - result_layout, - list, - before_layout, - after_layout, - ) - } - (other1, other2) => { - unreachable!("invalid list layouts:\n{:?}\n{:?}", other1, other2) - } - } - } - ListKeepErrs => { - // List.keepErrs : List before, (before -> Result * after) -> List after - debug_assert_eq!(args.len(), 3); - - let (list, list_layout) = load_symbol_and_layout(scope, &args[0]); - - let function = passed_function_at_index!(1); - - let (closure, closure_layout) = load_symbol_and_lambda_set(scope, &args[2]); - - match (list_layout, return_layout) { - (_, Layout::Builtin(Builtin::EmptyList)) - | (Layout::Builtin(Builtin::EmptyList), _) => empty_list(env), - ( - Layout::Builtin(Builtin::List(before_layout)), - Layout::Builtin(Builtin::List(after_layout)), - ) => { - let argument_layouts = &[**before_layout]; - - let roc_function_call = roc_function_call( - env, - layout_ids, - function, - closure, - closure_layout, - function_owns_closure_data, - argument_layouts, - ); - - list_keep_errs( - env, - layout_ids, - roc_function_call, - result_layout, - list, - before_layout, - after_layout, - ) - } - (other1, other2) => { - unreachable!("invalid list layouts:\n{:?}\n{:?}", other1, other2) - } - } - } - ListWalk => { - list_walk!(crate::llvm::build_list::ListWalk::Walk) - } - ListWalkUntil => { - list_walk!(crate::llvm::build_list::ListWalk::WalkUntil) - } - ListWalkBackwards => { - list_walk!(crate::llvm::build_list::ListWalk::WalkBackwards) - } - ListSortWith => { - // List.sortWith : List a, (a, a -> Ordering) -> List a - debug_assert_eq!(args.len(), 3); - - let (list, list_layout) = load_symbol_and_layout(scope, &args[0]); - - let function = passed_function_at_index!(1); - - let (closure, closure_layout) = load_symbol_and_lambda_set(scope, &args[2]); - - match list_layout { - Layout::Builtin(Builtin::EmptyList) => empty_list(env), - Layout::Builtin(Builtin::List(element_layout)) => { - use crate::llvm::bitcode::build_compare_wrapper; - - let argument_layouts = &[**element_layout, **element_layout]; - - let compare_wrapper = - build_compare_wrapper(env, function, closure_layout, element_layout) - .as_global_value() - .as_pointer_value(); - - let roc_function_call = roc_function_call( - env, - layout_ids, - function, - closure, - closure_layout, - function_owns_closure_data, - argument_layouts, - ); - - list_sort_with( - env, - roc_function_call, - compare_wrapper, - list, - element_layout, - ) - } - _ => unreachable!("invalid list layout"), - } - } - DictWalk => { - debug_assert_eq!(args.len(), 4); - - let (dict, dict_layout) = load_symbol_and_layout(scope, &args[0]); - let (default, default_layout) = load_symbol_and_layout(scope, &args[1]); - let function = passed_function_at_index!(2); - let (closure, closure_layout) = load_symbol_and_lambda_set(scope, &args[3]); - - match dict_layout { - Layout::Builtin(Builtin::EmptyDict) => { - // no elements, so `key` is not in here - panic!("key type unknown") - } - Layout::Builtin(Builtin::Dict(key_layout, value_layout)) => { - let argument_layouts = &[*default_layout, **key_layout, **value_layout]; - - let roc_function_call = roc_function_call( - env, - layout_ids, - function, - closure, - closure_layout, - function_owns_closure_data, - argument_layouts, - ); - - dict_walk( - env, - roc_function_call, - dict, - default, - key_layout, - value_layout, - default_layout, - ) - } - _ => unreachable!("invalid dict layout"), - } - } - _ => unreachable!(), - } -} - // TODO: Fix me! I should be different in tests vs. user code! fn expect_failed() { panic!("An expectation failed!"); diff --git a/compiler/mono/src/alias_analysis.rs b/compiler/mono/src/alias_analysis.rs index 43abd3ed11..13485868d1 100644 --- a/compiler/mono/src/alias_analysis.rs +++ b/compiler/mono/src/alias_analysis.rs @@ -605,7 +605,7 @@ fn call_spec( *update_mode, call.arguments, ), - NewHigherOrderLowLevel { + HigherOrderLowLevel { specialization_id, closure_env_layout, op, @@ -798,223 +798,6 @@ fn call_spec( let result_type = layout_spec(builder, layout)?; - builder.add_unknown_with(block, &arguments, result_type) - } - HigherOrderLowLevel { - specialization_id, - closure_env_layout, - op, - arg_layouts, - ret_layout, - .. - } => { - let array = specialization_id.to_bytes(); - let spec_var = CalleeSpecVar(&array); - - let symbol = { - use roc_module::low_level::LowLevel::*; - - match op { - ListMap | ListMapWithIndex => call.arguments[1], - ListMap2 => call.arguments[2], - ListMap3 => call.arguments[3], - ListWalk | ListWalkUntil | ListWalkBackwards | DictWalk => call.arguments[2], - ListKeepIf | ListKeepOks | ListKeepErrs => call.arguments[1], - ListSortWith => call.arguments[1], - _ => unreachable!(), - } - }; - - let it = arg_layouts.iter().copied(); - let bytes = func_name_bytes_help(symbol, it, *ret_layout); - let name = FuncName(&bytes); - let module = MOD_APP; - - { - use roc_module::low_level::LowLevel::*; - - match op { - DictWalk => { - let dict = env.symbols[&call.arguments[0]]; - let state = env.symbols[&call.arguments[1]]; - let closure_env = env.symbols[&call.arguments[3]]; - - let bag = builder.add_get_tuple_field(block, dict, DICT_BAG_INDEX)?; - let _cell = builder.add_get_tuple_field(block, dict, DICT_CELL_INDEX)?; - - let first = builder.add_bag_get(block, bag)?; - - let key = builder.add_get_tuple_field(block, first, 0)?; - let val = builder.add_get_tuple_field(block, first, 1)?; - - let argument = if closure_env_layout.is_none() { - builder.add_make_tuple(block, &[state, key, val])? - } else { - builder.add_make_tuple(block, &[state, key, val, closure_env])? - }; - builder.add_call(block, spec_var, module, name, argument)?; - } - - ListWalk | ListWalkBackwards | ListWalkUntil => { - let list = env.symbols[&call.arguments[0]]; - let state = env.symbols[&call.arguments[1]]; - let closure_env = env.symbols[&call.arguments[3]]; - - let bag = builder.add_get_tuple_field(block, list, LIST_BAG_INDEX)?; - let _cell = builder.add_get_tuple_field(block, list, LIST_CELL_INDEX)?; - - let first = builder.add_bag_get(block, bag)?; - - let argument = if closure_env_layout.is_none() { - builder.add_make_tuple(block, &[state, first])? - } else { - builder.add_make_tuple(block, &[state, first, closure_env])? - }; - builder.add_call(block, spec_var, module, name, argument)?; - } - - ListMapWithIndex => { - let list = env.symbols[&call.arguments[0]]; - let closure_env = env.symbols[&call.arguments[2]]; - - let bag = builder.add_get_tuple_field(block, list, LIST_BAG_INDEX)?; - let _cell = builder.add_get_tuple_field(block, list, LIST_CELL_INDEX)?; - - let first = builder.add_bag_get(block, bag)?; - let index = builder.add_make_tuple(block, &[])?; - - let argument = if closure_env_layout.is_none() { - builder.add_make_tuple(block, &[index, first])? - } else { - builder.add_make_tuple(block, &[index, first, closure_env])? - }; - builder.add_call(block, spec_var, module, name, argument)?; - } - - ListMap => { - let list1 = env.symbols[&call.arguments[0]]; - let closure_env = env.symbols[&call.arguments[2]]; - - let bag1 = builder.add_get_tuple_field(block, list1, LIST_BAG_INDEX)?; - let _cell1 = builder.add_get_tuple_field(block, list1, LIST_CELL_INDEX)?; - - let elem1 = builder.add_bag_get(block, bag1)?; - - let argument = if closure_env_layout.is_none() { - builder.add_make_tuple(block, &[elem1])? - } else { - builder.add_make_tuple(block, &[elem1, closure_env])? - }; - builder.add_call(block, spec_var, module, name, argument)?; - } - - ListSortWith => { - let list1 = env.symbols[&call.arguments[0]]; - let closure_env = env.symbols[&call.arguments[2]]; - - let bag1 = builder.add_get_tuple_field(block, list1, LIST_BAG_INDEX)?; - let _cell1 = builder.add_get_tuple_field(block, list1, LIST_CELL_INDEX)?; - - let elem1 = builder.add_bag_get(block, bag1)?; - - let argument = if closure_env_layout.is_none() { - builder.add_make_tuple(block, &[elem1, elem1])? - } else { - builder.add_make_tuple(block, &[elem1, elem1, closure_env])? - }; - builder.add_call(block, spec_var, module, name, argument)?; - } - - ListMap2 => { - let list1 = env.symbols[&call.arguments[0]]; - let list2 = env.symbols[&call.arguments[1]]; - let closure_env = env.symbols[&call.arguments[3]]; - - let bag1 = builder.add_get_tuple_field(block, list1, LIST_BAG_INDEX)?; - let _cell1 = builder.add_get_tuple_field(block, list1, LIST_CELL_INDEX)?; - let elem1 = builder.add_bag_get(block, bag1)?; - - let bag2 = builder.add_get_tuple_field(block, list2, LIST_BAG_INDEX)?; - let _cell2 = builder.add_get_tuple_field(block, list2, LIST_CELL_INDEX)?; - let elem2 = builder.add_bag_get(block, bag2)?; - - let argument = if closure_env_layout.is_none() { - builder.add_make_tuple(block, &[elem1, elem2])? - } else { - builder.add_make_tuple(block, &[elem1, elem2, closure_env])? - }; - builder.add_call(block, spec_var, module, name, argument)?; - } - - ListMap3 => { - let list1 = env.symbols[&call.arguments[0]]; - let list2 = env.symbols[&call.arguments[1]]; - let list3 = env.symbols[&call.arguments[2]]; - let closure_env = env.symbols[&call.arguments[4]]; - - let bag1 = builder.add_get_tuple_field(block, list1, LIST_BAG_INDEX)?; - let _cell1 = builder.add_get_tuple_field(block, list1, LIST_CELL_INDEX)?; - let elem1 = builder.add_bag_get(block, bag1)?; - - let bag2 = builder.add_get_tuple_field(block, list2, LIST_BAG_INDEX)?; - let _cell2 = builder.add_get_tuple_field(block, list2, LIST_CELL_INDEX)?; - let elem2 = builder.add_bag_get(block, bag2)?; - - let bag3 = builder.add_get_tuple_field(block, list3, LIST_BAG_INDEX)?; - let _cell3 = builder.add_get_tuple_field(block, list3, LIST_CELL_INDEX)?; - let elem3 = builder.add_bag_get(block, bag3)?; - - let argument = if closure_env_layout.is_none() { - builder.add_make_tuple(block, &[elem1, elem2, elem3])? - } else { - builder.add_make_tuple(block, &[elem1, elem2, elem3, closure_env])? - }; - builder.add_call(block, spec_var, module, name, argument)?; - } - - ListKeepIf | ListKeepOks | ListKeepErrs => { - let list = env.symbols[&call.arguments[0]]; - let closure_env = env.symbols[&call.arguments[2]]; - - let bag = builder.add_get_tuple_field(block, list, LIST_BAG_INDEX)?; - // let _cell = builder.add_get_tuple_field(block, list, LIST_CELL_INDEX)?; - - let first = builder.add_bag_get(block, bag)?; - - let argument = if closure_env_layout.is_none() { - builder.add_make_tuple(block, &[first])? - } else { - builder.add_make_tuple(block, &[first, closure_env])? - }; - let result = builder.add_call(block, spec_var, module, name, argument)?; - let unit = builder.add_tuple_type(&[])?; - builder.add_unknown_with(block, &[result], unit)?; - } - - _ => { - // fake a call to the function argument - // to make sure the function is specialized - - // very invalid - let arg_value_id = build_tuple_value(builder, env, block, &[])?; - - builder.add_call(block, spec_var, module, name, arg_value_id)?; - } - } - } - - // TODO overly pessimstic - // filter_map because one of the arguments is a function name, which - // is not defined in the env - let arguments: Vec<_> = call - .arguments - .iter() - .filter_map(|symbol| env.symbols.get(symbol)) - .copied() - .collect(); - - let result_type = layout_spec(builder, layout)?; - builder.add_unknown_with(block, &arguments, result_type) } } diff --git a/compiler/mono/src/borrow.rs b/compiler/mono/src/borrow.rs index 9097ca8040..b337c5f87f 100644 --- a/compiler/mono/src/borrow.rs +++ b/compiler/mono/src/borrow.rs @@ -593,7 +593,7 @@ impl<'a> BorrowInfState<'a> { self.own_args_using_bools(arguments, ps); } - NewHigherOrderLowLevel { + HigherOrderLowLevel { op, arg_layouts, ret_layout, @@ -678,138 +678,6 @@ impl<'a> BorrowInfState<'a> { } } - HigherOrderLowLevel { - op, - arg_layouts, - ret_layout, - .. - } => { - use roc_module::low_level::LowLevel::*; - - debug_assert!(op.is_higher_order()); - - let closure_layout = ProcLayout { - arguments: arg_layouts, - result: *ret_layout, - }; - - match op { - ListMap | ListKeepIf | ListKeepOks | ListKeepErrs => { - match param_map.get_symbol(arguments[1], closure_layout) { - Some(function_ps) => { - // own the list if the function wants to own the element - if !function_ps[0].borrow { - self.own_var(arguments[0]); - } - - // own the closure environment if the function needs to own it - if let Some(false) = function_ps.get(1).map(|p| p.borrow) { - self.own_var(arguments[2]); - } - } - None => unreachable!(), - } - } - ListMapWithIndex => { - match param_map.get_symbol(arguments[1], closure_layout) { - Some(function_ps) => { - // own the list if the function wants to own the element - if !function_ps[1].borrow { - self.own_var(arguments[0]); - } - - // own the closure environment if the function needs to own it - if let Some(false) = function_ps.get(2).map(|p| p.borrow) { - self.own_var(arguments[2]); - } - } - None => unreachable!(), - } - } - ListMap2 => match param_map.get_symbol(arguments[2], closure_layout) { - Some(function_ps) => { - // own the lists if the function wants to own the element - if !function_ps[0].borrow { - self.own_var(arguments[0]); - } - - if !function_ps[1].borrow { - self.own_var(arguments[1]); - } - - // own the closure environment if the function needs to own it - if let Some(false) = function_ps.get(2).map(|p| p.borrow) { - self.own_var(arguments[3]); - } - } - None => unreachable!(), - }, - ListMap3 => match param_map.get_symbol(arguments[3], closure_layout) { - Some(function_ps) => { - // own the lists if the function wants to own the element - if !function_ps[0].borrow { - self.own_var(arguments[0]); - } - if !function_ps[1].borrow { - self.own_var(arguments[1]); - } - if !function_ps[2].borrow { - self.own_var(arguments[2]); - } - - // own the closure environment if the function needs to own it - if let Some(false) = function_ps.get(3).map(|p| p.borrow) { - self.own_var(arguments[4]); - } - } - None => unreachable!(), - }, - ListSortWith => { - match param_map.get_symbol(arguments[1], closure_layout) { - Some(function_ps) => { - // always own the input list - self.own_var(arguments[0]); - - // own the closure environment if the function needs to own it - if let Some(false) = function_ps.get(2).map(|p| p.borrow) { - self.own_var(arguments[2]); - } - } - None => unreachable!(), - } - } - ListWalk | ListWalkUntil | ListWalkBackwards | DictWalk => { - match param_map.get_symbol(arguments[2], closure_layout) { - Some(function_ps) => { - // own the default value if the function wants to own it - if !function_ps[0].borrow { - self.own_var(arguments[1]); - } - - // own the data structure if the function wants to own the element - if !function_ps[1].borrow { - self.own_var(arguments[0]); - } - - // own the closure environment if the function needs to own it - if let Some(false) = function_ps.get(2).map(|p| p.borrow) { - self.own_var(arguments[3]); - } - } - None => unreachable!(), - } - } - _ => { - // very unsure what demand RunLowLevel should place upon its arguments - self.own_var(z); - - let ps = lowlevel_borrow_signature(self.arena, *op); - - self.own_args_using_bools(arguments, ps); - } - } - } - Foreign { .. } => { // very unsure what demand ForeignCall should place upon its arguments self.own_var(z); @@ -1156,7 +1024,6 @@ fn call_info_call<'a>(call: &crate::ir::Call<'a>, info: &mut CallInfo<'a>) { Foreign { .. } => {} LowLevel { .. } => {} HigherOrderLowLevel { .. } => {} - NewHigherOrderLowLevel { .. } => {} } } diff --git a/compiler/mono/src/inc_dec.rs b/compiler/mono/src/inc_dec.rs index 195ad255c0..577dd3790c 100644 --- a/compiler/mono/src/inc_dec.rs +++ b/compiler/mono/src/inc_dec.rs @@ -463,7 +463,7 @@ impl<'a> Context<'a> { &*self.arena.alloc(Stmt::Let(z, v, l, b)) } - NewHigherOrderLowLevel { + HigherOrderLowLevel { op, closure_env_layout, specialization_id, @@ -620,222 +620,6 @@ impl<'a> Context<'a> { } } - HigherOrderLowLevel { - op, - closure_env_layout, - specialization_id, - arg_layouts, - ret_layout, - .. - } => { - macro_rules! create_call { - ($borrows:expr) => { - Expr::Call(crate::ir::Call { - call_type: if let Some(OWNED) = $borrows.map(|p| p.borrow) { - HigherOrderLowLevel { - op: *op, - closure_env_layout: *closure_env_layout, - function_owns_closure_data: true, - specialization_id: *specialization_id, - arg_layouts, - ret_layout: *ret_layout, - } - } else { - call_type - }, - arguments, - }) - }; - } - - macro_rules! decref_if_owned { - ($borrows:expr, $argument:expr, $stmt:expr) => { - if !$borrows { - self.arena.alloc(Stmt::Refcounting( - ModifyRc::DecRef($argument), - self.arena.alloc($stmt), - )) - } else { - $stmt - } - }; - } - - const FUNCTION: bool = BORROWED; - const CLOSURE_DATA: bool = BORROWED; - - let function_layout = ProcLayout { - arguments: arg_layouts, - result: *ret_layout, - }; - - match op { - roc_module::low_level::LowLevel::ListMap - | roc_module::low_level::LowLevel::ListKeepIf - | roc_module::low_level::LowLevel::ListKeepOks - | roc_module::low_level::LowLevel::ListKeepErrs => { - match self.param_map.get_symbol(arguments[1], function_layout) { - Some(function_ps) => { - let borrows = [function_ps[0].borrow, FUNCTION, CLOSURE_DATA]; - - let b = self.add_dec_after_lowlevel( - arguments, - &borrows, - b, - b_live_vars, - ); - - // if the list is owned, then all elements have been consumed, but not the list itself - let b = decref_if_owned!(function_ps[0].borrow, arguments[0], b); - - let v = create_call!(function_ps.get(1)); - - &*self.arena.alloc(Stmt::Let(z, v, l, b)) - } - None => unreachable!(), - } - } - roc_module::low_level::LowLevel::ListMapWithIndex => { - match self.param_map.get_symbol(arguments[1], function_layout) { - Some(function_ps) => { - let borrows = [function_ps[1].borrow, FUNCTION, CLOSURE_DATA]; - - let b = self.add_dec_after_lowlevel( - arguments, - &borrows, - b, - b_live_vars, - ); - - let b = decref_if_owned!(function_ps[1].borrow, arguments[0], b); - - let v = create_call!(function_ps.get(2)); - - &*self.arena.alloc(Stmt::Let(z, v, l, b)) - } - None => unreachable!(), - } - } - roc_module::low_level::LowLevel::ListMap2 => { - match self.param_map.get_symbol(arguments[2], function_layout) { - Some(function_ps) => { - let borrows = [ - function_ps[0].borrow, - function_ps[1].borrow, - FUNCTION, - CLOSURE_DATA, - ]; - - let b = self.add_dec_after_lowlevel( - arguments, - &borrows, - b, - b_live_vars, - ); - - let b = decref_if_owned!(function_ps[0].borrow, arguments[0], b); - let b = decref_if_owned!(function_ps[1].borrow, arguments[1], b); - - let v = create_call!(function_ps.get(2)); - - &*self.arena.alloc(Stmt::Let(z, v, l, b)) - } - None => unreachable!(), - } - } - roc_module::low_level::LowLevel::ListMap3 => { - match self.param_map.get_symbol(arguments[3], function_layout) { - Some(function_ps) => { - let borrows = [ - function_ps[0].borrow, - function_ps[1].borrow, - function_ps[2].borrow, - FUNCTION, - CLOSURE_DATA, - ]; - - let b = self.add_dec_after_lowlevel( - arguments, - &borrows, - b, - b_live_vars, - ); - - let b = decref_if_owned!(function_ps[0].borrow, arguments[0], b); - let b = decref_if_owned!(function_ps[1].borrow, arguments[1], b); - let b = decref_if_owned!(function_ps[2].borrow, arguments[2], b); - - let v = create_call!(function_ps.get(3)); - - &*self.arena.alloc(Stmt::Let(z, v, l, b)) - } - None => unreachable!(), - } - } - roc_module::low_level::LowLevel::ListSortWith => { - match self.param_map.get_symbol(arguments[1], function_layout) { - Some(function_ps) => { - let borrows = [OWNED, FUNCTION, CLOSURE_DATA]; - - let b = self.add_dec_after_lowlevel( - arguments, - &borrows, - b, - b_live_vars, - ); - - let v = create_call!(function_ps.get(2)); - - &*self.arena.alloc(Stmt::Let(z, v, l, b)) - } - None => unreachable!(), - } - } - roc_module::low_level::LowLevel::ListWalk - | roc_module::low_level::LowLevel::ListWalkUntil - | roc_module::low_level::LowLevel::ListWalkBackwards - | roc_module::low_level::LowLevel::DictWalk => { - match self.param_map.get_symbol(arguments[2], function_layout) { - Some(function_ps) => { - // borrow data structure based on first argument of the folded function - // borrow the default based on second argument of the folded function - let borrows = [ - function_ps[1].borrow, - function_ps[0].borrow, - FUNCTION, - CLOSURE_DATA, - ]; - - let b = self.add_dec_after_lowlevel( - arguments, - &borrows, - b, - b_live_vars, - ); - - let b = decref_if_owned!(function_ps[1].borrow, arguments[0], b); - - let v = create_call!(function_ps.get(2)); - - &*self.arena.alloc(Stmt::Let(z, v, l, b)) - } - None => unreachable!(), - } - } - _ => { - let ps = crate::borrow::lowlevel_borrow_signature(self.arena, *op); - let b = self.add_dec_after_lowlevel(arguments, ps, b, b_live_vars); - - let v = Expr::Call(crate::ir::Call { - call_type, - arguments, - }); - - &*self.arena.alloc(Stmt::Let(z, v, l, b)) - } - } - } - Foreign { .. } => { let ps = crate::borrow::foreign_borrow_signature(self.arena, arguments.len()); let b = self.add_dec_after_lowlevel(arguments, ps, b, b_live_vars); diff --git a/compiler/mono/src/ir.rs b/compiler/mono/src/ir.rs index 9f3a61738b..684a843c38 100644 --- a/compiler/mono/src/ir.rs +++ b/compiler/mono/src/ir.rs @@ -1050,13 +1050,6 @@ impl<'a> Call<'a> { .text(format!("lowlevel {:?} ", lowlevel)) .append(alloc.intersperse(it, " ")) } - NewHigherOrderLowLevel { op: lowlevel, .. } => { - let it = arguments.iter().map(|s| symbol_to_doc(alloc, *s)); - - alloc - .text(format!("lowlevel {:?} ", lowlevel)) - .append(alloc.intersperse(it, " ")) - } Foreign { ref foreign_symbol, .. } => { @@ -1109,18 +1102,6 @@ pub enum CallType<'a> { update_mode: UpdateModeId, }, HigherOrderLowLevel { - op: LowLevel, - /// the layout of the closure argument, if any - closure_env_layout: Option>, - /// specialization id of the function argument - specialization_id: CallSpecId, - /// does the function need to own the closure data - function_owns_closure_data: bool, - /// function layout - arg_layouts: &'a [Layout<'a>], - ret_layout: Layout<'a>, - }, - NewHigherOrderLowLevel { op: crate::low_level::HigherOrder, /// the layout of the closure argument, if any closure_env_layout: Option>, @@ -5464,7 +5445,6 @@ fn substitute_in_call<'a>( CallType::Foreign { .. } => None, CallType::LowLevel { .. } => None, CallType::HigherOrderLowLevel { .. } => None, - CallType::NewHigherOrderLowLevel { .. } => None, }; let mut did_change = false;