Skip to content

Commit 98e2e6a

Browse files
Auto merge of #142540 - cjgillot:renumber-cfg, r=<try>
Pre-compute MIR CFG caches for borrowck and other analyses I was puzzled that #142390 introduces additional computations of CFG traversals: borrowck computes them, right? It turns out that borrowck clones the MIR body, so doesn't share its cache with other analyses. This PR: - forces the computation of all caches in `mir_promoted` query; - modifies region renumbering to avoid dropping that cache. <!-- homu-ignore:start --> <!-- If this PR is related to an unstable feature or an otherwise tracked effort, please link to the relevant tracking issue here. If you don't know of a related tracking issue or there are none, feel free to ignore this. This PR will get automatically assigned to a reviewer. In case you would like a specific user to review your work, you can assign it to them by using r? <reviewer name> --> <!-- homu-ignore:end -->
2 parents 586ad39 + 3e77d40 commit 98e2e6a

File tree

2 files changed

+15
-6
lines changed

2 files changed

+15
-6
lines changed

compiler/rustc_borrowck/src/renumber.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ pub(crate) fn renumber_mir<'tcx>(
2121
let mut renumberer = RegionRenumberer { infcx };
2222

2323
for body in promoted.iter_mut() {
24-
renumberer.visit_body(body);
24+
renumberer.visit_body_preserves_cfg(body);
2525
}
2626

27-
renumberer.visit_body(body);
27+
renumberer.visit_body_preserves_cfg(body);
2828
}
2929

3030
// The fields are used only for debugging output in `sccs_info`.

compiler/rustc_middle/src/mir/basic_blocks.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::sync::OnceLock;
1+
use std::sync::{Arc, OnceLock};
22

33
use rustc_data_structures::fx::FxHashMap;
44
use rustc_data_structures::graph;
@@ -15,7 +15,8 @@ use crate::mir::{BasicBlock, BasicBlockData, START_BLOCK, Terminator, Terminator
1515
#[derive(Clone, TyEncodable, TyDecodable, Debug, HashStable, TypeFoldable, TypeVisitable)]
1616
pub struct BasicBlocks<'tcx> {
1717
basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
18-
cache: Cache,
18+
/// Use an `Arc` so we can share the cache when we clone the MIR body, as borrowck does.
19+
cache: Arc<Cache>,
1920
}
2021

2122
// Typically 95%+ of basic blocks have 4 or fewer predecessors.
@@ -49,9 +50,10 @@ struct Cache {
4950
impl<'tcx> BasicBlocks<'tcx> {
5051
#[inline]
5152
pub fn new(basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>) -> Self {
52-
BasicBlocks { basic_blocks, cache: Cache::default() }
53+
BasicBlocks { basic_blocks, cache: Arc::new(Cache::default()) }
5354
}
5455

56+
#[inline]
5557
pub fn dominators(&self) -> &Dominators<BasicBlock> {
5658
self.cache.dominators.get_or_init(|| dominators(self))
5759
}
@@ -142,7 +144,14 @@ impl<'tcx> BasicBlocks<'tcx> {
142144
/// All other methods that allow you to mutate the basic blocks also call this method
143145
/// themselves, thereby avoiding any risk of accidentally cache invalidation.
144146
pub fn invalidate_cfg_cache(&mut self) {
145-
self.cache = Cache::default();
147+
if let Some(cache) = Arc::get_mut(&mut self.cache) {
148+
// If we only have a single reference to this cache, clear it.
149+
*cache = Cache::default();
150+
} else {
151+
// If we have several references to this cache, overwrite the pointer itself so other
152+
// users can continue to use their (valid) cache.
153+
self.cache = Arc::new(Cache::default());
154+
}
146155
}
147156
}
148157

0 commit comments

Comments
 (0)