1- use std:: sync:: OnceLock ;
1+ use std:: sync:: { Arc , OnceLock } ;
22
33use rustc_data_structures:: fx:: FxHashMap ;
44use 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 ) ]
1616pub 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,15 +50,7 @@ struct Cache {
4950impl < ' tcx > BasicBlocks < ' tcx > {
5051 #[ inline]
5152 pub fn new ( basic_blocks : IndexVec < BasicBlock , BasicBlockData < ' tcx > > ) -> Self {
52- BasicBlocks { basic_blocks, cache : Cache :: default ( ) }
53- }
54-
55- /// Force caching of traversals.
56- pub fn cache_traversals ( & self ) {
57- let _ = self . predecessors ( ) ;
58- let _ = self . switch_sources ( ) ;
59- let _ = self . reverse_postorder ( ) ;
60- let _ = self . dominators ( ) ;
53+ BasicBlocks { basic_blocks, cache : Arc :: new ( Cache :: default ( ) ) }
6154 }
6255
6356 #[ inline]
@@ -151,7 +144,14 @@ impl<'tcx> BasicBlocks<'tcx> {
151144 /// All other methods that allow you to mutate the basic blocks also call this method
152145 /// themselves, thereby avoiding any risk of accidentally cache invalidation.
153146 pub fn invalidate_cfg_cache ( & mut self ) {
154- 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+ }
155155 }
156156}
157157
0 commit comments