about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2017-04-25 18:22:59 -0400
committerNiko Matsakis <niko@alum.mit.edu>2017-05-02 14:01:00 -0400
commit11b6b0663ae0a89eea913f44aa1eb859b0ef0d3a (patch)
treec5e207568d583d81f98e3e182e700bad32dadb5a
parent0e5e2f36345fbf44c72c60fda0929aceba5d74dd (diff)
downloadrust-11b6b0663ae0a89eea913f44aa1eb859b0ef0d3a.tar.gz
rust-11b6b0663ae0a89eea913f44aa1eb859b0ef0d3a.zip
rework `MirPass` API to be stateless and extract helper fns
-rw-r--r--src/librustc/mir/transform.rs70
-rw-r--r--src/librustc_borrowck/borrowck/mir/elaborate_drops.rs2
-rw-r--r--src/librustc_driver/driver.rs2
-rw-r--r--src/librustc_mir/transform/add_call_guards.rs2
-rw-r--r--src/librustc_mir/transform/copy_prop.rs2
-rw-r--r--src/librustc_mir/transform/deaggregator.rs2
-rw-r--r--src/librustc_mir/transform/dump_mir.rs4
-rw-r--r--src/librustc_mir/transform/erase_regions.rs2
-rw-r--r--src/librustc_mir/transform/inline.rs28
-rw-r--r--src/librustc_mir/transform/instcombine.rs28
-rw-r--r--src/librustc_mir/transform/no_landing_pads.rs2
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs4
-rw-r--r--src/librustc_mir/transform/simplify.rs4
-rw-r--r--src/librustc_mir/transform/simplify_branches.rs2
-rw-r--r--src/librustc_mir/transform/type_check.rs2
15 files changed, 74 insertions, 82 deletions
diff --git a/src/librustc/mir/transform.rs b/src/librustc/mir/transform.rs
index 78a3c1919db..37113cee4a5 100644
--- a/src/librustc/mir/transform.rs
+++ b/src/librustc/mir/transform.rs
@@ -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 @@ pub trait Pass {
 /// 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 @@ pub trait MirPassHook<'tcx>: Pass {
 
 /// 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);
             }
         }
     }
diff --git a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs
index ca313622a3a..106d8fe952d 100644
--- a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs
+++ b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs
@@ -33,7 +33,7 @@ use std::u32;
 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);
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index aa33d4b5539..5d6bc235761 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -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);
 
diff --git a/src/librustc_mir/transform/add_call_guards.rs b/src/librustc_mir/transform/add_call_guards.rs
index 80b17c6a008..9e67beb86e6 100644
--- a/src/librustc_mir/transform/add_call_guards.rs
+++ b/src/librustc_mir/transform/add_call_guards.rs
@@ -36,7 +36,7 @@ pub struct AddCallGuards;
  */
 
 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);
     }
 }
diff --git a/src/librustc_mir/transform/copy_prop.rs b/src/librustc_mir/transform/copy_prop.rs
index 5d127a5aed4..b7cacfe1296 100644
--- a/src/librustc_mir/transform/copy_prop.rs
+++ b/src/librustc_mir/transform/copy_prop.rs
@@ -41,7 +41,7 @@ pub struct CopyPropagation;
 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>) {
diff --git a/src/librustc_mir/transform/deaggregator.rs b/src/librustc_mir/transform/deaggregator.rs
index 3a93bef36c5..6d91e6fa55b 100644
--- a/src/librustc_mir/transform/deaggregator.rs
+++ b/src/librustc_mir/transform/deaggregator.rs
@@ -18,7 +18,7 @@ pub struct Deaggregator;
 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));
diff --git a/src/librustc_mir/transform/dump_mir.rs b/src/librustc_mir/transform/dump_mir.rs
index 6895facd6af..4c6754b88b6 100644
--- a/src/librustc_mir/transform/dump_mir.rs
+++ b/src/librustc_mir/transform/dump_mir.rs
@@ -23,7 +23,7 @@ use util as mir_util;
 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 @@ pub struct DumpMir;
 
 impl<'tcx> MirPassHook<'tcx> for DumpMir {
     fn on_mir_pass<'a>(
-        &mut self,
+        &self,
         tcx: TyCtxt<'a, 'tcx, 'tcx>,
         src: MirSource,
         mir: &Mir<'tcx>,
diff --git a/src/librustc_mir/transform/erase_regions.rs b/src/librustc_mir/transform/erase_regions.rs
index 5cc5cf29793..05e056ed0be 100644
--- a/src/librustc_mir/transform/erase_regions.rs
+++ b/src/librustc_mir/transform/erase_regions.rs
@@ -72,7 +72,7 @@ pub struct EraseRegions;
 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);
     }
diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs
index fcd5f970882..b11a3c805f9 100644
--- a/src/librustc_mir/transform/inline.rs
+++ b/src/librustc_mir/transform/inline.rs
@@ -18,7 +18,7 @@ use rustc_data_structures::graph;
 
 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 @@ pub struct Inline;
 
 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 @@ impl<'tcx> MirMapPass<'tcx> for Inline {
             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);
     }
 }
 
diff --git a/src/librustc_mir/transform/instcombine.rs b/src/librustc_mir/transform/instcombine.rs
index 3f6abb31fe9..89ac0762fbf 100644
--- a/src/librustc_mir/transform/instcombine.rs
+++ b/src/librustc_mir/transform/instcombine.rs
@@ -18,22 +18,12 @@ use rustc::util::nodemap::FxHashSet;
 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 @@ impl<'tcx> MirPass<'tcx> for InstCombine {
         // 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);
diff --git a/src/librustc_mir/transform/no_landing_pads.rs b/src/librustc_mir/transform/no_landing_pads.rs
index 3654ae6940c..264b2ea4bb9 100644
--- a/src/librustc_mir/transform/no_landing_pads.rs
+++ b/src/librustc_mir/transform/no_landing_pads.rs
@@ -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)
     }
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index f5662295296..e0948b75f27 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -942,7 +942,7 @@ pub struct QualifyAndPromoteConstants;
 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 @@ impl<'tcx> MirMapPass<'tcx> for QualifyAndPromoteConstants {
 }
 
 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);
diff --git a/src/librustc_mir/transform/simplify.rs b/src/librustc_mir/transform/simplify.rs
index ef7990653ba..0881585ddfe 100644
--- a/src/librustc_mir/transform/simplify.rs
+++ b/src/librustc_mir/transform/simplify.rs
@@ -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 @@ impl Pass for SimplifyLocals {
 }
 
 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
diff --git a/src/librustc_mir/transform/simplify_branches.rs b/src/librustc_mir/transform/simplify_branches.rs
index 3d5106c4b06..b16ee65e918 100644
--- a/src/librustc_mir/transform/simplify_branches.rs
+++ b/src/librustc_mir/transform/simplify_branches.rs
@@ -26,7 +26,7 @@ impl<'a> SimplifyBranches<'a> {
 }
 
 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 {
diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs
index d2e4c1a9649..02e34fd7998 100644
--- a/src/librustc_mir/transform/type_check.rs
+++ b/src/librustc_mir/transform/type_check.rs
@@ -738,7 +738,7 @@ impl TypeckMir {
 }
 
 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);