From 669d31683f97c173c404d27b841d30a6424bf639 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Mon, 1 May 2017 14:39:48 -0400 Subject: [PATCH] simplify down to one query per pass suite --- src/librustc/mir/transform.rs | 13 ++-- src/librustc/ty/maps.rs | 42 +--------- src/librustc_mir/build/mod.rs | 10 +-- src/librustc_mir/queries.rs | 47 ++++++++++-- src/librustc_mir/transform/mod.rs | 81 ++++---------------- src/librustc_mir/transform/qualify_consts.rs | 20 +++-- 6 files changed, 87 insertions(+), 126 deletions(-) diff --git a/src/librustc/mir/transform.rs b/src/librustc/mir/transform.rs index df6f98297d0..77d4eefb1de 100644 --- a/src/librustc/mir/transform.rs +++ b/src/librustc/mir/transform.rs @@ -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(&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] { + &self.suites[suite.0] } pub fn hooks(&self) -> &[Rc] { diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs index b3ca61550d7..5a5dece8a94 100644 --- a/src/librustc/ty/maps.rs +++ b/src/librustc/ty/maps.rs @@ -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_const: Mir(DefId) -> &'tcx Steal>, - /// 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>, - - /// 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_validated: Mir(DefId) -> &'tcx Steal>, /// 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 { fn mir_keys(_: CrateNum) -> DepNode { DepNode::MirKeys } - -fn mir_suite((_suite, def_id): (MirSuite, DefId)) -> DepNode { - DepNode::Mir(def_id) -} - -fn mir_pass((_suite, _pass_num, def_id): (MirSuite, MirPassIndex, DefId)) -> DepNode { - DepNode::Mir(def_id) -} diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index f5f6c307b15..8c057b02df2 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -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> { +/// 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> { 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); diff --git a/src/librustc_mir/queries.rs b/src/librustc_mir/queries.rs index aef637fed5e..980663ec675 100644 --- a/src/librustc_mir/queries.rs +++ b/src/librustc_mir/queries.rs @@ -16,27 +16,34 @@ //! - `#[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 { 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> { + 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> { + 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) +} diff --git a/src/librustc_mir/transform/mod.rs b/src/librustc_mir/transform/mod.rs index dc67c6f1ef4..971b0206a9e 100644 --- a/src/librustc_mir/transform/mod.rs +++ b/src/librustc_mir/transform/mod.rs @@ -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; @@ -31,77 +28,31 @@ 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> +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> -{ - 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) } - diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs index cd37372c2f1..4b1c82f383f 100644 --- a/src/librustc_mir/transform/qualify_consts.rs +++ b/src/librustc_mir/transform/qualify_consts.rs @@ -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(); } -- 2.44.0