thread reset-reuse through

This commit is contained in:
Folkert 2021-07-03 01:13:50 +02:00
parent 5bb3146aa8
commit ee67ee546a
5 changed files with 85 additions and 55 deletions

View file

@ -970,15 +970,25 @@ pub fn build_exp_expr<'a, 'ctx, 'env>(
struct_from_fields(env, struct_type, field_vals.into_iter().enumerate()).into() struct_from_fields(env, struct_type, field_vals.into_iter().enumerate()).into()
} }
Tag { Reuse {
arguments,
tag_layout: union_layout,
tag_id,
..
}
| Tag {
arguments, arguments,
tag_layout: union_layout, tag_layout: union_layout,
tag_id, tag_id,
.. ..
} => build_tag(env, scope, union_layout, *tag_id, arguments), } => build_tag(env, scope, union_layout, *tag_id, arguments),
Reset(_) => todo!(), Reset(_) => {
Reuse { .. } => todo!(), // 1. fetch refcount
// 2. if rc == 1, reset the value
// TODO
env.context.i64_type().const_zero().into()
}
StructAtIndex { StructAtIndex {
index, structure, .. index, structure, ..

View file

@ -2072,6 +2072,8 @@ fn update<'a>(
&mut state.procedures, &mut state.procedures,
); );
Proc::insert_refcount_operations(arena, &mut state.procedures);
// display the mono IR of the module, for debug purposes // display the mono IR of the module, for debug purposes
if roc_mono::ir::PRETTY_PRINT_IR_SYMBOLS { if roc_mono::ir::PRETTY_PRINT_IR_SYMBOLS {
let procs_string = state let procs_string = state
@ -2085,8 +2087,6 @@ fn update<'a>(
println!("{}", result); println!("{}", result);
} }
Proc::insert_refcount_operations(arena, &mut state.procedures);
// This is not safe with the new non-recursive RC updates that we do for tag unions // This is not safe with the new non-recursive RC updates that we do for tag unions
// //
// Proc::optimize_refcount_operations( // Proc::optimize_refcount_operations(

View file

