mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 23:31:12 +00:00
use toplevelfunctionlayout in refcount insertion
This commit is contained in:
parent
b6f0a3f693
commit
94cbb103ef
4 changed files with 67 additions and 30 deletions
|
@ -24,9 +24,8 @@ pub fn infer_borrow<'a>(
|
|||
items: MutMap::default(),
|
||||
};
|
||||
|
||||
for ((s, top_level), proc) in procs {
|
||||
let key = (*s, arena.alloc(*top_level).full());
|
||||
param_map.visit_proc(arena, proc, key);
|
||||
for (key, proc) in procs {
|
||||
param_map.visit_proc(arena, proc, *key);
|
||||
}
|
||||
|
||||
let mut env = BorrowInfState {
|
||||
|
@ -51,8 +50,7 @@ pub fn infer_borrow<'a>(
|
|||
// mutually recursive functions (or just make all their arguments owned)
|
||||
|
||||
for (key, proc) in procs {
|
||||
let layout = arena.alloc(key.1).full();
|
||||
env.collect_proc(proc, layout);
|
||||
env.collect_proc(proc, key.1);
|
||||
}
|
||||
|
||||
if !env.modified {
|
||||
|
@ -69,7 +67,7 @@ pub fn infer_borrow<'a>(
|
|||
|
||||
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
|
||||
pub enum Key<'a> {
|
||||
Declaration(Symbol, Layout<'a>),
|
||||
Declaration(Symbol, TopLevelFunctionLayout<'a>),
|
||||
JoinPoint(JoinPointId),
|
||||
}
|
||||
|
||||
|
@ -98,7 +96,11 @@ impl<'a> IntoIterator for &'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);
|
||||
|
||||
self.items.get(&key).copied()
|
||||
|
@ -153,7 +155,12 @@ impl<'a> ParamMap<'a> {
|
|||
.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 {
|
||||
self.visit_proc_always_owned(arena, proc, key);
|
||||
return;
|
||||
|
@ -171,7 +178,7 @@ impl<'a> ParamMap<'a> {
|
|||
&mut self,
|
||||
arena: &'a Bump,
|
||||
proc: &Proc<'a>,
|
||||
key: (Symbol, Layout<'a>),
|
||||
key: (Symbol, TopLevelFunctionLayout<'a>),
|
||||
) {
|
||||
let already_in_there = self.items.insert(
|
||||
Key::Declaration(proc.name, key.1),
|
||||
|
@ -359,12 +366,19 @@ impl<'a> BorrowInfState<'a> {
|
|||
|
||||
match call_type {
|
||||
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
|
||||
let ps = self
|
||||
.param_map
|
||||
.get_symbol(*name, *full_layout)
|
||||
.get_symbol(*name, top_level)
|
||||
.expect("function is defined");
|
||||
|
||||
// the return value will be owned
|
||||
|
@ -402,7 +416,10 @@ impl<'a> BorrowInfState<'a> {
|
|||
|
||||
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 {
|
||||
ListMap | ListKeepIf | ListKeepOks | ListKeepErrs => {
|
||||
|
@ -584,7 +601,8 @@ impl<'a> BorrowInfState<'a> {
|
|||
call_type:
|
||||
crate::ir::CallType::ByName {
|
||||
name: g,
|
||||
full_layout,
|
||||
arg_layouts,
|
||||
ret_layout,
|
||||
..
|
||||
},
|
||||
arguments: ys,
|
||||
|
@ -593,10 +611,15 @@ impl<'a> BorrowInfState<'a> {
|
|||
Stmt::Ret(z),
|
||||
) = (v, b)
|
||||
{
|
||||
let top_level = TopLevelFunctionLayout {
|
||||
arguments: arg_layouts,
|
||||
result: *ret_layout,
|
||||
};
|
||||
|
||||
if self.current_proc == *g && x == *z {
|
||||
// anonymous functions (for which the ps may not be known)
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
|
@ -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 ys = Vec::from_iter_in(proc.args.iter().map(|t| t.1), self.arena).into_bump_slice();
|
||||
|
|
|
@ -245,9 +245,6 @@ fn layout_for_constructor<'a>(
|
|||
HasFields(fields)
|
||||
}
|
||||
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)
|
||||
ConstructorLayout::Unknown
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
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 bumpalo::collections::Vec;
|
||||
use bumpalo::Bump;
|
||||
|
@ -497,7 +497,10 @@ impl<'a> Context<'a> {
|
|||
const FUNCTION: 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 {
|
||||
roc_module::low_level::LowLevel::ListMap
|
||||
|
@ -679,12 +682,20 @@ impl<'a> Context<'a> {
|
|||
}
|
||||
|
||||
ByName {
|
||||
name, full_layout, ..
|
||||
name,
|
||||
ret_layout,
|
||||
arg_layouts,
|
||||
..
|
||||
} => {
|
||||
let top_level = TopLevelFunctionLayout {
|
||||
arguments: arg_layouts,
|
||||
result: *ret_layout,
|
||||
};
|
||||
|
||||
// get the borrow signature
|
||||
let ps = self
|
||||
.param_map
|
||||
.get_symbol(*name, *full_layout)
|
||||
.get_symbol(*name, top_level)
|
||||
.expect("function is defined");
|
||||
|
||||
let v = Expr::Call(crate::ir::Call {
|
||||
|
@ -963,12 +974,20 @@ impl<'a> Context<'a> {
|
|||
}
|
||||
|
||||
CallType::ByName {
|
||||
name, full_layout, ..
|
||||
name,
|
||||
ret_layout,
|
||||
arg_layouts,
|
||||
..
|
||||
} => {
|
||||
let top_level = TopLevelFunctionLayout {
|
||||
arguments: arg_layouts,
|
||||
result: *ret_layout,
|
||||
};
|
||||
|
||||
// get the borrow signature
|
||||
let ps = self
|
||||
.param_map
|
||||
.get_symbol(*name, *full_layout)
|
||||
.get_symbol(*name, top_level)
|
||||
.expect("function is defined");
|
||||
self.add_dec_after_application(call.arguments, ps, cont, &invoke_live_vars)
|
||||
}
|
||||
|
@ -1222,7 +1241,7 @@ pub fn visit_proc<'a>(
|
|||
arena: &'a Bump,
|
||||
param_map: &'a ParamMap<'a>,
|
||||
proc: &mut Proc<'a>,
|
||||
layout: Layout<'a>,
|
||||
layout: TopLevelFunctionLayout<'a>,
|
||||
) {
|
||||
let ctx = Context::new(arena, param_map);
|
||||
|
||||
|
|
|
@ -215,7 +215,7 @@ impl<'a> Proc<'a> {
|
|||
let borrow_params = arena.alloc(crate::borrow::infer_borrow(arena, procs));
|
||||
|
||||
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));
|
||||
|
||||
for (key, proc) in result.iter_mut() {
|
||||
let layout = arena.alloc(key.1).full();
|
||||
crate::inc_dec::visit_proc(arena, borrow_params, proc, layout);
|
||||
crate::inc_dec::visit_proc(arena, borrow_params, proc, key.1);
|
||||
}
|
||||
|
||||
result
|
||||
|
@ -454,8 +453,7 @@ impl<'a> Procs<'a> {
|
|||
let borrow_params = arena.alloc(crate::borrow::infer_borrow(arena, &result));
|
||||
|
||||
for (key, proc) in result.iter_mut() {
|
||||
let layout = arena.alloc(key.1).full();
|
||||
crate::inc_dec::visit_proc(arena, borrow_params, proc, layout);
|
||||
crate::inc_dec::visit_proc(arena, borrow_params, proc, key.1);
|
||||
}
|
||||
|
||||
(result, borrow_params)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue