Skip to content

Commit

Permalink
feat: bubble up Instruction::Constrains to be applied as early as p…
Browse files Browse the repository at this point in the history
…ossible. (#4065)

# Description

## Problem\*

Resolves <!-- Link to GitHub Issue -->

## Summary\*

This PR adds a very simple pass which moves any
`Instruction::Constrain`s to immediately after when all of their inputs
are available. This allows the ACIR gen pass to use this information
earlier as well as simplifying using these constraints in order to
inform constant folding in future.

## Additional Context

Pulled out from #4060 

## Documentation\*

Check one:
- [x] No documentation needed.
- [ ] Documentation included in this PR.
- [ ] **[Exceptional Case]** 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 committed Jan 17, 2024
1 parent 555a4a5 commit 66f5cdd
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 0 deletions.
1 change: 1 addition & 0 deletions compiler/noirc_evaluator/src/ssa.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ pub(crate) fn optimize_into_acir(
.run_pass(Ssa::mem2reg, "After Mem2Reg:")
.run_pass(Ssa::fold_constants, "After Constant Folding:")
.run_pass(Ssa::dead_instruction_elimination, "After Dead Instruction Elimination:")
.run_pass(Ssa::bubble_up_constrains, "After Constraint Bubbling:")
.finish();

let brillig = ssa.to_brillig(print_brillig_trace);
Expand Down
43 changes: 43 additions & 0 deletions compiler/noirc_evaluator/src/ssa/opt/bubble_up_constrains.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
use crate::ssa::{ir::instruction::Instruction, ssa_gen::Ssa};

impl Ssa {
/// A simple SSA pass to go through each instruction and move every `Instruction::Constrain` to immediately
/// after when all of its inputs are available.
#[tracing::instrument(level = "trace", skip(self))]
pub(crate) fn bubble_up_constrains(mut self) -> Ssa {
for function in self.functions.values_mut() {
for block in function.reachable_blocks() {
let instructions = function.dfg[block].take_instructions();
let mut filtered_instructions = Vec::with_capacity(instructions.len());

let dfg = &function.dfg;
for instruction in instructions {
let (lhs, rhs) = match dfg[instruction] {
Instruction::Constrain(lhs, rhs, ..) => (lhs, rhs),
_ => {
filtered_instructions.push(instruction);
continue;
}
};

let index = filtered_instructions
.iter()
.rev()
.position(|instruction_id| {
let results = dfg.instruction_results(*instruction_id).to_vec();
results.contains(&lhs) || results.contains(&rhs)
})
// We iterate through the previous instructions in reverse order so the index is from the
// back of the vector. Subtract from vector length to get correct index.
.map(|reversed_index| filtered_instructions.len() - reversed_index)
.unwrap_or(filtered_instructions.len());

filtered_instructions.insert(index, instruction);
}

*function.dfg[block].instructions_mut() = filtered_instructions;
}
}
self
}
}
1 change: 1 addition & 0 deletions compiler/noirc_evaluator/src/ssa/opt/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
//! Generally, these passes are also expected to minimize the final amount of instructions.
mod array_use;
mod assert_constant;
mod bubble_up_constrains;
mod constant_folding;
mod defunctionalize;
mod die;
Expand Down

0 comments on commit 66f5cdd

Please sign in to comment.