rewrite Passes
to have sets of passes
Also, store the completed set of passes in the tcx.
This commit is contained in:
parent
e9e6ccc042
commit
668886a6cc
@ -167,24 +167,46 @@ impl<T: MirPass> DefIdPass for T {
|
||||
/// A manager for MIR passes.
|
||||
#[derive(Clone)]
|
||||
pub struct Passes {
|
||||
passes: Vec<Rc<Pass>>,
|
||||
pass_hooks: Vec<Rc<PassHook>>,
|
||||
plugin_passes: Vec<Rc<Pass>>
|
||||
sets: Vec<PassSet>,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
struct PassSet {
|
||||
passes: Vec<Rc<Pass>>,
|
||||
}
|
||||
|
||||
/// The number of "pass sets" that we have:
|
||||
///
|
||||
/// - ready for constant evaluation
|
||||
/// - unopt
|
||||
/// - optimized
|
||||
pub const MIR_PASS_SETS: usize = 3;
|
||||
|
||||
/// Run the passes we need to do constant qualification and evaluation.
|
||||
pub const MIR_CONST: usize = 0;
|
||||
|
||||
/// Run the passes we need to consider the MIR validated and ready for borrowck etc.
|
||||
pub const MIR_VALIDATED: usize = 1;
|
||||
|
||||
/// Run the passes we need to consider the MIR *optimized*.
|
||||
pub const MIR_OPTIMIZED: usize = 2;
|
||||
|
||||
impl<'a, 'tcx> Passes {
|
||||
pub fn new() -> Passes {
|
||||
let passes = Passes {
|
||||
passes: Vec::new(),
|
||||
Passes {
|
||||
pass_hooks: Vec::new(),
|
||||
plugin_passes: Vec::new()
|
||||
};
|
||||
passes
|
||||
sets: (0..MIR_PASS_SETS).map(|_| PassSet { passes: Vec::new() }).collect(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run_passes(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
||||
pub fn run_passes(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, set_index: usize) {
|
||||
let set = &self.sets[set_index];
|
||||
|
||||
let start_num: usize = self.sets[..set_index].iter().map(|s| s.passes.len()).sum();
|
||||
|
||||
// NB: passes are numbered from 1, since "construction" is zero.
|
||||
for (pass, pass_num) in self.plugin_passes.iter().chain(&self.passes).zip(1..) {
|
||||
for (pass, pass_num) in set.passes.iter().zip(start_num + 1..) {
|
||||
for hook in &self.pass_hooks {
|
||||
hook.on_mir_pass(tcx, &**pass, pass_num, false);
|
||||
}
|
||||
@ -198,8 +220,8 @@ impl<'a, 'tcx> Passes {
|
||||
}
|
||||
|
||||
/// Pushes a built-in pass.
|
||||
pub fn push_pass<T: Pass + 'static>(&mut self, pass: T) {
|
||||
self.passes.push(Rc::new(pass));
|
||||
pub fn push_pass<T: Pass + 'static>(&mut self, set: usize, pass: T) {
|
||||
self.sets[set].passes.push(Rc::new(pass));
|
||||
}
|
||||
|
||||
/// Pushes a pass hook.
|
||||
@ -207,10 +229,3 @@ impl<'a, 'tcx> Passes {
|
||||
self.pass_hooks.push(Rc::new(hook));
|
||||
}
|
||||
}
|
||||
|
||||
/// Copies the plugin passes.
|
||||
impl ::std::iter::Extend<Rc<Pass>> for Passes {
|
||||
fn extend<I: IntoIterator<Item=Rc<Pass>>>(&mut self, it: I) {
|
||||
self.plugin_passes.extend(it);
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ use middle::region::{CodeExtent, CodeExtentData};
|
||||
use middle::resolve_lifetime;
|
||||
use middle::stability;
|
||||
use mir::Mir;
|
||||
use mir::transform::Passes;
|
||||
use ty::subst::{Kind, Substs};
|
||||
use ty::ReprOptions;
|
||||
use traits;
|
||||
@ -47,11 +48,12 @@ use arena::{TypedArena, DroplessArena};
|
||||
use rustc_data_structures::indexed_vec::IndexVec;
|
||||
use std::borrow::Borrow;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::cmp::Ordering;
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::mem;
|
||||
use std::ops::Deref;
|
||||
use std::iter;
|
||||
use std::cmp::Ordering;
|
||||
use std::rc::Rc;
|
||||
use syntax::abi;
|
||||
use syntax::ast::{self, Name, NodeId};
|
||||
use syntax::attr;
|
||||
@ -441,8 +443,11 @@ pub struct GlobalCtxt<'tcx> {
|
||||
pub named_region_map: resolve_lifetime::NamedRegionMap,
|
||||
|
||||
pub hir: hir_map::Map<'tcx>,
|
||||
|
||||
pub maps: maps::Maps<'tcx>,
|
||||
|
||||
pub mir_passes: Rc<Passes>,
|
||||
|
||||
// Records the free variables refrenced by every closure
|
||||
// expression. Do not track deps for this, just recompute it from
|
||||
// scratch every time.
|
||||
@ -712,6 +717,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
pub fn create_and_enter<F, R>(s: &'tcx Session,
|
||||
local_providers: ty::maps::Providers<'tcx>,
|
||||
extern_providers: ty::maps::Providers<'tcx>,
|
||||
mir_passes: Rc<Passes>,
|
||||
arenas: &'tcx GlobalArenas<'tcx>,
|
||||
arena: &'tcx DroplessArena,
|
||||
resolutions: ty::Resolutions,
|
||||
@ -746,6 +752,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||
fulfilled_predicates: RefCell::new(fulfilled_predicates),
|
||||
hir: hir,
|
||||
maps: maps::Maps::new(dep_graph, providers),
|
||||
mir_passes,
|
||||
freevars: RefCell::new(resolutions.freevars),
|
||||
maybe_unused_trait_imports: resolutions.maybe_unused_trait_imports,
|
||||
rcache: RefCell::new(FxHashMap()),
|
||||
|
@ -20,6 +20,7 @@ use rustc::session::search_paths::PathKind;
|
||||
use rustc::lint;
|
||||
use rustc::middle::{self, dependency_format, stability, reachable};
|
||||
use rustc::middle::privacy::AccessLevels;
|
||||
use rustc::mir::transform::{MIR_CONST, MIR_VALIDATED, MIR_OPTIMIZED};
|
||||
use rustc::ty::{self, TyCtxt, Resolutions, GlobalArenas};
|
||||
use rustc::util::common::time;
|
||||
use rustc::util::nodemap::NodeSet;
|
||||
@ -903,9 +904,43 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
|
||||
// FIXME(eddyb) get rid of this once we replace const_eval with miri.
|
||||
rustc_const_eval::provide(&mut extern_providers);
|
||||
|
||||
// Setup the MIR passes that we want to run.
|
||||
let mut passes = sess.mir_passes.borrow().clone();
|
||||
passes.push_hook(mir::transform::dump_mir::DumpMir);
|
||||
|
||||
// What we need to do constant evaluation.
|
||||
passes.push_pass(MIR_CONST, mir::transform::simplify::SimplifyCfg::new("initial"));
|
||||
passes.push_pass(MIR_CONST, mir::transform::type_check::TypeckMir);
|
||||
|
||||
// What we need to run borrowck etc.
|
||||
passes.push_pass(MIR_VALIDATED, mir::transform::qualify_consts::QualifyAndPromoteConstants);
|
||||
passes.push_pass(MIR_VALIDATED, mir::transform::simplify_branches::SimplifyBranches::new("initial"));
|
||||
passes.push_pass(MIR_VALIDATED, mir::transform::simplify::SimplifyCfg::new("qualify-consts"));
|
||||
|
||||
// Optimizations begin.
|
||||
passes.push_pass(MIR_OPTIMIZED, mir::transform::no_landing_pads::NoLandingPads);
|
||||
passes.push_pass(MIR_OPTIMIZED, mir::transform::simplify::SimplifyCfg::new("no-landing-pads"));
|
||||
|
||||
// From here on out, regions are gone.
|
||||
passes.push_pass(MIR_OPTIMIZED, mir::transform::erase_regions::EraseRegions);
|
||||
passes.push_pass(MIR_OPTIMIZED, mir::transform::add_call_guards::AddCallGuards);
|
||||
passes.push_pass(MIR_OPTIMIZED, borrowck::ElaborateDrops);
|
||||
passes.push_pass(MIR_OPTIMIZED, mir::transform::no_landing_pads::NoLandingPads);
|
||||
passes.push_pass(MIR_OPTIMIZED, mir::transform::simplify::SimplifyCfg::new("elaborate-drops"));
|
||||
|
||||
// No lifetime analysis based on borrowing can be done from here on out.
|
||||
passes.push_pass(MIR_OPTIMIZED, mir::transform::inline::Inline);
|
||||
passes.push_pass(MIR_OPTIMIZED, mir::transform::instcombine::InstCombine);
|
||||
passes.push_pass(MIR_OPTIMIZED, mir::transform::deaggregator::Deaggregator);
|
||||
passes.push_pass(MIR_OPTIMIZED, mir::transform::copy_prop::CopyPropagation);
|
||||
passes.push_pass(MIR_OPTIMIZED, mir::transform::simplify::SimplifyLocals);
|
||||
passes.push_pass(MIR_OPTIMIZED, mir::transform::add_call_guards::AddCallGuards);
|
||||
passes.push_pass(MIR_OPTIMIZED, mir::transform::dump_mir::Marker("PreTrans"));
|
||||
|
||||
TyCtxt::create_and_enter(sess,
|
||||
local_providers,
|
||||
extern_providers,
|
||||
Rc::new(passes),
|
||||
arenas,
|
||||
arena,
|
||||
resolutions,
|
||||
@ -971,18 +1006,8 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
|
||||
}
|
||||
|
||||
time(time_passes, "MIR cleanup and validation", || {
|
||||
let mut passes = sess.mir_passes.borrow_mut();
|
||||
// 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(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);
|
||||
tcx.mir_passes.run_passes(tcx, MIR_CONST);
|
||||
tcx.mir_passes.run_passes(tcx, MIR_VALIDATED);
|
||||
});
|
||||
|
||||
time(time_passes,
|
||||
@ -1040,30 +1065,7 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
// Run the passes that transform the MIR into a more suitable form for translation to LLVM
|
||||
// code.
|
||||
time(time_passes, "MIR optimisations", || {
|
||||
let mut passes = ::rustc::mir::transform::Passes::new();
|
||||
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(mir::transform::erase_regions::EraseRegions);
|
||||
|
||||
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(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);
|
||||
tcx.mir_passes.run_passes(tcx, MIR_OPTIMIZED);
|
||||
});
|
||||
|
||||
if tcx.sess.opts.debugging_opts.mir_stats {
|
||||
|
Loading…
Reference in New Issue
Block a user