mirror of
https://github.com/roc-lang/roc.git
synced 2025-10-03 08:34:33 +00:00
WIP infer join points too
This commit is contained in:
parent
0932c542ca
commit
047779d981
18 changed files with 156 additions and 94 deletions
|
@ -349,8 +349,9 @@ where
|
|||
}
|
||||
|
||||
match opt_level {
|
||||
OptLevel::Development | OptLevel::Normal => morphic_lib::solve_trivial(program),
|
||||
OptLevel::Optimize | OptLevel::Size => morphic_lib::solve(program),
|
||||
// OptLevel::Development | OptLevel::Normal => morphic_lib::solve_trivial(program),
|
||||
// OptLevel::Optimize | OptLevel::Size => morphic_lib::solve(program),
|
||||
_ => morphic_lib::solve_trivial(program),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
use bumpalo::{collections::Vec, Bump};
|
||||
use bumpalo::{
|
||||
collections::{CollectIn, Vec},
|
||||
Bump,
|
||||
};
|
||||
use roc_collections::{MutMap, ReferenceMatrix};
|
||||
use roc_error_macros::todo_lambda_erasure;
|
||||
use roc_module::symbol::Symbol;
|
||||
|
||||
use crate::{
|
||||
inc_dec::Ownership,
|
||||
ir::{Call, CallType, Expr, Proc, ProcLayout, Stmt},
|
||||
ir::{Call, CallType, Expr, JoinPointId, Param, Proc, ProcLayout, Stmt},
|
||||
layout::{Builtin, InLayout, LayoutInterner, LayoutRepr, Niche},
|
||||
};
|
||||
|
||||
|
@ -46,15 +48,19 @@ impl BorrowSignature {
|
|||
}
|
||||
}
|
||||
|
||||
fn set(&mut self, index: usize, ownership: Ownership) {
|
||||
fn set(&mut self, index: usize, ownership: Ownership) -> bool {
|
||||
assert!(index < self.len());
|
||||
|
||||
let modified = self.get(index) != Some(&ownership);
|
||||
|
||||
let mask = 1 << (index + 8);
|
||||
|
||||
match ownership {
|
||||
Ownership::Owned => self.0 |= mask,
|
||||
Ownership::Borrowed => self.0 &= !mask,
|
||||
}
|
||||
|
||||
modified
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> impl Iterator<Item = Ownership> + '_ {
|
||||
|
@ -76,27 +82,35 @@ impl std::ops::Index<usize> for BorrowSignature {
|
|||
}
|
||||
}
|
||||
|
||||
pub(crate) type BorrowSignatures<'a> = MutMap<(Symbol, ProcLayout<'a>), BorrowSignature>;
|
||||
pub(crate) struct BorrowSignatures<'a> {
|
||||
pub(crate) procs: MutMap<(Symbol, ProcLayout<'a>), BorrowSignature>,
|
||||
}
|
||||
|
||||
pub(crate) fn infer_borrow_signatures<'a, 'b: 'a>(
|
||||
arena: &'a Bump,
|
||||
interner: &impl LayoutInterner<'a>,
|
||||
procs: &'b MutMap<(Symbol, ProcLayout<'a>), Proc<'a>>,
|
||||
) -> BorrowSignatures<'a> {
|
||||
let mut borrow_signatures: BorrowSignatures = procs
|
||||
.iter()
|
||||
.map(|(_key, proc)| {
|
||||
let mut signature = BorrowSignature::new(proc.args.len());
|
||||
let mut borrow_signatures: BorrowSignatures = BorrowSignatures {
|
||||
procs: procs
|
||||
.iter()
|
||||
.map(|(_key, proc)| {
|
||||
let mut signature = BorrowSignature::new(proc.args.len());
|
||||
|
||||
let key = (proc.name.name(), proc.proc_layout(arena));
|
||||
let key = (proc.name.name(), proc.proc_layout(arena));
|
||||
|
||||
for (i, in_layout) in key.1.arguments.iter().enumerate() {
|
||||
signature.set(i, layout_to_ownership(*in_layout, interner));
|
||||
}
|
||||
for (i, in_layout) in key.1.arguments.iter().enumerate() {
|
||||
signature.set(i, layout_to_ownership(*in_layout, interner));
|
||||
}
|
||||
|
||||
(key, signature)
|
||||
})
|
||||
.collect();
|
||||
(key, signature)
|
||||
})
|
||||
.collect(),
|
||||
};
|
||||
|
||||
let mut join_points: Vec<_> = std::iter::repeat_with(MutMap::default)
|
||||
.take(procs.len())
|
||||
.collect_in(arena);
|
||||
|
||||
// next we first partition the functions into strongly connected components, then do a
|
||||
// topological sort on these components, finally run the fix-point borrow analysis on each
|
||||
|
@ -105,6 +119,9 @@ pub(crate) fn infer_borrow_signatures<'a, 'b: 'a>(
|
|||
let matrix = construct_reference_matrix(arena, procs);
|
||||
let sccs = matrix.strongly_connected_components_all();
|
||||
|
||||
let mut join_point_stack = Vec::new_in(arena);
|
||||
let mut proc_join_points = MutMap::default();
|
||||
|
||||
for (group, _) in sccs.groups() {
|
||||
// This is a fixed-point analysis
|
||||
//
|
||||
|
@ -121,22 +138,38 @@ pub(crate) fn infer_borrow_signatures<'a, 'b: 'a>(
|
|||
let (_, proc) = procs.iter().nth(index).unwrap();
|
||||
let key = (proc.name.name(), proc.proc_layout(arena));
|
||||
|
||||
std::mem::swap(&mut proc_join_points, &mut join_points[index]);
|
||||
|
||||
if proc.args.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut state = State {
|
||||
args: proc.args,
|
||||
borrow_signature: *borrow_signatures.get(&key).unwrap(),
|
||||
borrow_signature: *borrow_signatures.procs.get(&key).unwrap(),
|
||||
join_point_stack,
|
||||
join_points: proc_join_points,
|
||||
modified: false,
|
||||
};
|
||||
|
||||
state.inspect_stmt(&mut borrow_signatures, &proc.body);
|
||||
state.inspect_stmt(interner, &mut borrow_signatures, &proc.body);
|
||||
|
||||
let Some(old) = borrow_signatures.insert(key, state.borrow_signature) else {
|
||||
let Some(old) = borrow_signatures.procs.insert(key, state.borrow_signature) else {
|
||||
unreachable!("key should be present");
|
||||
};
|
||||
|
||||
modified |= old != state.borrow_signature
|
||||
// TODO I think this should use state.modified, but that loops infinitely currently
|
||||
// also maybe a change in join point signature is always immediately reflected in a
|
||||
// change in proc signature, in which case using the join point changes may not
|
||||
// have any effect.
|
||||
modified |= old != state.borrow_signature;
|
||||
|
||||
proc_join_points = state.join_points;
|
||||
|
||||
std::mem::swap(&mut proc_join_points, &mut join_points[index]);
|
||||
|
||||
join_point_stack = state.join_point_stack;
|
||||
join_point_stack.clear();
|
||||
}
|
||||
|
||||
if !modified {
|
||||
|
@ -156,7 +189,7 @@ fn infer_borrow_signature<'a>(
|
|||
proc: &'a Proc<'a>,
|
||||
) -> BorrowSignature {
|
||||
let mut state = State::new(arena, interner, borrow_signatures, proc);
|
||||
state.inspect_stmt(borrow_signatures, &proc.body);
|
||||
state.inspect_stmt(interner, borrow_signatures, &proc.body);
|
||||
state.borrow_signature
|
||||
}
|
||||
|
||||
|
@ -165,6 +198,9 @@ struct State<'a> {
|
|||
/// for which borrow inference might decide to pass as borrowed
|
||||
args: &'a [(InLayout<'a>, Symbol)],
|
||||
borrow_signature: BorrowSignature,
|
||||
join_point_stack: Vec<'a, (JoinPointId, &'a [Param<'a>])>,
|
||||
join_points: MutMap<JoinPointId, BorrowSignature>,
|
||||
modified: bool,
|
||||
}
|
||||
|
||||
fn layout_to_ownership<'a>(
|
||||
|
@ -172,7 +208,8 @@ fn layout_to_ownership<'a>(
|
|||
interner: &impl LayoutInterner<'a>,
|
||||
) -> Ownership {
|
||||
match interner.get_repr(in_layout) {
|
||||
LayoutRepr::Builtin(Builtin::Str | Builtin::List(_)) => Ownership::Borrowed,
|
||||
LayoutRepr::Builtin(Builtin::Str) => Ownership::Borrowed,
|
||||
LayoutRepr::Builtin(Builtin::List(_)) => Ownership::Borrowed,
|
||||
LayoutRepr::LambdaSet(inner) => {
|
||||
layout_to_ownership(inner.runtime_representation(), interner)
|
||||
}
|
||||
|
@ -190,7 +227,7 @@ impl<'a> State<'a> {
|
|||
let key = (proc.name.name(), proc.proc_layout(arena));
|
||||
|
||||
// initialize the borrow signature based on the layout if first time
|
||||
let borrow_signature = borrow_signatures.entry(key).or_insert_with(|| {
|
||||
let borrow_signature = borrow_signatures.procs.entry(key).or_insert_with(|| {
|
||||
let mut borrow_signature = BorrowSignature::new(proc.args.len());
|
||||
|
||||
for (i, in_layout) in key.1.arguments.iter().enumerate() {
|
||||
|
@ -203,6 +240,9 @@ impl<'a> State<'a> {
|
|||
Self {
|
||||
args: proc.args,
|
||||
borrow_signature: *borrow_signature,
|
||||
join_point_stack: Vec::new_in(arena),
|
||||
join_points: MutMap::default(),
|
||||
modified: false,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -211,15 +251,30 @@ impl<'a> State<'a> {
|
|||
/// Currently argument symbols participate if `layout_to_ownership` returns `Borrowed` for their layout.
|
||||
fn mark_owned(&mut self, symbol: Symbol) {
|
||||
if let Some(index) = self.args.iter().position(|(_, s)| *s == symbol) {
|
||||
self.borrow_signature.set(index, Ownership::Owned);
|
||||
self.modified |= self.borrow_signature.set(index, Ownership::Owned);
|
||||
}
|
||||
|
||||
for (id, params) in &self.join_point_stack {
|
||||
if let Some(index) = params.iter().position(|p| p.symbol == symbol) {
|
||||
self.modified |= self
|
||||
.join_points
|
||||
.get_mut(id)
|
||||
.unwrap()
|
||||
.set(index, Ownership::Owned);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn inspect_stmt(&mut self, borrow_signatures: &mut BorrowSignatures<'a>, stmt: &'a Stmt<'a>) {
|
||||
fn inspect_stmt(
|
||||
&mut self,
|
||||
interner: &impl LayoutInterner<'a>,
|
||||
borrow_signatures: &mut BorrowSignatures<'a>,
|
||||
stmt: &'a Stmt<'a>,
|
||||
) {
|
||||
match stmt {
|
||||
Stmt::Let(_, expr, _, stmt) => {
|
||||
self.inspect_expr(borrow_signatures, expr);
|
||||
self.inspect_stmt(borrow_signatures, stmt);
|
||||
self.inspect_stmt(interner, borrow_signatures, stmt);
|
||||
}
|
||||
Stmt::Switch {
|
||||
branches,
|
||||
|
@ -227,9 +282,9 @@ impl<'a> State<'a> {
|
|||
..
|
||||
} => {
|
||||
for (_, _, stmt) in branches.iter() {
|
||||
self.inspect_stmt(borrow_signatures, stmt);
|
||||
self.inspect_stmt(interner, borrow_signatures, stmt);
|
||||
}
|
||||
self.inspect_stmt(borrow_signatures, default_branch.1);
|
||||
self.inspect_stmt(interner, borrow_signatures, default_branch.1);
|
||||
}
|
||||
Stmt::Ret(s) => {
|
||||
// to return a value we must own it
|
||||
|
@ -239,20 +294,47 @@ impl<'a> State<'a> {
|
|||
Stmt::Refcounting(_, _) => unreachable!("not inserted yet"),
|
||||
Stmt::Expect { remainder, .. } | Stmt::ExpectFx { remainder, .. } => {
|
||||
// based on my reading of inc_dec.rs, expect borrows the symbols
|
||||
self.inspect_stmt(borrow_signatures, remainder);
|
||||
self.inspect_stmt(interner, borrow_signatures, remainder);
|
||||
}
|
||||
Stmt::Dbg { remainder, .. } => {
|
||||
// based on my reading of inc_dec.rs, expect borrows the symbol
|
||||
self.inspect_stmt(borrow_signatures, remainder);
|
||||
self.inspect_stmt(interner, borrow_signatures, remainder);
|
||||
}
|
||||
Stmt::Join {
|
||||
body, remainder, ..
|
||||
id,
|
||||
parameters,
|
||||
body,
|
||||
remainder,
|
||||
} => {
|
||||
self.inspect_stmt(borrow_signatures, body);
|
||||
self.inspect_stmt(borrow_signatures, remainder);
|
||||
self.join_points.entry(*id).or_insert_with(|| {
|
||||
let mut signature = BorrowSignature::new(parameters.len());
|
||||
|
||||
for (i, param) in parameters.iter().enumerate() {
|
||||
signature.set(i, layout_to_ownership(param.layout, interner));
|
||||
}
|
||||
|
||||
signature
|
||||
});
|
||||
self.join_point_stack.push((*id, parameters));
|
||||
self.inspect_stmt(interner, borrow_signatures, body);
|
||||
self.join_point_stack.pop().unwrap();
|
||||
self.inspect_stmt(interner, borrow_signatures, remainder);
|
||||
}
|
||||
|
||||
Stmt::Jump(_, _) | Stmt::Crash(_, _) => { /* not relevant for ownership */ }
|
||||
Stmt::Jump(id, arguments) => {
|
||||
let borrow_signature = match self.join_points.get(id) {
|
||||
Some(s) => *s,
|
||||
None => unreachable!("no borrow signature for join point {id:?} layout"),
|
||||
};
|
||||
|
||||
for (argument, ownership) in arguments.iter().zip(borrow_signature.iter()) {
|
||||
if let Ownership::Owned = ownership {
|
||||
self.mark_owned(*argument);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Stmt::Crash(_, _) => { /* not relevant for ownership */ }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -281,10 +363,11 @@ impl<'a> State<'a> {
|
|||
niche: Niche::NONE,
|
||||
};
|
||||
|
||||
let borrow_signature = match borrow_signatures.get(&(name.name(), proc_layout)) {
|
||||
Some(s) => s,
|
||||
None => unreachable!("no borrow signature for {name:?} layout"),
|
||||
};
|
||||
let borrow_signature =
|
||||
match borrow_signatures.procs.get(&(name.name(), proc_layout)) {
|
||||
Some(s) => s,
|
||||
None => unreachable!("no borrow signature for {name:?} layout"),
|
||||
};
|
||||
|
||||
for (argument, ownership) in arguments.iter().zip(borrow_signature.iter()) {
|
||||
if let Ownership::Owned = ownership {
|
||||
|
|
|
@ -38,7 +38,7 @@ pub fn insert_inc_dec_operations<'a>(
|
|||
let borrow_signatures = crate::borrow::infer_borrow_signatures(arena, layout_interner, ps);
|
||||
let borrow_signatures = arena.alloc(borrow_signatures);
|
||||
|
||||
// for ((s, _), sig) in borrow_signatures.iter() {
|
||||
// for ((s, _), sig) in borrow_signatures.procs.iter() {
|
||||
// dbg!((s, sig));
|
||||
// }
|
||||
|
||||
|
@ -58,10 +58,8 @@ pub fn insert_inc_dec_operations<'a>(
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
Enum indicating whether a symbol should be reference counted or not.
|
||||
This includes layouts that themselves can be stack allocated but that contain a heap allocated item.
|
||||
*/
|
||||
/// Enum indicating whether a symbol should be reference counted or not.
|
||||
/// This includes layouts that themselves can be stack allocated but that contain a heap allocated item.
|
||||
#[derive(Copy, Clone)]
|
||||
enum VarRcType {
|
||||
ReferenceCounted,
|
||||
|
@ -435,6 +433,7 @@ fn insert_inc_dec_operations_proc<'a>(
|
|||
|
||||
// Add all arguments to the environment (if they are reference counted)
|
||||
let borrow_signature = borrow_signatures
|
||||
.procs
|
||||
.get(&(proc.name.name(), proc.proc_layout(arena)))
|
||||
.unwrap();
|
||||
for ((_, symbol), ownership) in proc.args.iter().zip(borrow_signature.iter()) {
|
||||
|
@ -1008,10 +1007,6 @@ fn insert_refcount_operations_binding<'a>(
|
|||
ret_layout,
|
||||
..
|
||||
} => {
|
||||
// let new_let = new_let!(stmt);
|
||||
//
|
||||
// inc_owned!(arguments.iter().copied(), new_let)
|
||||
|
||||
let proc_layout = ProcLayout {
|
||||
arguments: arg_layouts,
|
||||
result: ret_layout,
|
||||
|
@ -1020,6 +1015,7 @@ fn insert_refcount_operations_binding<'a>(
|
|||
|
||||
let borrow_signature = match environment
|
||||
.borrow_signatures
|
||||
.procs
|
||||
.get(&(name.name(), proc_layout))
|
||||
{
|
||||
Some(s) => s,
|
||||
|
|
|
@ -29,7 +29,8 @@ const TEST_WRAPPER_NAME: &str = "test_wrapper";
|
|||
|
||||
#[allow(dead_code)]
|
||||
pub const OPT_LEVEL: OptLevel = if cfg!(debug_assertions) {
|
||||
OptLevel::Normal
|
||||
// OptLevel::Normal
|
||||
OptLevel::Optimize
|
||||
} else {
|
||||
OptLevel::Optimize
|
||||
};
|
||||
|
|
|
@ -51,7 +51,7 @@ procedure Test.11 (#Derived_gen.10, #Derived_gen.11):
|
|||
joinpoint Test.27 Test.12 #Attr.12:
|
||||
let Test.34 : Int1 = UnionAtIndex (Id 2) (Index 1) #Attr.12;
|
||||
let Test.33 : [<rnw><null>, C *self Int1, C *self Int1] = UnionAtIndex (Id 2) (Index 0) #Attr.12;
|
||||
joinpoint #Derived_gen.16:
|
||||
joinpoint #Derived_gen.14:
|
||||
joinpoint Test.31 Test.29:
|
||||
let Test.30 : U8 = GetTagId Test.33;
|
||||
switch Test.30:
|
||||
|
@ -78,16 +78,15 @@ procedure Test.11 (#Derived_gen.10, #Derived_gen.11):
|
|||
jump Test.31 Test.32;
|
||||
|
||||
in
|
||||
let #Derived_gen.17 : Int1 = lowlevel RefCountIsUnique #Attr.12;
|
||||
if #Derived_gen.17 then
|
||||
let #Derived_gen.15 : Int1 = lowlevel RefCountIsUnique #Attr.12;
|
||||
if #Derived_gen.15 then
|
||||
free #Attr.12;
|
||||
jump #Derived_gen.16;
|
||||
jump #Derived_gen.14;
|
||||
else
|
||||
inc Test.33;
|
||||
decref #Attr.12;
|
||||
jump #Derived_gen.16;
|
||||
jump #Derived_gen.14;
|
||||
in
|
||||
inc #Derived_gen.10;
|
||||
jump Test.27 #Derived_gen.10 #Derived_gen.11;
|
||||
|
||||
procedure Test.2 (Test.13):
|
||||
|
@ -144,7 +143,6 @@ procedure Test.9 (Test.10, #Attr.12):
|
|||
|
||||
default:
|
||||
let Test.41 : Str = CallByName Test.11 Test.10 Test.42;
|
||||
dec Test.10;
|
||||
jump Test.40 Test.41;
|
||||
|
||||
in
|
||||
|
@ -180,6 +178,5 @@ procedure Test.0 ():
|
|||
|
||||
default:
|
||||
let Test.17 : Str = CallByName Test.11 Test.18 Test.16;
|
||||
dec Test.18;
|
||||
ret Test.17;
|
||||
|
||||
|
|
|
@ -128,7 +128,6 @@ procedure List.92 (#Derived_gen.29, #Derived_gen.30, #Derived_gen.31, #Derived_g
|
|||
ret List.164;
|
||||
in
|
||||
inc #Derived_gen.29;
|
||||
inc #Derived_gen.30;
|
||||
jump List.603 #Derived_gen.29 #Derived_gen.30 #Derived_gen.31 #Derived_gen.32 #Derived_gen.33;
|
||||
|
||||
procedure List.92 (#Derived_gen.37, #Derived_gen.38, #Derived_gen.39, #Derived_gen.40, #Derived_gen.41):
|
||||
|
@ -146,7 +145,6 @@ procedure List.92 (#Derived_gen.37, #Derived_gen.38, #Derived_gen.39, #Derived_g
|
|||
ret List.164;
|
||||
in
|
||||
inc #Derived_gen.37;
|
||||
inc #Derived_gen.38;
|
||||
jump List.577 #Derived_gen.37 #Derived_gen.38 #Derived_gen.39 #Derived_gen.40 #Derived_gen.41;
|
||||
|
||||
procedure Num.127 (#Attr.2):
|
||||
|
@ -235,7 +233,6 @@ procedure Test.67 (Test.68, Test.262, Test.66):
|
|||
let Test.69 : List U8 = CallByName Test.3 Test.68 Test.290 Test.291;
|
||||
let Test.265 : {} = Struct {};
|
||||
let Test.264 : List U8 = CallByName List.18 Test.66 Test.69 Test.265;
|
||||
dec Test.69;
|
||||
ret Test.264;
|
||||
|
||||
procedure Test.67 (Test.68, Test.262, Test.66):
|
||||
|
@ -244,7 +241,6 @@ procedure Test.67 (Test.68, Test.262, Test.66):
|
|||
let Test.69 : List U8 = CallByName Test.3 Test.68 Test.322 Test.323;
|
||||
let Test.297 : {} = Struct {};
|
||||
let Test.296 : List U8 = CallByName List.18 Test.66 Test.69 Test.297;
|
||||
dec Test.69;
|
||||
ret Test.296;
|
||||
|
||||
procedure Test.70 (Test.71, Test.266):
|
||||
|
|
|
@ -85,7 +85,6 @@ procedure List.92 (#Derived_gen.13, #Derived_gen.14, #Derived_gen.15, #Derived_g
|
|||
dec List.163;
|
||||
ret List.164;
|
||||
in
|
||||
inc #Derived_gen.14;
|
||||
inc #Derived_gen.13;
|
||||
jump List.577 #Derived_gen.13 #Derived_gen.14 #Derived_gen.15 #Derived_gen.16 #Derived_gen.17;
|
||||
|
||||
|
@ -171,7 +170,6 @@ procedure Test.67 (Test.68, Test.261, Test.66):
|
|||
let Test.69 : List U8 = CallByName Test.3 Test.68 Test.289 Test.290;
|
||||
let Test.264 : {} = Struct {};
|
||||
let Test.263 : List U8 = CallByName List.18 Test.66 Test.69 Test.264;
|
||||
dec Test.69;
|
||||
ret Test.263;
|
||||
|
||||
procedure Test.70 (Test.71, Test.265):
|
||||
|
|
|
@ -93,7 +93,6 @@ procedure List.92 (#Derived_gen.17, #Derived_gen.18, #Derived_gen.19, #Derived_g
|
|||
ret List.164;
|
||||
in
|
||||
inc #Derived_gen.17;
|
||||
inc #Derived_gen.18;
|
||||
jump List.577 #Derived_gen.17 #Derived_gen.18 #Derived_gen.19 #Derived_gen.20 #Derived_gen.21;
|
||||
|
||||
procedure Num.127 (#Attr.2):
|
||||
|
@ -178,7 +177,6 @@ procedure Test.67 (Test.68, Test.262, Test.66):
|
|||
let Test.69 : List U8 = CallByName Test.3 Test.68 Test.290 Test.291;
|
||||
let Test.265 : {} = Struct {};
|
||||
let Test.264 : List U8 = CallByName List.18 Test.66 Test.69 Test.265;
|
||||
dec Test.69;
|
||||
ret Test.264;
|
||||
|
||||
procedure Test.70 (Test.71, Test.266):
|
||||
|
|
|
@ -90,7 +90,6 @@ procedure List.92 (#Derived_gen.13, #Derived_gen.14, #Derived_gen.15, #Derived_g
|
|||
dec List.163;
|
||||
ret List.164;
|
||||
in
|
||||
inc #Derived_gen.14;
|
||||
inc #Derived_gen.13;
|
||||
jump List.577 #Derived_gen.13 #Derived_gen.14 #Derived_gen.15 #Derived_gen.16 #Derived_gen.17;
|
||||
|
||||
|
@ -192,7 +191,6 @@ procedure Test.60 (Test.61, Test.266, #Attr.12):
|
|||
let Test.62 : List U8 = CallByName Test.3 Test.61 Test.274 Test.275;
|
||||
let Test.268 : List U8 = CallByName List.18 Test.58 Test.62 Test.59;
|
||||
dec Test.58;
|
||||
dec Test.62;
|
||||
ret Test.268;
|
||||
|
||||
procedure Test.63 (Test.64, Test.65, Test.59):
|
||||
|
|
|
@ -93,7 +93,6 @@ procedure List.92 (#Derived_gen.14, #Derived_gen.15, #Derived_gen.16, #Derived_g
|
|||
dec List.163;
|
||||
ret List.164;
|
||||
in
|
||||
inc #Derived_gen.15;
|
||||
inc #Derived_gen.14;
|
||||
jump List.577 #Derived_gen.14 #Derived_gen.15 #Derived_gen.16 #Derived_gen.17 #Derived_gen.18;
|
||||
|
||||
|
@ -195,7 +194,6 @@ procedure Test.60 (Test.61, Test.267, #Attr.12):
|
|||
let Test.62 : List U8 = CallByName Test.3 Test.61 Test.275 Test.276;
|
||||
let Test.269 : List U8 = CallByName List.18 Test.58 Test.62 Test.59;
|
||||
dec Test.58;
|
||||
dec Test.62;
|
||||
ret Test.269;
|
||||
|
||||
procedure Test.63 (Test.64, Test.65, Test.59):
|
||||
|
|
|
@ -141,7 +141,6 @@ procedure Dict.38 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.
|
|||
let Dict.766 : U32 = CallByName Num.131 Dict.236;
|
||||
let Dict.752 : {U32, U32} = Struct {Dict.766, Dict.224};
|
||||
let Dict.237 : List {U32, U32} = CallByName Dict.67 Dict.221 Dict.752 Dict.223;
|
||||
dec Dict.221;
|
||||
let Dict.751 : {List {U32, U32}, List {Str, I64}, U64, Float32, U8} = Struct {Dict.237, Dict.235, Dict.227, Dict.228, Dict.229};
|
||||
ret Dict.751;
|
||||
else
|
||||
|
@ -150,8 +149,6 @@ procedure Dict.38 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.
|
|||
let Dict.239 : U32 = CallByName Dict.48 Dict.224;
|
||||
jump Dict.736 Dict.221 Dict.222 Dict.238 Dict.239 Dict.225 Dict.226 Dict.227 Dict.228 Dict.229;
|
||||
in
|
||||
inc #Derived_gen.0;
|
||||
inc #Derived_gen.1;
|
||||
inc #Derived_gen.4;
|
||||
jump Dict.736 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.4 #Derived_gen.5 #Derived_gen.6 #Derived_gen.7 #Derived_gen.8;
|
||||
|
||||
|
@ -232,7 +229,6 @@ procedure Dict.59 (Dict.719):
|
|||
let Dict.381 : List {U32, U32} = StructAtIndex 0 Dict.855;
|
||||
let Dict.382 : U64 = StructAtIndex 1 Dict.855;
|
||||
let Dict.383 : List {U32, U32} = CallByName Dict.64 Dict.381 Dict.376 Dict.380;
|
||||
dec Dict.381;
|
||||
let Dict.837 : {List {U32, U32}, List {Str, I64}, U64, Float32, U8} = Struct {Dict.383, Dict.376, Dict.382, Dict.378, Dict.380};
|
||||
ret Dict.837;
|
||||
else
|
||||
|
@ -324,7 +320,6 @@ procedure Dict.67 (#Derived_gen.28, #Derived_gen.29, #Derived_gen.30):
|
|||
let Dict.754 : List {U32, U32} = CallByName List.3 Dict.414 Dict.416 Dict.415;
|
||||
ret Dict.754;
|
||||
in
|
||||
inc #Derived_gen.28;
|
||||
jump Dict.753 #Derived_gen.28 #Derived_gen.29 #Derived_gen.30;
|
||||
|
||||
procedure Dict.68 (Dict.419, Dict.420):
|
||||
|
@ -422,8 +417,6 @@ procedure Dict.8 (Dict.210, Dict.211, Dict.212):
|
|||
let Dict.219 : U32 = CallByName Dict.70 Dict.218;
|
||||
let Dict.220 : U64 = CallByName Dict.71 Dict.218 Dict.217;
|
||||
let Dict.735 : {List {U32, U32}, List {Str, I64}, U64, Float32, U8} = CallByName Dict.38 Dict.213 Dict.214 Dict.220 Dict.219 Dict.211 Dict.212 Dict.215 Dict.216 Dict.217;
|
||||
dec Dict.214;
|
||||
dec Dict.213;
|
||||
dec Dict.211;
|
||||
ret Dict.735;
|
||||
in
|
||||
|
@ -900,7 +893,6 @@ procedure Inspect.60 (Inspect.298):
|
|||
procedure List.11 (List.138, List.139):
|
||||
let List.636 : List {U32, U32} = CallByName List.68 List.139;
|
||||
let List.635 : List {U32, U32} = CallByName List.90 List.138 List.139 List.636;
|
||||
dec List.636;
|
||||
ret List.635;
|
||||
|
||||
procedure List.18 (List.160, List.161, List.162):
|
||||
|
@ -1011,7 +1003,6 @@ procedure List.90 (#Derived_gen.33, #Derived_gen.34, #Derived_gen.35):
|
|||
else
|
||||
ret List.142;
|
||||
in
|
||||
inc #Derived_gen.35;
|
||||
jump List.625 #Derived_gen.33 #Derived_gen.34 #Derived_gen.35;
|
||||
|
||||
procedure List.92 (#Derived_gen.50, #Derived_gen.51, #Derived_gen.52, #Derived_gen.53, #Derived_gen.54):
|
||||
|
@ -1055,7 +1046,6 @@ procedure List.93 (#Derived_gen.23, #Derived_gen.24, #Derived_gen.25, #Derived_g
|
|||
let List.622 : {Str, I64} = CallByName List.66 List.172 List.175;
|
||||
inc List.622;
|
||||
let List.177 : List {U32, U32} = CallByName Dict.398 List.173 List.622 List.175 List.174;
|
||||
dec List.173;
|
||||
let List.621 : U64 = 1i64;
|
||||
let List.620 : U64 = CallByName Num.51 List.175 List.621;
|
||||
jump List.616 List.172 List.177 List.174 List.620 List.176;
|
||||
|
@ -1063,7 +1053,6 @@ procedure List.93 (#Derived_gen.23, #Derived_gen.24, #Derived_gen.25, #Derived_g
|
|||
dec List.172;
|
||||
ret List.173;
|
||||
in
|
||||
inc #Derived_gen.24;
|
||||
inc #Derived_gen.23;
|
||||
jump List.616 #Derived_gen.23 #Derived_gen.24 #Derived_gen.25 #Derived_gen.26 #Derived_gen.27;
|
||||
|
||||
|
|
|
@ -34,7 +34,6 @@ procedure Inspect.202 (Inspect.203, #Attr.12):
|
|||
let Inspect.321 : Str = CallByName Inspect.59 Inspect.333 Inspect.335;
|
||||
dec Inspect.335;
|
||||
let Inspect.317 : Str = CallByName Inspect.204 Inspect.321 Inspect.336;
|
||||
dec Inspect.321;
|
||||
dec Inspect.336;
|
||||
let Inspect.318 : Str = ")";
|
||||
let Inspect.316 : Str = CallByName Inspect.59 Inspect.317 Inspect.318;
|
||||
|
@ -168,7 +167,6 @@ procedure List.92 (#Derived_gen.10, #Derived_gen.11, #Derived_gen.12, #Derived_g
|
|||
dec List.163;
|
||||
ret List.164;
|
||||
in
|
||||
inc #Derived_gen.11;
|
||||
inc #Derived_gen.10;
|
||||
jump List.577 #Derived_gen.10 #Derived_gen.11 #Derived_gen.12 #Derived_gen.13 #Derived_gen.14;
|
||||
|
||||
|
|
|
@ -37,7 +37,6 @@ procedure Inspect.202 (Inspect.203, #Attr.12):
|
|||
let Inspect.321 : Str = CallByName Inspect.59 Inspect.333 Inspect.335;
|
||||
dec Inspect.335;
|
||||
let Inspect.317 : Str = CallByName Inspect.204 Inspect.321 Inspect.336;
|
||||
dec Inspect.321;
|
||||
dec Inspect.336;
|
||||
let Inspect.318 : Str = ")";
|
||||
let Inspect.316 : Str = CallByName Inspect.59 Inspect.317 Inspect.318;
|
||||
|
@ -171,7 +170,6 @@ procedure List.92 (#Derived_gen.13, #Derived_gen.14, #Derived_gen.15, #Derived_g
|
|||
dec List.163;
|
||||
ret List.164;
|
||||
in
|
||||
inc #Derived_gen.14;
|
||||
inc #Derived_gen.13;
|
||||
jump List.577 #Derived_gen.13 #Derived_gen.14 #Derived_gen.15 #Derived_gen.16 #Derived_gen.17;
|
||||
|
||||
|
|
|
@ -23,14 +23,12 @@ procedure Test.1 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2):
|
|||
let Test.20 : I64 = 1i64;
|
||||
let Test.19 : I64 = CallByName Num.20 Test.5 Test.20;
|
||||
let Test.16 : List I64 = CallByName Test.1 Test.6 Test.3 Test.19;
|
||||
dec Test.6;
|
||||
let Test.18 : I64 = 1i64;
|
||||
let Test.17 : I64 = CallByName Num.19 Test.5 Test.18;
|
||||
jump Test.12 Test.16 Test.17 Test.4;
|
||||
else
|
||||
ret Test.2;
|
||||
in
|
||||
inc #Derived_gen.0;
|
||||
jump Test.12 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2;
|
||||
|
||||
procedure Test.0 ():
|
||||
|
@ -38,5 +36,4 @@ procedure Test.0 ():
|
|||
let Test.10 : I64 = 0i64;
|
||||
let Test.11 : I64 = 0i64;
|
||||
let Test.8 : List I64 = CallByName Test.1 Test.9 Test.10 Test.11;
|
||||
dec Test.9;
|
||||
ret Test.8;
|
||||
|
|
|
@ -80,7 +80,6 @@ procedure List.92 (#Derived_gen.0, #Derived_gen.1, #Derived_gen.2, #Derived_gen.
|
|||
ret List.164;
|
||||
in
|
||||
inc #Derived_gen.0;
|
||||
inc #Derived_gen.1;
|
||||
jump List.577 #Derived_gen.0 #Derived_gen.1 #Derived_gen.2 #Derived_gen.3 #Derived_gen.4;
|
||||
|
||||
procedure Num.127 (#Attr.2):
|
||||
|
@ -196,7 +195,6 @@ procedure Test.63 (Test.64, Test.276, #Attr.12):
|
|||
let Test.65 : List U8 = CallByName Test.4 Test.64 Test.284 Test.285;
|
||||
let Test.278 : List U8 = CallByName List.18 Test.61 Test.65 Test.62;
|
||||
dec Test.61;
|
||||
dec Test.65;
|
||||
ret Test.278;
|
||||
|
||||
procedure Test.66 (Test.67, Test.68, Test.62):
|
||||
|
|
|
@ -156,7 +156,6 @@ procedure List.92 (#Derived_gen.29, #Derived_gen.30, #Derived_gen.31, #Derived_g
|
|||
ret List.164;
|
||||
in
|
||||
inc #Derived_gen.29;
|
||||
inc #Derived_gen.30;
|
||||
jump List.577 #Derived_gen.29 #Derived_gen.30 #Derived_gen.31 #Derived_gen.32 #Derived_gen.33;
|
||||
|
||||
procedure List.92 (#Derived_gen.52, #Derived_gen.53, #Derived_gen.54, #Derived_gen.55, #Derived_gen.56):
|
||||
|
@ -173,7 +172,6 @@ procedure List.92 (#Derived_gen.52, #Derived_gen.53, #Derived_gen.54, #Derived_g
|
|||
dec List.163;
|
||||
ret List.164;
|
||||
in
|
||||
inc #Derived_gen.53;
|
||||
inc #Derived_gen.52;
|
||||
jump List.604 #Derived_gen.52 #Derived_gen.53 #Derived_gen.54 #Derived_gen.55 #Derived_gen.56;
|
||||
|
||||
|
@ -323,7 +321,6 @@ procedure Test.63 (Test.64, Test.279, #Attr.12):
|
|||
let Test.65 : List U8 = CallByName Test.4 Test.64 Test.331 Test.332;
|
||||
let Test.325 : List U8 = CallByName List.18 Test.61 Test.65 Test.62;
|
||||
dec Test.61;
|
||||
dec Test.65;
|
||||
ret Test.325;
|
||||
|
||||
procedure Test.63 (Test.64, Test.279, #Attr.12):
|
||||
|
@ -334,7 +331,6 @@ procedure Test.63 (Test.64, Test.279, #Attr.12):
|
|||
let Test.65 : List U8 = CallByName Test.4 Test.64 Test.287 Test.288;
|
||||
let Test.281 : List U8 = CallByName List.18 Test.61 Test.65 Test.62;
|
||||
dec Test.61;
|
||||
dec Test.65;
|
||||
ret Test.281;
|
||||
|
||||
procedure Test.66 (Test.67, Test.68, Test.62):
|
||||
|
|
|
@ -1286,6 +1286,7 @@ writeIndents = \buf, indents ->
|
|||
|> Str.concat indent
|
||||
|> writeIndents (indents - 1)
|
||||
|
||||
writeTagImpls : Str, List { name : Str, payload : [Some TypeId, None] }, Str, U64, (Str, [Some TypeId, None] -> Str) -> Str
|
||||
writeTagImpls = \buf, tags, discriminantName, indents, f ->
|
||||
buf
|
||||
|> writeIndents indents
|
||||
|
|
|
@ -566,3 +566,22 @@ fn freeing_boxes() {
|
|||
"#
|
||||
));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn joinpoint_that_owns() {
|
||||
valgrind_test(indoc!(
|
||||
r#"
|
||||
(
|
||||
writeIndents = \buf, indents ->
|
||||
if indents <= 0 then
|
||||
buf
|
||||
else
|
||||
buf
|
||||
|> Str.concat " "
|
||||
|> writeIndents (indents - 1)
|
||||
|
||||
List.walk [{}, {}] "" \accum, {} -> accum |> writeIndents 4
|
||||
)
|
||||
"#
|
||||
));
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue