use toplevelfunctionlayout in refcount insertion

This commit is contained in:
Folkert 2021-06-18 20:46:15 +02:00
parent b6f0a3f693
commit 94cbb103ef
4 changed files with 67 additions and 30 deletions

View file

@ -24,9 +24,8 @@ pub fn infer_borrow<'a>(
items: MutMap::default(), items: MutMap::default(),
}; };
for ((s, top_level), proc) in procs { for (key, proc) in procs {
let key = (*s, arena.alloc(*top_level).full()); param_map.visit_proc(arena, proc, *key);
param_map.visit_proc(arena, proc, key);
} }
let mut env = BorrowInfState { let mut env = BorrowInfState {
@ -51,8 +50,7 @@ pub fn infer_borrow<'a>(
// mutually recursive functions (or just make all their arguments owned) // mutually recursive functions (or just make all their arguments owned)
for (key, proc) in procs { for (key, proc) in procs {
let layout = arena.alloc(key.1).full(); env.collect_proc(proc, key.1);
env.collect_proc(proc, layout);
} }
if !env.modified { if !env.modified {
@ -69,7 +67,7 @@ pub fn infer_borrow<'a>(
#[derive(Debug, PartialEq, Eq, Hash, Clone)] #[derive(Debug, PartialEq, Eq, Hash, Clone)]
pub enum Key<'a> { pub enum Key<'a> {
Declaration(Symbol, Layout<'a>), Declaration(Symbol, TopLevelFunctionLayout<'a>),
JoinPoint(JoinPointId), JoinPoint(JoinPointId),
} }
@ -98,7 +96,11 @@ impl<'a> IntoIterator for &'a ParamMap<'a> {
} }
impl<'a> ParamMap<'a> { impl<'a> ParamMap<'a> {
pub fn get_symbol(&self, symbol: Symbol, layout: Layout<'a>) -> Option<&'a [Param<'a>]> { pub fn get_symbol(
&self,
symbol: Symbol,
layout: TopLevelFunctionLayout<'a>,
) -> Option<&'a [Param<'a>]> {
let key = Key::Declaration(symbol, layout); let key = Key::Declaration(symbol, layout);
self.items.get(&key).copied() self.items.get(&key).copied()
@ -153,7 +155,12 @@ impl<'a> ParamMap<'a> {
.into_bump_slice() .into_bump_slice()
} }
fn visit_proc(&mut self, arena: &'a Bump, proc: &Proc<'a>, key: (Symbol, Layout<'a>)) { fn visit_proc(
&mut self,
arena: &'a Bump,
proc: &Proc<'a>,
key: (Symbol, TopLevelFunctionLayout<'a>),
) {
if proc.must_own_arguments { if proc.must_own_arguments {
self.visit_proc_always_owned(arena, proc, key); self.visit_proc_always_owned(arena, proc, key);
return; return;
@ -171,7 +178,7 @@ impl<'a> ParamMap<'a> {
&mut self, &mut self,
arena: &'a Bump, arena: &'a Bump,
proc: &Proc<'a>, proc: &Proc<'a>,
key: (Symbol, Layout<'a>), key: (Symbol, TopLevelFunctionLayout<'a>),
) { ) {
let already_in_there = self.items.insert( let already_in_there = self.items.insert(
Key::Declaration(proc.name, key.1), Key::Declaration(proc.name, key.1),
@ -359,12 +366,19 @@ impl<'a> BorrowInfState<'a> {
match call_type { match call_type {
ByName { ByName {
name, full_layout, .. name,
ret_layout,
arg_layouts,
..
} => { } => {
let top_level = TopLevelFunctionLayout {
arguments: arg_layouts,
result: *ret_layout,
};
// get the borrow signature of the applied function // get the borrow signature of the applied function
let ps = self let ps = self
.param_map .param_map
.get_symbol(*name, *full_layout) .get_symbol(*name, top_level)
.expect("function is defined"); .expect("function is defined");
// the return value will be owned // the return value will be owned
@ -402,7 +416,10 @@ impl<'a> BorrowInfState<'a> {
debug_assert!(op.is_higher_order()); debug_assert!(op.is_higher_order());
let closure_layout = Layout::FunctionPointer(arg_layouts, ret_layout); let closure_layout = TopLevelFunctionLayout {
arguments: arg_layouts,
result: *ret_layout,
};
match op { match op {
ListMap | ListKeepIf | ListKeepOks | ListKeepErrs => { ListMap | ListKeepIf | ListKeepOks | ListKeepErrs => {
@ -584,7 +601,8 @@ impl<'a> BorrowInfState<'a> {
call_type: call_type:
crate::ir::CallType::ByName { crate::ir::CallType::ByName {
name: g, name: g,
full_layout, arg_layouts,
ret_layout,
.. ..
}, },
arguments: ys, arguments: ys,
@ -593,10 +611,15 @@ impl<'a> BorrowInfState<'a> {
Stmt::Ret(z), Stmt::Ret(z),
) = (v, b) ) = (v, b)
{ {
let top_level = TopLevelFunctionLayout {
arguments: arg_layouts,
result: *ret_layout,
};
if self.current_proc == *g && x == *z { if self.current_proc == *g && x == *z {
// anonymous functions (for which the ps may not be known) // anonymous functions (for which the ps may not be known)
// can never be tail-recursive, so this is fine // can never be tail-recursive, so this is fine
if let Some(ps) = self.param_map.get_symbol(*g, *full_layout) { if let Some(ps) = self.param_map.get_symbol(*g, top_level) {
self.own_params_using_args(ys, ps) self.own_params_using_args(ys, ps)
} }
} }
@ -684,7 +707,7 @@ impl<'a> BorrowInfState<'a> {
} }
} }
fn collect_proc(&mut self, proc: &Proc<'a>, layout: Layout<'a>) { fn collect_proc(&mut self, proc: &Proc<'a>, layout: TopLevelFunctionLayout<'a>) {
let old = self.param_set.clone(); let old = self.param_set.clone();
let ys = Vec::from_iter_in(proc.args.iter().map(|t| t.1), self.arena).into_bump_slice(); let ys = Vec::from_iter_in(proc.args.iter().map(|t| t.1), self.arena).into_bump_slice();

View file

@ -245,9 +245,6 @@ fn layout_for_constructor<'a>(
HasFields(fields) HasFields(fields)
} }
Closure(_arguments, _lambda_set, _result) => { Closure(_arguments, _lambda_set, _result) => {
// TODO can this be improved again?
// let fpointer = Layout::FunctionPointer(arguments, result);
// let fields = arena.alloc([fpointer, *lambda_set.layout]);
// HasFields(fields) // HasFields(fields)
ConstructorLayout::Unknown ConstructorLayout::Unknown
} }

View file

@ -1,5 +1,5 @@
use crate::borrow::{ParamMap, BORROWED, OWNED}; use crate::borrow::{ParamMap, BORROWED, OWNED};
use crate::ir::{Expr, JoinPointId, ModifyRc, Param, Proc, Stmt}; use crate::ir::{Expr, JoinPointId, ModifyRc, Param, Proc, Stmt, TopLevelFunctionLayout};
use crate::layout::Layout; use crate::layout::Layout;
use bumpalo::collections::Vec; use bumpalo::collections::Vec;
use bumpalo::Bump; use bumpalo::Bump;
@ -497,7 +497,10 @@ impl<'a> Context<'a> {
const FUNCTION: bool = BORROWED; const FUNCTION: bool = BORROWED;
const CLOSURE_DATA: bool = BORROWED; const CLOSURE_DATA: bool = BORROWED;
let function_layout = Layout::FunctionPointer(arg_layouts, ret_layout); let function_layout = TopLevelFunctionLayout {
arguments: arg_layouts,
result: *ret_layout,
};
match op { match op {
roc_module::low_level::LowLevel::ListMap roc_module::low_level::LowLevel::ListMap
@ -679,12 +682,20 @@ impl<'a> Context<'a> {
} }
ByName { ByName {
name, full_layout, .. name,
ret_layout,
arg_layouts,
..
} => { } => {
let top_level = TopLevelFunctionLayout {
arguments: arg_layouts,
result: *ret_layout,
};
// get the borrow signature // get the borrow signature
let ps = self let ps = self
.param_map .param_map
.get_symbol(*name, *full_layout) .get_symbol(*name, top_level)
.expect("function is defined"); .expect("function is defined");
let v = Expr::Call(crate::ir::Call { let v = Expr::Call(crate::ir::Call {
@ -963,12 +974,20 @@ impl<'a> Context<'a> {
} }
CallType::ByName { CallType::ByName {
name, full_layout, .. name,
ret_layout,
arg_layouts,
..
} => { } => {
let top_level = TopLevelFunctionLayout {
arguments: arg_layouts,
result: *ret_layout,
};
// get the borrow signature // get the borrow signature
let ps = self let ps = self
.param_map .param_map
.get_symbol(*name, *full_layout) .get_symbol(*name, top_level)
.expect("function is defined"); .expect("function is defined");
self.add_dec_after_application(call.arguments, ps, cont, &invoke_live_vars) self.add_dec_after_application(call.arguments, ps, cont, &invoke_live_vars)
} }
@ -1222,7 +1241,7 @@ pub fn visit_proc<'a>(
arena: &'a Bump, arena: &'a Bump,
param_map: &'a ParamMap<'a>, param_map: &'a ParamMap<'a>,
proc: &mut Proc<'a>, proc: &mut Proc<'a>,
layout: Layout<'a>, layout: TopLevelFunctionLayout<'a>,
) { ) {
let ctx = Context::new(arena, param_map); let ctx = Context::new(arena, param_map);

View file

@ -215,7 +215,7 @@ impl<'a> Proc<'a> {
let borrow_params = arena.alloc(crate::borrow::infer_borrow(arena, procs)); let borrow_params = arena.alloc(crate::borrow::infer_borrow(arena, procs));
for (key, proc) in procs.iter_mut() { for (key, proc) in procs.iter_mut() {
crate::inc_dec::visit_proc(arena, borrow_params, proc, arena.alloc(key.1).full()); crate::inc_dec::visit_proc(arena, borrow_params, proc, key.1);
} }
} }
@ -410,8 +410,7 @@ impl<'a> Procs<'a> {
let borrow_params = arena.alloc(crate::borrow::infer_borrow(arena, &result)); let borrow_params = arena.alloc(crate::borrow::infer_borrow(arena, &result));
for (key, proc) in result.iter_mut() { for (key, proc) in result.iter_mut() {
let layout = arena.alloc(key.1).full(); crate::inc_dec::visit_proc(arena, borrow_params, proc, key.1);
crate::inc_dec::visit_proc(arena, borrow_params, proc, layout);
} }
result result
@ -454,8 +453,7 @@ impl<'a> Procs<'a> {
let borrow_params = arena.alloc(crate::borrow::infer_borrow(arena, &result)); let borrow_params = arena.alloc(crate::borrow::infer_borrow(arena, &result));
for (key, proc) in result.iter_mut() { for (key, proc) in result.iter_mut() {
let layout = arena.alloc(key.1).full(); crate::inc_dec::visit_proc(arena, borrow_params, proc, key.1);
crate::inc_dec::visit_proc(arena, borrow_params, proc, layout);
} }
(result, borrow_params) (result, borrow_params)