diff --git a/compiler/noirc_evaluator/src/acir/acir_variable.rs b/compiler/noirc_evaluator/src/acir/acir_variable.rs index bb277751b9e..a253999bfd0 100644 --- a/compiler/noirc_evaluator/src/acir/acir_variable.rs +++ b/compiler/noirc_evaluator/src/acir/acir_variable.rs @@ -112,9 +112,6 @@ impl From for AcirType { pub(crate) struct AcirContext> { blackbox_solver: B, - /// Two-way map that links `AcirVar` to `AcirVarData`. - /// - /// The vars object is an instance of the `TwoWayMap`, which provides a bidirectional mapping between `AcirVar` and `AcirVarData`. vars: HashMap>, constant_witnesses: HashMap, diff --git a/compiler/noirc_evaluator/src/ssa.rs b/compiler/noirc_evaluator/src/ssa.rs index 9377cadb260..8d22e8e628d 100644 --- a/compiler/noirc_evaluator/src/ssa.rs +++ b/compiler/noirc_evaluator/src/ssa.rs @@ -5,7 +5,6 @@ //! elimination and constant folding. //! //! This module heavily borrows from Cranelift -#![allow(dead_code)] use std::{ collections::{BTreeMap, BTreeSet}, diff --git a/compiler/noirc_evaluator/src/ssa/function_builder/mod.rs b/compiler/noirc_evaluator/src/ssa/function_builder/mod.rs index 855034cedd2..28cf48bb171 100644 --- a/compiler/noirc_evaluator/src/ssa/function_builder/mod.rs +++ b/compiler/noirc_evaluator/src/ssa/function_builder/mod.rs @@ -133,6 +133,7 @@ impl FunctionBuilder { } /// Insert a numeric constant into the current function of type Field + #[cfg(test)] pub(crate) fn field_constant(&mut self, value: impl Into) -> ValueId { self.numeric_constant(value.into(), NumericType::NativeField) } @@ -328,6 +329,7 @@ impl FunctionBuilder { .first() } + #[cfg(test)] pub(crate) fn insert_mutable_array_set( &mut self, array: ValueId, diff --git a/compiler/noirc_evaluator/src/ssa/ir/dfg.rs b/compiler/noirc_evaluator/src/ssa/ir/dfg.rs index 902ff0775a9..f531e8307f1 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/dfg.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/dfg.rs @@ -17,7 +17,6 @@ use super::{ use acvm::{acir::AcirField, FieldElement}; use fxhash::FxHashMap as HashMap; use iter_extended::vecmap; -use noirc_errors::Location; use serde::{Deserialize, Serialize}; use serde_with::serde_as; use serde_with::DisplayFromStr; @@ -247,12 +246,6 @@ impl DataFlowGraph { } } - /// Insert a value into the dfg's storage and return an id to reference it. - /// Until the value is used in an instruction it is unreachable. - pub(crate) fn make_value(&mut self, value: Value) -> ValueId { - self.values.insert(value) - } - /// Set the value of value_to_replace to refer to the value referred to by new_value. /// /// This is the preferred method to call for optimizations simplifying @@ -437,12 +430,6 @@ impl DataFlowGraph { value_id } - /// Returns the number of instructions - /// inserted into functions. - pub(crate) fn num_instructions(&self) -> usize { - self.instructions.len() - } - /// Returns all of result values which are attached to this instruction. pub(crate) fn instruction_results(&self, instruction_id: InstructionId) -> &[ValueId] { self.results.get(&instruction_id).expect("expected a list of Values").as_slice() @@ -544,15 +531,6 @@ impl DataFlowGraph { self.locations.get(&instruction).cloned().unwrap_or_default() } - pub(crate) fn add_location_to_instruction( - &mut self, - instruction: InstructionId, - location: Location, - ) { - let call_stack = self.locations.entry(instruction).or_default(); - *call_stack = self.call_stack_data.add_child(*call_stack, location); - } - pub(crate) fn get_call_stack(&self, call_stack: CallStackId) -> CallStack { self.call_stack_data.get_call_stack(call_stack) } diff --git a/compiler/noirc_evaluator/src/ssa/ir/instruction.rs b/compiler/noirc_evaluator/src/ssa/ir/instruction.rs index 0c8d8affeb1..a66e272fb0c 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/instruction.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction.rs @@ -1300,31 +1300,6 @@ pub(crate) enum TerminatorInstruction { } impl TerminatorInstruction { - /// Map each ValueId in this terminator to a new value. - pub(crate) fn map_values( - &self, - mut f: impl FnMut(ValueId) -> ValueId, - ) -> TerminatorInstruction { - use TerminatorInstruction::*; - match self { - JmpIf { condition, then_destination, else_destination, call_stack } => JmpIf { - condition: f(*condition), - then_destination: *then_destination, - else_destination: *else_destination, - call_stack: *call_stack, - }, - Jmp { destination, arguments, call_stack } => Jmp { - destination: *destination, - arguments: vecmap(arguments, |value| f(*value)), - call_stack: *call_stack, - }, - Return { return_values, call_stack } => Return { - return_values: vecmap(return_values, |value| f(*value)), - call_stack: *call_stack, - }, - } - } - /// Mutate each ValueId to a new ValueId using the given mapping function pub(crate) fn map_values_mut(&mut self, mut f: impl FnMut(ValueId) -> ValueId) { use TerminatorInstruction::*; diff --git a/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs b/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs index 6da4c7702c8..b6b1ac3f063 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/instruction/call.rs @@ -3,7 +3,7 @@ use std::{collections::VecDeque, sync::Arc}; use acvm::{ acir::{AcirField, BlackBoxFunc}, - BlackBoxResolutionError, FieldElement, + FieldElement, }; use bn254_blackbox_solver::derive_generators; use iter_extended::vecmap; @@ -501,12 +501,20 @@ fn simplify_black_box_func( } }; match bb_func { - BlackBoxFunc::Blake2s => { - simplify_hash(dfg, arguments, acvm::blackbox_solver::blake2s, block, call_stack) - } - BlackBoxFunc::Blake3 => { - simplify_hash(dfg, arguments, acvm::blackbox_solver::blake3, block, call_stack) - } + BlackBoxFunc::Blake2s => blackbox::simplify_hash( + dfg, + arguments, + acvm::blackbox_solver::blake2s, + block, + call_stack, + ), + BlackBoxFunc::Blake3 => blackbox::simplify_hash( + dfg, + arguments, + acvm::blackbox_solver::blake3, + block, + call_stack, + ), BlackBoxFunc::Keccakf1600 => { if let Some((array_input, _)) = dfg.get_array_constant(arguments[0]) { if array_is_constant(dfg, &array_input) { @@ -658,78 +666,6 @@ fn array_is_constant(dfg: &DataFlowGraph, values: &im::Vector>) -> boo values.iter().all(|value| dfg.get_numeric_constant(*value).is_some()) } -fn simplify_hash( - dfg: &mut DataFlowGraph, - arguments: &[ValueId], - hash_function: fn(&[u8]) -> Result<[u8; 32], BlackBoxResolutionError>, - block: BasicBlockId, - call_stack: CallStackId, -) -> SimplifyResult { - match dfg.get_array_constant(arguments[0]) { - Some((input, _)) if array_is_constant(dfg, &input) => { - let input_bytes: Vec = to_u8_vec(dfg, input); - - let hash = hash_function(&input_bytes) - .expect("Rust solvable black box function should not fail"); - - let hash_values = hash.iter().map(|byte| FieldElement::from_be_bytes_reduce(&[*byte])); - - let u8_type = NumericType::Unsigned { bit_size: 8 }; - let result_array = make_constant_array(dfg, hash_values, u8_type, block, call_stack); - SimplifyResult::SimplifiedTo(result_array) - } - _ => SimplifyResult::None, - } -} - -type ECDSASignatureVerifier = fn( - hashed_msg: &[u8], - public_key_x: &[u8; 32], - public_key_y: &[u8; 32], - signature: &[u8; 64], -) -> Result; -fn simplify_signature( - dfg: &mut DataFlowGraph, - arguments: &[ValueId], - signature_verifier: ECDSASignatureVerifier, -) -> SimplifyResult { - match ( - dfg.get_array_constant(arguments[0]), - dfg.get_array_constant(arguments[1]), - dfg.get_array_constant(arguments[2]), - dfg.get_array_constant(arguments[3]), - ) { - ( - Some((public_key_x, _)), - Some((public_key_y, _)), - Some((signature, _)), - Some((hashed_message, _)), - ) if array_is_constant(dfg, &public_key_x) - && array_is_constant(dfg, &public_key_y) - && array_is_constant(dfg, &signature) - && array_is_constant(dfg, &hashed_message) => - { - let public_key_x: [u8; 32] = to_u8_vec(dfg, public_key_x) - .try_into() - .expect("ECDSA public key fields are 32 bytes"); - let public_key_y: [u8; 32] = to_u8_vec(dfg, public_key_y) - .try_into() - .expect("ECDSA public key fields are 32 bytes"); - let signature: [u8; 64] = - to_u8_vec(dfg, signature).try_into().expect("ECDSA signatures are 64 bytes"); - let hashed_message: Vec = to_u8_vec(dfg, hashed_message); - - let valid_signature = - signature_verifier(&hashed_message, &public_key_x, &public_key_y, &signature) - .expect("Rust solvable black box function should not fail"); - - let valid_signature = dfg.make_constant(valid_signature.into(), NumericType::bool()); - SimplifyResult::SimplifiedTo(valid_signature) - } - _ => SimplifyResult::None, - } -} - fn simplify_derive_generators( dfg: &mut DataFlowGraph, arguments: &[ValueId], diff --git a/compiler/noirc_evaluator/src/ssa/ir/map.rs b/compiler/noirc_evaluator/src/ssa/ir/map.rs index 0fb02f19b14..1d637309191 100644 --- a/compiler/noirc_evaluator/src/ssa/ir/map.rs +++ b/compiler/noirc_evaluator/src/ssa/ir/map.rs @@ -1,4 +1,3 @@ -use fxhash::FxHashMap as HashMap; use serde::{Deserialize, Serialize}; use std::{ collections::BTreeMap, @@ -180,11 +179,6 @@ pub(crate) struct DenseMap { } impl DenseMap { - /// Returns the number of elements in the map. - pub(crate) fn len(&self) -> usize { - self.storage.len() - } - /// Adds an element to the map. /// Returns the identifier/reference to that element. pub(crate) fn insert(&mut self, element: T) -> Id { @@ -193,14 +187,6 @@ impl DenseMap { id } - /// Given the Id of the element being created, adds the element - /// returned by the given function to the map - pub(crate) fn insert_with_id(&mut self, f: impl FnOnce(Id) -> T) -> Id { - let id = Id::new(self.storage.len().try_into().unwrap()); - self.storage.push(f(id)); - id - } - /// Gets an iterator to a reference to each element in the dense map paired with its id. /// /// The id-element pairs are ordered by the numeric values of the ids. @@ -246,19 +232,6 @@ pub(crate) struct SparseMap { } impl SparseMap { - /// Returns the number of elements in the map. - pub(crate) fn len(&self) -> usize { - self.storage.len() - } - - /// Adds an element to the map. - /// Returns the identifier/reference to that element. - pub(crate) fn insert(&mut self, element: T) -> Id { - let id = Id::new(self.storage.len().try_into().unwrap()); - self.storage.insert(id, element); - id - } - /// Given the Id of the element being created, adds the element /// returned by the given function to the map pub(crate) fn insert_with_id(&mut self, f: impl FnOnce(Id) -> T) -> Id { @@ -267,13 +240,6 @@ impl SparseMap { id } - /// Remove an element from the map and return it. - /// This may return None if the element was already - /// previously removed from the map. - pub(crate) fn remove(&mut self, id: Id) -> Option { - self.storage.remove(&id) - } - /// Unwraps the inner storage of this map pub(crate) fn into_btree(self) -> BTreeMap, T> { self.storage @@ -300,65 +266,6 @@ impl std::ops::IndexMut> for SparseMap { } } -/// A TwoWayMap is a map from both key to value and value to key. -/// This is accomplished by keeping the map bijective - for every -/// value there is exactly one key and vice-versa. Any duplicate values -/// are prevented in the call to insert. -#[derive(Debug)] -pub(crate) struct TwoWayMap { - key_to_value: HashMap, - value_to_key: HashMap, -} - -impl TwoWayMap { - /// Returns the number of elements in the map. - pub(crate) fn len(&self) -> usize { - self.key_to_value.len() - } - - /// Adds an element to the map. - /// Returns the identifier/reference to that element. - pub(crate) fn insert(&mut self, key: K, element: V) -> K { - if let Some(existing) = self.value_to_key.get(&element) { - return existing.clone(); - } - - self.key_to_value.insert(key.clone(), element.clone()); - self.value_to_key.insert(element, key.clone()); - - key - } - - pub(crate) fn get(&self, key: &K) -> Option<&V> { - self.key_to_value.get(key) - } -} - -impl Default for TwoWayMap { - fn default() -> Self { - Self { key_to_value: HashMap::default(), value_to_key: HashMap::default() } - } -} - -// Note that there is no impl for IndexMut, -// if we allowed mutable access to map elements they may be -// mutated such that elements are no longer unique -impl std::ops::Index for TwoWayMap { - type Output = V; - - fn index(&self, id: K) -> &Self::Output { - &self.key_to_value[&id] - } -} - -impl std::ops::Index<&K> for TwoWayMap { - type Output = V; - - fn index(&self, id: &K) -> &Self::Output { - &self.key_to_value[id] - } -} - /// A simple counter to create fresh Ids without any storage. /// Useful for assigning ids before the storage is created or assigning ids /// for types that have no single owner. diff --git a/compiler/noirc_evaluator/src/ssa/opt/array_set.rs b/compiler/noirc_evaluator/src/ssa/opt/array_set.rs index 09339cf0797..05ceafcf450 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/array_set.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/array_set.rs @@ -62,7 +62,6 @@ struct Context<'f> { // Mapping of an array that comes from a load and whether the address // it was loaded from is a reference parameter passed to the block. arrays_from_load: HashMap, - inner_nested_arrays: HashMap, } impl<'f> Context<'f> { @@ -72,7 +71,6 @@ impl<'f> Context<'f> { array_to_last_use: HashMap::default(), instructions_that_can_be_made_mutable: HashSet::default(), arrays_from_load: HashMap::default(), - inner_nested_arrays: HashMap::default(), } } diff --git a/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg.rs b/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg.rs index cbaacf1d70e..16abf03eec0 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg.rs @@ -152,7 +152,6 @@ use crate::ssa::{ }; mod branch_analysis; -mod capacity_tracker; pub(crate) mod value_merger; impl Ssa { @@ -194,10 +193,6 @@ struct Context<'f> { /// the most recent condition combined with all previous conditions via `And` instructions. condition_stack: Vec, - /// Maps SSA array values with a slice type to their size. - /// This is maintained by appropriate calls to the `SliceCapacityTracker` and is used by the `ValueMerger`. - slice_sizes: HashMap, - /// Stack of block arguments /// When processing a block, we pop this stack to get its arguments /// and at the end we push the arguments for his successor @@ -259,7 +254,6 @@ fn flatten_function_cfg(function: &mut Function, no_predicates: &HashMap bool) -> usize { - function.dfg[function.entry_block()] - .instructions() - .iter() - .filter(|id| f(&function.dfg[**id])) - .count() - } - #[test] fn nested_branch_stores() { // Here we build some SSA with control flow given by the following graph. diff --git a/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg/branch_analysis.rs b/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg/branch_analysis.rs index 85240106f9f..78091285208 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg/branch_analysis.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg/branch_analysis.rs @@ -169,8 +169,8 @@ mod test { builder.switch_to_block(b9); builder.terminate_with_return(vec![]); - let mut ssa = builder.finish(); - let function = ssa.main_mut(); + let ssa = builder.finish(); + let function = ssa.main(); let cfg = ControlFlowGraph::with_function(function); let branch_ends = find_branch_ends(function, &cfg); assert_eq!(branch_ends.len(), 2); @@ -253,8 +253,8 @@ mod test { builder.switch_to_block(b15); builder.terminate_with_return(vec![]); - let mut ssa = builder.finish(); - let function = ssa.main_mut(); + let ssa = builder.finish(); + let function = ssa.main(); let cfg = ControlFlowGraph::with_function(function); find_branch_ends(function, &cfg); } diff --git a/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg/capacity_tracker.rs b/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg/capacity_tracker.rs deleted file mode 100644 index a01be691778..00000000000 --- a/compiler/noirc_evaluator/src/ssa/opt/flatten_cfg/capacity_tracker.rs +++ /dev/null @@ -1,171 +0,0 @@ -use crate::ssa::ir::{ - dfg::DataFlowGraph, - instruction::{Instruction, Intrinsic}, - types::Type, - value::{Value, ValueId}, -}; - -use acvm::{acir::AcirField, FieldElement}; -use fxhash::FxHashMap as HashMap; - -pub(crate) struct SliceCapacityTracker<'a> { - dfg: &'a DataFlowGraph, -} - -impl<'a> SliceCapacityTracker<'a> { - pub(crate) fn new(dfg: &'a DataFlowGraph) -> Self { - SliceCapacityTracker { dfg } - } - - /// Determine how the slice sizes map needs to be updated according to the provided instruction. - pub(crate) fn collect_slice_information( - &self, - instruction: &Instruction, - slice_sizes: &mut HashMap, - results: &[ValueId], - ) { - match instruction { - Instruction::ArrayGet { array, .. } => { - if let Some((_, array_type)) = self.dfg.get_array_constant(*array) { - if array_type.contains_slice_element() { - // Initial insertion into the slice sizes map - // Any other insertions should only occur if the value is already - // a part of the map. - self.compute_slice_capacity(*array, slice_sizes); - } - } - } - Instruction::ArraySet { array, value, .. } => { - if let Some((_, array_type)) = self.dfg.get_array_constant(*array) { - if array_type.contains_slice_element() { - // Initial insertion into the slice sizes map - // Any other insertions should only occur if the value is already - // a part of the map. - self.compute_slice_capacity(*array, slice_sizes); - } - } - - let value_typ = self.dfg.type_of_value(*value); - // Compiler sanity check - assert!(!value_typ.contains_slice_element(), "ICE: Nested slices are not allowed and should not have reached the flattening pass of SSA"); - - if let Some(capacity) = slice_sizes.get(array) { - slice_sizes.insert(results[0], *capacity); - } - } - Instruction::Call { func, arguments } => { - let func = &self.dfg[*func]; - if let Value::Intrinsic(intrinsic) = func { - let (argument_index, result_index) = match intrinsic { - Intrinsic::SlicePushBack - | Intrinsic::SlicePushFront - | Intrinsic::SlicePopBack - | Intrinsic::SliceInsert - | Intrinsic::SliceRemove => (1, 1), - // `pop_front` returns the popped element, and then the respective slice. - // This means in the case of a slice with structs, the result index of the popped slice - // will change depending on the number of elements in the struct. - // For example, a slice with four elements will look as such in SSA: - // v3, v4, v5, v6, v7, v8 = call slice_pop_front(v1, v2) - // where v7 is the slice length and v8 is the popped slice itself. - Intrinsic::SlicePopFront => (1, results.len() - 1), - Intrinsic::AsSlice => (0, 1), - _ => return, - }; - let result_slice = results[result_index]; - match intrinsic { - Intrinsic::SlicePushBack - | Intrinsic::SlicePushFront - | Intrinsic::SliceInsert => { - let slice_contents = arguments[argument_index]; - - for arg in &arguments[(argument_index + 1)..] { - let element_typ = self.dfg.type_of_value(*arg); - if element_typ.contains_slice_element() { - self.compute_slice_capacity(*arg, slice_sizes); - } - } - - if let Some(contents_capacity) = slice_sizes.get(&slice_contents) { - let new_capacity = *contents_capacity + 1; - slice_sizes.insert(result_slice, new_capacity); - } - } - Intrinsic::SlicePopBack - | Intrinsic::SliceRemove - | Intrinsic::SlicePopFront => { - let slice_contents = arguments[argument_index]; - - if let Some(contents_capacity) = slice_sizes.get(&slice_contents) { - // We use a saturating sub here as calling `pop_front` or `pop_back` - // on a zero-length slice would otherwise underflow. - let new_capacity = contents_capacity.saturating_sub(1); - slice_sizes.insert(result_slice, new_capacity); - } - } - Intrinsic::ToBits(_) => { - // Compiler sanity check - assert!(matches!(self.dfg.type_of_value(result_slice), Type::Slice(_))); - slice_sizes.insert(result_slice, FieldElement::max_num_bits()); - } - Intrinsic::ToRadix(_) => { - // Compiler sanity check - assert!(matches!(self.dfg.type_of_value(result_slice), Type::Slice(_))); - slice_sizes.insert(result_slice, FieldElement::max_num_bytes()); - } - Intrinsic::AsSlice => { - let array_size = self - .dfg - .try_get_array_length(arguments[argument_index]) - .expect("ICE: Should be have an array length for AsSlice input"); - slice_sizes.insert(result_slice, array_size); - } - _ => {} - } - } - } - Instruction::Store { address, value } => { - let value_typ = self.dfg.type_of_value(*value); - if value_typ.contains_slice_element() { - self.compute_slice_capacity(*value, slice_sizes); - - let value_capacity = slice_sizes.get(value).unwrap_or_else(|| { - panic!("ICE: should have slice capacity set for value {value} being stored at {address}") - }); - - slice_sizes.insert(*address, *value_capacity); - } - } - Instruction::Load { address } => { - let load_typ = self.dfg.type_of_value(*address); - if load_typ.contains_slice_element() { - let result = results[0]; - - let address_capacity = slice_sizes.get(address).unwrap_or_else(|| { - panic!("ICE: should have slice capacity set at address {address} being loaded into {result}") - }); - - slice_sizes.insert(result, *address_capacity); - } - } - _ => {} - } - } - - /// Computes the starting capacity of a slice which is still a `Value::Array` - pub(crate) fn compute_slice_capacity( - &self, - array_id: ValueId, - slice_sizes: &mut HashMap, - ) { - if let Some((array, typ)) = self.dfg.get_array_constant(array_id) { - // Compiler sanity check - assert!(!typ.is_nested_slice(), "ICE: Nested slices are not allowed and should not have reached the flattening pass of SSA"); - if let Type::Slice(_) = typ { - let element_size = typ.element_size(); - let len = array.len() / element_size; - slice_sizes.insert(array_id, len as u32); - } - } - } -} diff --git a/compiler/noirc_evaluator/src/ssa/opt/loop_invariant.rs b/compiler/noirc_evaluator/src/ssa/opt/loop_invariant.rs index 0a3c18c1b1e..c1f2a6b88e5 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/loop_invariant.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/loop_invariant.rs @@ -304,8 +304,8 @@ mod test { } "; - let mut ssa = Ssa::from_str(src).unwrap(); - let main = ssa.main_mut(); + let ssa = Ssa::from_str(src).unwrap(); + let main = ssa.main(); let instructions = main.dfg[main.entry_block()].instructions(); assert_eq!(instructions.len(), 0); // The final return is not counted @@ -361,8 +361,8 @@ mod test { } "; - let mut ssa = Ssa::from_str(src).unwrap(); - let main = ssa.main_mut(); + let ssa = Ssa::from_str(src).unwrap(); + let main = ssa.main(); let instructions = main.dfg[main.entry_block()].instructions(); assert_eq!(instructions.len(), 0); // The final return is not counted @@ -429,8 +429,8 @@ mod test { } "; - let mut ssa = Ssa::from_str(src).unwrap(); - let main = ssa.main_mut(); + let ssa = Ssa::from_str(src).unwrap(); + let main = ssa.main(); let instructions = main.dfg[main.entry_block()].instructions(); assert_eq!(instructions.len(), 0); // The final return is not counted @@ -488,8 +488,8 @@ mod test { } "; - let mut ssa = Ssa::from_str(src).unwrap(); - let main = ssa.main_mut(); + let ssa = Ssa::from_str(src).unwrap(); + let main = ssa.main(); let instructions = main.dfg[main.entry_block()].instructions(); assert_eq!(instructions.len(), 4); // The final return is not counted diff --git a/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs b/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs index 4356a23335c..29ddfff323d 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs @@ -909,8 +909,8 @@ mod tests { } "; - let mut ssa = Ssa::from_str(src).unwrap(); - let main = ssa.main_mut(); + let ssa = Ssa::from_str(src).unwrap(); + let main = ssa.main(); let instructions = main.dfg[main.entry_block()].instructions(); assert_eq!(instructions.len(), 6); // The final return is not counted diff --git a/compiler/noirc_evaluator/src/ssa/opt/remove_if_else.rs b/compiler/noirc_evaluator/src/ssa/opt/remove_if_else.rs index 9a931e36ea2..8dde79a3c60 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/remove_if_else.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/remove_if_else.rs @@ -52,10 +52,6 @@ impl Function { struct Context { slice_sizes: HashMap, - // Maps array_set result -> element that was overwritten by that instruction. - // Used to undo array_sets while merging values - prev_array_set_elem_values: HashMap, - // Maps array_set result -> enable_side_effects_if value which was active during it. array_set_conditionals: HashMap, } diff --git a/compiler/noirc_evaluator/src/ssa/parser/lexer.rs b/compiler/noirc_evaluator/src/ssa/parser/lexer.rs index 5b66810c641..e22b6a661de 100644 --- a/compiler/noirc_evaluator/src/ssa/parser/lexer.rs +++ b/compiler/noirc_evaluator/src/ssa/parser/lexer.rs @@ -275,10 +275,6 @@ impl<'a> Lexer<'a> { self.chars.clone().next().map(|(_, ch)| ch) } - fn is_code_whitespace(c: char) -> bool { - c.is_ascii_whitespace() - } - pub(crate) fn newline_follows(&self) -> bool { let chars = self.chars.clone(); chars.take_while(|(_, char)| char.is_ascii_whitespace()).any(|(_, char)| char == '\n') diff --git a/compiler/noirc_evaluator/src/ssa/parser/mod.rs b/compiler/noirc_evaluator/src/ssa/parser/mod.rs index 24a5ff43071..b400c28875a 100644 --- a/compiler/noirc_evaluator/src/ssa/parser/mod.rs +++ b/compiler/noirc_evaluator/src/ssa/parser/mod.rs @@ -859,10 +859,6 @@ impl<'a> Parser<'a> { self.token.token() == &token } - fn at_keyword(&self, keyword: Keyword) -> bool { - self.at(Token::Keyword(keyword)) - } - fn newline_follows(&self) -> bool { self.lexer.newline_follows() } diff --git a/compiler/noirc_evaluator/src/ssa/ssa_gen/program.rs b/compiler/noirc_evaluator/src/ssa/ssa_gen/program.rs index de01a4596ad..12892efa598 100644 --- a/compiler/noirc_evaluator/src/ssa/ssa_gen/program.rs +++ b/compiler/noirc_evaluator/src/ssa/ssa_gen/program.rs @@ -62,6 +62,7 @@ impl Ssa { } /// Returns the entry-point function of the program as a mutable reference + #[cfg(test)] pub(crate) fn main_mut(&mut self) -> &mut Function { self.functions.get_mut(&self.main_id).expect("ICE: Ssa should have a main function") } diff --git a/compiler/noirc_evaluator/src/ssa/ssa_gen/value.rs b/compiler/noirc_evaluator/src/ssa/ssa_gen/value.rs index d71d4e5604e..5d148dd181c 100644 --- a/compiler/noirc_evaluator/src/ssa/ssa_gen/value.rs +++ b/compiler/noirc_evaluator/src/ssa/ssa_gen/value.rs @@ -96,18 +96,6 @@ impl Tree { } } - /// Map mutably over this tree, mutating each leaf value within using the given function - pub(super) fn map_mut(&mut self, mut f: impl FnMut(&T) -> Tree) { - self.map_mut_helper(&mut f); - } - - fn map_mut_helper(&mut self, f: &mut impl FnMut(&T) -> Tree) { - match self { - Tree::Branch(trees) => trees.iter_mut().for_each(|tree| tree.map_mut_helper(f)), - Tree::Leaf(value) => *self = f(value), - } - } - /// Calls the given function on each leaf node, mapping this tree into a new one. /// /// Because the given function returns a Tree rather than a U, it is possible