Skip to content

Commit 3c232fe

Browse files
committed
Make term_patch_map sparse.
1 parent b216cf3 commit 3c232fe

File tree

1 file changed

+18
-14
lines changed
  • compiler/rustc_mir_transform/src

1 file changed

+18
-14
lines changed

compiler/rustc_mir_transform/src/patch.rs

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
use rustc_index::{Idx, IndexVec};
1+
use rustc_data_structures::fx::FxHashMap;
2+
use rustc_index::Idx;
23
use rustc_middle::mir::*;
34
use rustc_middle::ty::Ty;
45
use rustc_span::Span;
@@ -9,7 +10,7 @@ use tracing::debug;
910
/// and replacement of terminators, and then apply the queued changes all at
1011
/// once with `apply`. This is useful for MIR transformation passes.
1112
pub(crate) struct MirPatch<'tcx> {
12-
term_patch_map: IndexVec<BasicBlock, Option<TerminatorKind<'tcx>>>,
13+
term_patch_map: FxHashMap<BasicBlock, TerminatorKind<'tcx>>,
1314
new_blocks: Vec<BasicBlockData<'tcx>>,
1415
new_statements: Vec<(Location, StatementKind<'tcx>)>,
1516
new_locals: Vec<LocalDecl<'tcx>>,
@@ -22,17 +23,19 @@ pub(crate) struct MirPatch<'tcx> {
2223
terminate_block: Option<(BasicBlock, UnwindTerminateReason)>,
2324
body_span: Span,
2425
next_local: usize,
26+
next_block: usize,
2527
}
2628

2729
impl<'tcx> MirPatch<'tcx> {
2830
/// Creates a new, empty patch.
2931
pub(crate) fn new(body: &Body<'tcx>) -> Self {
3032
let mut result = MirPatch {
31-
term_patch_map: IndexVec::from_elem(None, &body.basic_blocks),
33+
term_patch_map: Default::default(),
3234
new_blocks: vec![],
3335
new_statements: vec![],
3436
new_locals: vec![],
3537
next_local: body.local_decls.len(),
38+
next_block: body.basic_blocks.len(),
3639
resume_block: None,
3740
unreachable_cleanup_block: None,
3841
unreachable_no_cleanup_block: None,
@@ -141,7 +144,7 @@ impl<'tcx> MirPatch<'tcx> {
141144

142145
/// Has a replacement of this block's terminator been queued in this patch?
143146
pub(crate) fn is_term_patched(&self, bb: BasicBlock) -> bool {
144-
self.term_patch_map[bb].is_some()
147+
self.term_patch_map.contains_key(&bb)
145148
}
146149

147150
/// Universal getter for block data, either it is in 'old' blocks or in patched ones
@@ -194,18 +197,17 @@ impl<'tcx> MirPatch<'tcx> {
194197

195198
/// Queues the addition of a new basic block.
196199
pub(crate) fn new_block(&mut self, data: BasicBlockData<'tcx>) -> BasicBlock {
197-
let block = self.term_patch_map.next_index();
200+
let block = BasicBlock::from_usize(self.next_block + self.new_blocks.len());
198201
debug!("MirPatch: new_block: {:?}: {:?}", block, data);
199202
self.new_blocks.push(data);
200-
self.term_patch_map.push(None);
201203
block
202204
}
203205

204206
/// Queues the replacement of a block's terminator.
205207
pub(crate) fn patch_terminator(&mut self, block: BasicBlock, new: TerminatorKind<'tcx>) {
206-
assert!(self.term_patch_map[block].is_none());
208+
assert!(!self.term_patch_map.contains_key(&block));
207209
debug!("MirPatch: patch_terminator({:?}, {:?})", block, new);
208-
self.term_patch_map[block] = Some(new);
210+
self.term_patch_map.insert(block, new);
209211
}
210212

211213
/// Queues the insertion of a statement at a given location. The statement
@@ -244,18 +246,20 @@ impl<'tcx> MirPatch<'tcx> {
244246
self.new_blocks.len(),
245247
body.basic_blocks.len()
246248
);
247-
let bbs = if self.term_patch_map.iter().all(Option::is_none) && self.new_blocks.is_empty() {
249+
debug_assert_eq!(self.next_block, body.basic_blocks.len());
250+
let bbs = if self.term_patch_map.is_empty() && self.new_blocks.is_empty() {
248251
body.basic_blocks.as_mut_preserves_cfg()
249252
} else {
250253
body.basic_blocks.as_mut()
251254
};
252255
bbs.extend(self.new_blocks);
253256
body.local_decls.extend(self.new_locals);
254-
for (src, patch) in self.term_patch_map.into_iter_enumerated() {
255-
if let Some(patch) = patch {
256-
debug!("MirPatch: patching block {:?}", src);
257-
bbs[src].terminator_mut().kind = patch;
258-
}
257+
258+
// The order in which we patch terminators does not change the result.
259+
#[allow(rustc::potential_query_instability)]
260+
for (src, patch) in self.term_patch_map {
261+
debug!("MirPatch: patching block {:?}", src);
262+
bbs[src].terminator_mut().kind = patch;
259263
}
260264

261265
let mut new_statements = self.new_statements;

0 commit comments

Comments
 (0)