mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-30 15:21: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(),
|
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();
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue