about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2017-04-27 11:46:17 -0400
committerNiko Matsakis <niko@alum.mit.edu>2017-05-02 14:01:01 -0400
commite9e6ccc042696e3334abff8319e769cbffa3ede8 (patch)
treefc92d314fe727d53e5e80907db6aff1434fbc7f8 /src
parent46b342fbc03664566d65e1b3248f89cbef93ef4c (diff)
downloadrust-e9e6ccc042696e3334abff8319e769cbffa3ede8.tar.gz
rust-e9e6ccc042696e3334abff8319e769cbffa3ede8.zip
introduce `DefIdPass` and remove all impls of `Pass` but `Inline`
Diffstat (limited to 'src')
-rw-r--r--src/librustc/mir/transform.rs80
-rw-r--r--src/librustc/ty/maps.rs2
-rw-r--r--src/librustc_driver/driver.rs44
-rw-r--r--src/librustc_mir/transform/dump_mir.rs8
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs33
5 files changed, 96 insertions, 71 deletions
diff --git a/src/librustc/mir/transform.rs b/src/librustc/mir/transform.rs
index 89f2fb59d51..14ad413c538 100644
--- a/src/librustc/mir/transform.rs
+++ b/src/librustc/mir/transform.rs
@@ -8,12 +8,12 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use dep_graph::DepNode;
 use hir;
 use hir::def_id::{DefId, LOCAL_CRATE};
 use hir::map::DefPathData;
 use mir::{Mir, Promoted};
 use ty::TyCtxt;
+use std::rc::Rc;
 use syntax::ast::NodeId;
 use util::common::time;
 
@@ -99,51 +99,77 @@ pub trait PassHook {
 }
 
 /// A streamlined trait that you can implement to create a pass; the
-/// pass will be named after the type, and it will consist of a main
-/// loop that goes over each available MIR and applies `run_pass`.
-pub trait MirPass {
+/// pass will be invoked to process the MIR with the given `def_id`.
+/// This lets you do things before we fetch the MIR itself.  You may
+/// prefer `MirPass`.
+pub trait DefIdPass {
     fn name<'a>(&'a self) -> Cow<'a, str> {
         default_name::<Self>()
     }
 
     fn run_pass<'a, 'tcx>(&self,
                           tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                          src: MirSource,
-                          mir: &mut Mir<'tcx>);
+                          def_id: DefId);
 }
 
-impl<T: MirPass> Pass for T {
+impl<T: DefIdPass> Pass for T {
     fn name<'a>(&'a self) -> Cow<'a, str> {
-        MirPass::name(self)
+        DefIdPass::name(self)
     }
 
     fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) {
         for &def_id in tcx.mir_keys(LOCAL_CRATE).iter() {
-            run_map_pass_task(tcx, self, def_id);
+            DefIdPass::run_pass(self, tcx, def_id);
         }
     }
 }
 
-fn run_map_pass_task<'a, 'tcx, T: MirPass>(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();
+/// A streamlined trait that you can implement to create a pass; the
+/// pass will be named after the type, and it will consist of a main
+/// loop that goes over each available MIR and applies `run_pass`.
+pub trait MirPass: DepGraphSafe {
+    fn name<'a>(&'a self) -> Cow<'a, str> {
+        default_name::<Self>()
+    }
+
+    fn run_pass<'a, 'tcx>(&self,
+                          tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                          source: MirSource,
+                          mir: &mut Mir<'tcx>);
+}
+
+fn for_each_assoc_mir<'a, 'tcx, OP>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                                    def_id: DefId,
+                                    mut op: OP)
+    where OP: FnMut(MirSource, &mut Mir<'tcx>)
+{
     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);
+    let mir = &mut tcx.mir(def_id).borrow_mut();
+    op(source, mir);
+
+    for (promoted_index, promoted_mir) in mir.promoted.iter_enumerated_mut() {
+        let promoted_source = MirSource::Promoted(id, promoted_index);
+        op(promoted_source, promoted_mir);
+    }
+}
+
+impl<T: MirPass> DefIdPass for T {
+    fn name<'a>(&'a self) -> Cow<'a, str> {
+        MirPass::name(self)
+    }
 
-    for (i, mir) in mir.promoted.iter_enumerated_mut() {
-        let source = MirSource::Promoted(id, i);
-        MirPass::run_pass(pass, tcx, source, mir);
+    fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) {
+        for_each_assoc_mir(tcx, def_id, |src, mir| MirPass::run_pass(self, tcx, src, mir));
     }
 }
 
 /// A manager for MIR passes.
