Skip to content

Commit eabf390

Browse files
committed
Auto merge of #146697 - cjgillot:invalidate-patch, r=lcnr
Avoid invalidating CFG caches from MirPatch::apply. Small effort to reduce invalidating CFG caches.
2 parents 6f34f4e + ce677c7 commit eabf390

1 file changed

Lines changed: 21 additions & 15 deletions

File tree

  • compiler/rustc_mir_transform/src

‎compiler/rustc_mir_transform/src/patch.rs‎

Lines changed: 21 additions & 15 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)structMirPatch<'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,21 @@ pub(crate) struct MirPatch<'tcx> {
2223
terminate_block:Option<(BasicBlock,UnwindTerminateReason)>,
2324
body_span:Span,
2425
next_local:usize,
26+
/// The number of blocks at the start of the transformation. New blocks
27+
/// get appended at the end.
28+
next_block:usize,
2529
}
2630

2731
impl<'tcx>MirPatch<'tcx>{
2832
/// Creates a new, empty patch.
2933
pub(crate)fnnew(body:&Body<'tcx>) -> Self{
3034
letmut result = MirPatch{
31-
term_patch_map:IndexVec::from_elem(None,&body.basic_blocks),
35+
term_patch_map:Default::default(),
3236
new_blocks:vec![],
3337
new_statements:vec![],
3438
new_locals:vec![],
3539
next_local: body.local_decls.len(),
40+
next_block: body.basic_blocks.len(),
3641
resume_block:None,
3742
unreachable_cleanup_block:None,
3843
unreachable_no_cleanup_block:None,
@@ -141,7 +146,7 @@ impl<'tcx> MirPatch<'tcx> {
141146

142147
/// Has a replacement of this block's terminator been queued in this patch?
143148
pub(crate)fnis_term_patched(&self,bb:BasicBlock) -> bool{
144-
self.term_patch_map[bb].is_some()
149+
self.term_patch_map.contains_key(&bb)
145150
}
146151

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

195200
/// Queues the addition of a new basic block.
196201
pub(crate)fnnew_block(&mutself,data:BasicBlockData<'tcx>) -> BasicBlock{
197-
let block = self.term_patch_map.next_index();
202+
let block = BasicBlock::from_usize(self.next_block + self.new_blocks.len());
198203
debug!("MirPatch: new_block: {:?}: {:?}", block, data);
199204
self.new_blocks.push(data);
200-
self.term_patch_map.push(None);
201205
block
202206
}
203207

204208
/// Queues the replacement of a block's terminator.
205209
pub(crate)fnpatch_terminator(&mutself,block:BasicBlock,new:TerminatorKind<'tcx>){
206-
assert!(self.term_patch_map[block].is_none());
210+
assert!(!self.term_patch_map.contains_key(&block));
207211
debug!("MirPatch: patch_terminator({:?}, {:?})", block, new);
208-
self.term_patch_map[block] = Some(new);
212+
self.term_patch_map.insert(block,new);
209213
}
210214

211215
/// Queues the insertion of a statement at a given location. The statement
@@ -244,18 +248,20 @@ impl<'tcx> MirPatch<'tcx> {
244248
self.new_blocks.len(),
245249
body.basic_blocks.len()
246250
);
251+
debug_assert_eq!(self.next_block, body.basic_blocks.len());
247252
let bbs = ifself.term_patch_map.is_empty() && self.new_blocks.is_empty(){
248253
body.basic_blocks.as_mut_preserves_cfg()
249254
}else{
250255
body.basic_blocks.as_mut()
251256
};
252257
bbs.extend(self.new_blocks);
253258
body.local_decls.extend(self.new_locals);
254-
for(src, patch)inself.term_patch_map.into_iter_enumerated(){
255-
ifletSome(patch) = patch {
256-
debug!("MirPatch: patching block {:?}", src);
257-
bbs[src].terminator_mut().kind = patch;
258-
}
259+
260+
// The order in which we patch terminators does not change the result.
261+
#[allow(rustc::potential_query_instability)]
262+
for(src, patch)inself.term_patch_map{
263+
debug!("MirPatch: patching block {:?}", src);
264+
bbs[src].terminator_mut().kind = patch;
259265
}
260266

261267
letmut new_statements = self.new_statements;
@@ -273,8 +279,8 @@ impl<'tcx> MirPatch<'tcx> {
273279
}
274280
debug!("MirPatch: adding statement {:?} at loc {:?}+{}", stmt, loc, delta);
275281
loc.statement_index += delta;
276-
let source_info = Self::source_info_for_index(&body[loc.block], loc);
277-
body[loc.block]
282+
let source_info = Self::source_info_for_index(&bbs[loc.block], loc);
283+
bbs[loc.block]
278284
.statements
279285
.insert(loc.statement_index,Statement::new(source_info, stmt));
280286
delta += 1;

0 commit comments

Comments
 (0)