Skip to content

Commit

Permalink
feat: optimize logic gate acir-gen
Browse files Browse the repository at this point in the history
  • Loading branch information
TomAFrench committed Dec 21, 2023
1 parent b8c7078 commit eda2b63
Showing 1 changed file with 37 additions and 0 deletions.
37 changes: 37 additions & 0 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 @@ -368,6 +368,21 @@ impl AcirContext {
rhs: AcirVar,
typ: AcirType,
) -> Result<AcirVar, RuntimeError> {
let lhs_expr = self.var_to_expression(lhs)?;
let rhs_expr = self.var_to_expression(rhs)?;

if lhs_expr == rhs_expr {
// x ^ x == 0
let zero = self.add_constant(FieldElement::zero());
return Ok(zero);
} else if lhs_expr.is_zero() {
// x ^ 0 == x
return Ok(rhs);
} else if rhs_expr.is_zero() {
// 0 ^ x == x
return Ok(lhs);
}

let inputs = vec![AcirValue::Var(lhs, typ.clone()), AcirValue::Var(rhs, typ)];
let outputs = self.black_box_function(BlackBoxFunc::XOR, inputs, 1)?;
Ok(outputs[0])
Expand All @@ -380,6 +395,18 @@ impl AcirContext {
rhs: AcirVar,
typ: AcirType,
) -> Result<AcirVar, RuntimeError> {
let lhs_expr = self.var_to_expression(lhs)?;
let rhs_expr = self.var_to_expression(rhs)?;

if lhs_expr == rhs_expr {
// x & x == x
return Ok(lhs);
} else if lhs_expr.is_zero() || rhs_expr.is_zero() {
// x & 0 == 0 and 0 & x == 0
let zero = self.add_constant(FieldElement::zero());
return Ok(zero);
}

let bit_size = typ.bit_size();
if bit_size == 1 {
// Operands are booleans.
Expand All @@ -398,6 +425,16 @@ impl AcirContext {
rhs: AcirVar,
typ: AcirType,
) -> Result<AcirVar, RuntimeError> {
let lhs_expr = self.var_to_expression(lhs)?;
let rhs_expr = self.var_to_expression(rhs)?;
if lhs_expr.is_zero() {
// x | 0 == x
return Ok(rhs);
} else if rhs_expr.is_zero() {
// 0 | x == x
return Ok(lhs);
}

let bit_size = typ.bit_size();
if bit_size == 1 {
// Operands are booleans
Expand Down

0 comments on commit eda2b63

Please sign in to comment.