optimization: increase the cases that inline_basic_reduce can handle

This commit is contained in:
microproofs 2023-09-29 14:26:55 -04:00 committed by Kasey
parent 4c278e2f9d
commit 5e2a78173b
2 changed files with 22 additions and 4 deletions

View File

@ -26,4 +26,6 @@ pub fn aiken_optimize_and_intern(program: Program<Name>) -> Program<Name> {
.wrap_data_reduce()
.lambda_reduce()
.inline_reduce()
.lambda_reduce()
.inline_reduce()
}

View File

@ -283,17 +283,21 @@ fn inline_basic_reduce(term: &mut Term<Name>) {
} = func
{
let occurrences = var_occurrences(body, parameter_name.clone());
// TODO: Once case and constr is live we need to also check if case is delaying values
let delays = delayed_execution(body.as_ref());
if occurrences == 1 {
if let replace_term @ (Term::Var(_)
if delays == 0 {
*term = substitute_term(body.as_ref(), parameter_name.clone(), arg);
} else if let Term::Var(_)
| Term::Constant(_)
| Term::Error
| Term::Delay(_)
| Term::Lambda { .. }
| Term::Builtin(_)) = arg
| Term::Builtin(_) = arg
{
*term =
substitute_term(body.as_ref(), parameter_name.clone(), replace_term);
*term = substitute_term(body.as_ref(), parameter_name.clone(), arg);
}
// This will strip out unused terms that can't throw an error by themselves
} else if occurrences == 0 {
if let Term::Var(_)
| Term::Constant(_)
@ -464,6 +468,18 @@ fn var_occurrences(term: &Term<Name>, search_for: Rc<Name>) -> usize {
}
}
fn delayed_execution(term: &Term<Name>) -> usize {
match term {
Term::Delay(body) => 1 + delayed_execution(body.as_ref()),
Term::Lambda { body, .. } => 1 + delayed_execution(body.as_ref()),
Term::Apply { function, argument } => {
delayed_execution(function.as_ref()) + delayed_execution(argument.as_ref())
}
Term::Force(x) => delayed_execution(x.as_ref()),
_ => 0,
}
}
fn lambda_reduce(term: &mut Term<Name>) {
match term {
Term::Apply { function, argument } => {