]> git.lizzy.rs Git - rust.git/commitdiff
rework `MirPass` API to be stateless and extract helper fns
authorNiko Matsakis <niko@alum.mit.edu>
Tue, 25 Apr 2017 22:22:59 +0000 (18:22 -0400)
committerNiko Matsakis <niko@alum.mit.edu>
Tue, 2 May 2017 18:01:00 +0000 (14:01 -0400)
15 files changed:
src/librustc/mir/transform.rs
src/librustc_borrowck/borrowck/mir/elaborate_drops.rs
src/librustc_driver/driver.rs
src/librustc_mir/transform/add_call_guards.rs
src/librustc_mir/transform/copy_prop.rs
src/librustc_mir/transform/deaggregator.rs
src/librustc_mir/transform/dump_mir.rs
src/librustc_mir/transform/erase_regions.rs
src/librustc_mir/transform/inline.rs
src/librustc_mir/transform/instcombine.rs
src/librustc_mir/transform/no_landing_pads.rs
src/librustc_mir/transform/qualify_consts.rs
src/librustc_mir/transform/simplify.rs
src/librustc_mir/transform/simplify_branches.rs
src/librustc_mir/transform/type_check.rs

index 78a3c1919db2996b14ad4276f5be215318f936f9..37113cee4a5ac91664013167a46642572ba310b8 100644 (file)
@@ -10,7 +10,7 @@
 
 use dep_graph::DepNode;
 use hir;
-use hir::def_id::LOCAL_CRATE;
+use hir::def_id::{DefId, LOCAL_CRATE};
 use hir::map::DefPathData;
 use mir::{Mir, Promoted};
 use ty::TyCtxt;
@@ -88,14 +88,14 @@ fn disambiguator<'a>(&'a self) -> Option<Box<fmt::Display+'a>> { None }
 /// A pass which inspects the whole Mir map.
 pub trait MirMapPass<'tcx>: Pass {
     fn run_pass<'a>(
-        &mut self,
+        &self,
         tcx: TyCtxt<'a, 'tcx, 'tcx>,
         hooks: &mut [Box<for<'s> MirPassHook<'s>>]);
 }
 
 pub trait MirPassHook<'tcx>: Pass {
     fn on_mir_pass<'a>(
-        &mut self,
+        &self,
         tcx: TyCtxt<'a, 'tcx, 'tcx>,
         src: MirSource,
         mir: &Mir<'tcx>,
@@ -106,40 +106,58 @@ fn on_mir_pass<'a>(
 
 /// A pass which inspects Mir of functions in isolation.
 pub trait MirPass<'tcx>: Pass {
-    fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    fn run_pass<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     src: MirSource, mir: &mut Mir<'tcx>);
 }
 
 impl<'tcx, T: MirPass<'tcx>> MirMapPass<'tcx> for T {
-    fn run_pass<'a>(&mut self,
+    fn run_pass<'a>(&self,
                     tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     hooks: &mut [Box<for<'s> MirPassHook<'s>>])
     {
         for &def_id in tcx.mir_keys(LOCAL_CRATE).iter() {
-            let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id));
-            let mir = &mut tcx.mir(def_id).borrow_mut();
-            tcx.dep_graph.write(DepNode::Mir(def_id));
+            run_hooks(tcx, hooks, self, false);
+            run_map_pass_task(tcx, self, def_id);
+            run_hooks(tcx, hooks, self, false);
+        }
+    }
+}
 
-            let id = tcx.hir.as_local_node_id(def_id).unwrap();
-            let src = MirSource::from_node(tcx, id);
+fn run_map_pass_task<'a, 'tcx, T: MirPass<'tcx>>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                                                 pass: &T,
+                                                 def_id: DefId) {
+    let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id));
+    let mir = &mut tcx.mir(def_id).borrow_mut();
+    let id = tcx.hir.as_local_node_id(def_id).expect("mir source requires local def-id");
+    let source = MirSource::from_node(tcx, id);
+    MirPass::run_pass(pass, tcx, source, mir);
+
+    for (i, mir) in mir.promoted.iter_enumerated_mut() {
+        let source = MirSource::Promoted(id, i);
+        MirPass::run_pass(pass, tcx, source, mir);
+    }
+}
 
