Skip to content

Commit 184e17c

Browse files
committed
Use an Arc to share caches between clones.
1 parent f5a5a37 commit 184e17c

File tree

1 file changed

+13
-4
lines changed

1 file changed

+13
-4
lines changed

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::graph;
44
use rustc_data_structures::graph::dominators::{Dominators, dominators};
@@ -14,7 +14,8 @@ use crate::mir::{BasicBlock, BasicBlockData, START_BLOCK};
1414
#[derive(Clone, TyEncodable, TyDecodable, Debug, HashStable, TypeFoldable, TypeVisitable)]
1515
pub struct BasicBlocks<'tcx> {
1616
basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>,
17-
cache: Cache,
17+
/// Use an `Arc` so we can share the cache when we clone the MIR body, as borrowck does.
18+
cache: Arc<Cache>,
1819
}
1920

2021
// Typically 95%+ of basic blocks have 4 or fewer predecessors.
@@ -38,9 +39,10 @@ struct Cache {
3839
impl<'tcx> BasicBlocks<'tcx> {
3940
#[inline]
4041
pub fn new(basic_blocks: IndexVec<BasicBlock, BasicBlockData<'tcx>>) -> Self {
41-
BasicBlocks { basic_blocks, cache: Cache::default() }
42+
BasicBlocks { basic_blocks, cache: Arc::new(Cache::default()) }
4243
}
4344

45+
#[inline]
4446
pub fn dominators(&self) -> &Dominators<BasicBlock> {
4547
self.cache.dominators.get_or_init(|| dominators(self))
4648
}
@@ -104,7 +106,14 @@ impl<'tcx> BasicBlocks<'tcx> {
104106
/// All other methods that allow you to mutate the basic blocks also call this method
105107
/// themselves, thereby avoiding any risk of accidentally cache invalidation.
106108
pub fn invalidate_cfg_cache(&mut self) {
107-
self.cache = Cache::default();
109+
if let Some(cache) = Arc::get_mut(&mut self.cache) {
110+
// If we only have a single reference to this cache, clear it.
111+
*cache = Cache::default();
112+
} else {
113+
// If we have several references to this cache, overwrite the pointer itself so other
114+
// users can continue to use their (valid) cache.
115+
self.cache = Arc::new(Cache::default());
116+
}
108117
}
109118
}
110119

0 commit comments

Comments
 (0)