Skip to content

Commit

Permalink
chore: strip initialization of unused memory blocks from ACIR (#2985)
Browse files Browse the repository at this point in the history
Co-authored-by: Maxim Vezenov <[email protected]>
  • Loading branch information
TomAFrench and vezenovm authored Oct 4, 2023
1 parent 269e490 commit fde5daa
Show file tree
Hide file tree
Showing 54 changed files with 69 additions and 0 deletions.
8 changes: 8 additions & 0 deletions acvm-repo/acvm/src/compiler/optimizers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,13 @@ use acir::circuit::{Circuit, Opcode};

mod general;
mod redundant_range;
mod unused_memory;

pub(crate) use general::GeneralOptimizer;
pub(crate) use redundant_range::RangeOptimizer;

use self::unused_memory::UnusedMemoryOptimizer;

use super::AcirTransformationMap;

/// Applies [`ProofSystemCompiler`][crate::ProofSystemCompiler] independent optimizations to a [`Circuit`].
Expand All @@ -26,6 +29,11 @@ pub fn optimize(acir: Circuit) -> (Circuit, AcirTransformationMap) {
// by applying the modifications done to the circuit opcodes and also to the opcode_positions (delete and insert)
let acir_opcode_positions = acir.opcodes.iter().enumerate().map(|(i, _)| i).collect();

// Unused memory optimization pass
let memory_optimizer = UnusedMemoryOptimizer::new(acir);
let (acir, acir_opcode_positions) =
memory_optimizer.remove_unused_memory_initializations(acir_opcode_positions);

// Range optimization pass
let range_optimizer = RangeOptimizer::new(acir);
let (acir, acir_opcode_positions) =
Expand Down
61 changes: 61 additions & 0 deletions acvm-repo/acvm/src/compiler/optimizers/unused_memory.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
use acir::circuit::{opcodes::BlockId, Circuit, Opcode};
use std::collections::HashSet;

/// `UnusedMemoryOptimizer` will remove initializations of memory blocks which are unused.
pub(crate) struct UnusedMemoryOptimizer {
unused_memory_initializations: HashSet<BlockId>,
circuit: Circuit,
}

impl UnusedMemoryOptimizer {
/// Creates a new `UnusedMemoryOptimizer ` by collecting unused memory init
/// opcodes from `Circuit`.
pub(crate) fn new(circuit: Circuit) -> Self {
let unused_memory_initializations = Self::collect_unused_memory_initializations(&circuit);
Self { circuit, unused_memory_initializations }
}

/// Creates a set of ids for memory blocks for which no [`Opcode::MemoryOp`]s exist.
///
/// These memory blocks can be safely removed.
fn collect_unused_memory_initializations(circuit: &Circuit) -> HashSet<BlockId> {
let mut unused_memory_initialization = HashSet::new();

for opcode in &circuit.opcodes {
match opcode {
Opcode::MemoryInit { block_id, .. } => {
unused_memory_initialization.insert(*block_id);
}
Opcode::MemoryOp { block_id, .. } => {
unused_memory_initialization.remove(block_id);
}
_ => (),
}
}
unused_memory_initialization
}

/// Returns a `Circuit` where [`Opcode::MemoryInit`]s for unused memory blocks are dropped.
pub(crate) fn remove_unused_memory_initializations(
self,
order_list: Vec<usize>,
) -> (Circuit, Vec<usize>) {
let mut new_order_list = Vec::with_capacity(order_list.len());
let mut optimized_opcodes = Vec::with_capacity(self.circuit.opcodes.len());
for (idx, opcode) in self.circuit.opcodes.iter().enumerate() {
match opcode {
Opcode::MemoryInit { block_id, .. }
if self.unused_memory_initializations.contains(block_id) =>
{
// Drop opcode
}
_ => {
new_order_list.push(order_list[idx]);
optimized_opcodes.push(opcode.clone());
}
}
}

(Circuit { opcodes: optimized_opcodes, ..self.circuit }, new_order_list)
}
}
Binary file modified tooling/nargo_cli/tests/acir_artifacts/6/target/acir.gz
Binary file not shown.
Binary file modified tooling/nargo_cli/tests/acir_artifacts/6_array/target/acir.gz
Binary file not shown.
Binary file modified tooling/nargo_cli/tests/acir_artifacts/7/target/acir.gz
Binary file not shown.
Binary file modified tooling/nargo_cli/tests/acir_artifacts/7_function/target/acir.gz
Binary file not shown.
Binary file not shown.
Binary file modified tooling/nargo_cli/tests/acir_artifacts/array_eq/target/acir.gz
Binary file not shown.
Binary file modified tooling/nargo_cli/tests/acir_artifacts/array_len/target/acir.gz
Binary file not shown.
Binary file modified tooling/nargo_cli/tests/acir_artifacts/array_neq/target/acir.gz
Binary file not shown.
Binary file modified tooling/nargo_cli/tests/acir_artifacts/array_sort/target/acir.gz
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified tooling/nargo_cli/tests/acir_artifacts/keccak256/target/acir.gz
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified tooling/nargo_cli/tests/acir_artifacts/modulus/target/acir.gz
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified tooling/nargo_cli/tests/acir_artifacts/regression/target/acir.gz
Binary file not shown.
Binary file not shown.
Binary file modified tooling/nargo_cli/tests/acir_artifacts/schnorr/target/acir.gz
Binary file not shown.
Binary file modified tooling/nargo_cli/tests/acir_artifacts/sha256/target/acir.gz
Binary file not shown.
Binary file not shown.
Binary file modified tooling/nargo_cli/tests/acir_artifacts/sha2_byte/target/acir.gz
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file modified tooling/nargo_cli/tests/acir_artifacts/strings/target/acir.gz
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.

0 comments on commit fde5daa

Please sign in to comment.