+#[derive(Clone)]
 pub struct Passes {
-    passes: Vec<Box<Pass>>,
-    pass_hooks: Vec<Box<PassHook>>,
-    plugin_passes: Vec<Box<Pass>>
+    passes: Vec<Rc<Pass>>,
+    pass_hooks: Vec<Rc<PassHook>>,
+    plugin_passes: Vec<Rc<Pass>>
 }
 
 impl<'a, 'tcx> Passes {
@@ -172,19 +198,19 @@ impl<'a, 'tcx> Passes {
     }
 
     /// Pushes a built-in pass.
-    pub fn push_pass(&mut self, pass: Box<Pass>) {
-        self.passes.push(pass);
+    pub fn push_pass<T: Pass + 'static>(&mut self, pass: T) {
+        self.passes.push(Rc::new(pass));
     }
 
     /// Pushes a pass hook.
-    pub fn push_hook(&mut self, hook: Box<PassHook>) {
-        self.pass_hooks.push(hook);
+    pub fn push_hook<T: PassHook + 'static>(&mut self, hook: T) {
+        self.pass_hooks.push(Rc::new(hook));
     }
 }
 
 /// Copies the plugin passes.
-impl ::std::iter::Extend<Box<Pass>> for Passes {
-    fn extend<I: IntoIterator<Item=Box<Pass>>>(&mut self, it: I) {
+impl ::std::iter::Extend<Rc<Pass>> for Passes {
+    fn extend<I: IntoIterator<Item=Rc<Pass>>>(&mut self, it: I) {
         self.plugin_passes.extend(it);
     }
 }
diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs
index ba475367bc6..a9deb52efb6 100644
--- a/src/librustc/ty/maps.rs
+++ b/src/librustc/ty/maps.rs
@@ -549,7 +549,7 @@ define_maps! { <'tcx>
     ///
     /// Note that cross-crate MIR appears to be always borrowed
     /// (in the `RefCell` sense) to prevent accidental mutation.
-    [pub] mir: Mir(DefId) -> &'tcx RefCell<mir::Mir<'tcx>>,
+    [] mir: Mir(DefId) -> &'tcx RefCell<mir::Mir<'tcx>>,
 
     /// Set of all the def-ids in this crate that have MIR associated with
     /// them. This includes all the body owners, but also things like struct
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index 64fb2168ca1..be344176fd2 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -975,12 +975,12 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
             // Push all the built-in validation passes.
             // NB: if you’re adding an *optimisation* it ought to go to another set of passes
             // in stage 4 below.
-            passes.push_hook(box mir::transform::dump_mir::DumpMir);
-            passes.push_pass(box mir::transform::simplify::SimplifyCfg::new("initial"));
-            passes.push_pass(box mir::transform::type_check::TypeckMir);
-            passes.push_pass(box mir::transform::qualify_consts::QualifyAndPromoteConstants);
-            passes.push_pass(box mir::transform::simplify_branches::SimplifyBranches::new("initial"));
-            passes.push_pass(box mir::transform::simplify::SimplifyCfg::new("qualify-consts"));
+            passes.push_hook(mir::transform::dump_mir::DumpMir);
+            passes.push_pass(mir::transform::simplify::SimplifyCfg::new("initial"));
+            passes.push_pass(mir::transform::type_check::TypeckMir);
+            passes.push_pass(mir::transform::qualify_consts::QualifyAndPromoteConstants);
+            passes.push_pass(mir::transform::simplify_branches::SimplifyBranches::new("initial"));
+            passes.push_pass(mir::transform::simplify::SimplifyCfg::new("qualify-consts"));
             // And run everything.
             passes.run_passes(tcx);
         });
@@ -1041,27 +1041,27 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     // code.
     time(time_passes, "MIR optimisations", || {
         let mut passes = ::rustc::mir::transform::Passes::new();
-        passes.push_hook(box mir::transform::dump_mir::DumpMir);
-        passes.push_pass(box mir::transform::no_landing_pads::NoLandingPads);
-        passes.push_pass(box mir::transform::simplify::SimplifyCfg::new("no-landing-pads"));
+        passes.push_hook(mir::transform::dump_mir::DumpMir);
+        passes.push_pass(mir::transform::no_landing_pads::NoLandingPads);
+        passes.push_pass(mir::transform::simplify::SimplifyCfg::new("no-landing-pads"));
 
         // From here on out, regions are gone.
-        passes.push_pass(box mir::transform::erase_regions::EraseRegions);
+        passes.push_pass(mir::transform::erase_regions::EraseRegions);
 
-        passes.push_pass(box mir::transform::add_call_guards::AddCallGuards);
-        passes.push_pass(box borrowck::ElaborateDrops);
-        passes.push_pass(box mir::transform::no_landing_pads::NoLandingPads);
-        passes.push_pass(box mir::transform::simplify::SimplifyCfg::new("elaborate-drops"));
+        passes.push_pass(mir::transform::add_call_guards::AddCallGuards);
+        passes.push_pass(borrowck::ElaborateDrops);
+        passes.push_pass(mir::transform::no_landing_pads::NoLandingPads);
+        passes.push_pass(mir::transform::simplify::SimplifyCfg::new("elaborate-drops"));
 
         // 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);
-        passes.push_pass(box mir::transform::deaggregator::Deaggregator);
-        passes.push_pass(box mir::transform::copy_prop::CopyPropagation);
-
-        passes.push_pass(box mir::transform::simplify::SimplifyLocals);
-        passes.push_pass(box mir::transform::add_call_guards::AddCallGuards);
-        passes.push_pass(box mir::transform::dump_mir::Marker("PreTrans"));
+        passes.push_pass(mir::transform::inline::Inline);
+        passes.push_pass(mir::transform::instcombine::InstCombine);
+        passes.push_pass(mir::transform::deaggregator::Deaggregator);
+        passes.push_pass(mir::transform::copy_prop::CopyPropagation);
+
+        passes.push_pass(mir::transform::simplify::SimplifyLocals);
+        passes.push_pass(mir::transform::add_call_guards::AddCallGuards);
+        passes.push_pass(mir::transform::dump_mir::Marker("PreTrans"));
 
         passes.run_passes(tcx);
     });
diff --git a/src/librustc_mir/transform/dump_mir.rs b/src/librustc_mir/transform/dump_mir.rs
index 528afd184c6..43fb0acf2dd 100644
--- a/src/librustc_mir/transform/dump_mir.rs
+++ b/src/librustc_mir/transform/dump_mir.rs
@@ -15,20 +15,20 @@ use std::fmt;
 use std::fs::File;
 use std::io;
 
-use rustc::hir::def_id::LOCAL_CRATE;
+use rustc::hir::def_id::{DefId, LOCAL_CRATE};
 use rustc::session::config::{OutputFilenames, OutputType};
 use rustc::ty::TyCtxt;
-use rustc::mir::transform::{Pass, PassHook, MirSource};
+use rustc::mir::transform::{DefIdPass, Pass, PassHook, MirSource};
 use util as mir_util;
 
 pub struct Marker(pub &'static str);
 
-impl Pass for Marker {
+impl DefIdPass for Marker {
     fn name<'a>(&'a self) -> Cow<'a, str> {
         Cow::Borrowed(self.0)
     }
 
-    fn run_pass<'a, 'tcx>(&self, _tcx: TyCtxt<'a, 'tcx, 'tcx>) {
+    fn run_pass<'a, 'tcx>(&self, _: TyCtxt<'a, 'tcx, 'tcx>, _: DefId) {
         // no-op
     }
 }
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 7e7e85f2ec9..80ec83fcaef 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -19,7 +19,7 @@ use rustc_data_structures::indexed_vec::{IndexVec, Idx};
 use rustc::dep_graph::DepNode;
 use rustc::hir;
 use rustc::hir::map as hir_map;
-use rustc::hir::def_id::{DefId, LOCAL_CRATE};
+use rustc::hir::def_id::DefId;
 use rustc::hir::map::blocks::FnLikeNode;
 use rustc::traits::{self, Reveal};
 use rustc::ty::{self, TyCtxt, Ty, TypeFoldable};
@@ -27,7 +27,7 @@ use rustc::ty::cast::CastTy;
 use rustc::ty::maps::Providers;
 use rustc::mir::*;
 use rustc::mir::traversal::ReversePostorder;
-use rustc::mir::transform::{Pass, MirSource};
+use rustc::mir::transform::{DefIdPass, MirSource};
 use rustc::mir::visit::{LvalueContext, Visitor};
 use rustc::middle::lang_items;
 use syntax::abi::Abi;
@@ -939,25 +939,24 @@ fn qualify_const_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
 pub struct QualifyAndPromoteConstants;
 
-impl Pass for QualifyAndPromoteConstants {
+impl DefIdPass for QualifyAndPromoteConstants {
     fn run_pass<'a, 'tcx>(&self,
-                          tcx: TyCtxt<'a, 'tcx, 'tcx>)
+                          tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                          def_id: DefId)
     {
-        for &def_id in tcx.mir_keys(LOCAL_CRATE).iter() {
-            let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id));
-            let id = tcx.hir.as_local_node_id(def_id).unwrap();
-            let src = MirSource::from_node(tcx, id);
-
-            if let MirSource::Const(_) = src {
-                tcx.mir_const_qualif(def_id);
-                continue;
-            }
-
-            let mir = &mut tcx.mir(def_id).borrow_mut();
-            tcx.dep_graph.write(DepNode::Mir(def_id));
+        let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id));
+        let id = tcx.hir.as_local_node_id(def_id).unwrap();
+        let src = MirSource::from_node(tcx, id);
 
-            self.run_pass(tcx, src, mir);
+        if let MirSource::Const(_) = src {
+            tcx.mir_const_qualif(def_id);
+            return;
         }
+
+        let mir = &mut tcx.mir(def_id).borrow_mut();
+        tcx.dep_graph.write(DepNode::Mir(def_id));
+
+        self.run_pass(tcx, src, mir);
     }
 }