diff --git a/Cargo.lock b/Cargo.lock index 89287609a2b..e82d47d690a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -644,6 +644,12 @@ version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +[[package]] +name = "binary-merge" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "597bb81c80a54b6a4381b23faba8d7774b144c94cbd1d6fe3f1329bd776554ab" + [[package]] name = "bincode" version = "1.3.3" @@ -2519,6 +2525,15 @@ dependencies = [ "libc", ] +[[package]] +name = "inplace-vec-builder" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf64c2edc8226891a71f127587a2861b132d2b942310843814d5001d99a1d307" +dependencies = [ + "smallvec", +] + [[package]] name = "is-terminal" version = "0.4.13" @@ -3366,6 +3381,7 @@ dependencies = [ "thiserror", "tracing", "tracing-test", + "vec-collections", ] [[package]] @@ -4807,6 +4823,12 @@ dependencies = [ "sha1", ] +[[package]] +name = "sorted-iter" +version = "0.1.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bceb57dc07c92cdae60f5b27b3fa92ecaaa42fe36c55e22dbfb0b44893e0b1f7" + [[package]] name = "spin" version = "0.9.8" @@ -5497,6 +5519,21 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" +[[package]] +name = "vec-collections" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c9965c8f2ffed1dbcd16cafe18a009642f540fa22661c6cfd6309ddb02e4982" +dependencies = [ + "binary-merge", + "inplace-vec-builder", + "lazy_static", + "num-traits", + "serde", + "smallvec", + "sorted-iter", +] + [[package]] name = "version_check" version = "0.9.5" diff --git a/compiler/noirc_evaluator/Cargo.toml b/compiler/noirc_evaluator/Cargo.toml index 15531fafff7..3e30fa6673d 100644 --- a/compiler/noirc_evaluator/Cargo.toml +++ b/compiler/noirc_evaluator/Cargo.toml @@ -29,6 +29,7 @@ chrono = "0.4.37" rayon.workspace = true cfg-if.workspace = true smallvec = { version = "1.13.2", features = ["serde"] } +vec-collections = "0.4.3" [dev-dependencies] proptest.workspace = true diff --git a/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs b/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs index 96a24583837..ce76825877a 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs @@ -79,6 +79,7 @@ mod block; use std::collections::{BTreeMap, BTreeSet}; use fxhash::{FxHashMap as HashMap, FxHashSet as HashSet}; +use vec_collections::VecSet; use crate::ssa::{ ir::{ @@ -619,7 +620,7 @@ impl<'f> PerFunctionContext<'f> { // then those parameters also alias each other. // We save parameters with repeat arguments to later mark those // parameters as aliasing one another. - let mut arg_set: HashMap> = HashMap::default(); + let mut arg_set = HashMap::default(); // Add an alias for each reference parameter for (parameter, argument) in destination_parameters.iter().zip(arguments) { @@ -632,7 +633,8 @@ impl<'f> PerFunctionContext<'f> { aliases.insert(*parameter); // Check if we have seen the same argument - let seen_parameters = arg_set.entry(argument).or_default(); + let seen_parameters = + arg_set.entry(argument).or_insert_with(VecSet::empty); // Add the current parameter to the parameters we have seen for this argument. // The previous parameters and the current one alias one another. seen_parameters.insert(*parameter); diff --git a/compiler/noirc_evaluator/src/ssa/opt/mem2reg/alias_set.rs b/compiler/noirc_evaluator/src/ssa/opt/mem2reg/alias_set.rs index e32eaa70186..ab85fbe3a96 100644 --- a/compiler/noirc_evaluator/src/ssa/opt/mem2reg/alias_set.rs +++ b/compiler/noirc_evaluator/src/ssa/opt/mem2reg/alias_set.rs @@ -1,4 +1,4 @@ -use std::collections::BTreeSet; +use vec_collections::VecSet; use crate::ssa::ir::value::ValueId; @@ -10,7 +10,7 @@ use crate::ssa::ir::value::ValueId; /// "unknown which aliases this may refer to" - `None`. #[derive(Debug, Default, Clone)] pub(super) struct AliasSet { - aliases: Option>, + aliases: Option>, } impl AliasSet { @@ -19,12 +19,10 @@ impl AliasSet { } pub(super) fn known(value: ValueId) -> AliasSet { - let mut aliases = BTreeSet::new(); - aliases.insert(value); - Self { aliases: Some(aliases) } + Self { aliases: Some(VecSet::single(value)) } } - pub(super) fn known_multiple(values: BTreeSet) -> AliasSet { + pub(super) fn known_multiple(values: VecSet<[ValueId; 1]>) -> AliasSet { Self { aliases: Some(values) } } @@ -32,7 +30,7 @@ impl AliasSet { /// particular value will be known to be zero, which is distinct from being unknown and /// possibly referring to any alias. pub(super) fn known_empty() -> AliasSet { - Self { aliases: Some(BTreeSet::new()) } + Self { aliases: Some(VecSet::empty()) } } pub(super) fn is_unknown(&self) -> bool { @@ -44,14 +42,14 @@ impl AliasSet { pub(super) fn single_alias(&self) -> Option { self.aliases .as_ref() - .and_then(|aliases| (aliases.len() == 1).then(|| *aliases.first().unwrap())) + .and_then(|aliases| (aliases.len() == 1).then(|| *aliases.iter().next().unwrap())) } /// Unify this alias set with another. The result of this set is empty if either set is empty. /// Otherwise, it is the union of both alias sets. pub(super) fn unify(&mut self, other: &Self) { if let (Some(self_aliases), Some(other_aliases)) = (&mut self.aliases, &other.aliases) { - self_aliases.extend(other_aliases); + self_aliases.extend(other_aliases.iter().cloned()); } else { self.aliases = None; } @@ -82,6 +80,6 @@ impl AliasSet { /// The ordering is arbitrary (by lowest ValueId) so this method should only be /// used when you need an arbitrary ValueId from the alias set. pub(super) fn first(&self) -> Option { - self.aliases.as_ref().and_then(|aliases| aliases.first().copied()) + self.aliases.as_ref().and_then(|aliases| aliases.iter().next().copied()) } }