diff --git a/compiler/noirc_evaluator/src/ssa/opt/defunctionalize.rs b/compiler/noirc_evaluator/src/ssa/opt/defunctionalize.rs index 754e550af9..3062edfe60 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/defunctionalize.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/defunctionalize.rs @@ -8,6 +8,7 @@ use std::collections::{BTreeMap, BTreeSet, HashSet}; use acvm::FieldElement; use iter_extended::vecmap; +use noirc_frontend::monomorphization::ast::InlineType; use crate::ssa::{ function_builder::FunctionBuilder, @@ -277,7 +278,7 @@ fn function_id_to_field(function_id: FunctionId) -> FieldElement { fn create_apply_function( ssa: &mut Ssa, signature: Signature, - runtime: RuntimeType, + caller_runtime: RuntimeType, function_ids: Vec, ) -> FunctionId { assert!(!function_ids.is_empty()); @@ -285,6 +286,12 @@ fn create_apply_function( ssa.add_fn(|id| { let mut function_builder = FunctionBuilder::new("apply".to_string(), id); function_builder.set_globals(globals); + + // We want to push for apply functions to be inlined more aggressively. + let runtime = match caller_runtime { + RuntimeType::Acir(_) => RuntimeType::Acir(InlineType::InlineAlways), + RuntimeType::Brillig(_) => RuntimeType::Brillig(InlineType::InlineAlways), + }; function_builder.set_runtime(runtime); let target_id = function_builder.add_parameter(Type::field()); let params_ids = vecmap(signature.params, |typ| function_builder.add_parameter(typ)); diff --git a/compiler/noirc_evaluator/src/ssa/opt/inlining.rs b/compiler/noirc_evaluator/src/ssa/opt/inlining.rs index b5cbc90e30..5d97a41616 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/inlining.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/inlining.rs @@ -66,22 +66,27 @@ impl Ssa { self.functions = btree_map(inline_sources, |entry_point| { let should_inline_call = |_context: &PerFunctionContext, ssa: &Ssa, called_func_id: FunctionId| -> bool { - let function = &ssa.functions[&called_func_id]; + let callee = &ssa.functions[&called_func_id]; + let caller_runtime = ssa.functions[entry_point].runtime(); - match function.runtime() { + match callee.runtime() { RuntimeType::Acir(inline_type) => { // If the called function is acir, we inline if it's not an entry point // If we have not already finished the flattening pass, functions marked // to not have predicates should be preserved. let preserve_function = - !inline_no_predicates_functions && function.is_no_predicates(); + !inline_no_predicates_functions && callee.is_no_predicates(); !inline_type.is_entry_point() && !preserve_function } RuntimeType::Brillig(_) => { - // If the called function is brillig, we inline only if it's into brillig and the function is not recursive - ssa.functions[entry_point].runtime().is_brillig() - && !inline_sources.contains(&called_func_id) + if caller_runtime.is_acir() { + // We never inline a brillig function into an ACIR function. + return false; + } + + // Avoid inlining recursive functions. + !inline_sources.contains(&called_func_id) } } };