]> git.lizzy.rs Git - rust.git/commitdiff
simplify down to one query per pass suite
authorNiko Matsakis <niko@alum.mit.edu>
Mon, 1 May 2017 18:39:48 +0000 (14:39 -0400)
committerNiko Matsakis <niko@alum.mit.edu>
Tue, 2 May 2017 20:21:55 +0000 (16:21 -0400)
src/librustc/mir/transform.rs
src/librustc/ty/maps.rs
src/librustc_mir/build/mod.rs
src/librustc_mir/queries.rs
src/librustc_mir/transform/mod.rs
src/librustc_mir/transform/qualify_consts.rs

index df6f98297d0222ab2c27c5d334b31a9113213ec6..77d4eefb1def5602e58f74d274708fe093156ac2 100644 (file)
@@ -37,6 +37,11 @@ pub enum MirSource {
 }
 
 impl<'a, 'tcx> MirSource {
+    pub fn from_local_def_id(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> MirSource {
+        let id = tcx.hir.as_local_node_id(def_id).expect("mir source requires local def-id");
+        Self::from_node(tcx, id)
+    }
+
     pub fn from_node(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: NodeId) -> MirSource {
         use hir::*;
 
@@ -169,12 +174,8 @@ pub fn push_hook<T: PassHook + 'static>(&mut self, hook: T) {
         self.pass_hooks.push(Rc::new(hook));
     }
 
-    pub fn len_passes(&self, suite: MirSuite) -> usize {
-        self.suites[suite.0].len()
-    }
-
-    pub fn pass(&self, suite: MirSuite, pass: MirPassIndex) -> &MirPass {
-        &*self.suites[suite.0][pass.0]
+    pub fn passes(&self, suite: MirSuite) -> &[Rc<MirPass>] {
+        &self.suites[suite.0]
     }
 
     pub fn hooks(&self) -> &[Rc<PassHook>] {
index b3ca61550d7c3e373d1b68bcdc5a088e7964a912..5a5dece8a94ec5163f6fbc4c289daa833c13aa84 100644 (file)
@@ -404,18 +404,6 @@ fn describe(tcx: TyCtxt, def_id: DefId) -> String {
     }
 }
 
-impl<'tcx> QueryDescription for queries::mir_suite<'tcx> {
-    fn describe(_: TyCtxt, (suite, _): (MirSuite, DefId)) -> String {
-        format!("MIR suite #{}.*", suite.0)
-    }
-}
-
-impl<'tcx> QueryDescription for queries::mir_pass<'tcx> {
-    fn describe(_: TyCtxt, (suite, pass_num, _): (MirSuite, MirPassIndex, DefId)) -> String {
-        format!("MIR pass #{}.{}", suite.0, pass_num.0)
-    }
-}
-
 macro_rules! define_maps {
     (<$tcx:tt>
      $($(#[$attr:meta])*
@@ -798,27 +786,13 @@ fn default() -> Self {
     /// the value isn't known except to the pass itself.
     [] mir_const_qualif: Mir(DefId) -> u8,
 
-    /// Performs the initial MIR construction. You almost certainly do not
-    /// want to use this query, because its output is intended to be stolen
-    /// immediately by the MIR passes below. Consider `optimized_mir` instead.
+    /// Fetch the MIR for a given def-id up till the point where it is
+    /// ready for const evaluation.
     ///
     /// See the README for the `mir` module for details.
-    [] mir_build: Mir(DefId) -> &'tcx Steal<mir::Mir<'tcx>>,
+    [] mir_const: Mir(DefId) -> &'tcx Steal<mir::Mir<'tcx>>,
 
-    /// Fetch the MIR for a given def-id after the given set of passes has ben
-    /// applied to it. This is mostly an "intermediate" query. Normally, you would
-    /// prefer to use `optimized_mir(def_id)`, which will fetch the MIR after all
-    /// optimizations and so forth.
-    ///
-    /// See the README for the `mir` module for details.
-    [] mir_suite: mir_suite((MirSuite, DefId)) -> &'tcx Steal<mir::Mir<'tcx>>,
-
-    /// Fetch the MIR for a given def-id after a given pass has been executed. This is
-    /// **only** intended to be used by the `mir_suite` provider -- if you are using it
-    /// manually, you're doing it wrong.
-    ///
-    /// See the README for the `mir` module for details.
-    [] mir_pass: mir_pass((MirSuite, MirPassIndex, DefId)) -> &'tcx Steal<mir::Mir<'tcx>>,
+    [] mir_validated: Mir(DefId) -> &'tcx Steal<mir::Mir<'tcx>>,
 
     /// MIR after our optimization passes have run. This is MIR that is ready
     /// for trans. This is also the only query that can fetch non-local MIR, at present.
@@ -921,11 +895,3 @@ fn const_eval_dep_node((def_id, _): (DefId, &Substs)) -> DepNode<DefId> {
 fn mir_keys(_: CrateNum) -> DepNode<DefId> {
     DepNode::MirKeys
 }
-
-fn mir_suite((_suite, def_id): (MirSuite, DefId)) -> DepNode<DefId> {
-    DepNode::Mir(def_id)
-}
-
-fn mir_pass((_suite, _pass_num, def_id): (MirSuite, MirPassIndex, DefId)) -> DepNode<DefId> {
-    DepNode::Mir(def_id)
-}
index f5f6c307b152a1d6a52b8e1628dcd632551c153c..8c057b02df2bf35c07c81dd550669a2ecbd82227 100644 (file)
@@ -20,7 +20,6 @@
 use rustc::mir::visit::MutVisitor;
 use rustc::traits::Reveal;
 use rustc::ty::{self, Ty, TyCtxt};
-use rustc::ty::steal::Steal;
 use rustc::ty::subst::Substs;
 use rustc::util::nodemap::NodeMap;
 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
@@ -33,7 +32,8 @@
 use syntax_pos::Span;
 use util as mir_util;
 
-pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Steal<Mir<'tcx>> {
+/// Construct the MIR for a given def-id.
+pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Mir<'tcx> {
     let id = tcx.hir.as_local_node_id(def_id).unwrap();
     let unsupported = || {
         span_bug!(tcx.hir.span(id), "can't build MIR for {:?}", def_id);
@@ -131,7 +131,7 @@ pub fn mir_build<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx
 
         mir_util::dump_mir(tcx, None, "mir_map", &0, src, &mir);
 
-        tcx.alloc_steal_mir(mir)
+        mir
     })
 }
 
@@ -168,7 +168,7 @@ fn visit_substs(&mut self, substs: &mut &'tcx Substs<'tcx>) {
 fn create_constructor_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                      ctor_id: ast::NodeId,
                                      v: &'tcx hir::VariantData)
-                                     -> &'tcx Steal<Mir<'tcx>>
+                                     -> Mir<'tcx>
 {
     let span = tcx.hir.span(ctor_id);
     if let hir::VariantData::Tuple(ref fields, ctor_id) = *v {
@@ -190,7 +190,7 @@ fn create_constructor_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
             mir_util::dump_mir(tcx, None, "mir_map", &0, src, &mir);
 
-            tcx.alloc_steal_mir(mir)
+            mir
         })
     } else {
         span_bug!(span, "attempting to create MIR for non-tuple variant {:?}", v);
index aef637fed5ee0983c3db1ebf231785a2fdd09eed..980663ec675858ed7067bcaed4a672417fe04527 100644 (file)
 //! - `#[rustc_mir(graphviz="file.gv")]`
 //! - `#[rustc_mir(pretty="file.mir")]`
 
-use rustc::hir::def_id::{CrateNum, LOCAL_CRATE};
-
-use rustc::ty::TyCtxt;
+use build;
+use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
+use rustc::mir::Mir;
+use rustc::mir::transform::{MirSource, MIR_CONST, MIR_VALIDATED, MIR_OPTIMIZED};
+use rustc::ty::{self, TyCtxt};
 use rustc::ty::maps::Providers;
+use rustc::ty::steal::Steal;
 use rustc::hir;
 use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
 use rustc::util::nodemap::DefIdSet;
 use syntax::ast;
-use syntax_pos::Span;
+use syntax_pos::{DUMMY_SP, Span};
+use transform;
 
 use std::rc::Rc;
 
 pub fn provide(providers: &mut Providers) {
-    use build::mir_build;
     *providers = Providers {
-        mir_build,
         mir_keys,
+        mir_const,
+        mir_validated,
+        optimized_mir,
         ..*providers
     };
 }
 
+/// Finds the full set of def-ids within the current crate that have
+/// MIR associated with them.
 fn mir_keys<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, krate: CrateNum)
                       -> Rc<DefIdSet> {
     assert_eq!(krate, LOCAL_CRATE);
@@ -75,3 +82,31 @@ fn nested_visit_map<'b>(&'b mut self) -> NestedVisitorMap<'b, 'tcx> {
 
     Rc::new(set)
 }
+
+fn mir_const<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Steal<Mir<'tcx>> {
+    let mut mir = build::mir_build(tcx, def_id);
+    let source = MirSource::from_local_def_id(tcx, def_id);
+    transform::run_suite(tcx, source, MIR_CONST, &mut mir);
+    tcx.alloc_steal_mir(mir)
+}
+
+fn mir_validated<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Steal<Mir<'tcx>> {
+    let source = MirSource::from_local_def_id(tcx, def_id);
+    if let MirSource::Const(_) = source {
+        // Ensure that we compute the `mir_const_qualif` for constants at
+        // this point, before we steal the mir-const result. We don't
+        // directly need the result or `mir_const_qualif`, so we can just force it.
+        ty::queries::mir_const_qualif::force(tcx, DUMMY_SP, def_id);
+    }
+
+    let mut mir = tcx.mir_const(def_id).steal();
+    transform::run_suite(tcx, source, MIR_VALIDATED, &mut mir);
+    tcx.alloc_steal_mir(mir)
+}
+
+fn optimized_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Mir<'tcx> {
+    let mut mir = tcx.mir_validated(def_id).steal();
+    let source = MirSource::from_local_def_id(tcx, def_id);
+    transform::run_suite(tcx, source, MIR_OPTIMIZED, &mut mir);
+    tcx.alloc_mir(mir)
+}
index dc67c6f1ef45f168567d396245a5b653e6c476bb..971b0206a9ebd6a2e0818752c94a04b07dac7823 100644 (file)
@@ -8,13 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use rustc::hir::def_id::DefId;
 use rustc::mir::Mir;
-use rustc::mir::transform::{MirPassIndex, MirSuite, MirSource, MIR_VALIDATED, MIR_OPTIMIZED};
-use rustc::ty::{self, TyCtxt};
-use rustc::ty::steal::Steal;
+use rustc::mir::transform::{MirPassIndex, MirSuite, MirSource};
+use rustc::ty::TyCtxt;
 use rustc::ty::maps::Providers;
-use syntax_pos::DUMMY_SP;
 
 pub mod simplify_branches;
 pub mod simplify;
 pub mod inline;
 pub mod interprocedural;
 
-pub fn provide(providers: &mut Providers) {
+pub(crate) fn provide(providers: &mut Providers) {
     self::qualify_consts::provide(providers);
     *providers = Providers {
-        optimized_mir,
-        mir_suite,
-        mir_pass,
         ..*providers
     };
 }
 
-fn optimized_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Mir<'tcx> {
-    let mir = tcx.mir_suite((MIR_OPTIMIZED, def_id)).steal();
-    tcx.alloc_mir(mir)
-}
-
-fn mir_suite<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                       (suite, def_id): (MirSuite, DefId))
-                       -> &'tcx Steal<Mir<'tcx>>
+pub(crate) fn run_suite<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                                  source: MirSource,
+                                  suite: MirSuite,
+                                  mir: &mut Mir<'tcx>)
 {
-    let passes = &tcx.mir_passes;
-
-    if suite == MIR_VALIDATED {
-        let id = tcx.hir.as_local_node_id(def_id).expect("mir source requires local def-id");
-        let source = MirSource::from_node(tcx, id);
-        if let MirSource::Const(_) = source {
-            // Ensure that we compute the `mir_const_qualif` for
-            // constants at this point, before we do any further
-            // optimization (and before we steal the previous
-            // MIR). We don't directly need the result, so we can
-            // just force it.
-            ty::queries::mir_const_qualif::force(tcx, DUMMY_SP, def_id);
-        }
-    }
-
-    let len = passes.len_passes(suite);
-    assert!(len > 0, "no passes in {:?}", suite);
-    tcx.mir_pass((suite, MirPassIndex(len - 1), def_id))
-}
+    let passes = tcx.mir_passes.passes(suite);
 
-fn mir_pass<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                      (suite, pass_num, def_id): (MirSuite, MirPassIndex, DefId))
-                      -> &'tcx Steal<Mir<'tcx>>
-{
-    let passes = &tcx.mir_passes;
-    let pass = passes.pass(suite, pass_num);
+    for (pass, index) in passes.iter().zip(0..) {
+        let pass_num = MirPassIndex(index);
 
-    let id = tcx.hir.as_local_node_id(def_id).expect("mir source requires local def-id");
-    let source = MirSource::from_node(tcx, id);
-
-    let mut mir = {
-        let MirSuite(suite) = suite;
-        let MirPassIndex(pass_num) = pass_num;
-        if pass_num > 0 {
-            tcx.mir_pass((MirSuite(suite), MirPassIndex(pass_num - 1), def_id)).steal()
-        } else if suite > 0 {
-            tcx.mir_suite((MirSuite(suite - 1), def_id)).steal()
-        } else {
-            tcx.mir_build(def_id).steal()
+        for hook in tcx.mir_passes.hooks() {
+            hook.on_mir_pass(tcx, suite, pass_num, &pass.name(), source, &mir, false);
         }
-    };
-
-    for hook in passes.hooks() {
-        hook.on_mir_pass(tcx, suite, pass_num, &pass.name(), source, &mir, false);
-    }
 
-    pass.run_pass(tcx, source, &mut mir);
+        pass.run_pass(tcx, source, mir);
 
-    for hook in passes.hooks() {
-        hook.on_mir_pass(tcx, suite, pass_num, &pass.name(), source, &mir, true);
+        for hook in tcx.mir_passes.hooks() {
+            hook.on_mir_pass(tcx, suite, pass_num, &pass.name(), source, &mir, true);
+        }
     }
-
-    tcx.alloc_steal_mir(mir)
 }
-
index cd37372c2f1229754d51dc2caf105407063b06a2..4b1c82f383f85ce1a638dc2e048b0980f1af43a3 100644 (file)
@@ -26,7 +26,7 @@
 use rustc::ty::maps::Providers;
 use rustc::mir::*;
 use rustc::mir::traversal::ReversePostorder;
-use rustc::mir::transform::{MirPass, MirSource, MIR_CONST};
+use rustc::mir::transform::{MirPass, MirSource};
 use rustc::mir::visit::{LvalueContext, Visitor};
 use rustc::middle::lang_items;
 use syntax::abi::Abi;
@@ -918,13 +918,21 @@ fn visit_terminator(&mut self,
 }
 
 pub fn provide(providers: &mut Providers) {
-    providers.mir_const_qualif = qualify_const_item;
+    *providers = Providers {
+        mir_const_qualif,
+        ..*providers
+    };
 }
 
-fn qualify_const_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                def_id: DefId)
-                                -> u8 {
-    let mir = &tcx.mir_suite((MIR_CONST, def_id)).borrow();
+fn mir_const_qualif<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                              def_id: DefId)
+                              -> u8 {
+    // NB: This `borrow()` is guaranteed to be valid (i.e., the value
+    // cannot yet be stolen), because `mir_validated()`, which steals
+    // from `mir_const(), forces this query to execute before
+    // performing the steal.
+    let mir = &tcx.mir_const(def_id).borrow();
+
     if mir.return_ty.references_error() {
         return Qualif::NOT_CONST.bits();
     }