From addf130be5965b14de76a6bbfde2271b525bcd90 Mon Sep 17 00:00:00 2001 From: Folkert Date: Mon, 22 Mar 2021 13:09:56 +0100 Subject: [PATCH] optimize Path --- compiler/mono/src/decision_tree.rs | 159 +++++++++++++++-------------- 1 file changed, 83 insertions(+), 76 deletions(-) diff --git a/compiler/mono/src/decision_tree.rs b/compiler/mono/src/decision_tree.rs index 5dec912230..e4fb09c041 100644 --- a/compiler/mono/src/decision_tree.rs +++ b/compiler/mono/src/decision_tree.rs @@ -22,7 +22,7 @@ pub fn compile<'a>(raw_branches: Vec<(Guard<'a>, Pattern<'a>, u64)>) -> Decision .into_iter() .map(|(guard, pattern, index)| Branch { goal: index, - patterns: vec![(Path::Empty, guard, pattern)], + patterns: vec![(Vec::new(), guard, pattern)], }) .collect(); @@ -52,7 +52,7 @@ impl<'a> Guard<'a> { pub enum DecisionTree<'a> { Match(Label), Decision { - path: Path, + path: Vec, edges: Vec<(Test<'a>, DecisionTree<'a>)>, default: Option>>, }, @@ -148,7 +148,7 @@ pub enum Path { #[derive(Clone, Debug, PartialEq)] struct Branch<'a> { goal: Label, - patterns: Vec<(Path, Guard<'a>, Pattern<'a>)>, + patterns: Vec<(Vec, Guard<'a>, Pattern<'a>)>, } fn to_decision_tree(raw_branches: Vec) -> DecisionTree { @@ -218,8 +218,8 @@ fn flatten_patterns(branch: Branch) -> Branch { } fn flatten<'a>( - path_pattern: (Path, Guard<'a>, Pattern<'a>), - path_patterns: &mut Vec<(Path, Guard<'a>, Pattern<'a>)>, + path_pattern: (Vec, Guard<'a>, Pattern<'a>), + path_patterns: &mut Vec<(Vec, Guard<'a>, Pattern<'a>)>, ) { match path_pattern.2 { Pattern::AppliedTag { @@ -237,12 +237,13 @@ fn flatten<'a>( { // TODO ^ do we need to check that guard.is_none() here? - let path = path_pattern.0; + let mut path = path_pattern.0; // Theory: unbox doesn't have any value for us, because one-element tag unions // don't store the tag anyway. if arguments.len() == 1 { + // NOTE here elm will unbox, but we don't use that path_patterns.push(( - Path::Unbox(Box::new(path)), + path, path_pattern.1.clone(), Pattern::AppliedTag { union, @@ -254,13 +255,15 @@ fn flatten<'a>( )); } else { for (index, (arg_pattern, _)) in arguments.iter().enumerate() { + let mut new_path = path.clone(); + new_path.push(PathInstruction { + index: index as u64, + tag_id, + }); + flatten( ( - Path::Index { - index: index as u64, - tag_id, - path: Box::new(path.clone()), - }, + new_path, // same guard here? path_pattern.1.clone(), arg_pattern.clone(), @@ -300,7 +303,7 @@ fn check_for_match(branches: &Vec) -> Option