From 6ee1a7aaa02f7e7713c8b60d785610983dc69ee7 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 5 Dec 2024 11:15:59 +1100 Subject: 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. --- compiler/rustc_mir_dataflow/src/framework/fmt.rs | 22 +++++++++++++++++++++- .../rustc_mir_dataflow/src/framework/lattice.rs | 8 +++++++- compiler/rustc_mir_dataflow/src/framework/mod.rs | 18 +++++++++++++++++- 3 files changed, 45 insertions(+), 3 deletions(-) (limited to 'compiler/rustc_mir_dataflow/src/framework') diff --git a/compiler/rustc_mir_dataflow/src/framework/fmt.rs b/compiler/rustc_mir_dataflow/src/framework/fmt.rs index dc176ba2d03..186172b3b86 100644 --- a/compiler/rustc_mir_dataflow/src/framework/fmt.rs +++ b/compiler/rustc_mir_dataflow/src/framework/fmt.rs @@ -4,7 +4,7 @@ use std::fmt; use rustc_index::Idx; -use rustc_index::bit_set::{BitSet, ChunkedBitSet}; +use rustc_index::bit_set::{BitSet, ChunkedBitSet, MixedBitSet}; use super::lattice::MaybeReachable; @@ -127,6 +127,26 @@ where } } +impl DebugWithContext for MixedBitSet +where + T: Idx + DebugWithContext, +{ + fn fmt_with(&self, ctxt: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match self { + MixedBitSet::Small(set) => set.fmt_with(ctxt, f), + MixedBitSet::Large(set) => set.fmt_with(ctxt, f), + } + } + + fn fmt_diff_with(&self, old: &Self, ctxt: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result { + match (self, old) { + (MixedBitSet::Small(set), MixedBitSet::Small(old)) => set.fmt_diff_with(old, ctxt, f), + (MixedBitSet::Large(set), MixedBitSet::Large(old)) => set.fmt_diff_with(old, ctxt, f), + _ => panic!("MixedBitSet size mismatch"), + } + } +} + impl DebugWithContext for MaybeReachable where S: DebugWithContext, diff --git a/compiler/rustc_mir_dataflow/src/framework/lattice.rs b/compiler/rustc_mir_dataflow/src/framework/lattice.rs index e2b56aedca3..852099e2ac8 100644 --- a/compiler/rustc_mir_dataflow/src/framework/lattice.rs +++ b/compiler/rustc_mir_dataflow/src/framework/lattice.rs @@ -40,7 +40,7 @@ use std::iter; -use rustc_index::bit_set::{BitSet, ChunkedBitSet}; +use rustc_index::bit_set::{BitSet, ChunkedBitSet, MixedBitSet}; use rustc_index::{Idx, IndexVec}; use crate::framework::BitSetExt; @@ -132,6 +132,12 @@ impl JoinSemiLattice for ChunkedBitSet { } } +impl JoinSemiLattice for MixedBitSet { + fn join(&mut self, other: &Self) -> bool { + self.union(other) + } +} + /// Extends a type `T` with top and bottom elements to make it a partially ordered set in which no /// value of `T` is comparable with any other. /// diff --git a/compiler/rustc_mir_dataflow/src/framework/mod.rs b/compiler/rustc_mir_dataflow/src/framework/mod.rs index b9407882ec5..40fb22014e5 100644 --- a/compiler/rustc_mir_dataflow/src/framework/mod.rs +++ b/compiler/rustc_mir_dataflow/src/framework/mod.rs @@ -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 BitSetExt for ChunkedBitSet { } } +impl BitSetExt for MixedBitSet { + 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 GenKill for ChunkedBitSet { } } +impl GenKill for MixedBitSet { + fn gen_(&mut self, elem: T) { + self.insert(elem); + } + + fn kill(&mut self, elem: T) { + self.remove(elem); + } +} + impl> GenKill for MaybeReachable { fn gen_(&mut self, elem: T) { match self { -- cgit 1.4.1-3-g733a5