Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,9 @@ use crate::{
brillig_ir::{BrilligContext, artifact::BrilligArtifact},
},
ssa::ir::types::NumericType,
ssa::opt::brillig_entry_points::{build_inner_call_to_entry_points, get_brillig_entry_points},
ssa::opt::brillig_entry_points::{
build_inner_call_to_entry_points, get_brillig_entry_points_with_reachability,
},
};

/// Context structure for generating Brillig globals
Expand Down Expand Up @@ -62,7 +64,8 @@ impl BrilligGlobals {
main_id: FunctionId,
) -> Self {
let call_graph = CallGraph::from_ssa(ssa);
let brillig_entry_points = get_brillig_entry_points(&ssa.functions, main_id, &call_graph);
let brillig_entry_points =
get_brillig_entry_points_with_reachability(&ssa.functions, main_id, &call_graph);

let mut hoisted_global_constants: HashMap<FunctionId, ConstantCounterMap> =
HashMap::default();
Expand Down
59 changes: 36 additions & 23 deletions compiler/noirc_evaluator/src/ssa/opt/brillig_entry_points.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ impl Ssa {
// From the call graph find the Brillig entry points and set up
// the functions needing specialization before performing the actual call site rewrites.
let brillig_entry_points =
get_brillig_entry_points(&self.functions, self.main_id, &call_graph);
get_brillig_entry_points_with_reachability(&self.functions, self.main_id, &call_graph);
let functions_to_clone_map = build_functions_to_clone(&brillig_entry_points);
let (calls_to_update, mut new_functions_map) =
build_calls_to_update(&mut self, functions_to_clone_map, &brillig_entry_points);
Expand Down Expand Up @@ -312,14 +312,45 @@ fn collect_callsites_to_rewrite(
new_calls_to_update
}

/// Returns the set of Brillig entry points
///
/// A Brillig entry point is defined as a Brillig function that is directly called
/// from at least one ACIR function, or is the `main` function itself if it is Brillig.
pub(crate) fn get_brillig_entry_points(
functions: &BTreeMap<FunctionId, Function>,
main_id: FunctionId,
call_graph: &CallGraph,
) -> BTreeSet<FunctionId> {
let mut entry_points = BTreeSet::new();

// Only ACIR callers can introduce Brillig entry points
let acir_callers = call_graph
.callees()
.into_iter()
.filter(|(caller, _)| functions[caller].runtime().is_acir());

for (_, callees) in acir_callers {
// Filter only the Brillig callees. These are the Brillig entry points.
entry_points
.extend(callees.keys().filter(|callee| functions[callee].runtime().is_brillig()));
}

// If main has been marked as Brillig, it is itself an entry point.
if functions[&main_id].runtime().is_brillig() {
entry_points.insert(main_id);
}

entry_points
}

/// Returns a map of Brillig entry points to all reachable functions from that entry point.
///
/// A Brillig entry point is defined as a Brillig function that is directly called
/// from at least one ACIR function, or is the `main` function itself if it is Brillig.
///
/// The value set for each entry point includes all functions reachable
/// from the entry point (excluding the entry itself if it is non-recursive).
pub(crate) fn get_brillig_entry_points(
pub(crate) fn get_brillig_entry_points_with_reachability(
functions: &BTreeMap<FunctionId, Function>,
main_id: FunctionId,
call_graph: &CallGraph,
Expand All @@ -328,7 +359,7 @@ pub(crate) fn get_brillig_entry_points(
get_brillig_entry_points_with_recursive(functions, main_id, call_graph, &recursive_functions)
}

/// Like [get_brillig_entry_points], but uses a precomputed set of recursive functions
/// Like [get_brillig_entry_points_with_reachability], but uses a precomputed set of recursive functions
/// to avoid recomputing SCCs.
pub(crate) fn get_brillig_entry_points_with_recursive(
functions: &BTreeMap<FunctionId, Function>,
Expand All @@ -338,27 +369,9 @@ pub(crate) fn get_brillig_entry_points_with_recursive(
) -> BTreeMap<FunctionId, BTreeSet<FunctionId>> {
let mut brillig_entry_points = BTreeMap::default();

// Only ACIR callers can introduce Brillig entry points
let acir_callers = call_graph
.callees()
.into_iter()
.filter(|(caller, _)| functions[caller].runtime().is_acir());
for (_, callees) in acir_callers {
// Filter only the Brillig callees. These are the Brillig entry points.
let entry_points = callees.keys().filter(|callee| functions[callee].runtime().is_brillig());
for &entry_point in entry_points {
brillig_entry_points.insert(
entry_point,
brillig_reachable(call_graph, recursive_functions, entry_point),
);
}
}

// If main has been marked as Brillig, it is itself an entry point.
// Run the same analysis from above on main.
if functions[&main_id].runtime().is_brillig() {
for entry_point in get_brillig_entry_points(functions, main_id, call_graph) {
brillig_entry_points
.insert(main_id, brillig_reachable(call_graph, recursive_functions, main_id));
.insert(entry_point, brillig_reachable(call_graph, recursive_functions, entry_point));
}

brillig_entry_points
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ impl Ssa {
}

// Do not inline Brillig entry points
if brillig_entry_points.contains_key(&callee.id()) {
if brillig_entry_points.contains(&callee.id()) {
return false;
}

Expand Down
Loading