11//! Lazily compute the reverse control-flow graph for the MIR. 
22
33use  rustc_data_structures:: stable_hasher:: { HashStable ,  StableHasher } ; 
4- use  rustc_data_structures:: sync:: { Lock ,   Lrc } ; 
4+ use  rustc_data_structures:: sync:: OnceCell ; 
55use  rustc_index:: vec:: IndexVec ; 
66use  rustc_serialize as  serialize; 
77use  smallvec:: SmallVec ; 
@@ -13,37 +13,33 @@ pub type Predecessors = IndexVec<BasicBlock, SmallVec<[BasicBlock; 4]>>;
1313
1414#[ derive( Clone ,  Debug ) ]  
1515pub ( super )  struct  PredecessorCache  { 
16-     cache :  Lock < Option < Lrc < Predecessors > > > , 
16+     cache :  OnceCell < Predecessors > , 
1717} 
1818
1919impl  PredecessorCache  { 
2020    #[ inline]  
2121    pub ( super )  fn  new ( )  -> Self  { 
22-         PredecessorCache  {  cache :  Lock :: new ( None )  } 
22+         PredecessorCache  {  cache :  OnceCell :: new ( )  } 
2323    } 
2424
2525    /// Invalidates the predecessor cache. 
2626     /// 
2727     /// Invalidating the predecessor cache requires mutating the MIR, which in turn requires a 
2828     /// unique reference (`&mut`) to the `mir::Body`. Because of this, we can assume that all 
2929     /// callers of `invalidate` have a unique reference to the MIR and thus to the predecessor 
30-      /// cache. This means we don't actually  need to take a lock  when `invalidate` is called. 
30+      /// cache. This means we never  need to do synchronization  when `invalidate` is called. 
3131     #[ inline]  
3232    pub ( super )  fn  invalidate ( & mut  self )  { 
33-         * self . cache . get_mut ( )  = None ; 
33+         self . cache  = OnceCell :: new ( ) ; 
3434    } 
3535
36-     /// Returns a ref-counted smart pointer containing the predecessor graph for this MIR. 
37-      /// 
38-      /// We use ref-counting instead of a mapped `LockGuard` here to ensure that the lock for 
39-      /// `cache` is only held inside this function. As long as no other locks are taken while 
40-      /// computing the predecessor graph, deadlock is impossible. 
36+     /// Returns the the predecessor graph for this MIR. 
4137     #[ inline]  
4238    pub ( super )  fn  compute ( 
4339        & self , 
4440        basic_blocks :  & IndexVec < BasicBlock ,  BasicBlockData < ' _ > > , 
45-     )  -> Lrc < Predecessors >  { 
46-         Lrc :: clone ( self . cache . lock ( ) . get_or_insert_with ( || { 
41+     )  -> & Predecessors  { 
42+         self . cache . get_or_init ( || { 
4743            let  mut  preds = IndexVec :: from_elem ( SmallVec :: new ( ) ,  basic_blocks) ; 
4844            for  ( bb,  data)  in  basic_blocks. iter_enumerated ( )  { 
4945                if  let  Some ( term)  = & data. terminator  { 
@@ -53,8 +49,8 @@ impl PredecessorCache {
5349                } 
5450            } 
5551
56-             Lrc :: new ( preds) 
57-         } ) ) 
52+             preds
53+         } ) 
5854    } 
5955} 
6056
0 commit comments