From e32a06b088c29539a01bbdeef573549f92d62a36 Mon Sep 17 00:00:00 2001 From: Folkert Date: Sun, 11 Jul 2021 00:39:30 +0200 Subject: [PATCH] assign guarded patterns at the last moment --- compiler/mono/src/decision_tree.rs | 29 +++++++++++++++++------------ compiler/mono/src/ir.rs | 12 +++++------- compiler/test_gen/src/gen_tags.rs | 4 ++-- 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/compiler/mono/src/decision_tree.rs b/compiler/mono/src/decision_tree.rs index 679feb7997..ae2de26840 100644 --- a/compiler/mono/src/decision_tree.rs +++ b/compiler/mono/src/decision_tree.rs @@ -34,9 +34,8 @@ fn compile<'a>(raw_branches: Vec<(Guard<'a>, Pattern<'a>, u64)>) -> DecisionTree pub enum Guard<'a> { NoGuard, Guard { - /// Symbol that stores a boolean - /// when true this branch is picked, otherwise skipped - symbol: Symbol, + /// pattern + pattern: Pattern<'a>, /// after assigning to symbol, the stmt jumps to this label id: JoinPointId, stmt: Stmt<'a>, @@ -63,8 +62,11 @@ enum DecisionTree<'a> { enum GuardedTest<'a> { // e.g. `_ if True -> ...` GuardedNoTest { + /// pattern + pattern: Pattern<'a>, /// after assigning to symbol, the stmt jumps to this label id: JoinPointId, + /// body stmt: Stmt<'a>, }, TestNotGuarded { @@ -172,12 +174,8 @@ fn to_decision_tree(raw_branches: Vec) -> DecisionTree { match first.guard { Guard::NoGuard => unreachable!(), - Guard::Guard { - symbol: _, - id, - stmt, - } => { - let guarded_test = GuardedTest::GuardedNoTest { id, stmt }; + Guard::Guard { id, stmt, pattern } => { + let guarded_test = GuardedTest::GuardedNoTest { id, stmt, pattern }; // the guard test does not have a path let path = vec![]; @@ -1042,6 +1040,7 @@ enum Decider<'a, T> { /// after assigning to symbol, the stmt jumps to this label id: JoinPointId, stmt: Stmt<'a>, + pattern: Pattern<'a>, success: Box>, failure: Box>, @@ -1577,6 +1576,7 @@ fn decide_to_branching<'a>( Guarded { id, stmt, + pattern, success, failure, } => { @@ -1622,12 +1622,14 @@ fn decide_to_branching<'a>( borrow: false, }; - Stmt::Join { + let join = Stmt::Join { id, parameters: arena.alloc([param]), remainder: arena.alloc(stmt), body: arena.alloc(decide), - } + }; + + crate::ir::store_pattern(env, procs, layout_cache, &pattern, cond_symbol, join) } Chain { test_chain, @@ -1949,13 +1951,14 @@ fn chain_decider<'a>( success_tree: DecisionTree<'a>, ) -> Decider<'a, u64> { match guarded_test { - GuardedTest::GuardedNoTest { id, stmt } => { + GuardedTest::GuardedNoTest { id, stmt, pattern } => { let failure = Box::new(tree_to_decider(failure_tree)); let success = Box::new(tree_to_decider(success_tree)); Decider::Guarded { id, stmt, + pattern, success, failure: failure.clone(), } @@ -2082,11 +2085,13 @@ fn insert_choices<'a>( Guarded { id, stmt, + pattern, success, failure, } => Guarded { id, stmt, + pattern, success: Box::new(insert_choices(choice_dict, *success)), failure: Box::new(insert_choices(choice_dict, *failure)), }, diff --git a/compiler/mono/src/ir.rs b/compiler/mono/src/ir.rs index 4f0d18b4bf..55d1bc585e 100644 --- a/compiler/mono/src/ir.rs +++ b/compiler/mono/src/ir.rs @@ -5096,16 +5096,14 @@ fn from_can_when<'a>( jump, ); - let new_guard_stmt = - store_pattern(env, procs, layout_cache, &pattern, cond_symbol, guard_stmt); + // let new_guard_stmt = store_pattern(env, procs, layout_cache, &pattern, cond_symbol, guard_stmt); - dbg!(symbol); ( - pattern, + pattern.clone(), Guard::Guard { id, - symbol, - stmt: new_guard_stmt, + pattern, + stmt: guard_stmt, }, branch_stmt, ) @@ -5512,7 +5510,7 @@ fn substitute_in_expr<'a>( } #[allow(clippy::too_many_arguments)] -fn store_pattern<'a>( +pub fn store_pattern<'a>( env: &mut Env<'a, '_>, procs: &mut Procs<'a>, layout_cache: &mut LayoutCache<'a>, diff --git a/compiler/test_gen/src/gen_tags.rs b/compiler/test_gen/src/gen_tags.rs index ccbfa75b45..40e5403914 100644 --- a/compiler/test_gen/src/gen_tags.rs +++ b/compiler/test_gen/src/gen_tags.rs @@ -510,8 +510,8 @@ fn if_guard_multiple() { f = \n -> when Identity n 0 is Identity x _ if x == 0 -> x + 0 - # Identity x _ if x == 1 -> x + 0 - # Identity x _ if x == 2 -> x + 0 + Identity x _ if x == 1 -> x + 0 + Identity x _ if x == 2 -> x + 0 Identity x _ -> x - x { a: f 0, b: f 1, c: f 2, d: f 4 }