store the layout of a function passed to a lowlevel

This commit is contained in:
Folkert 2021-05-15 20:54:26 +02:00
parent 27a6a179da
commit 357f93a2ee
6 changed files with 72 additions and 33 deletions

View file

@ -882,9 +882,10 @@ pub fn build_exp_call<'a, 'ctx, 'env>(
.unwrap_or_else(|| panic!("LLVM error: Invalid call by pointer.")) .unwrap_or_else(|| panic!("LLVM error: Invalid call by pointer."))
} }
CallType::LowLevel { op } => { CallType::LowLevel {
run_low_level(env, layout_ids, scope, parent, layout, *op, arguments) op,
} opt_closure_layout,
} => run_low_level(env, layout_ids, scope, parent, layout, *op, arguments),
CallType::Foreign { CallType::Foreign {
foreign_symbol, foreign_symbol,

View file

@ -211,9 +211,10 @@ where
} }
} }
CallType::LowLevel { op: lowlevel } => { CallType::LowLevel {
self.build_run_low_level(sym, lowlevel, arguments, layout) op: lowlevel,
} opt_closure_layout: _,
} => self.build_run_low_level(sym, lowlevel, arguments, layout),
x => Err(format!("the call type, {:?}, is not yet implemented", x)), x => Err(format!("the call type, {:?}, is not yet implemented", x)),
} }
} }

View file

@ -407,7 +407,10 @@ impl<'a> BorrowInfState<'a> {
self.own_args(arguments); self.own_args(arguments);
} }
LowLevel { op } => { LowLevel {
op,
opt_closure_layout: _,
} => {
// very unsure what demand RunLowLevel should place upon its arguments // very unsure what demand RunLowLevel should place upon its arguments
self.own_var(z); self.own_var(z);

View file

@ -1405,7 +1405,10 @@ fn compile_test_help<'a>(
}; };
let test = Expr::Call(crate::ir::Call { let test = Expr::Call(crate::ir::Call {
call_type: crate::ir::CallType::LowLevel { op: LowLevel::Eq }, call_type: crate::ir::CallType::LowLevel {
op: LowLevel::Eq,
opt_closure_layout: None,
},
arguments: arena.alloc([lhs, rhs]), arguments: arena.alloc([lhs, rhs]),
}); });

View file

@ -442,7 +442,10 @@ impl<'a> Context<'a> {
use crate::ir::CallType::*; use crate::ir::CallType::*;
match &call_type { match &call_type {
LowLevel { op } => { LowLevel {
op,
opt_closure_layout: _,
} => {
let ps = crate::borrow::lowlevel_borrow_signature(self.arena, *op); let ps = crate::borrow::lowlevel_borrow_signature(self.arena, *op);
let b = self.add_dec_after_lowlevel(arguments, ps, b, b_live_vars); let b = self.add_dec_after_lowlevel(arguments, ps, b, b_live_vars);
@ -762,7 +765,10 @@ impl<'a> Context<'a> {
use crate::ir::CallType; use crate::ir::CallType;
let stmt = match &call.call_type { let stmt = match &call.call_type {
CallType::LowLevel { op } => { CallType::LowLevel {
op,
opt_closure_layout: _,
} => {
let ps = crate::borrow::lowlevel_borrow_signature(self.arena, *op); let ps = crate::borrow::lowlevel_borrow_signature(self.arena, *op);
self.add_dec_after_lowlevel(call.arguments, ps, cont, &invoke_live_vars) self.add_dec_after_lowlevel(call.arguments, ps, cont, &invoke_live_vars)
} }

View file

@ -1040,7 +1040,10 @@ impl<'a> Call<'a> {
.text("CallByPointer ") .text("CallByPointer ")
.append(alloc.intersperse(it, " ")) .append(alloc.intersperse(it, " "))
} }
LowLevel { op: lowlevel } => { LowLevel {
op: lowlevel,
opt_closure_layout: _,
} => {
let it = arguments.iter().map(|s| symbol_to_doc(alloc, *s)); let it = arguments.iter().map(|s| symbol_to_doc(alloc, *s));
alloc alloc
@ -1082,6 +1085,8 @@ pub enum CallType<'a> {
}, },
LowLevel { LowLevel {
op: LowLevel, op: LowLevel,
/// the layout of the closure argument, if any
opt_closure_layout: Option<Layout<'a>>,
}, },
} }
@ -2671,8 +2676,8 @@ macro_rules! match_on_closure_argument {
$env, $env,
lambda_set, lambda_set,
$closure_data_symbol, $closure_data_symbol,
|top_level_function, closure_data| self::Call { |top_level_function, closure_data, function_layout| self::Call {
call_type: CallType::LowLevel { op: $op }, call_type: CallType::LowLevel { op: $op, opt_closure_layout: Some(function_layout) },
arguments: arena.alloc([$($x,)* top_level_function, closure_data]), arguments: arena.alloc([$($x,)* top_level_function, closure_data]),
}, },
arena.alloc(top_level).full(), arena.alloc(top_level).full(),
@ -4357,7 +4362,10 @@ pub fn with_hole<'a>(
} }
_ => { _ => {
let call = self::Call { let call = self::Call {
call_type: CallType::LowLevel { op }, call_type: CallType::LowLevel {
op,
opt_closure_layout: None,
},
arguments: arg_symbols, arguments: arg_symbols,
}; };
@ -4577,6 +4585,7 @@ pub fn from_can<'a>(
let call_type = CallType::LowLevel { let call_type = CallType::LowLevel {
op: LowLevel::ExpectTrue, op: LowLevel::ExpectTrue,
opt_closure_layout: None,
}; };
let arguments = env.arena.alloc([cond_symbol]); let arguments = env.arena.alloc([cond_symbol]);
let call = self::Call { let call = self::Call {
@ -7634,18 +7643,18 @@ pub fn num_argument_to_int_or_float(
} }
/// Use the lambda set to figure out how to make a lowlevel call /// Use the lambda set to figure out how to make a lowlevel call
fn lowlevel_match_on_lambda_set<'a, F>( fn lowlevel_match_on_lambda_set<'a, ToLowLevelCall>(
env: &mut Env<'a, '_>, env: &mut Env<'a, '_>,
lambda_set: LambdaSet<'a>, lambda_set: LambdaSet<'a>,
closure_data_symbol: Symbol, closure_data_symbol: Symbol,
to_lowlevel_call: F, to_lowlevel_call: ToLowLevelCall,
function_layout: Layout<'a>, function_layout: Layout<'a>,
return_layout: Layout<'a>, return_layout: Layout<'a>,
assigned: Symbol, assigned: Symbol,
hole: &'a Stmt<'a>, hole: &'a Stmt<'a>,
) -> Stmt<'a> ) -> Stmt<'a>
where where
F: Fn(Symbol, Symbol) -> Call<'a> + Copy, ToLowLevelCall: Fn(Symbol, Symbol, Layout<'a>) -> Call<'a> + Copy,
{ {
match lambda_set.runtime_representation() { match lambda_set.runtime_representation() {
Layout::Union(_) => { Layout::Union(_) => {
@ -7687,7 +7696,11 @@ where
// build the call // build the call
let stmt = Stmt::Let( let stmt = Stmt::Let(
assigned, assigned,
Expr::Call(to_lowlevel_call(bound, closure_data_symbol)), Expr::Call(to_lowlevel_call(
bound,
closure_data_symbol,
function_layout,
)),
return_layout, return_layout,
env.arena.alloc(hole), env.arena.alloc(hole),
); );
@ -7736,20 +7749,20 @@ where
} }
} }
fn lowlevel_union_lambda_set_to_switch<'a, F>( fn lowlevel_union_lambda_set_to_switch<'a, ToLowLevelCall>(
env: &mut Env<'a, '_>, env: &mut Env<'a, '_>,
lambda_set: &'a [(Symbol, &'a [Layout<'a>])], lambda_set: &'a [(Symbol, &'a [Layout<'a>])],
closure_tag_id_symbol: Symbol, closure_tag_id_symbol: Symbol,
closure_tag_id_layout: Layout<'a>, closure_tag_id_layout: Layout<'a>,
closure_data_symbol: Symbol, closure_data_symbol: Symbol,
to_lowlevel_call: F, to_lowlevel_call: ToLowLevelCall,
function_layout: Layout<'a>, function_layout: Layout<'a>,
return_layout: Layout<'a>, return_layout: Layout<'a>,
assigned: Symbol, assigned: Symbol,
hole: &'a Stmt<'a>, hole: &'a Stmt<'a>,
) -> Stmt<'a> ) -> Stmt<'a>
where where
F: Fn(Symbol, Symbol) -> Call<'a> + Copy, ToLowLevelCall: Fn(Symbol, Symbol, Layout<'a>) -> Call<'a> + Copy,
{ {
debug_assert!(!lambda_set.is_empty()); debug_assert!(!lambda_set.is_empty());
@ -7767,7 +7780,11 @@ where
// build the call // build the call
let stmt = Stmt::Let( let stmt = Stmt::Let(
assigned, assigned,
Expr::Call(to_lowlevel_call(bound, closure_data_symbol)), Expr::Call(to_lowlevel_call(
bound,
closure_data_symbol,
function_layout,
)),
return_layout, return_layout,
env.arena.alloc(hole), env.arena.alloc(hole),
); );
@ -7810,18 +7827,18 @@ where
} }
} }
fn lowlevel_union_lambda_set_branch<'a, F>( fn lowlevel_union_lambda_set_branch<'a, ToLowLevelCall>(
env: &mut Env<'a, '_>, env: &mut Env<'a, '_>,
join_point_id: JoinPointId, join_point_id: JoinPointId,
function_symbol: Symbol, function_symbol: Symbol,
closure_data_symbol: Symbol, closure_data_symbol: Symbol,
closure_data_layout: Layout<'a>, closure_data_layout: Layout<'a>,
function_layout: Layout<'a>, function_layout: Layout<'a>,
to_lowlevel_call: F, to_lowlevel_call: ToLowLevelCall,
return_layout: Layout<'a>, return_layout: Layout<'a>,
) -> Stmt<'a> ) -> Stmt<'a>
where where
F: Fn(Symbol, Symbol) -> Call<'a> + Copy, ToLowLevelCall: Fn(Symbol, Symbol, Layout<'a>) -> Call<'a> + Copy,
{ {
let assigned = env.unique_symbol(); let assigned = env.unique_symbol();
@ -7832,7 +7849,11 @@ where
// build the call // build the call
let stmt = Stmt::Let( let stmt = Stmt::Let(
assigned, assigned,
Expr::Call(to_lowlevel_call(bound, closure_data_symbol)), Expr::Call(to_lowlevel_call(
bound,
closure_data_symbol,
function_layout,
)),
return_layout, return_layout,
env.arena.alloc(hole), env.arena.alloc(hole),
); );
@ -8225,20 +8246,20 @@ fn enum_lambda_set_branch_help<'a>(
) )
} }
fn lowlevel_enum_lambda_set_to_switch<'a, F>( fn lowlevel_enum_lambda_set_to_switch<'a, ToLowLevelCall>(
env: &mut Env<'a, '_>, env: &mut Env<'a, '_>,
lambda_set: &'a [(Symbol, &'a [Layout<'a>])], lambda_set: &'a [(Symbol, &'a [Layout<'a>])],
closure_tag_id_symbol: Symbol, closure_tag_id_symbol: Symbol,
closure_tag_id_layout: Layout<'a>, closure_tag_id_layout: Layout<'a>,
closure_data_symbol: Symbol, closure_data_symbol: Symbol,
to_lowlevel_call: F, to_lowlevel_call: ToLowLevelCall,
function_layout: Layout<'a>, function_layout: Layout<'a>,
return_layout: Layout<'a>, return_layout: Layout<'a>,
assigned: Symbol, assigned: Symbol,
hole: &'a Stmt<'a>, hole: &'a Stmt<'a>,
) -> Stmt<'a> ) -> Stmt<'a>
where where
F: Fn(Symbol, Symbol) -> Call<'a> + Copy, ToLowLevelCall: Fn(Symbol, Symbol, Layout<'a>) -> Call<'a> + Copy,
{ {
debug_assert!(!lambda_set.is_empty()); debug_assert!(!lambda_set.is_empty());
@ -8290,18 +8311,18 @@ where
} }
} }
fn lowlevel_enum_lambda_set_branch<'a, F>( fn lowlevel_enum_lambda_set_branch<'a, ToLowLevelCall>(
env: &mut Env<'a, '_>, env: &mut Env<'a, '_>,
join_point_id: JoinPointId, join_point_id: JoinPointId,
function_symbol: Symbol, function_symbol: Symbol,
closure_data_symbol: Symbol, closure_data_symbol: Symbol,
closure_data_layout: Layout<'a>, closure_data_layout: Layout<'a>,
to_lowlevel_call: F, to_lowlevel_call: ToLowLevelCall,
function_layout: Layout<'a>, function_layout: Layout<'a>,
return_layout: Layout<'a>, return_layout: Layout<'a>,
) -> Stmt<'a> ) -> Stmt<'a>
where where
F: Fn(Symbol, Symbol) -> Call<'a> + Copy, ToLowLevelCall: Fn(Symbol, Symbol, Layout<'a>) -> Call<'a> + Copy,
{ {
let result_symbol = env.unique_symbol(); let result_symbol = env.unique_symbol();
@ -8312,7 +8333,11 @@ where
// build the call // build the call
let stmt = Stmt::Let( let stmt = Stmt::Let(
result_symbol, result_symbol,
Expr::Call(to_lowlevel_call(bound, closure_data_symbol)), Expr::Call(to_lowlevel_call(
bound,
closure_data_symbol,
function_layout,
)),
return_layout, return_layout,
env.arena.alloc(hole), env.arena.alloc(hole),
); );