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::values::{BasicValue, BasicValueEnum, CallSiteValue, FunctionValue, InstructionValue};
use inkwell::AddressSpace; use inkwell::AddressSpace;
use roc_module::symbol::Symbol; 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>( pub fn call_bitcode_fn<'a, 'ctx, 'env>(
env: &Env<'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>( pub fn build_transform_caller<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>, env: &Env<'a, 'ctx, 'env>,
function: FunctionValue<'ctx>, function: FunctionValue<'ctx>,
closure_data_layout: Layout<'a>, closure_data_layout: LambdaSet<'a>,
argument_layouts: &[Layout<'a>], argument_layouts: &[Layout<'a>],
) -> FunctionValue<'ctx> { ) -> FunctionValue<'ctx> {
let fn_name: &str = &format!( 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>( fn build_transform_caller_help<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>, env: &Env<'a, 'ctx, 'env>,
roc_function: FunctionValue<'ctx>, roc_function: FunctionValue<'ctx>,
closure_data_layout: Layout<'a>, closure_data_layout: LambdaSet<'a>,
argument_layouts: &[Layout<'a>], argument_layouts: &[Layout<'a>],
fn_name: &str, fn_name: &str,
) -> FunctionValue<'ctx> { ) -> FunctionValue<'ctx> {
@ -270,7 +270,7 @@ fn build_transform_caller_help<'a, 'ctx, 'env>(
arguments_cast.push(argument); arguments_cast.push(argument);
} }
match closure_data_layout { match closure_data_layout.runtime_representation() {
Layout::Struct(&[]) => { Layout::Struct(&[]) => {
// nothing to add // nothing to add
} }
@ -529,7 +529,7 @@ pub fn build_eq_wrapper<'a, 'ctx, 'env>(
pub fn build_compare_wrapper<'a, 'ctx, 'env>( pub fn build_compare_wrapper<'a, 'ctx, 'env>(
env: &Env<'a, 'ctx, 'env>, env: &Env<'a, 'ctx, 'env>,
roc_function: FunctionValue<'ctx>, roc_function: FunctionValue<'ctx>,
closure_data_layout: Layout<'a>, closure_data_layout: LambdaSet<'a>,
layout: &Layout<'a>, layout: &Layout<'a>,
) -> FunctionValue<'ctx> { ) -> FunctionValue<'ctx> {
let block = env.builder.get_insert_block().expect("to be in a function"); 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 default = [value1, value2];
let arguments_cast = match closure_data_layout { let arguments_cast = match closure_data_layout.runtime_representation() {
Layout::Struct(&[]) => { Layout::Struct(&[]) => {
// nothing to add // nothing to add
&default &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), 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>( fn access_index_struct_value<'ctx>(
builder: &Builder<'ctx>, builder: &Builder<'ctx>,
from_value: StructValue<'ctx>, from_value: StructValue<'ctx>,
@ -4102,31 +4114,26 @@ fn roc_function_call<'a, 'ctx, 'env>(
layout_ids: &mut LayoutIds<'a>, layout_ids: &mut LayoutIds<'a>,
transform: FunctionValue<'ctx>, transform: FunctionValue<'ctx>,
closure_data: BasicValueEnum<'ctx>, closure_data: BasicValueEnum<'ctx>,
closure_data_layout: Layout<'a>, lambda_set: LambdaSet<'a>,
closure_data_is_owned: bool, closure_data_is_owned: bool,
argument_layouts: &[Layout<'a>], argument_layouts: &[Layout<'a>],
) -> RocFunctionCall<'ctx> { ) -> RocFunctionCall<'ctx> {
use crate::llvm::bitcode::{build_inc_n_wrapper, build_transform_caller}; 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 let closure_data_ptr = env
.builder .builder
.build_alloca(closure_data.get_type(), "closure_data_ptr"); .build_alloca(closure_data.get_type(), "closure_data_ptr");
env.builder.build_store(closure_data_ptr, closure_data); env.builder.build_store(closure_data_ptr, closure_data);
let stepper_caller = let stepper_caller = build_transform_caller(env, transform, lambda_set, argument_layouts)
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)
.as_global_value() .as_global_value()
.as_pointer_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 let closure_data_is_owned = env
.context .context
.bool_type() .bool_type()
@ -4180,7 +4187,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
let function = passed_function_at_index!(2); 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 { match list_layout {
Layout::Builtin(Builtin::EmptyList) => default, Layout::Builtin(Builtin::EmptyList) => default,
@ -4192,7 +4199,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
layout_ids, layout_ids,
function, function,
closure, closure,
*closure_layout, closure_layout,
function_owns_closure_data, function_owns_closure_data,
argument_layouts, argument_layouts,
); );
@ -4222,7 +4229,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
let function = passed_function_at_index!(1); 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) { match (list_layout, return_layout) {
(Layout::Builtin(Builtin::EmptyList), _) => empty_list(env), (Layout::Builtin(Builtin::EmptyList), _) => empty_list(env),
@ -4237,7 +4244,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
layout_ids, layout_ids,
function, function,
closure, closure,
*closure_layout, closure_layout,
function_owns_closure_data, function_owns_closure_data,
argument_layouts, 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 (list2, list2_layout) = load_symbol_and_layout(scope, &args[1]);
let function = passed_function_at_index!(2); 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) { match (list1_layout, list2_layout, return_layout) {
( (
@ -4269,7 +4276,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
layout_ids, layout_ids,
function, function,
closure, closure,
*closure_layout, closure_layout,
function_owns_closure_data, function_owns_closure_data,
argument_layouts, 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 (list3, list3_layout) = load_symbol_and_layout(scope, &args[2]);
let function = passed_function_at_index!(3); 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) { match (list1_layout, list2_layout, list3_layout, return_layout) {
( (
@ -4315,7 +4322,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
layout_ids, layout_ids,
function, function,
closure, closure,
*closure_layout, closure_layout,
function_owns_closure_data, function_owns_closure_data,
argument_layouts, argument_layouts,
); );
@ -4347,7 +4354,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
let function = passed_function_at_index!(1); 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) { match (list_layout, return_layout) {
(Layout::Builtin(Builtin::EmptyList), _) => empty_list(env), (Layout::Builtin(Builtin::EmptyList), _) => empty_list(env),
@ -4362,7 +4369,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
layout_ids, layout_ids,
function, function,
closure, closure,
*closure_layout, closure_layout,
function_owns_closure_data, function_owns_closure_data,
argument_layouts, argument_layouts,
); );
@ -4380,7 +4387,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
let function = passed_function_at_index!(1); 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 { match list_layout {
Layout::Builtin(Builtin::EmptyList) => empty_list(env), Layout::Builtin(Builtin::EmptyList) => empty_list(env),
@ -4392,7 +4399,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
layout_ids, layout_ids,
function, function,
closure, closure,
*closure_layout, closure_layout,
function_owns_closure_data, function_owns_closure_data,
argument_layouts, argument_layouts,
); );
@ -4410,7 +4417,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
let function = passed_function_at_index!(1); 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) { match (list_layout, return_layout) {
(_, Layout::Builtin(Builtin::EmptyList)) (_, Layout::Builtin(Builtin::EmptyList))
@ -4426,7 +4433,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
layout_ids, layout_ids,
function, function,
closure, closure,
*closure_layout, closure_layout,
function_owns_closure_data, function_owns_closure_data,
argument_layouts, argument_layouts,
); );
@ -4454,7 +4461,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
let function = passed_function_at_index!(1); 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) { match (list_layout, return_layout) {
(_, Layout::Builtin(Builtin::EmptyList)) (_, Layout::Builtin(Builtin::EmptyList))
@ -4470,7 +4477,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
layout_ids, layout_ids,
function, function,
closure, closure,
*closure_layout, closure_layout,
function_owns_closure_data, function_owns_closure_data,
argument_layouts, argument_layouts,
); );
@ -4507,7 +4514,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
let function = passed_function_at_index!(1); 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 { match list_layout {
Layout::Builtin(Builtin::EmptyList) => empty_list(env), 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 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 = 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_global_value()
.as_pointer_value(); .as_pointer_value();
@ -4531,7 +4533,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
layout_ids, layout_ids,
function, function,
closure, closure,
*closure_layout, closure_layout,
function_owns_closure_data, function_owns_closure_data,
argument_layouts, 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 (dict, dict_layout) = load_symbol_and_layout(scope, &args[0]);
let (default, default_layout) = load_symbol_and_layout(scope, &args[1]); let (default, default_layout) = load_symbol_and_layout(scope, &args[1]);
let function = passed_function_at_index!(2); 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 { match dict_layout {
Layout::Builtin(Builtin::EmptyDict) => { Layout::Builtin(Builtin::EmptyDict) => {
@ -4568,7 +4570,7 @@ fn run_higher_order_low_level<'a, 'ctx, 'env>(
layout_ids, layout_ids,
function, function,
closure, closure,
*closure_layout, closure_layout,
function_owns_closure_data, function_owns_closure_data,
argument_layouts, argument_layouts,
); );