-            for hook in &mut *hooks {
-                hook.on_mir_pass(tcx, src, mir, self, false);
-            }
-            MirPass::run_pass(self, tcx, src, mir);
-            for hook in &mut *hooks {
-                hook.on_mir_pass(tcx, src, mir, self, true);
-            }
+/// Invokes `hooks` on all the MIR that exists. This is read-only, so
+/// new new tasks need to be created.
+pub fn run_hooks<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                           hooks: &mut [Box<for<'s> MirPassHook<'s>>],
+                           pass: &Pass,
+                           is_after: bool)
+{
+    for &def_id in tcx.mir_keys(LOCAL_CRATE).iter() {
+        let mir = tcx.item_mir(def_id);
+        let id = tcx.hir.as_local_node_id(def_id).expect("mir source requires local def-id");
+
+        let source = MirSource::from_node(tcx, id);
+        for hook in &mut *hooks {
+            hook.on_mir_pass(tcx, source, &mir, pass, is_after);
+        }
 
-            for (i, mir) in mir.promoted.iter_enumerated_mut() {
-                let src = MirSource::Promoted(id, i);
-                for hook in &mut *hooks {
-                    hook.on_mir_pass(tcx, src, mir, self, false);
-                }
-                MirPass::run_pass(self, tcx, src, mir);
-                for hook in &mut *hooks {
-                    hook.on_mir_pass(tcx, src, mir, self, true);
-                }
+        for (i, mir) in mir.promoted.iter_enumerated() {
+            let source = MirSource::Promoted(id, i);
+            for hook in &mut *hooks {
+                hook.on_mir_pass(tcx, source, &mir, pass, false);
             }
         }
     }
index ca313622a3afd1928e5f2ffd1210d6a119f0fbc0..106d8fe952d4f4e87264a810988416ca2940fd65 100644 (file)
@@ -33,7 +33,7 @@
 pub struct ElaborateDrops;
 
 impl<'tcx> MirPass<'tcx> for ElaborateDrops {
-    fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    fn run_pass<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     src: MirSource, mir: &mut Mir<'tcx>)
     {
         debug!("elaborate_drops({:?} @ {:?})", src, mir.span);
index aa33d4b55399818240221378260859c068dfdc1f..5d6bc235761cf6609ffff8336fad52b36f9c35f0 100644 (file)
@@ -1056,7 +1056,7 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
         // No lifetime analysis based on borrowing can be done from here on out.
         passes.push_pass(box mir::transform::inline::Inline);
-        passes.push_pass(box mir::transform::instcombine::InstCombine::new());
+        passes.push_pass(box mir::transform::instcombine::InstCombine);
         passes.push_pass(box mir::transform::deaggregator::Deaggregator);
         passes.push_pass(box mir::transform::copy_prop::CopyPropagation);
 
index 80b17c6a008f5902334915c89c4677e99d6c0f82..9e67beb86e65ce6b725b132af3154be230867127 100644 (file)
@@ -36,7 +36,7 @@
  */
 
 impl<'tcx> MirPass<'tcx> for AddCallGuards {
-    fn run_pass<'a>(&mut self, _tcx: TyCtxt<'a, 'tcx, 'tcx>, _src: MirSource, mir: &mut Mir<'tcx>) {
+    fn run_pass<'a>(&self, _tcx: TyCtxt<'a, 'tcx, 'tcx>, _src: MirSource, mir: &mut Mir<'tcx>) {
         add_call_guards(mir);
     }
 }
index 5d127a5aed4618d0c5c76e8380f2eb744e346120..b7cacfe12960d409fcc3345283cea977cf3dc04c 100644 (file)
@@ -41,7 +41,7 @@
 impl Pass for CopyPropagation {}
 
 impl<'tcx> MirPass<'tcx> for CopyPropagation {
-    fn run_pass<'a>(&mut self,
+    fn run_pass<'a>(&self,
                     tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     source: MirSource,
                     mir: &mut Mir<'tcx>) {
index 3a93bef36c5f77c958f21ac9918ac6e15774cbbd..6d91e6fa55b62a3c8e84d894a305304778083fd6 100644 (file)
@@ -18,7 +18,7 @@
 impl Pass for Deaggregator {}
 
 impl<'tcx> MirPass<'tcx> for Deaggregator {
-    fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    fn run_pass<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     source: MirSource, mir: &mut Mir<'tcx>) {
         let node_id = source.item_id();
         let node_path = tcx.item_path_str(tcx.hir.local_def_id(node_id));
index 6895facd6af606be1589d1fbd2e44b1e294b8944..4c6754b88b623fcd9d01aeb849ee6d7dadc78580 100644 (file)
@@ -23,7 +23,7 @@
 pub struct Marker<'a>(pub &'a str);
 
 impl<'b, 'tcx> MirPass<'tcx> for Marker<'b> {
-    fn run_pass<'a>(&mut self, _tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    fn run_pass<'a>(&self, _tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     _src: MirSource, _mir: &mut Mir<'tcx>)
     {}
 }
@@ -52,7 +52,7 @@ fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
 
 impl<'tcx> MirPassHook<'tcx> for DumpMir {
     fn on_mir_pass<'a>(
-        &mut self,
+        &self,
         tcx: TyCtxt<'a, 'tcx, 'tcx>,
         src: MirSource,
         mir: &Mir<'tcx>,
index 5cc5cf297936d3606a90a5f62bd4e7155608c860..05e056ed0be21c40f744ee1799eb0b6d6ee51782 100644 (file)
@@ -72,7 +72,7 @@ fn visit_closure_substs(&mut self,
 impl Pass for EraseRegions {}
 
 impl<'tcx> MirPass<'tcx> for EraseRegions {
-    fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    fn run_pass<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     _: MirSource, mir: &mut Mir<'tcx>) {
         EraseRegionsVisitor::new(tcx).visit_mir(mir);
     }
index fcd5f970882d7fa27d36ad16db532ecf3b2b08b7..b11a3c805f9cc9dfea383646b5f91e9447280755 100644 (file)
@@ -18,7 +18,7 @@
 
 use rustc::dep_graph::DepNode;
 use rustc::mir::*;
-use rustc::mir::transform::{MirMapPass, MirPassHook, MirSource, Pass};
+use rustc::mir::transform::{self, MirMapPass, MirPassHook, MirSource, Pass};
 use rustc::mir::visit::*;
 use rustc::traits;
 use rustc::ty::{self, Ty, TyCtxt};
@@ -44,7 +44,7 @@
 
 impl<'tcx> MirMapPass<'tcx> for Inline {
     fn run_pass<'a>(
-        &mut self,
+        &self,
         tcx: TyCtxt<'a, 'tcx, 'tcx>,
         hooks: &mut [Box<for<'s> MirPassHook<'s>>]) {
 
@@ -58,33 +58,13 @@ fn run_pass<'a>(
             tcx: tcx,
         };
 
-        for &def_id in tcx.mir_keys(LOCAL_CRATE).iter() {
-            let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id));
-            let mir = &tcx.item_mir(def_id);
-
-            let id = tcx.hir.as_local_node_id(def_id).unwrap();
-            let src = MirSource::from_node(tcx, id);
-
-            for hook in &mut *hooks {
-                hook.on_mir_pass(tcx, src, mir, self, false);
-            }
-        }
+        transform::run_hooks(tcx, hooks, self, false);
 
         for scc in callgraph.scc_iter() {
             inliner.inline_scc(&callgraph, &scc);
         }
 
-        for &def_id in tcx.mir_keys(LOCAL_CRATE).iter() {
-            let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id));
-            let mir = &tcx.item_mir(def_id);
-
-            let id = tcx.hir.as_local_node_id(def_id).unwrap();
-            let src = MirSource::from_node(tcx, id);
-
-            for hook in &mut *hooks {
-                hook.on_mir_pass(tcx, src, mir, self, true);
-            }
-        }
+        transform::run_hooks(tcx, hooks, self, true);
     }
 }
 
index 3f6abb31fe9d9c78e01e5e6afca46db00c3b3e38..89ac0762fbf59e8e8fb5be5710cbb036c1ec8fb9 100644 (file)
 use rustc_data_structures::indexed_vec::Idx;
 use std::mem;
 
-pub struct InstCombine {
-    optimizations: OptimizationList,
-}
-
-impl InstCombine {
-    pub fn new() -> InstCombine {
-        InstCombine {
-            optimizations: OptimizationList::default(),
-        }
-    }
-}
+pub struct InstCombine;
 
 impl Pass for InstCombine {}
 
 impl<'tcx> MirPass<'tcx> for InstCombine {
-    fn run_pass<'a>(&mut self,
+    fn run_pass<'a>(&self,
                     tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     _: MirSource,
                     mir: &mut Mir<'tcx>) {
@@ -45,18 +35,22 @@ fn run_pass<'a>(&mut self,
         // First, find optimization opportunities. This is done in a pre-pass to keep the MIR
         // read-only so that we can do global analyses on the MIR in the process (e.g.
         // `Lvalue::ty()`).
-        {
+        let optimizations = {
             let mut optimization_finder = OptimizationFinder::new(mir, tcx);
             optimization_finder.visit_mir(mir);
-            self.optimizations = optimization_finder.optimizations
-        }
+            optimization_finder.optimizations
+        };
 
         // Then carry out those optimizations.
-        MutVisitor::visit_mir(&mut *self, mir);
+        MutVisitor::visit_mir(&mut InstCombineVisitor { optimizations }, mir);
     }
 }
 
