Introduce MixedBitSet.

It just uses `BitSet` for small/medium sizes (<= 2048 bits) and
`ChunkedBitSet` for larger sizes. This is good because `ChunkedBitSet`
is slow and memory-hungry at smaller sizes.
This commit is contained in:
Nicholas Nethercote
2024-12-05 11:15:59 +11:00
parent dff5ce6881
commit 6ee1a7aaa0
4 changed files with 200 additions and 3 deletions

View File

@@ -35,7 +35,7 @@
use std::cmp::Ordering;
use rustc_data_structures::work_queue::WorkQueue;
use rustc_index::bit_set::{BitSet, ChunkedBitSet};
use rustc_index::bit_set::{BitSet, ChunkedBitSet, MixedBitSet};
use rustc_index::{Idx, IndexVec};
use rustc_middle::bug;
use rustc_middle::mir::{self, BasicBlock, CallReturnPlaces, Location, TerminatorEdges, traversal};
@@ -77,6 +77,12 @@ impl<T: Idx> BitSetExt<T> for ChunkedBitSet<T> {
}
}
impl<T: Idx> BitSetExt<T> for MixedBitSet<T> {
fn contains(&self, elem: T) -> bool {
self.contains(elem)
}
}
/// A dataflow problem with an arbitrarily complex transfer function.
///
/// This trait specifies the lattice on which this analysis operates (the domain), its
@@ -337,6 +343,16 @@ impl<T: Idx> GenKill<T> for ChunkedBitSet<T> {
}
}
impl<T: Idx> GenKill<T> for MixedBitSet<T> {
fn gen_(&mut self, elem: T) {
self.insert(elem);
}
fn kill(&mut self, elem: T) {
self.remove(elem);
}
}
impl<T, S: GenKill<T>> GenKill<T> for MaybeReachable<S> {
fn gen_(&mut self, elem: T) {
match self {