]>
Commit | Line | Data |
---|---|---|
5869c6ff XL |
1 | use rustc_data_structures::graph::{ |
2 | self, DirectedGraph, WithNumNodes, WithStartNode, WithSuccessors, | |
3 | }; | |
4 | use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; | |
5 | use rustc_data_structures::sync::OnceCell; | |
923072b8 | 6 | use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; |
5869c6ff XL |
7 | |
8 | /// Helper type to cache the result of `graph::is_cyclic`. | |
9 | #[derive(Clone, Debug)] | |
10 | pub(super) struct GraphIsCyclicCache { | |
11 | cache: OnceCell<bool>, | |
12 | } | |
13 | ||
14 | impl GraphIsCyclicCache { | |
15 | #[inline] | |
16 | pub(super) fn new() -> Self { | |
17 | GraphIsCyclicCache { cache: OnceCell::new() } | |
18 | } | |
19 | ||
20 | pub(super) fn is_cyclic<G>(&self, graph: &G) -> bool | |
21 | where | |
22 | G: ?Sized + DirectedGraph + WithStartNode + WithSuccessors + WithNumNodes, | |
23 | { | |
24 | *self.cache.get_or_init(|| graph::is_cyclic(graph)) | |
25 | } | |
26 | ||
27 | /// Invalidates the cache. | |
28 | #[inline] | |
29 | pub(super) fn invalidate(&mut self) { | |
30 | // Invalidating the cache requires mutating the MIR, which in turn requires a unique | |
31 | // reference (`&mut`) to the `mir::Body`. Because of this, we can assume that all | |
32 | // callers of `invalidate` have a unique reference to the MIR and thus to the | |
33 | // cache. This means we never need to do synchronization when `invalidate` is called, | |
34 | // we can simply reinitialize the `OnceCell`. | |
35 | self.cache = OnceCell::new(); | |
36 | } | |
37 | } | |
38 | ||
923072b8 | 39 | impl<S: Encoder> Encodable<S> for GraphIsCyclicCache { |
5869c6ff | 40 | #[inline] |
923072b8 FG |
41 | fn encode(&self, s: &mut S) { |
42 | Encodable::encode(&(), s); | |
5869c6ff XL |
43 | } |
44 | } | |
45 | ||
923072b8 | 46 | impl<D: Decoder> Decodable<D> for GraphIsCyclicCache { |
5869c6ff | 47 | #[inline] |
5099ac24 | 48 | fn decode(d: &mut D) -> Self { |
923072b8 | 49 | let () = Decodable::decode(d); |
5099ac24 | 50 | Self::new() |
5869c6ff XL |
51 | } |
52 | } | |
53 | ||
54 | impl<CTX> HashStable<CTX> for GraphIsCyclicCache { | |
55 | #[inline] | |
56 | fn hash_stable(&self, _: &mut CTX, _: &mut StableHasher) { | |
57 | // do nothing | |
58 | } | |
59 | } | |
60 | ||
61 | TrivialTypeFoldableAndLiftImpls! { | |
62 | GraphIsCyclicCache, | |
63 | } |