From aac6fc72679522d50cc2f27e05e006ef227586ed Mon Sep 17 00:00:00 2001 From: Jim Blandy Date: Sat, 22 Jun 2024 22:33:02 -0700 Subject: [PATCH] [naga] Move `HandleSet` from `compact` into `arena`. --- naga/src/arena/handle_set.rs | 64 ++++++++++++++++++++++++++++++ naga/src/arena/mod.rs | 2 + naga/src/arena/range.rs | 8 ++++ naga/src/compact/functions.rs | 2 +- naga/src/compact/handle_set_map.rs | 64 +++--------------------------- naga/src/compact/mod.rs | 3 +- 6 files changed, 82 insertions(+), 61 deletions(-) create mode 100644 naga/src/arena/handle_set.rs diff --git a/naga/src/arena/handle_set.rs b/naga/src/arena/handle_set.rs new file mode 100644 index 0000000000..ed8313bbfc --- /dev/null +++ b/naga/src/arena/handle_set.rs @@ -0,0 +1,64 @@ +//! The [`HandleSet`] type and associated definitions. + +use crate::arena::{Arena, Handle, UniqueArena}; + +/// A set of `Handle` values. +pub struct HandleSet { + /// Bound on indexes of handles stored in this set. + len: usize, + + /// `members[i]` is true if the handle with index `i` is a member. + members: bit_set::BitSet, + + /// This type is indexed by values of type `T`. + as_keys: std::marker::PhantomData, +} + +impl HandleSet { + pub fn for_arena(arena: &impl ArenaType) -> Self { + let len = arena.len(); + Self { + len, + members: bit_set::BitSet::with_capacity(len), + as_keys: std::marker::PhantomData, + } + } + + /// Return an iterator over all handles that could be made members + /// of this set. + pub fn all_possible(&self) -> impl Iterator> { + super::Range::full_range_from_size(self.len) + } + + /// Add `handle` to the set. + pub fn insert(&mut self, handle: Handle) { + self.members.insert(handle.index()); + } + + /// Add handles from `iter` to the set. + pub fn insert_iter(&mut self, iter: impl IntoIterator>) { + for handle in iter { + self.insert(handle); + } + } + + pub fn contains(&self, handle: Handle) -> bool { + self.members.contains(handle.index()) + } +} + +pub trait ArenaType { + fn len(&self) -> usize; +} + +impl ArenaType for Arena { + fn len(&self) -> usize { + self.len() + } +} + +impl ArenaType for UniqueArena { + fn len(&self) -> usize { + self.len() + } +} diff --git a/naga/src/arena/mod.rs b/naga/src/arena/mod.rs index a1b64d793a..0747eaef72 100644 --- a/naga/src/arena/mod.rs +++ b/naga/src/arena/mod.rs @@ -21,11 +21,13 @@ source code span with each element. */ mod handle; +mod handle_set; mod handlevec; mod range; mod unique_arena; pub use handle::{BadHandle, Handle}; +pub(crate) use handle_set::HandleSet; pub(crate) use handlevec::HandleVec; pub use range::{BadRangeError, Range}; pub use unique_arena::UniqueArena; diff --git a/naga/src/arena/range.rs b/naga/src/arena/range.rs index 74e042abe2..b448f83c8c 100644 --- a/naga/src/arena/range.rs +++ b/naga/src/arena/range.rs @@ -94,6 +94,14 @@ impl Range { } } + /// Return a range covering all handles with indices from `0` to `size`. + pub(super) fn full_range_from_size(size: usize) -> Self { + Self { + inner: 0..size as u32, + marker: Default::default(), + } + } + /// return the first and last handles included in `self`. /// /// If `self` is an empty range, there are no handles included, so diff --git a/naga/src/compact/functions.rs b/naga/src/compact/functions.rs index 4ac2223eb7..372d472da3 100644 --- a/naga/src/compact/functions.rs +++ b/naga/src/compact/functions.rs @@ -1,4 +1,4 @@ -use super::handle_set_map::HandleSet; +use super::arena::HandleSet; use super::{FunctionMap, ModuleMap}; pub struct FunctionTracer<'a> { diff --git a/naga/src/compact/handle_set_map.rs b/naga/src/compact/handle_set_map.rs index 57a2749f87..29ae89e909 100644 --- a/naga/src/compact/handle_set_map.rs +++ b/naga/src/compact/handle_set_map.rs @@ -1,62 +1,7 @@ -use crate::arena::{Arena, Handle, Range, UniqueArena}; +use crate::arena::{Arena, Handle, HandleSet, Range}; type Index = crate::non_max_u32::NonMaxU32; -/// A set of `Handle` values. -pub struct HandleSet { - /// Bound on indexes of handles stored in this set. - len: usize, - - /// `members[i]` is true if the handle with index `i` is a member. - members: bit_set::BitSet, - - /// This type is indexed by values of type `T`. - as_keys: std::marker::PhantomData, -} - -impl HandleSet { - pub fn for_arena(arena: &impl ArenaType) -> Self { - let len = arena.len(); - Self { - len, - members: bit_set::BitSet::with_capacity(len), - as_keys: std::marker::PhantomData, - } - } - - /// Add `handle` to the set. - pub fn insert(&mut self, handle: Handle) { - self.members.insert(handle.index()); - } - - /// Add handles from `iter` to the set. - pub fn insert_iter(&mut self, iter: impl IntoIterator>) { - for handle in iter { - self.insert(handle); - } - } - - pub fn contains(&self, handle: Handle) -> bool { - self.members.contains(handle.index()) - } -} - -pub trait ArenaType { - fn len(&self) -> usize; -} - -impl ArenaType for Arena { - fn len(&self) -> usize { - self.len() - } -} - -impl ArenaType for UniqueArena { - fn len(&self) -> usize { - self.len() - } -} - /// A map from old handle indices to new, compressed handle indices. pub struct HandleMap { /// The indices assigned to handles in the compacted module. @@ -74,9 +19,10 @@ impl HandleMap { pub fn from_set(set: HandleSet) -> Self { let mut next_index = Index::new(0).unwrap(); Self { - new_index: (0..set.len) - .map(|index| { - if set.members.contains(index) { + new_index: set + .all_possible() + .map(|handle| { + if set.contains(handle) { // This handle will be retained in the compacted version, // so assign it a new index. let this = next_index; diff --git a/naga/src/compact/mod.rs b/naga/src/compact/mod.rs index 0d7a37b579..c40a1880e1 100644 --- a/naga/src/compact/mod.rs +++ b/naga/src/compact/mod.rs @@ -4,8 +4,9 @@ mod handle_set_map; mod statements; mod types; +use crate::arena::HandleSet; use crate::{arena, compact::functions::FunctionTracer}; -use handle_set_map::{HandleMap, HandleSet}; +use handle_set_map::HandleMap; /// Remove unused types, expressions, and constants from `module`. ///