Skip to content

Commit

Permalink
feat: add simple optimizations for constrain instructions
Browse files Browse the repository at this point in the history
  • Loading branch information
TomAFrench committed Aug 11, 2024
1 parent 400105a commit bb77a2c
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 2 deletions.
5 changes: 3 additions & 2 deletions compiler/noirc_evaluator/src/ssa/ir/instruction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ mod constrain;
pub(crate) use binary::{Binary, BinaryOp};
use call::simplify_call;
use cast::simplify_cast;
use constrain::decompose_constrain;
use constrain::{decompose_constrain, simplify_constrain};

/// Reference to an instruction
///
Expand Down Expand Up @@ -600,7 +600,8 @@ impl Instruction {
}
}
Instruction::Constrain(lhs, rhs, msg) => {
let constraints = decompose_constrain(*lhs, *rhs, msg, dfg);
let (lhs, rhs) = simplify_constrain(*lhs, *rhs, dfg);
let constraints = decompose_constrain(lhs, rhs, msg, dfg);
if constraints.is_empty() {
Remove
} else {
Expand Down
34 changes: 34 additions & 0 deletions compiler/noirc_evaluator/src/ssa/ir/instruction/constrain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,40 @@ use acvm::{acir::AcirField, FieldElement};

use super::{Binary, BinaryOp, ConstrainError, DataFlowGraph, Instruction, Type, Value, ValueId};

/// Try to simplify this constrain instruction. This function will inspect the inputs to the constraint such that
/// it acts on variables as early in the DFG as possible.
pub(super) fn simplify_constrain(
lhs: ValueId,
rhs: ValueId,
dfg: &mut DataFlowGraph,
) -> (ValueId, ValueId) {
let lhs = dfg.resolve(lhs);
let rhs = dfg.resolve(rhs);

match (&dfg[lhs], &dfg[rhs]) {
(Value::Instruction { instruction, .. }, Value::NumericConstant { constant, typ }) => {
let Instruction::Binary(Binary { lhs, rhs, operator: BinaryOp::Add }) = dfg[*instruction].clone()
else {
return (lhs, rhs);
};

let Value::NumericConstant { constant: inner_constant, .. } = dfg[rhs].clone()
else {
return (lhs, rhs);
};

if *constant > inner_constant {
let new_rhs = dfg.make_constant(*constant - inner_constant, typ.clone());
(lhs, new_rhs)
} else {
(lhs, rhs)
}
}

_ => (lhs, rhs),
}
}

/// Try to decompose this constrain instruction. This constraint will be broken down such that it instead constrains
/// all the values which are used to compute the values which were being constrained.
pub(super) fn decompose_constrain(
Expand Down

0 comments on commit bb77a2c

Please sign in to comment.