rework MirPass
API to be stateless and extract helper fns
This commit is contained in:
parent
0e5e2f3634
commit
11b6b0663a
15 changed files with 74 additions and 82 deletions
|
@ -10,7 +10,7 @@
|
|||
|
||||
use dep_graph::DepNode;
|
||||
use hir;
|
||||
use hir::def_id::LOCAL_CRATE;
|
||||
use hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use hir::map::DefPathData;
|
||||
use mir::{Mir, Promoted};
|
||||
use ty::TyCtxt;
|
||||
|
@ -88,14 +88,14 @@ pub trait Pass {
|
|||
/// A pass which inspects the whole Mir map.
|
||||
pub trait MirMapPass<'tcx>: Pass {
|
||||
fn run_pass<'a>(
|
||||
&mut self,
|
||||
&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
hooks: &mut [Box<for<'s> MirPassHook<'s>>]);
|
||||
}
|
||||
|
||||
pub trait MirPassHook<'tcx>: Pass {
|
||||
fn on_mir_pass<'a>(
|
||||
&mut self,
|
||||
&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
src: MirSource,
|
||||
mir: &Mir<'tcx>,
|
||||
|
@ -106,40 +106,58 @@ pub trait MirPassHook<'tcx>: Pass {
|
|||
|
||||
/// A pass which inspects Mir of functions in isolation.
|
||||
pub trait MirPass<'tcx>: Pass {
|
||||
fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
fn run_pass<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
src: MirSource, mir: &mut Mir<'tcx>);
|
||||
}
|
||||
|
||||
impl<'tcx, T: MirPass<'tcx>> MirMapPass<'tcx> for T {
|
||||
fn run_pass<'a>(&mut self,
|
||||
fn run_pass<'a>(&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
hooks: &mut [Box<for<'s> MirPassHook<'s>>])
|
||||
{
|
||||
for &def_id in tcx.mir_keys(LOCAL_CRATE).iter() {
|
||||
let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id));
|
||||
let mir = &mut tcx.mir(def_id).borrow_mut();
|
||||
tcx.dep_graph.write(DepNode::Mir(def_id));
|
||||
run_hooks(tcx, hooks, self, false);
|
||||
run_map_pass_task(tcx, self, def_id);
|
||||
run_hooks(tcx, hooks, self, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let id = tcx.hir.as_local_node_id(def_id).unwrap();
|
||||
let src = MirSource::from_node(tcx, id);
|
||||
fn run_map_pass_task<'a, 'tcx, T: MirPass<'tcx>>(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();
|
||||
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);
|
||||
|
||||
for (i, mir) in mir.promoted.iter_enumerated_mut() {
|
||||
let source = MirSource::Promoted(id, i);
|
||||
MirPass::run_pass(pass, tcx, source, mir);
|
||||
}
|
||||
}
|
||||
|
||||
/// Invokes `hooks` on all the MIR that exists. This is read-only, so
|
||||
/// new new tasks need to be created.
|
||||
pub fn run_hooks<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
hooks: &mut [Box<for<'s> MirPassHook<'s>>],
|
||||
pass: &Pass,
|
||||
is_after: bool)
|
||||
{
|
||||
for &def_id in tcx.mir_keys(LOCAL_CRATE).iter() {
|
||||
let mir = tcx.item_mir(def_id);
|
||||
let id = tcx.hir.as_local_node_id(def_id).expect("mir source requires local def-id");
|
||||
|
||||
let source = MirSource::from_node(tcx, id);
|
||||
for hook in &mut *hooks {
|
||||
hook.on_mir_pass(tcx, source, &mir, pass, is_after);
|
||||
}
|
||||
|
||||
for (i, mir) in mir.promoted.iter_enumerated() {
|
||||
let source = MirSource::Promoted(id, i);
|
||||
for hook in &mut *hooks {
|
||||
hook.on_mir_pass(tcx, src, mir, self, false);
|
||||
}
|
||||
MirPass::run_pass(self, tcx, src, mir);
|
||||
for hook in &mut *hooks {
|
||||
hook.on_mir_pass(tcx, src, mir, self, true);
|
||||
}
|
||||
|
||||
for (i, mir) in mir.promoted.iter_enumerated_mut() {
|
||||
let src = MirSource::Promoted(id, i);
|
||||
for hook in &mut *hooks {
|
||||
hook.on_mir_pass(tcx, src, mir, self, false);
|
||||
}
|
||||
MirPass::run_pass(self, tcx, src, mir);
|
||||
for hook in &mut *hooks {
|
||||
hook.on_mir_pass(tcx, src, mir, self, true);
|
||||
}
|
||||
hook.on_mir_pass(tcx, source, &mir, pass, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ use std::u32;
|
|||
pub struct ElaborateDrops;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for ElaborateDrops {
|
||||
fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
fn run_pass<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
src: MirSource, mir: &mut Mir<'tcx>)
|
||||
{
|
||||
debug!("elaborate_drops({:?} @ {:?})", src, mir.span);
|
||||
|
|
|
@ -1056,7 +1056,7 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||
|
||||
// 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::new());
|
||||
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);
|
||||
|
||||
|
|
|
@ -36,7 +36,7 @@ pub struct AddCallGuards;
|
|||
*/
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for AddCallGuards {
|
||||
fn run_pass<'a>(&mut self, _tcx: TyCtxt<'a, 'tcx, 'tcx>, _src: MirSource, mir: &mut Mir<'tcx>) {
|
||||
fn run_pass<'a>(&self, _tcx: TyCtxt<'a, 'tcx, 'tcx>, _src: MirSource, mir: &mut Mir<'tcx>) {
|
||||
add_call_guards(mir);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -41,7 +41,7 @@ pub struct CopyPropagation;
|
|||
impl Pass for CopyPropagation {}
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for CopyPropagation {
|
||||
fn run_pass<'a>(&mut self,
|
||||
fn run_pass<'a>(&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
source: MirSource,
|
||||
mir: &mut Mir<'tcx>) {
|
||||
|
|
|
@ -18,7 +18,7 @@ pub struct Deaggregator;
|
|||
impl Pass for Deaggregator {}
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for Deaggregator {
|
||||
fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
fn run_pass<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
source: MirSource, mir: &mut Mir<'tcx>) {
|
||||
let node_id = source.item_id();
|
||||
let node_path = tcx.item_path_str(tcx.hir.local_def_id(node_id));
|
||||
|
|
|
@ -23,7 +23,7 @@ use util as mir_util;
|
|||
pub struct Marker<'a>(pub &'a str);
|
||||
|
||||
impl<'b, 'tcx> MirPass<'tcx> for Marker<'b> {
|
||||
fn run_pass<'a>(&mut self, _tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
fn run_pass<'a>(&self, _tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
_src: MirSource, _mir: &mut Mir<'tcx>)
|
||||
{}
|
||||
}
|
||||
|
@ -52,7 +52,7 @@ pub struct DumpMir;
|
|||
|
||||
impl<'tcx> MirPassHook<'tcx> for DumpMir {
|
||||
fn on_mir_pass<'a>(
|
||||
&mut self,
|
||||
&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
src: MirSource,
|
||||
mir: &Mir<'tcx>,
|
||||
|
|
|
@ -72,7 +72,7 @@ pub struct EraseRegions;
|
|||
impl Pass for EraseRegions {}
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for EraseRegions {
|
||||
fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
fn run_pass<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
_: MirSource, mir: &mut Mir<'tcx>) {
|
||||
EraseRegionsVisitor::new(tcx).visit_mir(mir);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ use rustc_data_structures::graph;
|
|||
|
||||
use rustc::dep_graph::DepNode;
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::transform::{MirMapPass, MirPassHook, MirSource, Pass};
|
||||
use rustc::mir::transform::{self, MirMapPass, MirPassHook, MirSource, Pass};
|
||||
use rustc::mir::visit::*;
|
||||
use rustc::traits;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
|
@ -44,7 +44,7 @@ pub struct Inline;
|
|||
|
||||
impl<'tcx> MirMapPass<'tcx> for Inline {
|
||||
fn run_pass<'a>(
|
||||
&mut self,
|
||||
&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
hooks: &mut [Box<for<'s> MirPassHook<'s>>]) {
|
||||
|
||||
|
@ -58,33 +58,13 @@ impl<'tcx> MirMapPass<'tcx> for Inline {
|
|||
tcx: tcx,
|
||||
};
|
||||
|
||||
for &def_id in tcx.mir_keys(LOCAL_CRATE).iter() {
|
||||
let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id));
|
||||
let mir = &tcx.item_mir(def_id);
|
||||
|
||||
let id = tcx.hir.as_local_node_id(def_id).unwrap();
|
||||
let src = MirSource::from_node(tcx, id);
|
||||
|
||||
for hook in &mut *hooks {
|
||||
hook.on_mir_pass(tcx, src, mir, self, false);
|
||||
}
|
||||
}
|
||||
transform::run_hooks(tcx, hooks, self, false);
|
||||
|
||||
for scc in callgraph.scc_iter() {
|
||||
inliner.inline_scc(&callgraph, &scc);
|
||||
}
|
||||
|
||||
for &def_id in tcx.mir_keys(LOCAL_CRATE).iter() {
|
||||
let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id));
|
||||
let mir = &tcx.item_mir(def_id);
|
||||
|
||||
let id = tcx.hir.as_local_node_id(def_id).unwrap();
|
||||
let src = MirSource::from_node(tcx, id);
|
||||
|
||||
for hook in &mut *hooks {
|
||||
hook.on_mir_pass(tcx, src, mir, self, true);
|
||||
}
|
||||
}
|
||||
transform::run_hooks(tcx, hooks, self, true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,22 +18,12 @@ use rustc::util::nodemap::FxHashSet;
|
|||
use rustc_data_structures::indexed_vec::Idx;
|
||||
use std::mem;
|
||||
|
||||
pub struct InstCombine {
|
||||
optimizations: OptimizationList,
|
||||
}
|
||||
|
||||
impl InstCombine {
|
||||
pub fn new() -> InstCombine {
|
||||
InstCombine {
|
||||
optimizations: OptimizationList::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
pub struct InstCombine;
|
||||
|
||||
impl Pass for InstCombine {}
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for InstCombine {
|
||||
fn run_pass<'a>(&mut self,
|
||||
fn run_pass<'a>(&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
_: MirSource,
|
||||
mir: &mut Mir<'tcx>) {
|
||||
|
@ -45,18 +35,22 @@ impl<'tcx> MirPass<'tcx> for InstCombine {
|
|||
// First, find optimization opportunities. This is done in a pre-pass to keep the MIR
|
||||
// read-only so that we can do global analyses on the MIR in the process (e.g.
|
||||
// `Lvalue::ty()`).
|
||||
{
|
||||
let optimizations = {
|
||||
let mut optimization_finder = OptimizationFinder::new(mir, tcx);
|
||||
optimization_finder.visit_mir(mir);
|
||||
self.optimizations = optimization_finder.optimizations
|
||||
}
|
||||
optimization_finder.optimizations
|
||||
};
|
||||
|
||||
// Then carry out those optimizations.
|
||||
MutVisitor::visit_mir(&mut *self, mir);
|
||||
MutVisitor::visit_mir(&mut InstCombineVisitor { optimizations }, mir);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> MutVisitor<'tcx> for InstCombine {
|
||||
pub struct InstCombineVisitor {
|
||||
optimizations: OptimizationList,
|
||||
}
|
||||
|
||||
impl<'tcx> MutVisitor<'tcx> for InstCombineVisitor {
|
||||
fn visit_rvalue(&mut self, rvalue: &mut Rvalue<'tcx>, location: Location) {
|
||||
if self.optimizations.and_stars.remove(&location) {
|
||||
debug!("Replacing `&*`: {:?}", rvalue);
|
||||
|
|
|
@ -49,7 +49,7 @@ pub fn no_landing_pads<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, mir: &mut Mir<'tcx
|
|||
}
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for NoLandingPads {
|
||||
fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
fn run_pass<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
_: MirSource, mir: &mut Mir<'tcx>) {
|
||||
no_landing_pads(tcx, mir)
|
||||
}
|
||||
|
|
|
@ -942,7 +942,7 @@ pub struct QualifyAndPromoteConstants;
|
|||
impl Pass for QualifyAndPromoteConstants {}
|
||||
|
||||
impl<'tcx> MirMapPass<'tcx> for QualifyAndPromoteConstants {
|
||||
fn run_pass<'a>(&mut self,
|
||||
fn run_pass<'a>(&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
hooks: &mut [Box<for<'s> MirPassHook<'s>>])
|
||||
{
|
||||
|
@ -971,7 +971,7 @@ impl<'tcx> MirMapPass<'tcx> for QualifyAndPromoteConstants {
|
|||
}
|
||||
|
||||
impl<'tcx> QualifyAndPromoteConstants {
|
||||
fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
fn run_pass<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
src: MirSource, mir: &mut Mir<'tcx>) {
|
||||
let id = src.item_id();
|
||||
let def_id = tcx.hir.local_def_id(id);
|
||||
|
|
|
@ -62,7 +62,7 @@ pub fn simplify_cfg(mir: &mut Mir) {
|
|||
}
|
||||
|
||||
impl<'l, 'tcx> MirPass<'tcx> for SimplifyCfg<'l> {
|
||||
fn run_pass<'a>(&mut self, _tcx: TyCtxt<'a, 'tcx, 'tcx>, _src: MirSource, mir: &mut Mir<'tcx>) {
|
||||
fn run_pass<'a>(&self, _tcx: TyCtxt<'a, 'tcx, 'tcx>, _src: MirSource, mir: &mut Mir<'tcx>) {
|
||||
debug!("SimplifyCfg({:?}) - simplifying {:?}", self.label, mir);
|
||||
simplify_cfg(mir);
|
||||
}
|
||||
|
@ -320,7 +320,7 @@ impl Pass for SimplifyLocals {
|
|||
}
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for SimplifyLocals {
|
||||
fn run_pass<'a>(&mut self, _: TyCtxt<'a, 'tcx, 'tcx>, _: MirSource, mir: &mut Mir<'tcx>) {
|
||||
fn run_pass<'a>(&self, _: TyCtxt<'a, 'tcx, 'tcx>, _: MirSource, mir: &mut Mir<'tcx>) {
|
||||
let mut marker = DeclMarker { locals: BitVector::new(mir.local_decls.len()) };
|
||||
marker.visit_mir(mir);
|
||||
// Return pointer and arguments are always live
|
||||
|
|
|
@ -26,7 +26,7 @@ impl<'a> SimplifyBranches<'a> {
|
|||
}
|
||||
|
||||
impl<'l, 'tcx> MirPass<'tcx> for SimplifyBranches<'l> {
|
||||
fn run_pass<'a>(&mut self, _tcx: TyCtxt<'a, 'tcx, 'tcx>, _src: MirSource, mir: &mut Mir<'tcx>) {
|
||||
fn run_pass<'a>(&self, _tcx: TyCtxt<'a, 'tcx, 'tcx>, _src: MirSource, mir: &mut Mir<'tcx>) {
|
||||
for block in mir.basic_blocks_mut() {
|
||||
let terminator = block.terminator_mut();
|
||||
terminator.kind = match terminator.kind {
|
||||
|
|
|
@ -738,7 +738,7 @@ impl TypeckMir {
|
|||
}
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for TypeckMir {
|
||||
fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
fn run_pass<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
src: MirSource, mir: &mut Mir<'tcx>) {
|
||||
let item_id = src.item_id();
|
||||
let def_id = tcx.hir.local_def_id(item_id);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue