diff --git a/compiler/noirc_evaluator/src/acir/arrays.rs b/compiler/noirc_evaluator/src/acir/arrays.rs index c92b244b0d0..54894359ead 100644 --- a/compiler/noirc_evaluator/src/acir/arrays.rs +++ b/compiler/noirc_evaluator/src/acir/arrays.rs @@ -879,8 +879,14 @@ impl Context<'_> { AcirValue::Array(values) => { let flat_elem_type_sizes = calculate_element_type_sizes_array(values); + // If there's already a block with these same sizes, reuse it. It's fine do to so + // because the element type sizes array is never mutated. + if let Some(block_id) = self.type_sizes_to_blocks.get(&flat_elem_type_sizes) { + return Ok(*block_id); + } + // The final array should will the flattened index at each outer array index - let init_values = vecmap(flat_elem_type_sizes, |type_size| { + let init_values = vecmap(flat_elem_type_sizes.clone(), |type_size| { let var = self.acir_context.add_constant(type_size); AcirValue::Var(var, NumericType::NativeField) }); @@ -891,6 +897,8 @@ impl Context<'_> { Some(AcirValue::Array(init_values.into())), )?; + self.type_sizes_to_blocks.insert(flat_elem_type_sizes, element_type_sizes); + Ok(element_type_sizes) } diff --git a/compiler/noirc_evaluator/src/acir/mod.rs b/compiler/noirc_evaluator/src/acir/mod.rs index cac0b3c7b76..e5bf00d116f 100644 --- a/compiler/noirc_evaluator/src/acir/mod.rs +++ b/compiler/noirc_evaluator/src/acir/mod.rs @@ -91,6 +91,10 @@ struct Context<'a> { /// which utilizes this internal memory for ACIR generation. element_type_sizes_blocks: HashMap, BlockId>, + /// Maps type sizes to BlockId. This is used to reuse the same BlockId if different + /// non-homogenous arrays end up having the same type sizes layout. + type_sizes_to_blocks: HashMap, BlockId>, + /// Number of the next BlockId, it is used to construct /// a new BlockId max_block_id: u32, @@ -125,6 +129,7 @@ impl<'a> Context<'a> { initialized_arrays: HashSet::default(), memory_blocks: HashMap::default(), element_type_sizes_blocks: HashMap::default(), + type_sizes_to_blocks: HashMap::default(), max_block_id: 0, data_bus: DataBus::default(), shared_context,