Update script context handler to do less work with only fallback. Also optimize wrapped builtins too.
This commit is contained in:
parent
6d2e38851e
commit
a9bedda5ed
|
@ -567,7 +567,7 @@ impl TypedValidator {
|
||||||
let var_purpose_arg = "__purpose_arg__";
|
let var_purpose_arg = "__purpose_arg__";
|
||||||
let var_datum = "__datum__";
|
let var_datum = "__datum__";
|
||||||
|
|
||||||
TypedExpr::sequence(&[
|
let context_handler = TypedExpr::sequence(&[
|
||||||
TypedExpr::let_(
|
TypedExpr::let_(
|
||||||
TypedExpr::local_var(var_context, Type::script_context(), self.location),
|
TypedExpr::local_var(var_context, Type::script_context(), self.location),
|
||||||
TypedPattern::Constructor {
|
TypedPattern::Constructor {
|
||||||
|
@ -746,7 +746,29 @@ impl TypedValidator {
|
||||||
}))
|
}))
|
||||||
.collect(),
|
.collect(),
|
||||||
},
|
},
|
||||||
])
|
]);
|
||||||
|
|
||||||
|
if self.handlers.is_empty() {
|
||||||
|
let fallback = &self.fallback;
|
||||||
|
let arg = fallback.arguments.first().unwrap();
|
||||||
|
|
||||||
|
let then = match arg.get_variable_name() {
|
||||||
|
Some(arg_name) => TypedExpr::sequence(&[
|
||||||
|
TypedExpr::let_(
|
||||||
|
TypedExpr::local_var(var_context, arg.tipo.clone(), arg.location),
|
||||||
|
TypedPattern::var(arg_name),
|
||||||
|
arg.tipo.clone(),
|
||||||
|
arg.location,
|
||||||
|
),
|
||||||
|
fallback.body.clone(),
|
||||||
|
]),
|
||||||
|
None => fallback.body.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
then
|
||||||
|
} else {
|
||||||
|
context_handler
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_node(&self, byte_index: usize) -> Option<Located<'_>> {
|
pub fn find_node(&self, byte_index: usize) -> Option<Located<'_>> {
|
||||||
|
|
|
@ -1316,7 +1316,7 @@ impl Term<Name> {
|
||||||
// So it costs more size to have them hoisted
|
// So it costs more size to have them hoisted
|
||||||
Term::Delay(e) if matches!(e.as_ref(), Term::Error) => true,
|
Term::Delay(e) if matches!(e.as_ref(), Term::Error) => true,
|
||||||
// If it wraps a builtin with consts or arguments passed in then inline
|
// If it wraps a builtin with consts or arguments passed in then inline
|
||||||
l @ Term::Lambda { .. } if is_a_builtin_wrapper(l) => true,
|
Term::Lambda { .. } => arg_term.is_a_builtin_wrapper(&context),
|
||||||
// Inline smaller terms too
|
// Inline smaller terms too
|
||||||
Term::Constant(_) | Term::Var(_) | Term::Builtin(_) => true,
|
Term::Constant(_) | Term::Var(_) | Term::Builtin(_) => true,
|
||||||
|
|
||||||
|
@ -2194,7 +2194,7 @@ impl Term<Name> {
|
||||||
term
|
term
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pierce_no_inlines(mut self) -> Self {
|
fn pierce_no_inlines(mut self) -> Self {
|
||||||
let term = &mut self;
|
let term = &mut self;
|
||||||
|
|
||||||
while let Term::Lambda {
|
while let Term::Lambda {
|
||||||
|
@ -2211,6 +2211,59 @@ impl Term<Name> {
|
||||||
|
|
||||||
std::mem::replace(term, Term::Error.force())
|
std::mem::replace(term, Term::Error.force())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn is_a_builtin_wrapper(&self, context: &Context) -> bool {
|
||||||
|
let (names, term) = self.pop_lambdas_and_get_names();
|
||||||
|
|
||||||
|
let mut arg_names = vec![];
|
||||||
|
|
||||||
|
let mut term = term;
|
||||||
|
|
||||||
|
while let Term::Apply { function, argument } = term {
|
||||||
|
match argument.as_ref() {
|
||||||
|
Term::Var(name) => arg_names.push(format!("{}_{}", name.text, name.unique)),
|
||||||
|
|
||||||
|
Term::Constant(_) => {}
|
||||||
|
_ => {
|
||||||
|
//Break loop, it's not a builtin wrapper function
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
term = function.as_ref();
|
||||||
|
}
|
||||||
|
|
||||||
|
let func_is_builtin = match term {
|
||||||
|
Term::Var(name) => context
|
||||||
|
.builtins_map
|
||||||
|
.keys()
|
||||||
|
.map(|func| func.wrapped_name())
|
||||||
|
.any(|func| func == name.text),
|
||||||
|
|
||||||
|
Term::Builtin(_) => todo!(),
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
|
||||||
|
arg_names.iter().all(|item| names.contains(item)) && func_is_builtin
|
||||||
|
}
|
||||||
|
|
||||||
|
fn pop_lambdas_and_get_names(&self) -> (Vec<String>, &Term<Name>) {
|
||||||
|
let mut names = vec![];
|
||||||
|
|
||||||
|
let mut term = self;
|
||||||
|
|
||||||
|
while let Term::Lambda {
|
||||||
|
parameter_name,
|
||||||
|
body,
|
||||||
|
} = term
|
||||||
|
{
|
||||||
|
if parameter_name.text != NO_INLINE {
|
||||||
|
names.push(format!("{}_{}", parameter_name.text, parameter_name.unique));
|
||||||
|
}
|
||||||
|
term = body.as_ref();
|
||||||
|
}
|
||||||
|
|
||||||
|
(names, term)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Program<Name> {
|
impl Program<Name> {
|
||||||
|
@ -2651,48 +2704,6 @@ fn id_vec_function_to_var(func_name: &str, id_vec: &[usize]) -> String {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_a_builtin_wrapper(term: &Term<Name>) -> bool {
|
|
||||||
let (names, term) = pop_lambdas_and_get_names(term);
|
|
||||||
|
|
||||||
let mut arg_names = vec![];
|
|
||||||
|
|
||||||
let mut term = term;
|
|
||||||
|
|
||||||
while let Term::Apply { function, argument } = term {
|
|
||||||
match argument.as_ref() {
|
|
||||||
Term::Var(name) => arg_names.push(format!("{}_{}", name.text, name.unique)),
|
|
||||||
|
|
||||||
Term::Constant(_) => {}
|
|
||||||
_ => {
|
|
||||||
//Break loop, it's not a builtin wrapper function
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
term = function.as_ref();
|
|
||||||
}
|
|
||||||
|
|
||||||
arg_names.iter().all(|item| names.contains(item)) && matches!(term, Term::Builtin(_))
|
|
||||||
}
|
|
||||||
|
|
||||||
fn pop_lambdas_and_get_names(term: &Term<Name>) -> (Vec<String>, &Term<Name>) {
|
|
||||||
let mut names = vec![];
|
|
||||||
|
|
||||||
let mut term = term;
|
|
||||||
|
|
||||||
while let Term::Lambda {
|
|
||||||
parameter_name,
|
|
||||||
body,
|
|
||||||
} = term
|
|
||||||
{
|
|
||||||
if parameter_name.text != NO_INLINE {
|
|
||||||
names.push(format!("{}_{}", parameter_name.text, parameter_name.unique));
|
|
||||||
}
|
|
||||||
term = body.as_ref();
|
|
||||||
}
|
|
||||||
|
|
||||||
(names, term)
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::NO_INLINE;
|
use super::NO_INLINE;
|
||||||
|
|
Loading…
Reference in New Issue