Skip to content

Commit 8628b32

Browse files
authored
chore: remove some unnecessary clones (#10049)
This PR removes some of the unnecessary clones from `merge_expressions.rs`
1 parent aafef9c commit 8628b32

File tree

1 file changed

+24
-23
lines changed

1 file changed

+24
-23
lines changed

noir/noir-repo/acvm-repo/acvm/src/compiler/optimizers/merge_expressions.rs

+24-23
Original file line numberDiff line numberDiff line change
@@ -50,31 +50,36 @@ impl MergeExpressionsOptimizer {
5050
let mut new_circuit = Vec::new();
5151
let mut new_acir_opcode_positions = Vec::new();
5252
// For each opcode, try to get a target opcode to merge with
53-
for (i, opcode) in circuit.opcodes.iter().enumerate() {
53+
for (i, (opcode, opcode_position)) in
54+
circuit.opcodes.iter().zip(acir_opcode_positions).enumerate()
55+
{
5456
if !matches!(opcode, Opcode::AssertZero(_)) {
5557
new_circuit.push(opcode.clone());
56-
new_acir_opcode_positions.push(acir_opcode_positions[i]);
58+
new_acir_opcode_positions.push(opcode_position);
5759
continue;
5860
}
5961
let opcode = modified_gates.get(&i).unwrap_or(opcode).clone();
6062
let mut to_keep = true;
6163
let input_witnesses = self.witness_inputs(&opcode);
62-
for w in input_witnesses.clone() {
63-
let empty_gates = BTreeSet::new();
64-
let gates_using_w = used_witness.get(&w).unwrap_or(&empty_gates);
64+
for w in input_witnesses {
65+
let Some(gates_using_w) = used_witness.get(&w) else {
66+
continue;
67+
};
6568
// We only consider witness which are used in exactly two arithmetic gates
6669
if gates_using_w.len() == 2 {
67-
let gates_using_w: Vec<_> = gates_using_w.iter().collect();
68-
let mut b = *gates_using_w[1];
69-
if b == i {
70-
b = *gates_using_w[0];
70+
let first = *gates_using_w.first().expect("gates_using_w.len == 2");
71+
let second = *gates_using_w.last().expect("gates_using_w.len == 2");
72+
let b = if second == i {
73+
first
7174
} else {
7275
// sanity check
73-
assert!(i == *gates_using_w[0]);
74-
}
75-
let second_gate = modified_gates.get(&b).unwrap_or(&circuit.opcodes[b]).clone();
76+
assert!(i == first);
77+
second
78+
};
79+
80+
let second_gate = modified_gates.get(&b).unwrap_or(&circuit.opcodes[b]);
7681
if let (Opcode::AssertZero(expr_define), Opcode::AssertZero(expr_use)) =
77-
(opcode.clone(), second_gate)
82+
(&opcode, second_gate)
7883
{
7984
// We cannot merge an expression into an earlier opcode, because this
8085
// would break the 'execution ordering' of the opcodes
@@ -85,16 +90,15 @@ impl MergeExpressionsOptimizer {
8590
// - doing this pass again until there is no change, or
8691
// - merging 'b' into 'i' instead
8792
if i < b {
88-
if let Some(expr) = Self::merge(&expr_use, &expr_define, w) {
93+
if let Some(expr) = Self::merge(expr_use, expr_define, w) {
8994
modified_gates.insert(b, Opcode::AssertZero(expr));
9095
to_keep = false;
9196
// Update the 'used_witness' map to account for the merge.
92-
for w2 in CircuitSimulator::expr_wit(&expr_define) {
97+
for w2 in CircuitSimulator::expr_wit(expr_define) {
9398
if !circuit_inputs.contains(&w2) {
94-
let mut v = used_witness[&w2].clone();
99+
let v = used_witness.entry(w2).or_default();
95100
v.insert(b);
96101
v.remove(&i);
97-
used_witness.insert(w2, v);
98102
}
99103
}
100104
// We need to stop here and continue with the next opcode
@@ -107,12 +111,9 @@ impl MergeExpressionsOptimizer {
107111
}
108112

109113
if to_keep {
110-
if modified_gates.contains_key(&i) {
111-
new_circuit.push(modified_gates[&i].clone());
112-
} else {
113-
new_circuit.push(opcode.clone());
114-
}
115-
new_acir_opcode_positions.push(acir_opcode_positions[i]);
114+
let opcode = modified_gates.get(&i).cloned().unwrap_or(opcode);
115+
new_circuit.push(opcode);
116+
new_acir_opcode_positions.push(opcode_position);
116117
}
117118
}
118119
(new_circuit, new_acir_opcode_positions)

0 commit comments

Comments
 (0)