optimize def sorting

This commit is contained in:
Folkert 2022-03-01 21:42:39 +01:00
parent d4cce420a8
commit 5a0562c7f1
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C

View file

@ -399,7 +399,7 @@ pub fn sort_can_defs(
) -> (Result<Vec<Declaration>, RuntimeError>, Output) { ) -> (Result<Vec<Declaration>, RuntimeError>, Output) {
let CanDefs { let CanDefs {
refs_by_symbol, refs_by_symbol,
can_defs_by_symbol, mut can_defs_by_symbol,
aliases, aliases,
} = defs; } = defs;
@ -583,7 +583,7 @@ pub fn sort_can_defs(
&group, &group,
&env.closures, &env.closures,
&mut all_successors_with_self, &mut all_successors_with_self,
&can_defs_by_symbol, &mut can_defs_by_symbol,
&mut declarations, &mut declarations,
); );
} }
@ -717,7 +717,7 @@ pub fn sort_can_defs(
group, group,
&env.closures, &env.closures,
&mut all_successors_with_self, &mut all_successors_with_self,
&can_defs_by_symbol, &mut can_defs_by_symbol,
&mut declarations, &mut declarations,
); );
} }
@ -739,7 +739,7 @@ fn group_to_declaration(
group: &[Symbol], group: &[Symbol],
closures: &MutMap<Symbol, References>, closures: &MutMap<Symbol, References>,
successors: &mut dyn FnMut(&Symbol) -> ImSet<Symbol>, successors: &mut dyn FnMut(&Symbol) -> ImSet<Symbol>,
can_defs_by_symbol: &MutMap<Symbol, Def>, can_defs_by_symbol: &mut MutMap<Symbol, Def>,
declarations: &mut Vec<Declaration>, declarations: &mut Vec<Declaration>,
) { ) {
use Declaration::*; use Declaration::*;
@ -765,51 +765,54 @@ fn group_to_declaration(
if cycle.len() == 1 { if cycle.len() == 1 {
let symbol = &cycle[0]; let symbol = &cycle[0];
if let Some(can_def) = can_defs_by_symbol.get(symbol) { match can_defs_by_symbol.remove(symbol) {
let mut new_def = can_def.clone(); Some(mut new_def) => {
// Determine recursivity of closures that are not tail-recursive
if let Closure(ClosureData {
recursive: recursive @ Recursive::NotRecursive,
..
}) = &mut new_def.loc_expr.value
{
*recursive = closure_recursivity(*symbol, closures);
}
let is_recursive = successors(symbol).contains(symbol);
if !seen_pattern_regions.contains(&new_def.loc_pattern.region) {
if is_recursive {
declarations.push(DeclareRec(vec![new_def.clone()]));
} else {
declarations.push(Declare(new_def.clone()));
}
seen_pattern_regions.insert(new_def.loc_pattern.region);
}
}
} else {
let mut can_defs = Vec::new();
// Topological sort gives us the reverse of the sorting we want!
for symbol in cycle.into_iter().rev() {
if let Some(can_def) = can_defs_by_symbol.get(&symbol) {
let mut new_def = can_def.clone();
// Determine recursivity of closures that are not tail-recursive // Determine recursivity of closures that are not tail-recursive
if let Closure(ClosureData { if let Closure(ClosureData {
recursive: recursive @ Recursive::NotRecursive, recursive: recursive @ Recursive::NotRecursive,
.. ..
}) = &mut new_def.loc_expr.value }) = &mut new_def.loc_expr.value
{ {
*recursive = closure_recursivity(symbol, closures); *recursive = closure_recursivity(*symbol, closures);
} }
let is_recursive = successors(symbol).contains(symbol);
if !seen_pattern_regions.contains(&new_def.loc_pattern.region) { if !seen_pattern_regions.contains(&new_def.loc_pattern.region) {
can_defs.push(new_def.clone()); seen_pattern_regions.insert(new_def.loc_pattern.region);
}
seen_pattern_regions.insert(new_def.loc_pattern.region); if is_recursive {
declarations.push(DeclareRec(vec![new_def]));
} else {
declarations.push(Declare(new_def));
}
}
}
None => roc_error_macros::internal_error!("def not available {:?}", symbol),
}
} else {
let mut can_defs = Vec::new();
// Topological sort gives us the reverse of the sorting we want!
for symbol in cycle.into_iter().rev() {
match can_defs_by_symbol.remove(&symbol) {
Some(mut new_def) => {
// Determine recursivity of closures that are not tail-recursive
if let Closure(ClosureData {
recursive: recursive @ Recursive::NotRecursive,
..
}) = &mut new_def.loc_expr.value
{
*recursive = closure_recursivity(symbol, closures);
}
seen_pattern_regions.insert(new_def.loc_pattern.region);
if !seen_pattern_regions.contains(&new_def.loc_pattern.region) {
can_defs.push(new_def);
}
}
None => roc_error_macros::internal_error!("def not available {:?}", symbol),
} }
} }