Skip to content

Commit 8e8c97e

Browse files
committed
Ensure predecessors are recomputed at critical points, fixes panics
1 parent 570e418 commit 8e8c97e

File tree

4 files changed

+40
-22
lines changed

4 files changed

+40
-22
lines changed

src/librustc/mir/mod.rs

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -210,12 +210,14 @@ impl<'tcx> Body<'tcx> {
210210
&mut self, bb: BasicBlock
211211
) -> &mut Option<Terminator<'tcx>> {
212212
// FIXME we should look into improving the cache invalidation
213+
debug!("Invalidating predecessors cache through opt terminator for block at : {:?}", self.span.data());
213214
self.predecessors_cache = None;
214215
&mut self.basic_blocks[bb].terminator
215216
}
216217

217218
pub fn basic_block_terminator_mut(&mut self, bb: BasicBlock) -> &mut Terminator<'tcx> {
218219
// FIXME we should look into improving the cache invalidation
220+
debug!("Invalidating predecessors cache through terminator for block at : {:?}", self.span.data());
219221
self.predecessors_cache = None;
220222
self.basic_blocks[bb].terminator_mut()
221223
}
@@ -229,36 +231,35 @@ impl<'tcx> Body<'tcx> {
229231

230232
#[inline]
231233
pub fn unwrap_predecessors(&self) -> &IndexVec<BasicBlock, Vec<BasicBlock>> {
232-
assert!(self.predecessors_cache.is_some());
234+
assert!(self.predecessors_cache.is_some(), "Expected predecessors_cache to be `Some(...)` for block at: {:?}", self.span.data());
233235
self.predecessors_cache.as_ref().unwrap()
234236
}
235237

236238
#[inline]
237-
/// This will recompute the predecessors cache if it is not available
238-
pub fn predecessors(&mut self) -> &IndexVec<BasicBlock, Vec<BasicBlock>> {
239+
pub fn ensure_predecessors(&mut self) {
239240
if self.predecessors_cache.is_none() {
240-
self.predecessors_cache = Some(self.calculate_predecessors())
241-
}
242-
243-
self.predecessors_cache.as_ref().unwrap()
244-
}
245-
246-
fn calculate_predecessors(&self) -> IndexVec<BasicBlock, Vec<BasicBlock>> {
247-
let mut result = IndexVec::from_elem(vec![], self.basic_blocks());
248-
for (bb, data) in self.basic_blocks().iter_enumerated() {
249-
if let Some(ref term) = data.terminator {
250-
for &tgt in term.successors() {
251-
result[tgt].push(bb);
241+
let mut result = IndexVec::from_elem(vec![], self.basic_blocks());
242+
for (bb, data) in self.basic_blocks().iter_enumerated() {
243+
if let Some(ref term) = data.terminator {
244+
for &tgt in term.successors() {
245+
result[tgt].push(bb);
246+
}
252247
}
253248
}
249+
250+
self.predecessors_cache = Some(result)
254251
}
252+
}
255253

256-
result
254+
#[inline]
255+
/// This will recompute the predecessors cache if it is not available
256+
pub fn predecessors(&mut self) -> &IndexVec<BasicBlock, Vec<BasicBlock>> {
257+
self.ensure_predecessors();
258+
self.predecessors_cache.as_ref().unwrap()
257259
}
258260

259261
#[inline]
260262
pub fn predecessors_for(&self, bb: BasicBlock) -> &[BasicBlock] {
261-
// FIXME(nashenas88) could this be predecessors sometimes too?
262263
&self.unwrap_predecessors()[bb]
263264
}
264265

src/librustc_mir/shim.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,8 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> &'tcx
123123
&add_call_guards::CriticalCallEdges,
124124
]);
125125

126+
result.ensure_predecessors();
127+
126128
debug!("make_shim({:?}) = {:?}", instance, result);
127129

128130
tcx.arena.alloc(result)
@@ -909,12 +911,13 @@ pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> &Body<'_> {
909911
is_cleanup: false
910912
};
911913

912-
let body = new_body(
914+
let mut body = new_body(
913915
IndexVec::from_elem_n(start_block, 1),
914916
local_decls,
915917
sig.inputs().len(),
916918
span,
917919
);
920+
body.ensure_predecessors();
918921

919922
crate::util::dump_mir(
920923
tcx,

src/librustc_mir/transform/ensure_predecessors_cache.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,25 @@ use rustc::mir::Body;
22
use rustc::ty::TyCtxt;
33
use crate::transform::{MirPass, MirSource};
44

5-
pub struct EnsurePredecessorsCache;
5+
pub struct EnsurePredecessorsCache {
6+
label: String,
7+
}
8+
9+
impl EnsurePredecessorsCache {
10+
pub fn new<S: Into<String>>(label: S) -> Self {
11+
Self {
12+
label: label.into(),
13+
}
14+
}
15+
}
616

717
impl<'tcx> MirPass<'tcx> for EnsurePredecessorsCache {
818
fn run_pass(&self, _: TyCtxt<'tcx>, _: MirSource<'tcx>, body: &mut Body<'tcx>) {
19+
debug!("{}: Ensure predecessors cache: {:?}", self.label, body.span.data());
920
// predecessors is lazily calculated. We want to ensure that the cache is properly filled
10-
// before the next stages of compilation, since thise following stages will only be allowed
21+
// before the next stages of compilation, since these following stages will only be allowed
1122
// to read the cache and not generate it. If the cache is already up to date, this line is
1223
// a nop.
13-
let _predecessors = body.predecessors();
24+
body.ensure_predecessors();
1425
}
1526
}

src/librustc_mir/transform/mod.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ 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"),
252253
]);
253254
let promoted = promote_pass.promoted_fragments.into_inner();
254255
(tcx.alloc_steal_mir(body), tcx.alloc_steal_promoted(promoted))
@@ -296,6 +297,8 @@ fn run_optimization_passes<'tcx>(
296297
&uniform_array_move_out::RestoreSubsliceArrayMoveOut::new(tcx),
297298
&inline::Inline,
298299

300+
// State transform requires that predecessors have been predefined
301+
&ensure_predecessors_cache::EnsurePredecessorsCache::new("pre-state-transform"),
299302
// Lowering generator control-flow and variables
300303
// has to happen before we do anything else to them.
301304
&generator::StateTransform,
@@ -314,7 +317,7 @@ fn run_optimization_passes<'tcx>(
314317
&simplify::SimplifyLocals,
315318

316319
&add_call_guards::CriticalCallEdges,
317-
&ensure_predecessors_cache::EnsurePredecessorsCache,
320+
&ensure_predecessors_cache::EnsurePredecessorsCache::new("before-opt-dump"),
318321
&dump_mir::Marker("PreCodegen"),
319322
]);
320323
}

0 commit comments

Comments
 (0)