-impl<'tcx> MutVisitor<'tcx> for InstCombine {
+pub struct InstCombineVisitor {
+    optimizations: OptimizationList,
+}
+
+impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor {
     fn visit_rvalue(&mut self, rvalue: &mut Rvalue<'tcx>, location: Location) {
         if self.optimizations.and_stars.remove(&location) {
             debug!("Replacing `&*`: {:?}", rvalue);
index 3654ae6940c5257b11cf9ae37ed81d8f430b159a..264b2ea4bb923db048da1d4e963f28bd99e9d86d 100644 (file)
@@ -49,7 +49,7 @@ pub fn no_landing_pads<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, mir: &mut Mir<'tcx
 }
 
 impl<'tcx> MirPass<'tcx> for NoLandingPads {
-    fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    fn run_pass<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     _: MirSource, mir: &mut Mir<'tcx>) {
         no_landing_pads(tcx, mir)
     }
index f566229529676fe6d7543fb638a1e729a149b4a2..e0948b75f27ba5035cbefc8e7e84906d06a0c9fb 100644 (file)
@@ -942,7 +942,7 @@ fn qualify_const_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 impl Pass for QualifyAndPromoteConstants {}
 
 impl<'tcx> MirMapPass<'tcx> for QualifyAndPromoteConstants {
-    fn run_pass<'a>(&mut self,
+    fn run_pass<'a>(&self,
                     tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     hooks: &mut [Box<for<'s> MirPassHook<'s>>])
     {
@@ -971,7 +971,7 @@ fn run_pass<'a>(&mut self,
 }
 
 impl<'tcx> QualifyAndPromoteConstants {
-    fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    fn run_pass<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     src: MirSource, mir: &mut Mir<'tcx>) {
         let id = src.item_id();
         let def_id = tcx.hir.local_def_id(id);
index ef7990653ba982cc8de8319fad9e9401d1729535..0881585ddfe7462c5ac36f13c2713e65233858d1 100644 (file)
@@ -62,7 +62,7 @@ pub fn simplify_cfg(mir: &mut Mir) {
 }
 
 impl<'l, 'tcx> MirPass<'tcx> for SimplifyCfg<'l> {
-    fn run_pass<'a>(&mut self, _tcx: TyCtxt<'a, 'tcx, 'tcx>, _src: MirSource, mir: &mut Mir<'tcx>) {
+    fn run_pass<'a>(&self, _tcx: TyCtxt<'a, 'tcx, 'tcx>, _src: MirSource, mir: &mut Mir<'tcx>) {
         debug!("SimplifyCfg({:?}) - simplifying {:?}", self.label, mir);
         simplify_cfg(mir);
     }
@@ -320,7 +320,7 @@ fn name(&self) -> ::std::borrow::Cow<'static, str> { "SimplifyLocals".into() }
 }
 
 impl<'tcx> MirPass<'tcx> for SimplifyLocals {
-    fn run_pass<'a>(&mut self, _: TyCtxt<'a, 'tcx, 'tcx>, _: MirSource, mir: &mut Mir<'tcx>) {
+    fn run_pass<'a>(&self, _: TyCtxt<'a, 'tcx, 'tcx>, _: MirSource, mir: &mut Mir<'tcx>) {
         let mut marker = DeclMarker { locals: BitVector::new(mir.local_decls.len()) };
         marker.visit_mir(mir);
         // Return pointer and arguments are always live
index 3d5106c4b06f7bd4d7f43ed332e106a28be35625..b16ee65e918c587900c7e1ad87e4f92ed9968d64 100644 (file)
@@ -26,7 +26,7 @@ pub fn new(label: &'a str) -> Self {
 }
 
 impl<'l, 'tcx> MirPass<'tcx> for SimplifyBranches<'l> {
-    fn run_pass<'a>(&mut self, _tcx: TyCtxt<'a, 'tcx, 'tcx>, _src: MirSource, mir: &mut Mir<'tcx>) {
+    fn run_pass<'a>(&self, _tcx: TyCtxt<'a, 'tcx, 'tcx>, _src: MirSource, mir: &mut Mir<'tcx>) {
         for block in mir.basic_blocks_mut() {
             let terminator = block.terminator_mut();
             terminator.kind = match terminator.kind {
index d2e4c1a9649838f3fd1cb5b2d948fff1fedb49a1..02e34fd7998ce4fbb211a50028eaf002af59516c 100644 (file)
@@ -738,7 +738,7 @@ pub fn new() -> Self {
 }
 
 impl<'tcx> MirPass<'tcx> for TypeckMir {
-    fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
+    fn run_pass<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     src: MirSource, mir: &mut Mir<'tcx>) {
         let item_id = src.item_id();
         let def_id = tcx.hir.local_def_id(item_id);