assign guarded patterns at the last moment

This commit is contained in:
Folkert 2021-07-11 00:39:30 +02:00
parent 78309f2607
commit e32a06b088
3 changed files with 24 additions and 21 deletions

View file

@ -34,9 +34,8 @@ fn compile<'a>(raw_branches: Vec<(Guard<'a>, Pattern<'a>, u64)>) -> DecisionTree
pub enum Guard<'a> { pub enum Guard<'a> {
NoGuard, NoGuard,
Guard { Guard {
/// Symbol that stores a boolean /// pattern
/// when true this branch is picked, otherwise skipped pattern: Pattern<'a>,
symbol: Symbol,
/// after assigning to symbol, the stmt jumps to this label /// after assigning to symbol, the stmt jumps to this label
id: JoinPointId, id: JoinPointId,
stmt: Stmt<'a>, stmt: Stmt<'a>,
@ -63,8 +62,11 @@ enum DecisionTree<'a> {
enum GuardedTest<'a> { enum GuardedTest<'a> {
// e.g. `_ if True -> ...` // e.g. `_ if True -> ...`
GuardedNoTest { GuardedNoTest {
/// pattern
pattern: Pattern<'a>,
/// after assigning to symbol, the stmt jumps to this label /// after assigning to symbol, the stmt jumps to this label
id: JoinPointId, id: JoinPointId,
/// body
stmt: Stmt<'a>, stmt: Stmt<'a>,
}, },
TestNotGuarded { TestNotGuarded {
@ -172,12 +174,8 @@ fn to_decision_tree(raw_branches: Vec<Branch>) -> DecisionTree {
match first.guard { match first.guard {
Guard::NoGuard => unreachable!(), Guard::NoGuard => unreachable!(),
Guard::Guard { Guard::Guard { id, stmt, pattern } => {
symbol: _, let guarded_test = GuardedTest::GuardedNoTest { id, stmt, pattern };
id,
stmt,
} => {
let guarded_test = GuardedTest::GuardedNoTest { id, stmt };
// the guard test does not have a path // the guard test does not have a path
let path = vec![]; let path = vec![];
@ -1042,6 +1040,7 @@ enum Decider<'a, T> {
/// after assigning to symbol, the stmt jumps to this label /// after assigning to symbol, the stmt jumps to this label
id: JoinPointId, id: JoinPointId,
stmt: Stmt<'a>, stmt: Stmt<'a>,
pattern: Pattern<'a>,
success: Box<Decider<'a, T>>, success: Box<Decider<'a, T>>,
failure: Box<Decider<'a, T>>, failure: Box<Decider<'a, T>>,
@ -1577,6 +1576,7 @@ fn decide_to_branching<'a>(
Guarded { Guarded {
id, id,
stmt, stmt,
pattern,
success, success,
failure, failure,
} => { } => {
@ -1622,12 +1622,14 @@ fn decide_to_branching<'a>(
borrow: false, borrow: false,
}; };
Stmt::Join { let join = Stmt::Join {
id, id,
parameters: arena.alloc([param]), parameters: arena.alloc([param]),
remainder: arena.alloc(stmt), remainder: arena.alloc(stmt),
body: arena.alloc(decide), body: arena.alloc(decide),
} };
crate::ir::store_pattern(env, procs, layout_cache, &pattern, cond_symbol, join)
} }
Chain { Chain {
test_chain, test_chain,
@ -1949,13 +1951,14 @@ fn chain_decider<'a>(
success_tree: DecisionTree<'a>, success_tree: DecisionTree<'a>,
) -> Decider<'a, u64> { ) -> Decider<'a, u64> {
match guarded_test { match guarded_test {
GuardedTest::GuardedNoTest { id, stmt } => { GuardedTest::GuardedNoTest { id, stmt, pattern } => {
let failure = Box::new(tree_to_decider(failure_tree)); let failure = Box::new(tree_to_decider(failure_tree));
let success = Box::new(tree_to_decider(success_tree)); let success = Box::new(tree_to_decider(success_tree));
Decider::Guarded { Decider::Guarded {
id, id,
stmt, stmt,
pattern,
success, success,
failure: failure.clone(), failure: failure.clone(),
} }
@ -2082,11 +2085,13 @@ fn insert_choices<'a>(
Guarded { Guarded {
id, id,
stmt, stmt,
pattern,
success, success,
failure, failure,
} => Guarded { } => Guarded {
id, id,
stmt, stmt,
pattern,
success: Box::new(insert_choices(choice_dict, *success)), success: Box::new(insert_choices(choice_dict, *success)),
failure: Box::new(insert_choices(choice_dict, *failure)), failure: Box::new(insert_choices(choice_dict, *failure)),
}, },

View file

@ -5096,16 +5096,14 @@ fn from_can_when<'a>(
jump, jump,
); );
let new_guard_stmt = // let new_guard_stmt = store_pattern(env, procs, layout_cache, &pattern, cond_symbol, guard_stmt);
store_pattern(env, procs, layout_cache, &pattern, cond_symbol, guard_stmt);
dbg!(symbol);
( (
pattern, pattern.clone(),
Guard::Guard { Guard::Guard {
id, id,
symbol, pattern,
stmt: new_guard_stmt, stmt: guard_stmt,
}, },
branch_stmt, branch_stmt,
) )
@ -5512,7 +5510,7 @@ fn substitute_in_expr<'a>(
} }
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
fn store_pattern<'a>( pub fn store_pattern<'a>(
env: &mut Env<'a, '_>, env: &mut Env<'a, '_>,
procs: &mut Procs<'a>, procs: &mut Procs<'a>,
layout_cache: &mut LayoutCache<'a>, layout_cache: &mut LayoutCache<'a>,

View file

@ -510,8 +510,8 @@ fn if_guard_multiple() {
f = \n -> f = \n ->
when Identity n 0 is when Identity n 0 is
Identity x _ if x == 0 -> x + 0 Identity x _ if x == 0 -> x + 0
# Identity x _ if x == 1 -> x + 0 Identity x _ if x == 1 -> x + 0
# Identity x _ if x == 2 -> x + 0 Identity x _ if x == 2 -> x + 0
Identity x _ -> x - x Identity x _ -> x - x
{ a: f 0, b: f 1, c: f 2, d: f 4 } { a: f 0, b: f 1, c: f 2, d: f 4 }