Skip to content

Commit

Permalink
feat: remove type arrays for flat slices (#3466)
Browse files Browse the repository at this point in the history
  • Loading branch information
TomAFrench authored Nov 27, 2023
1 parent 70ee787 commit 8225b2b
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 39 deletions.
99 changes: 64 additions & 35 deletions compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,14 +101,16 @@ pub(crate) struct AcirDynamicArray {
len: usize,
/// Identification for the ACIR dynamic array
/// inner element type sizes array
element_type_sizes: BlockId,
element_type_sizes: Option<BlockId>,
}
impl Debug for AcirDynamicArray {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
write!(
f,
"id: {}, len: {}, element_type_sizes: {:?}",
self.block_id.0, self.len, self.element_type_sizes.0
self.block_id.0,
self.len,
self.element_type_sizes.map(|block_id| block_id.0)
)
}
}
Expand Down Expand Up @@ -921,7 +923,7 @@ impl Context {
// Read the value from the array at the specified index
let read = self.acir_context.read_from_memory(block_id, var_index)?;

// Incremement the var_index in case of a nested array
// Increment the var_index in case of a nested array
*var_index = self.acir_context.add_var(*var_index, one)?;

let typ = AcirType::NumericType(numeric_type);
Expand Down Expand Up @@ -1036,8 +1038,11 @@ impl Context {
}
}

let element_type_sizes =
self.init_element_type_sizes_array(&array_typ, array_id, None, dfg)?;
let element_type_sizes = if !can_omit_element_sizes_array(&array_typ) {
Some(self.init_element_type_sizes_array(&array_typ, array_id, None, dfg)?)
} else {
None
};
let result_value = AcirValue::DynamicArray(AcirDynamicArray {
block_id: result_block_id,
len: array_len,
Expand Down Expand Up @@ -1162,27 +1167,29 @@ impl Context {
element_type_sizes: inner_elem_type_sizes,
..
}) => {
if self.initialized_arrays.contains(&inner_elem_type_sizes) {
let type_sizes_array_len = self.internal_mem_block_lengths.get(&inner_elem_type_sizes).copied().ok_or_else(||
InternalError::General {
message: format!("Array {array_id}'s inner element type sizes array does not have a tracked length"),
if let Some(inner_elem_type_sizes) = inner_elem_type_sizes {
if self.initialized_arrays.contains(&inner_elem_type_sizes) {
let type_sizes_array_len = self.internal_mem_block_lengths.get(&inner_elem_type_sizes).copied().ok_or_else(||
InternalError::General {
message: format!("Array {array_id}'s inner element type sizes array does not have a tracked length"),
call_stack: self.acir_context.get_call_stack(),
}
)?;
self.copy_dynamic_array(
inner_elem_type_sizes,
element_type_sizes,
type_sizes_array_len,
)?;
self.internal_mem_block_lengths
.insert(element_type_sizes, type_sizes_array_len);
return Ok(element_type_sizes);
} else {
return Err(InternalError::General {
message: format!("Array {array_id}'s inner element type sizes array should be initialized"),
call_stack: self.acir_context.get_call_stack(),
}
)?;
self.copy_dynamic_array(
inner_elem_type_sizes,
element_type_sizes,
type_sizes_array_len,
)?;
self.internal_mem_block_lengths
.insert(element_type_sizes, type_sizes_array_len);
return Ok(element_type_sizes);
} else {
return Err(InternalError::General {
message: format!("Array {array_id}'s inner element type sizes array should be initialized"),
call_stack: self.acir_context.get_call_stack(),
.into());
}
.into());
}
}
AcirValue::Array(values) => {
Expand Down Expand Up @@ -1298,15 +1305,19 @@ impl Context {
var_index: AcirVar,
dfg: &DataFlowGraph,
) -> Result<AcirVar, RuntimeError> {
let element_type_sizes =
self.init_element_type_sizes_array(array_typ, array_id, None, dfg)?;
if !can_omit_element_sizes_array(array_typ) {
let element_type_sizes =
self.init_element_type_sizes_array(array_typ, array_id, None, dfg)?;

let predicate_index =
self.acir_context.mul_var(var_index, self.current_side_effects_enabled_var)?;
let flat_element_size_var =
self.acir_context.read_from_memory(element_type_sizes, &predicate_index)?;
let predicate_index =
self.acir_context.mul_var(var_index, self.current_side_effects_enabled_var)?;

Ok(flat_element_size_var)
self.acir_context
.read_from_memory(element_type_sizes, &predicate_index)
.map_err(RuntimeError::from)
} else {
Ok(var_index)
}
}

fn flattened_slice_size(&mut self, array_id: ValueId, dfg: &DataFlowGraph) -> usize {
Expand Down Expand Up @@ -1781,15 +1792,20 @@ impl Context {
let mut var_index = slice_length;
self.array_set_value(element, result_block_id, &mut var_index)?;

let result = AcirValue::DynamicArray(AcirDynamicArray {
block_id: result_block_id,
len: len + new_elem_size,
element_type_sizes: self.init_element_type_sizes_array(
let element_type_sizes = if !can_omit_element_sizes_array(&array_typ) {
Some(self.init_element_type_sizes_array(
&array_typ,
array_id,
Some(new_slice_val),
dfg,
)?,
)?)
} else {
None
};
let result = AcirValue::DynamicArray(AcirDynamicArray {
block_id: result_block_id,
len: len + new_elem_size,
element_type_sizes,
});
Ok(vec![AcirValue::Var(new_slice_length, AcirType::field()), result])
}
Expand Down Expand Up @@ -2041,3 +2057,16 @@ impl Context {
}
}
}

// We can omit the element size array for arrays which have elements of size 1 and do not contain slices.
// TODO: remove restriction on size 1 elements.
fn can_omit_element_sizes_array(array_typ: &Type) -> bool {
if array_typ.contains_slice_element() {
return false;
}
let Type::Array(types, _) = array_typ else {
panic!("ICE: expected array type");
};

types.len() == 1 && types[0].flattened_size() == 1
}
6 changes: 2 additions & 4 deletions compiler/noirc_evaluator/src/ssa/ir/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,17 +93,15 @@ impl Type {

/// Returns the flattened size of a Type
pub(crate) fn flattened_size(&self) -> usize {
let mut size = 0;
match self {
Type::Array(elements, len) => {
size = elements.iter().fold(size, |sum, elem| sum + (elem.flattened_size() * len));
elements.iter().fold(0, |sum, elem| sum + (elem.flattened_size() * len))
}
Type::Slice(_) => {
unimplemented!("ICE: cannot fetch flattened slice size");
}
_ => size += 1,
_ => 1,
}
size
}
}

Expand Down

0 comments on commit 8225b2b

Please sign in to comment.