@ -832,7 +832,14 @@ fn expr_spec(
match expr { match expr {
Literal(literal) => literal_spec(builder, block, literal), Literal(literal) => literal_spec(builder, block, literal),
Call(call) => call_spec(builder, env, block, layout, call), Call(call) => call_spec(builder, env, block, layout, call),
Tag { Reuse {
tag_layout,
tag_name: _,
tag_id,
arguments,
..
}
| Tag {
tag_layout, tag_layout,
tag_name: _, tag_name: _,
tag_id, tag_id,
@ -914,8 +921,12 @@ fn expr_spec(
Err(()) => unreachable!("empty array does not have a list layout"), Err(()) => unreachable!("empty array does not have a list layout"),
} }
} }
Reuse { .. } => todo!("currently unused"), Reset(symbol) => {
Reset(_) => todo!("currently unused"), let type_id = layout_spec(builder, layout)?;
let value_id = env.symbols[symbol];
builder.add_unknown_with(block, &[value_id], type_id)
}
RuntimeErrorFunction(_) => { RuntimeErrorFunction(_) => {
let type_id = layout_spec(builder, layout)?; let type_id = layout_spec(builder, layout)?;

View file

@ -234,7 +234,8 @@ impl<'a> Proc<'a> {
procs: &mut MutMap<(Symbol, ProcLayout<'a>), Proc<'a>>, procs: &mut MutMap<(Symbol, ProcLayout<'a>), Proc<'a>>,
) { ) {
for (key, proc) in procs.iter_mut() { for (key, proc) in procs.iter_mut() {
let new_proc = crate::reset_reuse::insert_reset_reuse(arena, home, ident_ids, proc.clone()); let new_proc =
crate::reset_reuse::insert_reset_reuse(arena, home, ident_ids, proc.clone());
*proc = new_proc; *proc = new_proc;
} }
} }
@ -1287,11 +1288,12 @@ impl<'a> Expr<'a> {
alloc alloc
.text("Reuse ") .text("Reuse ")
.append(symbol_to_doc(alloc, *symbol)) .append(symbol_to_doc(alloc, *symbol))
.append(alloc.space())
.append(doc_tag) .append(doc_tag)
.append(alloc.space()) .append(alloc.space())
.append(alloc.intersperse(it, " ")) .append(alloc.intersperse(it, " "))
} }
Reset(symbol) => alloc.text("Reuse ").append(symbol_to_doc(alloc, *symbol)), Reset(symbol) => alloc.text("Reset ").append(symbol_to_doc(alloc, *symbol)),
Struct(args) => { Struct(args) => {
let it = args.iter().map(|s| symbol_to_doc(alloc, *s)); let it = args.iter().map(|s| symbol_to_doc(alloc, *s));

View file

@ -1,5 +1,5 @@
use crate::inc_dec::{collect_stmt, occurring_variables_expr, JPLiveVarMap, LiveVarSet}; use crate::inc_dec::{collect_stmt, occurring_variables_expr, JPLiveVarMap, LiveVarSet};
use crate::ir::{Call, Expr, Proc, Stmt, BranchInfo}; use crate::ir::{BranchInfo, Call, Expr, Proc, Stmt};
use crate::layout::{Layout, UnionLayout}; use crate::layout::{Layout, UnionLayout};
use bumpalo::collections::Vec; use bumpalo::collections::Vec;
use bumpalo::Bump; use bumpalo::Bump;
@ -25,15 +25,16 @@ pub fn insert_reset_reuse<'a, 'i>(
proc proc
} }
#[derive(Debug)]
struct CtorInfo<'a> { struct CtorInfo<'a> {
id: u8, id: u8,
layout: UnionLayout<'a>, layout: UnionLayout<'a>,
} }
fn may_reuse(tag_layout: UnionLayout, tag_id: u8, other: &CtorInfo) -> bool { fn may_reuse(tag_layout: UnionLayout, tag_id: u8, other: &CtorInfo) -> bool {
if tag_layout != other.layout { // if tag_layout != other.layout {
return false; // return false;
} // }
// if the tag id is represented as NULL, there is no memory to re-use // if the tag id is represented as NULL, there is no memory to re-use
match tag_layout { match tag_layout {
@ -248,7 +249,8 @@ fn function_d_main<'a, 'i>(
let arena = env.arena; let arena = env.arena;
match stmt { match stmt {
Let(symbol, expr, layout, continuation) => match expr { Let(symbol, expr, layout, continuation) => {
match expr {
Expr::Tag { arguments, .. } if arguments.iter().any(|s| *s == x) => { Expr::Tag { arguments, .. } if arguments.iter().any(|s| *s == x) => {
// If the scrutinee `x` (the one that is providing memory) is being // If the scrutinee `x` (the one that is providing memory) is being
// stored in a constructor, then reuse will probably not be able to reuse memory at runtime. // stored in a constructor, then reuse will probably not be able to reuse memory at runtime.
@ -273,7 +275,8 @@ fn function_d_main<'a, 'i>(
(arena.alloc(let_stmt), found) (arena.alloc(let_stmt), found)
} }
} }
}, }
}
Invoke { Invoke {
symbol, symbol,
call, call,
@ -409,17 +412,19 @@ fn function_r<'a, 'i>(env: &mut Env<'a, 'i>, stmt: &'a Stmt<'a>) -> &'a Stmt<'a>
let new_body = match info { let new_body = match info {
BranchInfo::None => temp, BranchInfo::None => temp,
BranchInfo::Constructor { scrutinee, layout, tag_id } => { BranchInfo::Constructor {
match layout { scrutinee,
layout,
tag_id,
} => match layout {
Layout::Union(union_layout) => { Layout::Union(union_layout) => {
let ctor_info = CtorInfo { let ctor_info = CtorInfo {
layout: *union_layout, layout: *union_layout,
id: *tag_id, id: *tag_id,
}; };
function_d(env, *scrutinee, &ctor_info, temp) function_d(env, *scrutinee, &ctor_info, temp)
},
_ => temp,
} }
_ => temp,
}, },
}; };
@ -432,17 +437,19 @@ fn function_r<'a, 'i>(env: &mut Env<'a, 'i>, stmt: &'a Stmt<'a>) -> &'a Stmt<'a>
let new_body = match info { let new_body = match info {
BranchInfo::None => temp, BranchInfo::None => temp,
BranchInfo::Constructor { scrutinee, layout, tag_id } => { BranchInfo::Constructor {
match layout { scrutinee,
layout,
tag_id,
} => match layout {
Layout::Union(union_layout) => { Layout::Union(union_layout) => {
let ctor_info = CtorInfo { let ctor_info = CtorInfo {
layout: *union_layout, layout: *union_layout,
id: *tag_id, id: *tag_id,
}; };
function_d(env, *scrutinee, &ctor_info, temp) function_d(env, *scrutinee, &ctor_info, temp)
},
_ => temp,
} }
_ => temp,
}, },
}; };