Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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