]>
Commit | Line | Data |
---|---|---|
3157f602 XL |
1 | // Copyright 2016 The Rust Project Developers. See the COPYRIGHT |
2 | // file at the top-level directory of this distribution and at | |
3 | // http://rust-lang.org/COPYRIGHT. | |
4 | // | |
5 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
6 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
7 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
8 | // option. This file may not be copied, modified, or distributed | |
9 | // except according to those terms. | |
10 | ||
11 | use std::cell::{Ref, RefCell}; | |
12 | use rustc_data_structures::indexed_vec::IndexVec; | |
cc61c64b XL |
13 | use rustc_data_structures::stable_hasher::{HashStable, StableHasher, |
14 | StableHasherResult}; | |
15 | use ich::StableHashingContext; | |
c30ab7b3 | 16 | use mir::{Mir, BasicBlock}; |
3157f602 XL |
17 | |
18 | use rustc_serialize as serialize; | |
19 | ||
20 | #[derive(Clone, Debug)] | |
21 | pub struct Cache { | |
22 | predecessors: RefCell<Option<IndexVec<BasicBlock, Vec<BasicBlock>>>> | |
23 | } | |
24 | ||
25 | ||
26 | impl serialize::Encodable for Cache { | |
27 | fn encode<S: serialize::Encoder>(&self, s: &mut S) -> Result<(), S::Error> { | |
28 | serialize::Encodable::encode(&(), s) | |
29 | } | |
30 | } | |
31 | ||
32 | impl serialize::Decodable for Cache { | |
33 | fn decode<D: serialize::Decoder>(d: &mut D) -> Result<Self, D::Error> { | |
34 | serialize::Decodable::decode(d).map(|_v: ()| Self::new()) | |
35 | } | |
36 | } | |
37 | ||
ea8adc8c | 38 | impl<'gcx> HashStable<StableHashingContext<'gcx>> for Cache { |
cc61c64b | 39 | fn hash_stable<W: StableHasherResult>(&self, |
ea8adc8c | 40 | _: &mut StableHashingContext<'gcx>, |
cc61c64b XL |
41 | _: &mut StableHasher<W>) { |
42 | // do nothing | |
43 | } | |
44 | } | |
3157f602 XL |
45 | |
46 | impl Cache { | |
47 | pub fn new() -> Self { | |
48 | Cache { | |
49 | predecessors: RefCell::new(None) | |
50 | } | |
51 | } | |
52 | ||
53 | pub fn invalidate(&self) { | |
54 | // FIXME: consider being more fine-grained | |
55 | *self.predecessors.borrow_mut() = None; | |
56 | } | |
57 | ||
58 | pub fn predecessors(&self, mir: &Mir) -> Ref<IndexVec<BasicBlock, Vec<BasicBlock>>> { | |
59 | if self.predecessors.borrow().is_none() { | |
60 | *self.predecessors.borrow_mut() = Some(calculate_predecessors(mir)); | |
61 | } | |
62 | ||
63 | Ref::map(self.predecessors.borrow(), |p| p.as_ref().unwrap()) | |
64 | } | |
65 | } | |
66 | ||
67 | fn calculate_predecessors(mir: &Mir) -> IndexVec<BasicBlock, Vec<BasicBlock>> { | |
68 | let mut result = IndexVec::from_elem(vec![], mir.basic_blocks()); | |
69 | for (bb, data) in mir.basic_blocks().iter_enumerated() { | |
70 | if let Some(ref term) = data.terminator { | |
71 | for &tgt in term.successors().iter() { | |
72 | result[tgt].push(bb); | |
73 | } | |
74 | } | |
75 | } | |
76 | ||
77 | result | |
78 | } |