Skip to content

Commit 0e42435

Browse files
committed
Auto merge of #116152 - cjgillot:unchunck, r=nnethercote
Only use dense bitsets in dataflow analyses When a dataflow state has the size close to the number of locals, we should prefer a dense bitset, like we already store locals in a dense vector. Other occurrences of `ChunkedBitSet` need to be justified by the size of the dataflow state.
2 parents 8b94152 + e07ffe9 commit 0e42435

File tree

7 files changed

+24
-17
lines changed

7 files changed

+24
-17
lines changed

compiler/rustc_borrowck/src/type_check/liveness/trace.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
22
use rustc_data_structures::graph::WithSuccessors;
3-
use rustc_index::bit_set::HybridBitSet;
3+
use rustc_index::bit_set::BitSet;
44
use rustc_index::interval::IntervalSet;
55
use rustc_infer::infer::canonical::QueryRegionConstraints;
66
use rustc_infer::infer::outlives::for_liveness;
@@ -135,7 +135,7 @@ struct LivenessResults<'me, 'typeck, 'flow, 'tcx> {
135135
cx: LivenessContext<'me, 'typeck, 'flow, 'tcx>,
136136

137137
/// Set of points that define the current local.
138-
defs: HybridBitSet<PointIndex>,
138+
defs: BitSet<PointIndex>,
139139

140140
/// Points where the current variable is "use live" -- meaning
141141
/// that there is a future "full use" that may use its value.
@@ -158,7 +158,7 @@ impl<'me, 'typeck, 'flow, 'tcx> LivenessResults<'me, 'typeck, 'flow, 'tcx> {
158158
let num_points = cx.elements.num_points();
159159
LivenessResults {
160160
cx,
161-
defs: HybridBitSet::new_empty(num_points),
161+
defs: BitSet::new_empty(num_points),
162162
use_live_at: IntervalSet::new(num_points),
163163
drop_live_at: IntervalSet::new(num_points),
164164
drop_locations: vec![],

compiler/rustc_index/src/bit_set.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ impl<T: Idx> BitSet<T> {
284284
not_already
285285
}
286286

287-
fn last_set_in(&self, range: impl RangeBounds<T>) -> Option<T> {
287+
pub fn last_set_in(&self, range: impl RangeBounds<T>) -> Option<T> {
288288
let (start, end) = inclusive_start_end(range, self.domain_size)?;
289289
let (start_word_index, _) = word_index_and_mask(start);
290290
let (end_word_index, end_mask) = word_index_and_mask(end);
@@ -1299,7 +1299,7 @@ impl<T: Idx> SparseBitSet<T> {
12991299
}
13001300

13011301
impl<T: Idx + Ord> SparseBitSet<T> {
1302-
fn last_set_in(&self, range: impl RangeBounds<T>) -> Option<T> {
1302+
pub fn last_set_in(&self, range: impl RangeBounds<T>) -> Option<T> {
13031303
let mut last_leq = None;
13041304
for e in self.iter() {
13051305
if range.contains(e) {

compiler/rustc_mir_dataflow/src/impls/initialized.rs

+7
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,10 @@ impl<'a, 'tcx> DefinitelyInitializedPlaces<'a, 'tcx> {
305305
}
306306

307307
impl<'tcx> AnalysisDomain<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
308+
/// There can be many more `MovePathIndex` than there are locals in a MIR body.
309+
/// We use a chunked bitset to avoid paying too high a memory footprint.
308310
type Domain = MaybeReachable<ChunkedBitSet<MovePathIndex>>;
311+
309312
const NAME: &'static str = "maybe_init";
310313

311314
fn bottom_value(&self, _: &mir::Body<'tcx>) -> Self::Domain {
@@ -437,6 +440,8 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
437440
}
438441

439442
impl<'tcx> AnalysisDomain<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
443+
/// There can be many more `MovePathIndex` than there are locals in a MIR body.
444+
/// We use a chunked bitset to avoid paying too high a memory footprint.
440445
type Domain = ChunkedBitSet<MovePathIndex>;
441446

442447
const NAME: &'static str = "maybe_uninit";
@@ -636,6 +641,8 @@ impl<'tcx> GenKillAnalysis<'tcx> for DefinitelyInitializedPlaces<'_, 'tcx> {
636641
}
637642

638643
impl<'tcx> AnalysisDomain<'tcx> for EverInitializedPlaces<'_, 'tcx> {
644+
/// There can be many more `InitIndex` than there are locals in a MIR body.
645+
/// We use a chunked bitset to avoid paying too high a memory footprint.
639646
type Domain = ChunkedBitSet<InitIndex>;
640647

641648
const NAME: &'static str = "ever_init";

compiler/rustc_mir_dataflow/src/impls/liveness.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use rustc_index::bit_set::{BitSet, ChunkedBitSet};
1+
use rustc_index::bit_set::BitSet;
22
use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
33
use rustc_middle::mir::{
44
self, CallReturnPlaces, Local, Location, Place, StatementKind, TerminatorEdges,
@@ -26,14 +26,14 @@ use crate::{Analysis, AnalysisDomain, Backward, GenKill, GenKillAnalysis};
2626
pub struct MaybeLiveLocals;
2727

2828
impl<'tcx> AnalysisDomain<'tcx> for MaybeLiveLocals {
29-
type Domain = ChunkedBitSet<Local>;
29+
type Domain = BitSet<Local>;
3030
type Direction = Backward;
3131

3232
const NAME: &'static str = "liveness";
3333

3434
fn bottom_value(&self, body: &mir::Body<'tcx>) -> Self::Domain {
3535
// bottom = not live
36-
ChunkedBitSet::new_empty(body.local_decls.len())
36+
BitSet::new_empty(body.local_decls.len())
3737
}
3838

3939
fn initialize_start_block(&self, _: &mir::Body<'tcx>, _: &mut Self::Domain) {
@@ -233,14 +233,14 @@ impl<'a> MaybeTransitiveLiveLocals<'a> {
233233
}
234234

235235
impl<'a, 'tcx> AnalysisDomain<'tcx> for MaybeTransitiveLiveLocals<'a> {
236-
type Domain = ChunkedBitSet<Local>;
236+
type Domain = BitSet<Local>;
237237
type Direction = Backward;
238238

239239
const NAME: &'static str = "transitive liveness";
240240

241241
fn bottom_value(&self, body: &mir::Body<'tcx>) -> Self::Domain {
242242
// bottom = not live
243-
ChunkedBitSet::new_empty(body.local_decls.len())
243+
BitSet::new_empty(body.local_decls.len())
244244
}
245245

246246
fn initialize_start_block(&self, _: &mir::Body<'tcx>, _: &mut Self::Domain) {

compiler/rustc_mir_dataflow/src/points.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::framework::{visit_results, ResultsVisitable, ResultsVisitor};
2-
use rustc_index::bit_set::ChunkedBitSet;
2+
use rustc_index::bit_set::BitSet;
33
use rustc_index::interval::SparseIntervalMatrix;
44
use rustc_index::Idx;
55
use rustc_index::IndexVec;
@@ -102,7 +102,7 @@ pub fn save_as_intervals<'tcx, N, R>(
102102
) -> SparseIntervalMatrix<N, PointIndex>
103103
where
104104
N: Idx,
105-
R: ResultsVisitable<'tcx, FlowState = ChunkedBitSet<N>>,
105+
R: ResultsVisitable<'tcx, FlowState = BitSet<N>>,
106106
{
107107
let values = SparseIntervalMatrix::new(elements.num_points());
108108
let mut visitor = Visitor { elements, values };
@@ -124,7 +124,7 @@ impl<'mir, 'tcx, R, N> ResultsVisitor<'mir, 'tcx, R> for Visitor<'_, N>
124124
where
125125
N: Idx,
126126
{
127-
type FlowState = ChunkedBitSet<N>;
127+
type FlowState = BitSet<N>;
128128

129129
fn visit_statement_after_primary_effect(
130130
&mut self,

compiler/rustc_mir_dataflow/src/rustc_peek.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use crate::MoveDataParamEnv;
1212
use crate::{Analysis, JoinSemiLattice, ResultsCursor};
1313
use rustc_ast::MetaItem;
1414
use rustc_hir::def_id::DefId;
15-
use rustc_index::bit_set::ChunkedBitSet;
15+
use rustc_index::bit_set::BitSet;
1616
use rustc_middle::mir::MirPass;
1717
use rustc_middle::mir::{self, Body, Local, Location};
1818
use rustc_middle::ty::{self, Ty, TyCtxt};
@@ -275,7 +275,7 @@ impl<'tcx> RustcPeekAt<'tcx> for MaybeLiveLocals {
275275
&self,
276276
tcx: TyCtxt<'tcx>,
277277
place: mir::Place<'tcx>,
278-
flow_state: &ChunkedBitSet<Local>,
278+
flow_state: &BitSet<Local>,
279279
call: PeekCall,
280280
) {
281281
info!(?place, "peek_at");

compiler/rustc_mir_transform/src/nrvo.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! See the docs for [`RenameReturnPlace`].
22
33
use rustc_hir::Mutability;
4-
use rustc_index::bit_set::HybridBitSet;
4+
use rustc_index::bit_set::BitSet;
55
use rustc_middle::mir::visit::{MutVisitor, NonUseContext, PlaceContext, Visitor};
66
use rustc_middle::mir::{self, BasicBlock, Local, Location};
77
use rustc_middle::ty::TyCtxt;
@@ -123,7 +123,7 @@ fn find_local_assigned_to_return_place(
123123
body: &mut mir::Body<'_>,
124124
) -> Option<Local> {
125125
let mut block = start;
126-
let mut seen = HybridBitSet::new_empty(body.basic_blocks.len());
126+
let mut seen = BitSet::new_empty(body.basic_blocks.len());
127127

128128
// Iterate as long as `block` has exactly one predecessor that we have not yet visited.
129129
while seen.insert(block) {

0 commit comments

Comments
 (0)