use acir::circuit::{opcodes::BlockId, Circuit, Opcode};
use std::collections::HashSet;
pub(crate) struct UnusedMemoryOptimizer {
unused_memory_initializations: HashSet<BlockId>,
circuit: Circuit,
}
impl UnusedMemoryOptimizer {
pub(crate) fn new(circuit: Circuit) -> Self {
let unused_memory_initializations = Self::collect_unused_memory_initializations(&circuit);
Self { circuit, unused_memory_initializations }
}
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
}
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.into_iter().enumerate() {
match opcode {
Opcode::MemoryInit { block_id, .. }
if self.unused_memory_initializations.contains(&block_id) =>
{
}
_ => {
new_order_list.push(order_list[idx]);
optimized_opcodes.push(opcode);
}
}
}
(Circuit { opcodes: optimized_opcodes, ..self.circuit }, new_order_list)
}
}