Skip to content

Commit 9b335ce

Browse files
committed
Move predecessors cache back to its own type
This ensures that the cache can be properly ignored during encoding and decoding. Fix panics that arose due to lack of encoding
1 parent 22bc8a0 commit 9b335ce

File tree

4 files changed

+61
-14
lines changed

4 files changed

+61
-14
lines changed

src/librustc/mir/cache.rs

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
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;
6+
7+
#[derive(Clone, Debug)]
8+
pub(in crate::mir) struct Cache {
9+
pub(in crate::mir) predecessors: Option<IndexVec<BasicBlock, Vec<BasicBlock>>>
10+
}
11+
12+
13+
impl rustc_serialize::Encodable for Cache {
14+
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
15+
Encodable::encode(&(), s)
16+
}
17+
}
18+
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())
22+
}
23+
}
24+
25+
impl<'a> HashStable<StableHashingContext<'a>> for Cache {
26+
fn hash_stable(&self, _: &mut StableHashingContext<'a>, _: &mut StableHasher) {
27+
// Do nothing.
28+
}
29+
}
30+
31+
impl Cache {
32+
pub fn new() -> Self {
33+
Cache {
34+
predecessors: None
35+
}
36+
}
37+
38+
#[inline]
39+
pub fn invalidate_predecessors(&mut self) {
40+
// FIXME: consider being more fine-grained
41+
self.predecessors = None;
42+
}
43+
}
44+
45+
CloneTypeFoldableAndLiftImpls! {
46+
Cache,
47+
}

src/librustc/mir/mod.rs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ use syntax_pos::{Span, DUMMY_SP};
4040

4141
pub use crate::mir::interpret::AssertMessage;
4242

43+
mod cache;
4344
pub mod interpret;
4445
pub mod mono;
4546
pub mod tcx;
@@ -154,7 +155,7 @@ pub struct Body<'tcx> {
154155
pub span: Span,
155156

156157
/// A cache for various calculations.
157-
predecessors_cache: Option<IndexVec<BasicBlock, Vec<BasicBlock>>>,
158+
cache: cache::Cache,
158159
}
159160

160161
impl<'tcx> Body<'tcx> {
@@ -191,7 +192,7 @@ impl<'tcx> Body<'tcx> {
191192
spread_arg: None,
192193
var_debug_info,
193194
span,
194-
predecessors_cache: None,
195+
cache: cache::Cache::new(),
195196
control_flow_destroyed,
196197
}
197198
}
@@ -204,7 +205,7 @@ impl<'tcx> Body<'tcx> {
204205
#[inline]
205206
pub fn basic_blocks_mut(&mut self) -> &mut IndexVec<BasicBlock, BasicBlockData<'tcx>> {
206207
debug!("bbm: Clearing predecessors cache for body at: {:?}", self.span.data());
207-
self.predecessors_cache = None;
208+
self.cache.invalidate_predecessors();
208209
&mut self.basic_blocks
209210
}
210211

@@ -213,23 +214,23 @@ impl<'tcx> Body<'tcx> {
213214
&mut self,
214215
) -> (&mut IndexVec<BasicBlock, BasicBlockData<'tcx>>, &mut LocalDecls<'tcx>) {
215216
debug!("bbaldm: Clearing predecessors cache for body at: {:?}", self.span.data());
216-
self.predecessors_cache = None;
217+
self.cache.invalidate_predecessors();
217218
(&mut self.basic_blocks, &mut self.local_decls)
218219
}
219220

220221
#[inline]
221222
pub fn unwrap_predecessors(&self) -> &IndexVec<BasicBlock, Vec<BasicBlock>> {
222223
assert!(
223-
self.predecessors_cache.is_some(),
224-
"Expected predecessors_cache to be `Some(...)` for block at: {:?}",
224+
self.cache.predecessors.is_some(),
225+
"Expected cache.predecessors to be `Some(...)` for block at: {:?}",
225226
self.span.data()
226227
);
227-
self.predecessors_cache.as_ref().unwrap()
228+
self.cache.predecessors.as_ref().unwrap()
228229
}
229230

230231
#[inline]
231232
pub fn ensure_predecessors(&mut self) {
232-
if self.predecessors_cache.is_none() {
233+
if self.cache.predecessors.is_none() {
233234
let mut result = IndexVec::from_elem(vec![], self.basic_blocks());
234235
for (bb, data) in self.basic_blocks().iter_enumerated() {
235236
if let Some(ref term) = data.terminator {
@@ -239,15 +240,15 @@ impl<'tcx> Body<'tcx> {
239240
}
240241
}
241242

242-
self.predecessors_cache = Some(result)
243+
self.cache.predecessors = Some(result)
243244
}
244245
}
245246

246247
#[inline]
247248
/// This will recompute the predecessors cache if it is not available
248249
pub fn predecessors(&mut self) -> &IndexVec<BasicBlock, Vec<BasicBlock>> {
249250
self.ensure_predecessors();
250-
self.predecessors_cache.as_ref().unwrap()
251+
self.cache.predecessors.as_ref().unwrap()
251252
}
252253

253254
#[inline]
@@ -1030,8 +1031,6 @@ impl BasicBlock {
10301031
}
10311032
}
10321033

1033-
CloneTypeFoldableAndLiftImpls!{ BasicBlock, }
1034-
10351034
///////////////////////////////////////////////////////////////////////////
10361035
// BasicBlockData and Terminator
10371036

src/librustc_metadata/rmeta/decoder.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1082,7 +1082,7 @@ impl<'a, 'tcx> CrateMetadata {
10821082

10831083
fn get_optimized_mir(&self, tcx: TyCtxt<'tcx>, id: DefIndex) -> Body<'tcx> {
10841084
self.root.per_def.mir.get(self, id)
1085-
.filter(|_| !self.is_proc_macro(id))
1085+
self.entry_unless_proc_macro(id)
10861086
.unwrap_or_else(|| {
10871087
bug!("get_optimized_mir: missing MIR for `{:?}`", self.local_def_id(id))
10881088
})

src/librustc_mir/transform/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,8 +249,9 @@ fn mir_validated(
249249
// What we need to run borrowck etc.
250250
&promote_pass,
251251
&simplify::SimplifyCfg::new("qualify-consts"),
252-
&ensure_predecessors_cache::EnsurePredecessorsCache::new("qualify-consts"),
253252
]);
253+
254+
body.ensure_predecessors();
254255
let promoted = promote_pass.promoted_fragments.into_inner();
255256
(tcx.alloc_steal_mir(body), tcx.alloc_steal_promoted(promoted))
256257
}

0 commit comments

Comments
 (0)