From f17e2c93a69443c93aa42e0df0a119d35c4d49d9 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Fri, 15 May 2020 21:56:33 -0700 Subject: [PATCH] Use `OnceCell` for predecessor cache --- src/librustc_middle/mir/predecessors.rs | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/src/librustc_middle/mir/predecessors.rs b/src/librustc_middle/mir/predecessors.rs index 9508365886aa..36e92c71c07f 100644 --- a/src/librustc_middle/mir/predecessors.rs +++ b/src/librustc_middle/mir/predecessors.rs @@ -1,7 +1,7 @@ //! Lazily compute the reverse control-flow graph for the MIR. use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; -use rustc_data_structures::sync::{Lock, Lrc}; +use rustc_data_structures::sync::OnceCell; use rustc_index::vec::IndexVec; use rustc_serialize as serialize; use smallvec::SmallVec; @@ -13,13 +13,13 @@ pub type Predecessors = IndexVec>; #[derive(Clone, Debug)] pub(super) struct PredecessorCache { - cache: Lock>>, + cache: OnceCell, } impl PredecessorCache { #[inline] pub(super) fn new() -> Self { - PredecessorCache { cache: Lock::new(None) } + PredecessorCache { cache: OnceCell::new() } } /// Invalidates the predecessor cache. @@ -27,23 +27,19 @@ impl PredecessorCache { /// Invalidating the predecessor cache requires mutating the MIR, which in turn requires a /// unique reference (`&mut`) to the `mir::Body`. Because of this, we can assume that all /// callers of `invalidate` have a unique reference to the MIR and thus to the predecessor - /// cache. This means we don't actually need to take a lock when `invalidate` is called. + /// cache. This means we never need to do synchronization when `invalidate` is called. #[inline] pub(super) fn invalidate(&mut self) { - *self.cache.get_mut() = None; + self.cache = OnceCell::new(); } - /// Returns a ref-counted smart pointer containing the predecessor graph for this MIR. - /// - /// We use ref-counting instead of a mapped `LockGuard` here to ensure that the lock for - /// `cache` is only held inside this function. As long as no other locks are taken while - /// computing the predecessor graph, deadlock is impossible. + /// Returns the the predecessor graph for this MIR. #[inline] pub(super) fn compute( &self, basic_blocks: &IndexVec>, - ) -> Lrc { - Lrc::clone(self.cache.lock().get_or_insert_with(|| { + ) -> &Predecessors { + self.cache.get_or_init(|| { let mut preds = IndexVec::from_elem(SmallVec::new(), basic_blocks); for (bb, data) in basic_blocks.iter_enumerated() { if let Some(term) = &data.terminator { @@ -53,8 +49,8 @@ impl PredecessorCache { } } - Lrc::new(preds) - })) + preds + }) } }