From 435ab3520d06b6b4f898d41a5ad403c5ddbd7771 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Wed, 2 Aug 2023 16:51:04 +0100 Subject: [PATCH] feat: replace boolean `AND`s with multiplication (#1954) * feat: replace boolean `AND`s with multiplication * chore: move optimisation to live within ssa-gen * chore: fill out message in `unreachable` * chore: remove `SimplifyResult::None` * chore: abstract away `SimplifyResult::SimplifiedToInstruction(None)` * Revert "chore: abstract away `SimplifyResult::SimplifiedToInstruction(None)`" This reverts commit a7736eb418944864ff9a67b07aea01e7ba0bdb17. * Revert "chore: remove `SimplifyResult::None`" This reverts commit 429ccd473883ac3b210dda3eac59d780a0b45a2f. * chore: add `SimplifyResult.instruction()` --- .../noirc_evaluator/src/ssa_refactor/ir/dfg.rs | 3 ++- .../src/ssa_refactor/ir/instruction.rs | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/crates/noirc_evaluator/src/ssa_refactor/ir/dfg.rs b/crates/noirc_evaluator/src/ssa_refactor/ir/dfg.rs index caf65c85a7e..6d74e49b03b 100644 --- a/crates/noirc_evaluator/src/ssa_refactor/ir/dfg.rs +++ b/crates/noirc_evaluator/src/ssa_refactor/ir/dfg.rs @@ -158,7 +158,8 @@ impl DataFlowGraph { SimplifiedToMultiple(simplification) } SimplifyResult::Remove => InstructionRemoved, - SimplifyResult::None => { + result @ (SimplifyResult::SimplifiedToInstruction(_) | SimplifyResult::None) => { + let instruction = result.instruction().unwrap_or(instruction); let id = self.make_instruction(instruction, ctrl_typevars); self.blocks[block].insert_instruction(id); if let Some(location) = location { diff --git a/crates/noirc_evaluator/src/ssa_refactor/ir/instruction.rs b/crates/noirc_evaluator/src/ssa_refactor/ir/instruction.rs index a56b12ab875..afb47d423e2 100644 --- a/crates/noirc_evaluator/src/ssa_refactor/ir/instruction.rs +++ b/crates/noirc_evaluator/src/ssa_refactor/ir/instruction.rs @@ -736,6 +736,11 @@ impl Binary { if dfg.resolve(self.lhs) == dfg.resolve(self.rhs) { return SimplifyResult::SimplifiedTo(self.lhs); } + if operand_type == Type::bool() { + // Boolean AND is equivalent to multiplication, which is a cheaper operation. + let instruction = Instruction::binary(BinaryOp::Mul, self.lhs, self.rhs); + return SimplifyResult::SimplifiedToInstruction(instruction); + } } BinaryOp::Or => { if lhs_is_zero { @@ -898,9 +903,21 @@ pub(crate) enum SimplifyResult { /// a function such as a tuple SimplifiedToMultiple(Vec), + /// Replace this function with an simpler but equivalent function. + SimplifiedToInstruction(Instruction), + /// Remove the instruction, it is unnecessary Remove, /// Instruction could not be simplified None, } + +impl SimplifyResult { + pub(crate) fn instruction(self) -> Option { + match self { + SimplifyResult::SimplifiedToInstruction(instruction) => Some(instruction), + _ => None, + } + } +}