Skip to content

Commit 9d71a6f

Browse files
committed
reuse allocation used by always_storage_live_locals bitset
1 parent 9b8dbd5 commit 9d71a6f

File tree

5 files changed

+43
-17
lines changed

5 files changed

+43
-17
lines changed

compiler/rustc_const_eval/src/interpret/eval_context.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use std::mem;
55
use either::{Either, Left, Right};
66

77
use rustc_hir::{self as hir, def_id::DefId, definitions::DefPathData};
8+
use rustc_index::bit_set::GrowableBitSet;
89
use rustc_index::vec::IndexVec;
910
use rustc_middle::mir;
1011
use rustc_middle::mir::interpret::{ErrorHandled, InterpError, InvalidProgramInfo};
@@ -46,6 +47,9 @@ pub struct InterpCx<'mir, 'tcx, M: Machine<'mir, 'tcx>> {
4647

4748
/// The recursion limit (cached from `tcx.recursion_limit(())`)
4849
pub recursion_limit: Limit,
50+
51+
// reuse allocation for bit set
52+
always_live_locals_cache: GrowableBitSet<mir::Local>,
4953
}
5054

5155
// The Phantomdata exists to prevent this type from being `Send`. If it were sent across a thread
@@ -408,6 +412,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
408412
param_env,
409413
memory: Memory::new(),
410414
recursion_limit: tcx.recursion_limit(),
415+
always_live_locals_cache: Default::default(),
411416
}
412417
}
413418

@@ -705,13 +710,19 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
705710
let mut locals = IndexVec::from_elem(dummy, &body.local_decls);
706711

707712
// Now mark those locals as live that have no `Storage*` annotations.
708-
let always_live = always_storage_live_locals(self.body());
713+
// and take cached allocation for bitset ...
714+
let mut always_live = mem::take(&mut self.always_live_locals_cache);
715+
always_storage_live_locals(self.body(), &mut always_live);
716+
709717
for local in locals.indices() {
710718
if always_live.contains(local) {
711719
locals[local].value = LocalValue::Live(Operand::Immediate(Immediate::Uninit));
712720
}
713721
}
714722
// done
723+
// ... and place it back
724+
self.always_live_locals_cache = always_live;
725+
715726
self.frame_mut().locals = locals;
716727
M::after_stack_push(self)?;
717728
self.frame_mut().loc = Left(mir::Location::START);

compiler/rustc_const_eval/src/transform/validate.rs

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
//! Validates the MIR to ensure that invariants are upheld.
22
33
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
4-
use rustc_index::bit_set::BitSet;
4+
use rustc_index::bit_set::{BitSet, GrowableBitSet};
55
use rustc_index::vec::IndexVec;
66
use rustc_infer::traits::Reveal;
77
use rustc_middle::mir::interpret::Scalar;
@@ -52,11 +52,13 @@ impl<'tcx> MirPass<'tcx> for Validator {
5252
Reveal::All => tcx.param_env_reveal_all_normalized(def_id),
5353
};
5454

55-
let always_live_locals = always_storage_live_locals(body);
56-
let storage_liveness = MaybeStorageLive::new(std::borrow::Cow::Owned(always_live_locals))
57-
.into_engine(tcx, body)
58-
.iterate_to_fixpoint()
59-
.into_results_cursor(body);
55+
let mut always_live_locals = GrowableBitSet::new_empty();
56+
always_storage_live_locals(body, &mut always_live_locals);
57+
let storage_liveness =
58+
MaybeStorageLive::new(std::borrow::Cow::Owned(always_live_locals.into()))
59+
.into_engine(tcx, body)
60+
.iterate_to_fixpoint()
61+
.into_results_cursor(body);
6062

6163
let mut checker = TypeChecker {
6264
when: &self.when,

compiler/rustc_index/src/bit_set.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1552,6 +1552,17 @@ impl<T: Idx> GrowableBitSet<T> {
15521552
pub fn len(&self) -> usize {
15531553
self.bit_set.count()
15541554
}
1555+
1556+
// reuse allocation, set domain_size and fill
1557+
pub fn fill(&mut self, domain_size: usize) {
1558+
self.ensure(domain_size);
1559+
self.bit_set.domain_size = domain_size;
1560+
self.bit_set.insert_all();
1561+
}
1562+
1563+
pub fn as_bitset(&self) -> &BitSet<T> {
1564+
&self.bit_set
1565+
}
15551566
}
15561567

15571568
impl<T: Idx> From<BitSet<T>> for GrowableBitSet<T> {
Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
use rustc_index::bit_set::BitSet;
1+
use rustc_index::bit_set::GrowableBitSet;
22
use rustc_middle::mir::{self, Local};
33

44
/// The set of locals in a MIR body that do not have `StorageLive`/`StorageDead` annotations.
55
///
66
/// These locals have fixed storage for the duration of the body.
7-
pub fn always_storage_live_locals(body: &mir::Body<'_>) -> BitSet<Local> {
8-
let mut always_live_locals = BitSet::new_filled(body.local_decls.len());
7+
pub fn always_storage_live_locals(body: &mir::Body<'_>, locals: &mut GrowableBitSet<Local>) {
8+
locals.fill(body.local_decls.len());
9+
let always_live_locals = locals;
910

1011
for block in &*body.basic_blocks {
1112
for statement in &block.statements {
@@ -15,6 +16,4 @@ pub fn always_storage_live_locals(body: &mir::Body<'_>) -> BitSet<Local> {
1516
}
1617
}
1718
}
18-
19-
always_live_locals
2019
}

compiler/rustc_mir_transform/src/generator.rs

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1401,9 +1401,11 @@ pub(crate) fn mir_generator_witnesses<'tcx>(
14011401
};
14021402

14031403
// When first entering the generator, move the resume argument into its new local.
1404-
let always_live_locals = always_storage_live_locals(&body);
1404+
let mut always_live_locals = GrowableBitSet::new_empty();
1405+
always_storage_live_locals(&body, &mut always_live_locals);
14051406

1406-
let liveness_info = locals_live_across_suspend_points(tcx, body, &always_live_locals, movable);
1407+
let liveness_info =
1408+
locals_live_across_suspend_points(tcx, body, always_live_locals.as_bitset(), movable);
14071409

14081410
// Extract locals which are live across suspension point into `layout`
14091411
// `remap` gives a mapping from local indices onto generator struct indices
@@ -1493,10 +1495,11 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
14931495
},
14941496
);
14951497

1496-
let always_live_locals = always_storage_live_locals(&body);
1498+
let mut always_live_locals = GrowableBitSet::new_empty();
1499+
always_storage_live_locals(&body, &mut always_live_locals);
14971500

14981501
let liveness_info =
1499-
locals_live_across_suspend_points(tcx, body, &always_live_locals, movable);
1502+
locals_live_across_suspend_points(tcx, body, always_live_locals.as_bitset(), movable);
15001503

15011504
if tcx.sess.opts.unstable_opts.validate_mir {
15021505
let mut vis = EnsureGeneratorFieldAssignmentsNeverAlias {
@@ -1533,7 +1536,7 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
15331536
state_substs,
15341537
remap,
15351538
storage_liveness,
1536-
always_live_locals,
1539+
always_live_locals: always_live_locals.into(),
15371540
suspension_points: Vec::new(),
15381541
new_ret_local,
15391542
discr_ty,

0 commit comments

Comments
 (0)