Skip to content

Commit c0592fa

Browse files
committed
Move predecessor cache outside of Body, use wrapper types to manage Cache and Body (WIP, amend this commit)
1 parent 9b335ce commit c0592fa

File tree

6 files changed

+300
-161
lines changed

6 files changed

+300
-161
lines changed

src/librustc/mir/cache.rs

Lines changed: 233 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,255 @@
11
use rustc_index::vec::IndexVec;
2-
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
3-
use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
4-
use crate::ich::StableHashingContext;
5-
use crate::mir::BasicBlock;
2+
//use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
3+
//use rustc_serialize::{Encodable, Encoder, Decodable, Decoder};
4+
//use crate::ich::StableHashingContext;
5+
use crate::mir::{BasicBlock, BasicBlockData, Body, LocalDecls, Location, Successors};
6+
use rustc_data_structures::graph::{self, GraphPredecessors, GraphSuccessors};
7+
use rustc_data_structures::graph::dominators::{dominators, Dominators};
8+
use std::iter;
9+
use std::ops::{Index, IndexMut};
10+
use std::vec::IntoIter;
611

712
#[derive(Clone, Debug)]
8-
pub(in crate::mir) struct Cache {
9-
pub(in crate::mir) predecessors: Option<IndexVec<BasicBlock, Vec<BasicBlock>>>
13+
pub struct Cache {
14+
predecessors: Option<IndexVec<BasicBlock, Vec<BasicBlock>>>,
1015
}
1116

1217

13-
impl rustc_serialize::Encodable for Cache {
14-
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
15-
Encodable::encode(&(), s)
18+
//impl<'tcx, T> rustc_serialize::Encodable for Cache<'tcx, T> {
19+
// fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
20+
// Encodable::encode(&(), s)
21+
// }
22+
//}
23+
//
24+
//impl<'tcx, T> rustc_serialize::Decodable for Cache<'tcx, T> {
25+
// fn decode<D: Decoder>(d: &mut D) -> Result<Self, D::Error> {
26+
// Decodable::decode(d).map(|_v: ()| Self::new())
27+
// }
28+
//}
29+
//
30+
//impl<'a, 'tcx, T> HashStable<StableHashingContext<'a>> for Cache<'tcx, T> {
31+
// fn hash_stable(&self, _: &mut StableHashingContext<'a>, _: &mut StableHasher) {
32+
// // Do nothing.
33+
// }
34+
//}
35+
36+
impl Cache {
37+
pub fn new() -> Self {
38+
Self {
39+
predecessors: None,
40+
}
41+
}
42+
43+
#[inline]
44+
pub fn invalidate_predecessors(&mut self) {
45+
// FIXME: consider being more fine-grained
46+
self.predecessors = None;
47+
}
48+
49+
#[inline]
50+
/// This will recompute the predecessors cache if it is not available
51+
pub fn predecessors(&mut self, body: &Body<'_>) -> &IndexVec<BasicBlock, Vec<BasicBlock>> {
52+
if self.predecessors.is_none() {
53+
let mut result = IndexVec::from_elem(vec![], body.basic_blocks());
54+
for (bb, data) in body.basic_blocks().iter_enumerated() {
55+
if let Some(ref term) = data.terminator {
56+
for &tgt in term.successors() {
57+
result[tgt].push(bb);
58+
}
59+
}
60+
}
61+
62+
self.predecessors = Some(result)
63+
}
64+
65+
self.predecessors.as_ref().unwrap()
66+
}
67+
68+
#[inline]
69+
pub fn predecessors_for(&mut self, bb: BasicBlock, body: &Body<'_>) -> &[BasicBlock] {
70+
&self.predecessors(body)[bb]
71+
}
72+
73+
#[inline]
74+
pub fn predecessor_locations<'a>(&'a mut self, loc: Location, body: &'a Body<'a>) -> impl Iterator<Item = Location> + 'a {
75+
let if_zero_locations = if loc.statement_index == 0 {
76+
let predecessor_blocks = self.predecessors_for(loc.block, body);
77+
let num_predecessor_blocks = predecessor_blocks.len();
78+
Some(
79+
(0..num_predecessor_blocks)
80+
.map(move |i| predecessor_blocks[i])
81+
.map(move |bb| body.terminator_loc(bb)),
82+
)
83+
} else {
84+
None
85+
};
86+
87+
let if_not_zero_locations = if loc.statement_index == 0 {
88+
None
89+
} else {
90+
Some(Location { block: loc.block, statement_index: loc.statement_index - 1 })
91+
};
92+
93+
if_zero_locations.into_iter().flatten().chain(if_not_zero_locations)
94+
}
95+
96+
#[inline]
97+
pub fn basic_blocks_mut<'a, 'tcx>(&mut self, body: &'a mut Body<'tcx>) -> &'a mut IndexVec<BasicBlock, BasicBlockData<'tcx>> {
98+
debug!("bbm: Clearing predecessors cache for body at: {:?}", body.span.data());
99+
self.invalidate_predecessors();
100+
&mut body.basic_blocks
101+
}
102+
103+
#[inline]
104+
pub fn basic_blocks_and_local_decls_mut<'a, 'tcx>(
105+
&mut self,
106+
body: &'a mut Body<'tcx>
107+
) -> (&'a mut IndexVec<BasicBlock, BasicBlockData<'tcx>>, &'a mut LocalDecls<'tcx>) {
108+
debug!("bbaldm: Clearing predecessors cache for body at: {:?}", body.span.data());
109+
self.invalidate_predecessors();
110+
(&mut body.basic_blocks, &mut body.local_decls)
111+
}
112+
}
113+
114+
pub struct OwningCache<'tcx> {
115+
cache: Cache,
116+
body: Body<'tcx>,
117+
}
118+
119+
impl<'tcx> OwningCache<'tcx> {
120+
pub fn borrow(&mut self) -> BorrowedCache<'_, 'tcx> {
121+
BorrowedCache {
122+
cache: &mut self.cache,
123+
body: &self.body,
124+
}
125+
}
126+
127+
pub fn borrow_mut(&mut self) -> MutCache<'_, 'tcx> {
128+
MutCache {
129+
cache: &mut self.cache,
130+
body: &mut self.body,
131+
}
132+
}
133+
}
134+
135+
pub struct BorrowedCache<'a, 'tcx> {
136+
cache: &'a mut Cache,
137+
body: &'a Body<'tcx>
138+
}
139+
140+
impl<'a, 'tcx> BorrowedCache<'a, 'tcx> {
141+
#[inline]
142+
pub fn predecessors_for(&mut self, bb: BasicBlock) -> &[BasicBlock] {
143+
self.cache.predecessors_for(bb, self.body)
144+
}
145+
146+
#[inline]
147+
pub fn body(&self) -> &Body<'tcx> {
148+
self.body
149+
}
150+
151+
#[inline]
152+
pub fn basic_blocks(&self) -> &IndexVec<BasicBlock, BasicBlockData<'tcx>> {
153+
&self.body.basic_blocks
154+
}
155+
156+
#[inline]
157+
pub fn dominators(&mut self) -> Dominators<BasicBlock> {
158+
dominators(self)
16159
}
17160
}
18161

