Skip to content

Commit 668886a

Browse files
committed
rewrite Passes to have sets of passes
Also, store the completed set of passes in the tcx.
1 parent e9e6ccc commit 668886a

File tree

3 files changed

+79
-55
lines changed

3 files changed

+79
-55
lines changed

src/librustc/mir/transform.rs

Lines changed: 33 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -167,24 +167,46 @@ impl<T: MirPass> DefIdPass for T {
167167
/// A manager for MIR passes.
168168
#[derive(Clone)]
169169
pub struct Passes {
170-
passes: Vec<Rc<Pass>>,
171170
pass_hooks: Vec<Rc<PassHook>>,
172-
plugin_passes: Vec<Rc<Pass>>
171+
sets: Vec<PassSet>,
172+
}
173+
174+
#[derive(Clone)]
175+
struct PassSet {
176+
passes: Vec<Rc<Pass>>,
173177
}
174178

179+
/// The number of "pass sets" that we have:
180+
///
181+
/// - ready for constant evaluation
182+
/// - unopt
183+
/// - optimized
184+
pub const MIR_PASS_SETS: usize = 3;
185+
186+
/// Run the passes we need to do constant qualification and evaluation.
187+
pub const MIR_CONST: usize = 0;
188+
189+
/// Run the passes we need to consider the MIR validated and ready for borrowck etc.
190+
pub const MIR_VALIDATED: usize = 1;
191+
192+
/// Run the passes we need to consider the MIR *optimized*.
193+
pub const MIR_OPTIMIZED: usize = 2;
194+
175195
impl<'a, 'tcx> Passes {
176196
pub fn new() -> Passes {
177-
let passes = Passes {
178-
passes: Vec::new(),
197+
Passes {
179198
pass_hooks: Vec::new(),
180-
plugin_passes: Vec::new()
181-
};
182-
passes
199+
sets: (0..MIR_PASS_SETS).map(|_| PassSet { passes: Vec::new() }).collect(),
200+
}
183201
}
184202

185-
pub fn run_passes(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>) {
203+
pub fn run_passes(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, set_index: usize) {
204+
let set = &self.sets[set_index];
205+
206+
let start_num: usize = self.sets[..set_index].iter().map(|s| s.passes.len()).sum();
207+
186208
// NB: passes are numbered from 1, since "construction" is zero.
187-
for (pass, pass_num) in self.plugin_passes.iter().chain(&self.passes).zip(1..) {
209+
for (pass, pass_num) in set.passes.iter().zip(start_num + 1..) {
188210
for hook in &self.pass_hooks {
189211
hook.on_mir_pass(tcx, &**pass, pass_num, false);
190212
}
@@ -198,19 +220,12 @@ impl<'a, 'tcx> Passes {
198220
}
199221

200222
/// Pushes a built-in pass.
201-
pub fn push_pass<T: Pass + 'static>(&mut self, pass: T) {
202-
self.passes.push(Rc::new(pass));
223+
pub fn push_pass<T: Pass + 'static>(&mut self, set: usize, pass: T) {
224+
self.sets[set].passes.push(Rc::new(pass));
203225
}
204226

205227
/// Pushes a pass hook.
206228
pub fn push_hook<T: PassHook + 'static>(&mut self, hook: T) {
207229
self.pass_hooks.push(Rc::new(hook));
208230
}
209231
}
210-
211-
/// Copies the plugin passes.
212-
impl ::std::iter::Extend<Rc<Pass>> for Passes {
213-
fn extend<I: IntoIterator<Item=Rc<Pass>>>(&mut self, it: I) {
214-
self.plugin_passes.extend(it);
215-
}
216-
}

src/librustc/ty/context.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use middle::region::{CodeExtent, CodeExtentData};
2525
use middle::resolve_lifetime;
2626
use middle::stability;
2727
use mir::Mir;
28+
use mir::transform::Passes;
2829
use ty::subst::{Kind, Substs};
2930
use ty::ReprOptions;
3031
use traits;
@@ -47,11 +48,12 @@ use arena::{TypedArena, DroplessArena};
4748
use rustc_data_structures::indexed_vec::IndexVec;
4849
use std::borrow::Borrow;
4950
use std::cell::{Cell, RefCell};
51+
use std::cmp::Ordering;
5052
use std::hash::{Hash, Hasher};
5153
use std::mem;
5254
use std::ops::Deref;
5355
use std::iter;
54-
use std::cmp::Ordering;
56+
use std::rc::Rc;
5557
use syntax::abi;
5658
use syntax::ast::{self, Name, NodeId};
5759
use syntax::attr;
@@ -441,8 +443,11 @@ pub struct GlobalCtxt<'tcx> {
441443
pub named_region_map: resolve_lifetime::NamedRegionMap,
442444

443445
pub hir: hir_map::Map<'tcx>,
446+
444447
pub maps: maps::Maps<'tcx>,
445448

449+
pub mir_passes: Rc<Passes>,
450+
446451
// Records the free variables refrenced by every closure
447452
// expression. Do not track deps for this, just recompute it from
448453
// scratch every time.
@@ -712,6 +717,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
712717
pub fn create_and_enter<F, R>(s: &'tcx Session,
713718
local_providers: ty::maps::Providers<'tcx>,
714719
extern_providers: ty::maps::Providers<'tcx>,
720+
mir_passes: Rc<Passes>,
715721
arenas: &'tcx GlobalArenas<'tcx>,
716722
arena: &'tcx DroplessArena,
717723
resolutions: ty::Resolutions,
@@ -746,6 +752,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
746752
fulfilled_predicates: RefCell::new(fulfilled_predicates),
747753
hir: hir,
748754
maps: maps::Maps::new(dep_graph, providers),
755+
mir_passes,
749756
freevars: RefCell::new(resolutions.freevars),
750757
maybe_unused_trait_imports: resolutions.maybe_unused_trait_imports,
751758
rcache: RefCell::new(FxHashMap()),

src/librustc_driver/driver.rs

Lines changed: 38 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use rustc::session::search_paths::PathKind;
2020
use rustc::lint;
2121
use rustc::middle::{self, dependency_format, stability, reachable};
2222
use rustc::middle::privacy::AccessLevels;
23+
use rustc::mir::transform::{MIR_CONST, MIR_VALIDATED, MIR_OPTIMIZED};
2324
use rustc::ty::{self, TyCtxt, Resolutions, GlobalArenas};
2425
use rustc::util::common::time;
2526
use rustc::util::nodemap::NodeSet;
@@ -903,9 +904,43 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
903904
// FIXME(eddyb) get rid of this once we replace const_eval with miri.
904905
rustc_const_eval::provide(&mut extern_providers);
905906

907+
// Setup the MIR passes that we want to run.
908+
let mut passes = sess.mir_passes.borrow().clone();
909+
passes.push_hook(mir::transform::dump_mir::DumpMir);
910+
911+
// What we need to do constant evaluation.
912+
passes.push_pass(MIR_CONST, mir::transform::simplify::SimplifyCfg::new("initial"));
913+
passes.push_pass(MIR_CONST, mir::transform::type_check::TypeckMir);
914+
915+
// What we need to run borrowck etc.
916+
passes.push_pass(MIR_VALIDATED, mir::transform::qualify_consts::QualifyAndPromoteConstants);
917+
passes.push_pass(MIR_VALIDATED, mir::transform::simplify_branches::SimplifyBranches::new("initial"));
918+
passes.push_pass(MIR_VALIDATED, mir::transform::simplify::SimplifyCfg::new("qualify-consts"));
919+
920+
// Optimizations begin.
921+
passes.push_pass(MIR_OPTIMIZED, mir::transform::no_landing_pads::NoLandingPads);
922+
passes.push_pass(MIR_OPTIMIZED, mir::transform::simplify::SimplifyCfg::new("no-landing-pads"));
923+
924+
// From here on out, regions are gone.
925+
passes.push_pass(MIR_OPTIMIZED, mir::transform::erase_regions::EraseRegions);
926+
passes.push_pass(MIR_OPTIMIZED, mir::transform::add_call_guards::AddCallGuards);
927+
passes.push_pass(MIR_OPTIMIZED, borrowck::ElaborateDrops);
928+
passes.push_pass(MIR_OPTIMIZED, mir::transform::no_landing_pads::NoLandingPads);
929+
passes.push_pass(MIR_OPTIMIZED, mir::transform::simplify::SimplifyCfg::new("elaborate-drops"));
930+
931+
// No lifetime analysis based on borrowing can be done from here on out.
932+
passes.push_pass(MIR_OPTIMIZED, mir::transform::inline::Inline);
933+
passes.push_pass(MIR_OPTIMIZED, mir::transform::instcombine::InstCombine);
934+
passes.push_pass(MIR_OPTIMIZED, mir::transform::deaggregator::Deaggregator);
935+
passes.push_pass(MIR_OPTIMIZED, mir::transform::copy_prop::CopyPropagation);
936+
passes.push_pass(MIR_OPTIMIZED, mir::transform::simplify::SimplifyLocals);
937+
passes.push_pass(MIR_OPTIMIZED, mir::transform::add_call_guards::AddCallGuards);
938+
passes.push_pass(MIR_OPTIMIZED, mir::transform::dump_mir::Marker("PreTrans"));
939+
906940
TyCtxt::create_and_enter(sess,
907941
local_providers,
908942
extern_providers,
943+
Rc::new(passes),
909944
arenas,
910945
arena,
911946
resolutions,
@@ -971,18 +1006,8 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
9711006
}
9721007

9731008
time(time_passes, "MIR cleanup and validation", || {
974-
let mut passes = sess.mir_passes.borrow_mut();
975-
// Push all the built-in validation passes.
976-
// NB: if you’re adding an *optimisation* it ought to go to another set of passes
977-
// in stage 4 below.
978-
passes.push_hook(mir::transform::dump_mir::DumpMir);
979-
passes.push_pass(mir::transform::simplify::SimplifyCfg::new("initial"));
980-
passes.push_pass(mir::transform::type_check::TypeckMir);
981-
passes.push_pass(mir::transform::qualify_consts::QualifyAndPromoteConstants);
982-
passes.push_pass(mir::transform::simplify_branches::SimplifyBranches::new("initial"));
983-
passes.push_pass(mir::transform::simplify::SimplifyCfg::new("qualify-consts"));
984-
// And run everything.
985-
passes.run_passes(tcx);
1009+
tcx.mir_passes.run_passes(tcx, MIR_CONST);
1010+
tcx.mir_passes.run_passes(tcx, MIR_VALIDATED);
9861011
});
9871012

9881013
time(time_passes,
@@ -1040,30 +1065,7 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
10401065
// Run the passes that transform the MIR into a more suitable form for translation to LLVM
10411066
// code.
10421067
time(time_passes, "MIR optimisations", || {
1043-
let mut passes = ::rustc::mir::transform::Passes::new();
1044-
passes.push_hook(mir::transform::dump_mir::DumpMir);
1045-
passes.push_pass(mir::transform::no_landing_pads::NoLandingPads);
1046-
passes.push_pass(mir::transform::simplify::SimplifyCfg::new("no-landing-pads"));
1047-
1048-
// From here on out, regions are gone.
1049-
passes.push_pass(mir::transform::erase_regions::EraseRegions);
1050-
1051-
passes.push_pass(mir::transform::add_call_guards::AddCallGuards);
1052-
passes.push_pass(borrowck::ElaborateDrops);
1053-
passes.push_pass(mir::transform::no_landing_pads::NoLandingPads);
1054-
passes.push_pass(mir::transform::simplify::SimplifyCfg::new("elaborate-drops"));
1055-
1056-
// No lifetime analysis based on borrowing can be done from here on out.
1057-
passes.push_pass(mir::transform::inline::Inline);
1058-
passes.push_pass(mir::transform::instcombine::InstCombine);
1059-
passes.push_pass(mir::transform::deaggregator::Deaggregator);
1060-
passes.push_pass(mir::transform::copy_prop::CopyPropagation);
1061-
1062-
passes.push_pass(mir::transform::simplify::SimplifyLocals);
1063-
passes.push_pass(mir::transform::add_call_guards::AddCallGuards);
1064-
passes.push_pass(mir::transform::dump_mir::Marker("PreTrans"));
1065-
1066-
passes.run_passes(tcx);
1068+
tcx.mir_passes.run_passes(tcx, MIR_OPTIMIZED);
10671069
});
10681070

10691071
if tcx.sess.opts.debugging_opts.mir_stats {

0 commit comments

Comments
 (0)