only unwrap lambda set at the last moment

This commit is contained in:
Folkert 2021-09-14 22:20:14 +02:00
parent 22722a3cf4
commit bd7ce52e26
2 changed files with 46 additions and 44 deletions

View file

@ -10,7 +10,7 @@ use inkwell::types::{BasicType, BasicTypeEnum};
use inkwell::values::{BasicValue, BasicValueEnum, CallSiteValue, FunctionValue, InstructionValue};
use inkwell::AddressSpace;
use roc_module::symbol::Symbol;
use roc_mono::layout::{Layout, LayoutIds, UnionLayout};
use roc_mono::layout::{LambdaSet, Layout, LayoutIds, UnionLayout};
pub fn call_bitcode_fn<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
@ -189,7 +189,7 @@ fn build_has_tag_id_help<'a, 'ctx, 'env>(
pub fn build_transform_caller<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
function: FunctionValue<'ctx>,
closure_data_layout: Layout<'a>,
closure_data_layout: LambdaSet<'a>,
argument_layouts: &[Layout<'a>],
) -> FunctionValue<'ctx> {
let fn_name: &str = &format!(
@ -212,7 +212,7 @@ pub fn build_transform_caller<'a, 'ctx, 'env>(
fn build_transform_caller_help<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
roc_function: FunctionValue<'ctx>,
closure_data_layout: Layout<'a>,
closure_data_layout: LambdaSet<'a>,
argument_layouts: &[Layout<'a>],
fn_name: &str,
) -> FunctionValue<'ctx> {
@ -270,7 +270,7 @@ fn build_transform_caller_help<'a, 'ctx, 'env>(
arguments_cast.push(argument);
}
match closure_data_layout {
match closure_data_layout.runtime_representation() {
Layout::Struct(&[]) => {
// nothing to add
}
@ -529,7 +529,7 @@ pub fn build_eq_wrapper<'a, 'ctx, 'env>(
pub fn build_compare_wrapper<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>,
roc_function: FunctionValue<'ctx>,
closure_data_layout: Layout<'a>,
closure_data_layout: LambdaSet<'a>,
layout: &Layout<'a>,
) -> FunctionValue<'ctx> {
let block = env.builder.get_insert_block().expect("to be in a function");
@ -595,7 +595,7 @@ pub fn build_compare_wrapper<'a, 'ctx, 'env>(
let default = [value1, value2];
let arguments_cast = match closure_data_layout {
let arguments_cast = match closure_data_layout.runtime_representation() {
Layout::Struct(&[]) => {
// nothing to add
&default

View file

@ -2609,6 +2609,18 @@ pub fn load_symbol_and_layout<'a, 'ctx, 'b>(
None => panic!("There was no entry for {:?} in scope {:?}", symbol, scope),
}
}
pub fn load_symbol_and_lambda_set<'a, 'ctx, 'b>(
scope: &'b Scope<'a, 'ctx>,
symbol: &Symbol,
) -> (BasicValueEnum<'ctx>, LambdaSet<'a>) {
match scope.get(symbol) {
Some((Layout::LambdaSet(lambda_set), ptr)) => (*ptr, *lambda_set),
Some((other, ptr)) => panic!("Not a lambda set: {:?}, {:?}", other, ptr),
None => panic!("There was no entry for {:?} in scope {:?}", symbol, scope),
}
}
fn access_index_struct_value<'ctx>(
builder: &Builder<'ctx>,
from_value: StructValue<'ctx>,
@ -4102,31 +4114,26 @@ fn roc_function_call<'a, 'ctx, 'env>(
layout_ids: &mut LayoutIds<'a>,
transform: FunctionValue<'ctx>,
closure_data: BasicValueEnum<'ctx>,
closure_data_layout: Layout<'a>,
lambda_set: LambdaSet<'a>,
closure_data_is_owned: bool,
argument_layouts: &[Layout<'a>],
) -> RocFunctionCall<'ctx> {
use crate::llvm::bitcode::{build_inc_n_wrapper, build_transform_caller};
let closure_data_layout = match closure_data_layout {
Layout::LambdaSet(lambda_set) => lambda_set.runtime_representation(),
_ => panic!("closure argument is not a lambda set!"),
};
let closure_data_ptr = env
.builder
.build_alloca(closure_data.get_type(), "closure_data_ptr");
env.builder.build_store(closure_data_ptr, closure_data);
let stepper_caller =
build_transform_caller(env, transform, closure_data_layout, argument_layouts)
.as_global_value()
.as_pointer_value();
let inc_closure_data = build_inc_n_wrapper(env, layout_ids, &closure_data_layout)
let stepper_caller = build_transform_caller(env, transform, lambda_set, argument_layouts)
.as_global_value()
.as_pointer_value();
let inc_closure_data =
build_inc_n_wrapper(env, layout_ids, &lambda_set.runtime_representation())
.as_global_value()
.as_pointer_value();
let closure_data_is_owned = env
.context
.bool_type()
@ -4180,7 +4187,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
let function = passed_function_at_index!(2);
let (closure, closure_layout) = load_symbol_and_layout(scope, &args[3]);
let (closure, closure_layout) = load_symbol_and_lambda_set(scope, &args[3]);
match list_layout {
Layout::Builtin(Builtin::EmptyList) => default,
@ -4192,7 +4199,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
layout_ids,
function,
closure,
*closure_layout,
closure_layout,
function_owns_closure_data,
argument_layouts,
);
@ -4222,7 +4229,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
let function = passed_function_at_index!(1);
let (closure, closure_layout) = load_symbol_and_layout(scope, &args[2]);
let (closure, closure_layout) = load_symbol_and_lambda_set(scope, &args[2]);
match (list_layout, return_layout) {
(Layout::Builtin(Builtin::EmptyList), _) => empty_list(env),
@ -4237,7 +4244,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
layout_ids,
function,
closure,
*closure_layout,
closure_layout,
function_owns_closure_data,
argument_layouts,
);
@ -4254,7 +4261,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
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_layout(scope, &args[3]);
let (closure, closure_layout) = load_symbol_and_lambda_set(scope, &args[3]);
match (list1_layout, list2_layout, return_layout) {
(
@ -4269,7 +4276,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
layout_ids,
function,
closure,
*closure_layout,
closure_layout,
function_owns_closure_data,
argument_layouts,
);
@ -4298,7 +4305,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
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_layout(scope, &args[4]);
let (closure, closure_layout) = load_symbol_and_lambda_set(scope, &args[4]);
match (list1_layout, list2_layout, list3_layout, return_layout) {
(
@ -4315,7 +4322,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
layout_ids,
function,
closure,
*closure_layout,
closure_layout,
function_owns_closure_data,
argument_layouts,
);
@ -4347,7 +4354,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
let function = passed_function_at_index!(1);
let (closure, closure_layout) = load_symbol_and_layout(scope, &args[2]);
let (closure, closure_layout) = load_symbol_and_lambda_set(scope, &args[2]);
match (list_layout, return_layout) {
(Layout::Builtin(Builtin::EmptyList), _) => empty_list(env),
@ -4362,7 +4369,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
layout_ids,
function,
closure,
*closure_layout,
closure_layout,
function_owns_closure_data,
argument_layouts,
);
@ -4380,7 +4387,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
let function = passed_function_at_index!(1);
let (closure, closure_layout) = load_symbol_and_layout(scope, &args[2]);
let (closure, closure_layout) = load_symbol_and_lambda_set(scope, &args[2]);
match list_layout {
Layout::Builtin(Builtin::EmptyList) => empty_list(env),
@ -4392,7 +4399,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
layout_ids,
function,
closure,
*closure_layout,
closure_layout,
function_owns_closure_data,
argument_layouts,
);
@ -4410,7 +4417,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
let function = passed_function_at_index!(1);
let (closure, closure_layout) = load_symbol_and_layout(scope, &args[2]);
let (closure, closure_layout) = load_symbol_and_lambda_set(scope, &args[2]);
match (list_layout, return_layout) {
(_, Layout::Builtin(Builtin::EmptyList))
@ -4426,7 +4433,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
layout_ids,
function,
closure,
*closure_layout,
closure_layout,
function_owns_closure_data,
argument_layouts,
);
@ -4454,7 +4461,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
let function = passed_function_at_index!(1);
let (closure, closure_layout) = load_symbol_and_layout(scope, &args[2]);
let (closure, closure_layout) = load_symbol_and_lambda_set(scope, &args[2]);
match (list_layout, return_layout) {
(_, Layout::Builtin(Builtin::EmptyList))
@ -4470,7 +4477,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
layout_ids,
function,
closure,
*closure_layout,
closure_layout,
function_owns_closure_data,
argument_layouts,
);
@ -4507,7 +4514,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
let function = passed_function_at_index!(1);
let (closure, closure_layout) = load_symbol_and_layout(scope, &args[2]);
let (closure, closure_layout) = load_symbol_and_lambda_set(scope, &args[2]);
match list_layout {
Layout::Builtin(Builtin::EmptyList) => empty_list(env),
@ -4516,13 +4523,8 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
let argument_layouts = &[**element_layout, **element_layout];
let closure_data_layout = match closure_layout {
Layout::LambdaSet(lambda_set) => lambda_set.runtime_representation(),
_ => panic!("closure argument is not a lambda set!"),
};
let compare_wrapper =
build_compare_wrapper(env, function, closure_data_layout, element_layout)
build_compare_wrapper(env, function, closure_layout, element_layout)
.as_global_value()
.as_pointer_value();
@ -4531,7 +4533,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
layout_ids,
function,
closure,
*closure_layout,
closure_layout,
function_owns_closure_data,
argument_layouts,
);
@ -4553,7 +4555,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
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_layout(scope, &args[3]);
let (closure, closure_layout) = load_symbol_and_lambda_set(scope, &args[3]);
match dict_layout {
Layout::Builtin(Builtin::EmptyDict) => {
@ -4568,7 +4570,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
layout_ids,
function,
closure,
*closure_layout,
closure_layout,
function_owns_closure_data,
argument_layouts,
);