Skip to content

Commit

Permalink
fix: skip emission of brillig calls which will never be executed (#5314)
Browse files Browse the repository at this point in the history
# Description

## Problem\*

Pulls across fix made in sync PR at
AztecProtocol/aztec-packages@e39be3d

## Summary\*

For some reason in the `noir-contracts` workspace, we're emitting a
_lot_ (100+ MB worth) of brillig call opcodes which have their predicate
hardcoded to zero (i.e. they will never actually be executed).

This PR adds a check before we emit a brillig call opcode to see if the
predicate is zero and, if so, we skip it and zero out all the outputs at
compile time.

## Additional Context



## Documentation\*

Check one:
- [x] No documentation needed.
- [ ] Documentation included in this PR.
- [ ] **[For Experimental Features]** Documentation to be submitted in a
separate PR.

# PR Checklist\*

- [x] I have tested the changes locally.
- [x] I have formatted the changes with [Prettier](https://prettier.io/)
and/or `cargo fmt` on default settings.
  • Loading branch information
TomAFrench authored Jun 24, 2024
1 parent 7689d59 commit b859ef9
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 3 deletions.
44 changes: 42 additions & 2 deletions compiler/noirc_evaluator/src/ssa/acir_gen/acir_ir/acir_variable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1522,6 +1522,26 @@ impl<F: AcirField> AcirContext<F> {
brillig_function_index: u32,
brillig_stdlib_func: Option<BrilligStdlibFunc>,
) -> Result<Vec<AcirValue>, RuntimeError> {
let predicate = self.var_to_expression(predicate)?;
if predicate.is_zero() {
// If the predicate has a constant value of zero, the brillig call will never be executed.
// We can then immediately zero out all of its outputs as this is the value which would be written
// if we waited until runtime to resolve this call.
let outputs_var = vecmap(outputs, |output| match output {
AcirType::NumericType(_) => {
let var = self.add_constant(F::zero());
AcirValue::Var(var, output.clone())
}
AcirType::Array(element_types, size) => {
self.zeroed_array_output(&element_types, size)
}
});

return Ok(outputs_var);
}
// Remove "always true" predicates.
let predicate = if predicate == Expression::one() { None } else { Some(predicate) };

let brillig_inputs: Vec<BrilligInputs<F>> =
try_vecmap(inputs, |i| -> Result<_, InternalError> {
match i {
Expand Down Expand Up @@ -1569,10 +1589,9 @@ impl<F: AcirField> AcirContext<F> {
acir_value
}
});
let predicate = self.var_to_expression(predicate)?;

self.acir_ir.brillig_call(
Some(predicate),
predicate,
generated_brillig,
brillig_inputs,
brillig_outputs,
Expand Down Expand Up @@ -1643,6 +1662,27 @@ impl<F: AcirField> AcirContext<F> {
Ok(())
}

/// Recursively create zeroed-out acir values for returned arrays. This is necessary because a brillig returned array can have nested arrays as elements.
fn zeroed_array_output(&mut self, element_types: &[AcirType], size: usize) -> AcirValue {
let mut array_values = im::Vector::new();
for _ in 0..size {
for element_type in element_types {
match element_type {
AcirType::Array(nested_element_types, nested_size) => {
let nested_acir_value =
self.zeroed_array_output(nested_element_types, *nested_size);
array_values.push_back(nested_acir_value);
}
AcirType::NumericType(_) => {
let var = self.add_constant(F::zero());
array_values.push_back(AcirValue::Var(var, element_type.clone()));
}
}
}
}
AcirValue::Array(array_values)
}

/// Recursively create acir values for returned arrays. This is necessary because a brillig returned array can have nested arrays as elements.
/// A singular array of witnesses is collected for a top level array, by deflattening the assigned witnesses at each level.
fn brillig_array_output(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -431,7 +431,7 @@ impl<F: AcirField> GeneratedAcir<F> {
let inputs = vec![BrilligInputs::Single(expr)];
let outputs = vec![BrilligOutputs::Simple(inverted_witness)];
self.brillig_call(
Some(Expression::one()),
None,
&inverse_code,
inputs,
outputs,
Expand Down

0 comments on commit b859ef9

Please sign in to comment.