From 2b3145606827d1bd2b78004c6012fc060dee3d08 Mon Sep 17 00:00:00 2001 From: Paul Daniel Faria Date: Sat, 28 Sep 2019 10:47:41 -0400 Subject: [PATCH] Add pass to ensure predecessors cache is generated after optimization --- src/librustc/mir/mod.rs | 18 +++--------------- .../transform/ensure_predecessors_cache.rs | 15 +++++++++++++++ src/librustc_mir/transform/mod.rs | 2 ++ 3 files changed, 20 insertions(+), 15 deletions(-) create mode 100644 src/librustc_mir/transform/ensure_predecessors_cache.rs diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index 0d07caa6cda3..78764ec8cd6e 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -207,27 +207,14 @@ impl<'tcx> Body<'tcx> { } pub fn basic_block_terminator_opt_mut(&mut self, bb: BasicBlock) -> &mut Option> { + // FIXME we should look into improving the cache invalidation self.predecessors_cache = None; &mut self.basic_blocks[bb].terminator } pub fn basic_block_terminator_mut(&mut self, bb: BasicBlock) -> &mut Terminator<'tcx> { + // FIXME we should look into improving the cache invalidation self.predecessors_cache = None; -/* - let data = &mut self.basic_blocks[bb]; - if let Some(cache) = self.predecessors_cache.as_mut() { - for successor in data.terminator().successors() { - let successor_vec = &mut cache[*successor]; - for i in (0..successor_vec.len()).rev() { - if successor_vec[i] == bb { - successor_vec.swap_remove(i); - break; - } - } - } - } -*/ - self.basic_blocks[bb].terminator_mut() } @@ -245,6 +232,7 @@ impl<'tcx> Body<'tcx> { } #[inline] + /// This will recompute the predecessors cache if it is not available pub fn predecessors(&mut self) -> &IndexVec> { if self.predecessors_cache.is_none() { self.predecessors_cache = Some(self.calculate_predecessors()) diff --git a/src/librustc_mir/transform/ensure_predecessors_cache.rs b/src/librustc_mir/transform/ensure_predecessors_cache.rs new file mode 100644 index 000000000000..ed5b26d7b059 --- /dev/null +++ b/src/librustc_mir/transform/ensure_predecessors_cache.rs @@ -0,0 +1,15 @@ +use rustc::mir::Body; +use rustc::ty::TyCtxt; +use crate::transform::{MirPass, MirSource}; + +pub struct EnsurePredecessorsCache; + +impl<'tcx> MirPass<'tcx> for EnsurePredecessorsCache { + fn run_pass(&self, _: TyCtxt<'tcx>, _: MirSource<'tcx>, body: &mut Body<'tcx>) { + // predecessors is lazily calculated. We want to ensure that the cache is properly filled + // before the next stages of compilation, since thise following stages will only be allowed + // to read the cache and not generate it. If the cache is already up to date, this line is + // a nop. + let _predecessors = body.predecessors(); + } +} diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index 2b2b52971ef0..096fe82ae995 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -20,6 +20,7 @@ pub mod check_unsafety; pub mod simplify_branches; pub mod simplify_try; pub mod simplify; +pub mod ensure_predecessors_cache; pub mod erase_regions; pub mod no_landing_pads; pub mod rustc_peek; @@ -313,6 +314,7 @@ fn run_optimization_passes<'tcx>( &simplify::SimplifyLocals, &add_call_guards::CriticalCallEdges, + &ensure_predecessors_cache::EnsurePredecessorsCache, &dump_mir::Marker("PreCodegen"), ]); }