19-
impl rustc_serialize::Decodable for Cache {
20-
fn decode<D: Decoder>(d: &mut D) -> Result<Self, D::Error> {
21-
Decodable::decode(d).map(|_v: ()| Self::new())
162+
impl<'a, 'tcx> Index<BasicBlock> for BorrowedCache<'a, 'tcx> {
163+
type Output = BasicBlockData<'tcx>;
164+
165+
#[inline]
166+
fn index(&self, index: BasicBlock) -> &BasicBlockData<'tcx> {
167+
&self.body[index]
22168
}
23169
}
24170

25-
impl<'a> HashStable<StableHashingContext<'a>> for Cache {
26-
fn hash_stable(&self, _: &mut StableHashingContext<'a>, _: &mut StableHasher) {
27-
// Do nothing.
171+
impl<'a, 'tcx> graph::DirectedGraph for BorrowedCache<'a, 'tcx> {
172+
type Node = BasicBlock;
173+
}
174+
175+
impl<'a, 'graph, 'tcx> graph::GraphPredecessors<'graph> for BorrowedCache<'a, 'tcx> {
176+
type Item = BasicBlock;
177+
type Iter = IntoIter<BasicBlock>;
178+
}
179+
180+
impl<'a, 'tcx> graph::WithPredecessors for BorrowedCache<'a, 'tcx> {
181+
fn predecessors(
182+
&mut self,
183+
node: Self::Node,
184+
) -> <Self as GraphPredecessors<'_>>::Iter {
185+
self.predecessors_for(node).to_vec().into_iter()
28186
}
29187
}
30188

31-
impl Cache {
32-
pub fn new() -> Self {
33-
Cache {
34-
predecessors: None
35-
}
189+
impl<'a, 'tcx> graph::WithNumNodes for BorrowedCache<'a, 'tcx> {
190+
fn num_nodes(&self) -> usize {
191+
self.body.num_nodes()
36192
}
193+
}
37194

195+
impl<'a, 'tcx> graph::WithStartNode for BorrowedCache<'a, 'tcx> {
196+
fn start_node(&self) -> Self::Node {
197+
self.body.start_node()
198+
}
199+
}
200+
201+
impl<'a, 'tcx> graph::WithSuccessors for BorrowedCache<'a, 'tcx> {
202+
fn successors(
203+
&self,
204+
node: Self::Node,
205+
) -> <Self as GraphSuccessors<'_>>::Iter {
206+
self.body.successors(node)
207+
}
208+
}
209+
210+
impl<'a, 'b, 'tcx> graph::GraphSuccessors<'b> for BorrowedCache<'a, 'tcx> {
211+
type Item = BasicBlock;
212+
type Iter = iter::Cloned<Successors<'b>>;
213+
}
214+
215+
pub struct MutCache<'a, 'tcx> {
216+
cache: &'a mut Cache,
217+
body: &'a mut Body<'tcx>,
218+
}
219+
220+
impl<'a, 'tcx> MutCache<'a, 'tcx> {
38221
#[inline]
39-
pub fn invalidate_predecessors(&mut self) {
40-
// FIXME: consider being more fine-grained
41-
self.predecessors = None;
222+
pub fn body(&mut self) -> &mut Body<'tcx> {
223+
self.body
224+
}
225+
226+
#[inline]
227+
pub fn basic_blocks(&self) -> &IndexVec<BasicBlock, BasicBlockData<'tcx>> {
228+
&self.body.basic_blocks
229+
}
230+
231+
#[inline]
232+
pub fn basic_blocks_mut(&mut self) -> &mut IndexVec<BasicBlock, BasicBlockData<'tcx>> {
233+
self.cache.basic_blocks_mut(&mut self.body)
42234
}
43235
}
44236

45-
CloneTypeFoldableAndLiftImpls! {
46-
Cache,
237+
impl<'a, 'tcx> Index<BasicBlock> for MutCache<'a, 'tcx> {
238+
type Output = BasicBlockData<'tcx>;
239+
240+
#[inline]
241+
fn index(&self, index: BasicBlock) -> &BasicBlockData<'tcx> {
242+
&self.body[index]
243+
}
47244
}
245+
246+
impl<'a, 'tcx> IndexMut<BasicBlock> for MutCache<'a, 'tcx> {
247+
fn index_mut(&mut self, index: BasicBlock) -> &mut Self::Output {
248+
self.cache.invalidate_predecessors();
249+
&mut self.body.basic_blocks[index]
250+
}
251+
}
252+
253+
//CloneTypeFoldableAndLiftImpls! {
254+
// Cache,
255+
//}

0 commit comments

Comments
 (0)