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.
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.
11 use rustc_data_structures
::indexed_vec
::IndexVec
;
12 use rustc_data_structures
::sync
::{RwLock, MappedReadGuard, ReadGuard}
;
13 use rustc_data_structures
::stable_hasher
::{HashStable
, StableHasher
,
15 use ich
::StableHashingContext
;
16 use mir
::{Mir, BasicBlock}
;
18 use rustc_serialize
as serialize
;
20 #[derive(Clone, Debug)]
22 predecessors
: RwLock
<Option
<IndexVec
<BasicBlock
, Vec
<BasicBlock
>>>>
26 impl serialize
::Encodable
for Cache
{
27 fn encode
<S
: serialize
::Encoder
>(&self, s
: &mut S
) -> Result
<(), S
::Error
> {
28 serialize
::Encodable
::encode(&(), s
)
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())
38 impl<'a
> HashStable
<StableHashingContext
<'a
>> for Cache
{
39 fn hash_stable
<W
: StableHasherResult
>(&self,
40 _
: &mut StableHashingContext
<'a
>,
41 _
: &mut StableHasher
<W
>) {
47 pub fn new() -> Self {
49 predecessors
: RwLock
::new(None
)
53 pub fn invalidate(&self) {
54 // FIXME: consider being more fine-grained
55 *self.predecessors
.borrow_mut() = None
;
61 ) -> MappedReadGuard
<'_
, IndexVec
<BasicBlock
, Vec
<BasicBlock
>>> {
62 if self.predecessors
.borrow().is_none() {
63 *self.predecessors
.borrow_mut() = Some(calculate_predecessors(mir
));
66 ReadGuard
::map(self.predecessors
.borrow(), |p
| p
.as_ref().unwrap())
70 fn calculate_predecessors(mir
: &Mir
<'_
>) -> IndexVec
<BasicBlock
, Vec
<BasicBlock
>> {
71 let mut result
= IndexVec
::from_elem(vec
![], mir
.basic_blocks());
72 for (bb
, data
) in mir
.basic_blocks().iter_enumerated() {
73 if let Some(ref term
) = data
.terminator
{
74 for &tgt
in term
.successors() {
83 CloneTypeFoldableAndLiftImpls
! {