Skip to content

Allow registering MIR-passes through compiler plugins #31425

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 9, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion mk/crates.mk
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ DEPS_rustc_passes := syntax rustc core rustc_front
DEPS_rustc_mir := rustc rustc_front syntax
DEPS_rustc_resolve := arena rustc rustc_front log syntax
DEPS_rustc_platform_intrinsics := rustc rustc_llvm
DEPS_rustc_plugin := rustc rustc_metadata syntax
DEPS_rustc_plugin := rustc rustc_metadata syntax rustc_mir
DEPS_rustc_privacy := rustc rustc_front log syntax
DEPS_rustc_trans := arena flate getopts graphviz libc rustc rustc_back rustc_mir \
log syntax serialize rustc_llvm rustc_front rustc_platform_intrinsics
Expand Down
2 changes: 2 additions & 0 deletions src/librustc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ pub mod mir {
pub mod repr;
pub mod tcx;
pub mod visit;
pub mod transform;
pub mod mir_map;
}

pub mod session;
Expand Down
5 changes: 3 additions & 2 deletions src/librustc/middle/cstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ use middle::lang_items;
use middle::ty::{self, Ty, VariantKind};
use middle::def_id::{DefId, DefIndex};
use mir::repr::Mir;
use mir::mir_map::MirMap;
use session::Session;
use session::search_paths::PathKind;
use util::nodemap::{FnvHashMap, NodeMap, NodeSet};
Expand Down Expand Up @@ -244,7 +245,7 @@ pub trait CrateStore<'tcx> : Any {
item_symbols: &RefCell<NodeMap<String>>,
link_meta: &LinkMeta,
reachable: &NodeSet,
mir_map: &NodeMap<Mir<'tcx>>,
mir_map: &MirMap<'tcx>,
krate: &hir::Crate) -> Vec<u8>;
fn metadata_encoding_version(&self) -> &[u8];
}
Expand Down Expand Up @@ -428,7 +429,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
item_symbols: &RefCell<NodeMap<String>>,
link_meta: &LinkMeta,
reachable: &NodeSet,
mir_map: &NodeMap<Mir<'tcx>>,
mir_map: &MirMap<'tcx>,
krate: &hir::Crate) -> Vec<u8> { vec![] }
fn metadata_encoding_version(&self) -> &[u8] { unimplemented!() }
}
Expand Down
28 changes: 28 additions & 0 deletions src/librustc/mir/mir_map.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use util::nodemap::NodeMap;
use mir::repr::Mir;
use mir::transform::MirPass;
use middle::ty;

pub struct MirMap<'tcx> {
pub map: NodeMap<Mir<'tcx>>,
}

impl<'tcx> MirMap<'tcx> {
pub fn run_passes(&mut self, passes: &mut [Box<MirPass>], tcx: &ty::ctxt<'tcx>) {
for (_, ref mut mir) in &mut self.map {
for pass in &mut *passes {
pass.run_on_mir(mir, tcx)
}
}
}
}
16 changes: 16 additions & 0 deletions src/librustc/mir/transform.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use mir::repr::Mir;
use middle::ty::ctxt;

pub trait MirPass {
fn run_on_mir<'tcx>(&mut self, mir: &mut Mir<'tcx>, tcx: &ctxt<'tcx>);
}
3 changes: 3 additions & 0 deletions src/librustc/session/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use middle::cstore::CrateStore;
use middle::dependency_format;
use session::search_paths::PathKind;
use util::nodemap::{NodeMap, FnvHashMap};
use mir::transform::MirPass;

use syntax::ast::{NodeId, NodeIdAssigner, Name};
use syntax::codemap::{Span, MultiSpan};
Expand Down Expand Up @@ -59,6 +60,7 @@ pub struct Session {
pub lint_store: RefCell<lint::LintStore>,
pub lints: RefCell<NodeMap<Vec<(lint::LintId, Span, String)>>>,
pub plugin_llvm_passes: RefCell<Vec<String>>,
pub plugin_mir_passes: RefCell<Vec<Box<MirPass>>>,
pub plugin_attributes: RefCell<Vec<(String, AttributeType)>>,
pub crate_types: RefCell<Vec<config::CrateType>>,
pub dependency_formats: RefCell<dependency_format::Dependencies>,
Expand Down Expand Up @@ -475,6 +477,7 @@ pub fn build_session_(sopts: config::Options,
lint_store: RefCell::new(lint::LintStore::new()),
lints: RefCell::new(NodeMap()),
plugin_llvm_passes: RefCell::new(Vec::new()),
plugin_mir_passes: RefCell::new(Vec::new()),
plugin_attributes: RefCell::new(Vec::new()),
crate_types: RefCell::new(Vec::new()),
dependency_formats: RefCell::new(FnvHashMap()),
Expand Down
11 changes: 8 additions & 3 deletions src/librustc_driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use rustc::dep_graph::DepGraph;
use rustc::front;
use rustc::front::map as hir_map;
use rustc_mir as mir;
use rustc_mir::mir_map::MirMap;
use rustc::mir::mir_map::MirMap;
use rustc::session::{Session, CompileResult, compile_result_from_err_count};
use rustc::session::config::{self, Input, OutputFilenames, OutputType};
use rustc::session::search_paths::PathKind;
Expand Down Expand Up @@ -545,7 +545,7 @@ pub fn phase_2_configure_and_expand(sess: &Session,
});

let Registry { syntax_exts, early_lint_passes, late_lint_passes, lint_groups,
llvm_passes, attributes, .. } = registry;
llvm_passes, attributes, mir_passes, .. } = registry;

try!(sess.track_errors(|| {
let mut ls = sess.lint_store.borrow_mut();
Expand All @@ -561,6 +561,7 @@ pub fn phase_2_configure_and_expand(sess: &Session,
}

*sess.plugin_llvm_passes.borrow_mut() = llvm_passes;
*sess.plugin_mir_passes.borrow_mut() = mir_passes;
*sess.plugin_attributes.borrow_mut() = attributes.clone();
}));

Expand Down Expand Up @@ -843,11 +844,15 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
"match checking",
|| middle::check_match::check_crate(tcx));

let mir_map =
let mut mir_map =
time(time_passes,
"MIR dump",
|| mir::mir_map::build_mir_for_crate(tcx));

time(time_passes,
"MIR passes",
|| mir_map.run_passes(&mut sess.plugin_mir_passes.borrow_mut(), tcx));

time(time_passes,
"liveness checking",
|| middle::liveness::check_crate(tcx));
Expand Down
3 changes: 2 additions & 1 deletion src/librustc_metadata/csearch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ use middle::def_id::{DefId, DefIndex};

use rustc::front::map as hir_map;
use rustc::mir::repr::Mir;
use rustc::mir::mir_map::MirMap;
use rustc::util::nodemap::{FnvHashMap, NodeMap, NodeSet};

use std::cell::RefCell;
Expand Down Expand Up @@ -502,7 +503,7 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
item_symbols: &RefCell<NodeMap<String>>,
link_meta: &LinkMeta,
reachable: &NodeSet,
mir_map: &NodeMap<Mir<'tcx>>,
mir_map: &MirMap<'tcx>,
krate: &hir::Crate) -> Vec<u8>
{
let encode_inlined_item: encoder::EncodeInlinedItem =
Expand Down
10 changes: 5 additions & 5 deletions src/librustc_metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ use middle::ty::{self, Ty};
use rustc::back::svh::Svh;
use rustc::front::map::{LinkedPath, PathElem, PathElems};
use rustc::front::map as ast_map;
use rustc::mir::repr::Mir;
use rustc::mir::mir_map::MirMap;
use rustc::session::config;
use rustc::util::nodemap::{FnvHashMap, NodeMap, NodeSet};

Expand Down Expand Up @@ -66,7 +66,7 @@ pub struct EncodeParams<'a, 'tcx: 'a> {
pub cstore: &'a cstore::CStore,
pub encode_inlined_item: EncodeInlinedItem<'a>,
pub reachable: &'a NodeSet,
pub mir_map: &'a NodeMap<Mir<'tcx>>,
pub mir_map: &'a MirMap<'tcx>,
}

pub struct EncodeContext<'a, 'tcx: 'a> {
Expand All @@ -79,7 +79,7 @@ pub struct EncodeContext<'a, 'tcx: 'a> {
pub encode_inlined_item: RefCell<EncodeInlinedItem<'a>>,
pub type_abbrevs: tyencode::abbrev_map<'tcx>,
pub reachable: &'a NodeSet,
pub mir_map: &'a NodeMap<Mir<'tcx>>,
pub mir_map: &'a MirMap<'tcx>,
}

impl<'a, 'tcx> EncodeContext<'a,'tcx> {
Expand Down Expand Up @@ -824,7 +824,7 @@ fn encode_inlined_item(ecx: &EncodeContext,
}

fn encode_mir(ecx: &EncodeContext, rbml_w: &mut Encoder, node_id: NodeId) {
if let Some(mir) = ecx.mir_map.get(&node_id) {
if let Some(mir) = ecx.mir_map.map.get(&node_id) {
rbml_w.start_tag(tag_mir as usize);
rbml_w.emit_opaque(|opaque_encoder| {
tls::enter_encoding_context(ecx, opaque_encoder, |_, opaque_encoder| {
Expand Down Expand Up @@ -1447,7 +1447,7 @@ fn my_visit_expr(expr: &hir::Expr,

ecx.tcx.map.with_path(expr.id, |path| encode_path(rbml_w, path));

assert!(ecx.mir_map.contains_key(&expr.id));
assert!(ecx.mir_map.map.contains_key(&expr.id));
encode_mir(ecx, rbml_w, expr.id);

rbml_w.end_tag();
Expand Down
35 changes: 18 additions & 17 deletions src/librustc_mir/mir_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,33 +17,34 @@
//! - `#[rustc_mir(pretty="file.mir")]`

extern crate syntax;
extern crate rustc;
extern crate rustc_front;

use build;
use graphviz;
use pretty;
use transform::{simplify_cfg, MirPass};
use transform::simplify_cfg;
use rustc::dep_graph::DepNode;
use rustc::mir::repr::Mir;
use hair::cx::Cx;
use std::fs::File;

use self::rustc::middle::infer;
use self::rustc::middle::region::CodeExtentData;
use self::rustc::middle::ty::{self, Ty};
use self::rustc::util::common::ErrorReported;
use self::rustc::util::nodemap::NodeMap;
use self::rustc_front::hir;
use self::rustc_front::intravisit::{self, Visitor};
use self::syntax::ast;
use self::syntax::attr::AttrMetaMethods;
use self::syntax::codemap::Span;

pub type MirMap<'tcx> = NodeMap<Mir<'tcx>>;
use rustc::mir::transform::MirPass;
use rustc::mir::mir_map::MirMap;
use rustc::middle::infer;
use rustc::middle::region::CodeExtentData;
use rustc::middle::ty::{self, Ty};
use rustc::util::common::ErrorReported;
use rustc::util::nodemap::NodeMap;
use rustc_front::hir;
use rustc_front::intravisit::{self, Visitor};
use syntax::ast;
use syntax::attr::AttrMetaMethods;
use syntax::codemap::Span;

pub fn build_mir_for_crate<'tcx>(tcx: &ty::ctxt<'tcx>) -> MirMap<'tcx> {
let mut map = NodeMap();
let mut map = MirMap {
map: NodeMap(),
};
{
let mut dump = OuterDump {
tcx: tcx,
Expand Down Expand Up @@ -147,7 +148,7 @@ impl<'a, 'm, 'tcx> Visitor<'tcx> for InnerDump<'a,'m,'tcx> {

match build_mir(Cx::new(&infcx), implicit_arg_tys, id, span, decl, body) {
Ok(mut mir) => {
simplify_cfg::SimplifyCfg::new().run_on_mir(&mut mir);
simplify_cfg::SimplifyCfg::new().run_on_mir(&mut mir, self.tcx);

let meta_item_list = self.attr
.iter()
Expand Down Expand Up @@ -182,7 +183,7 @@ impl<'a, 'm, 'tcx> Visitor<'tcx> for InnerDump<'a,'m,'tcx> {
}
}

let previous = self.map.insert(id, mir);
let previous = self.map.map.insert(id, mir);
assert!(previous.is_none());
}
Err(ErrorReported) => {}
Expand Down
28 changes: 15 additions & 13 deletions src/librustc_mir/transform/erase_regions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,24 +15,26 @@
use rustc::middle::ty;
use rustc::mir::repr::*;
use rustc::mir::visit::MutVisitor;
use mir_map::MirMap;
use transform::MirPass;
use rustc::mir::mir_map::MirMap;
use rustc::mir::transform::MirPass;

pub fn erase_regions<'tcx>(tcx: &ty::ctxt<'tcx>, mir_map: &mut MirMap<'tcx>) {
let mut eraser = EraseRegions::new(tcx);
let mut eraser = EraseRegions;

for mir in mir_map.iter_mut().map(|(_, v)| v) {
eraser.run_on_mir(mir);
for (_, mir) in &mut mir_map.map {
eraser.run_on_mir(mir, tcx);
}
}

pub struct EraseRegions<'a, 'tcx: 'a> {
pub struct EraseRegions;

struct EraseRegionsVisitor<'a, 'tcx: 'a> {
tcx: &'a ty::ctxt<'tcx>,
}

impl<'a, 'tcx> EraseRegions<'a, 'tcx> {
pub fn new(tcx: &'a ty::ctxt<'tcx>) -> EraseRegions<'a, 'tcx> {
EraseRegions {
impl<'a, 'tcx> EraseRegionsVisitor<'a, 'tcx> {
pub fn new(tcx: &'a ty::ctxt<'tcx>) -> Self {
EraseRegionsVisitor {
tcx: tcx
}
}
Expand All @@ -56,13 +58,13 @@ impl<'a, 'tcx> EraseRegions<'a, 'tcx> {
}
}

impl<'a, 'tcx> MirPass<'tcx> for EraseRegions<'a, 'tcx> {
fn run_on_mir(&mut self, mir: &mut Mir<'tcx>) {
self.visit_mir(mir);
impl MirPass for EraseRegions {
fn run_on_mir<'tcx>(&mut self, mir: &mut Mir<'tcx>, tcx: &ty::ctxt<'tcx>) {
EraseRegionsVisitor::new(tcx).visit_mir(mir);
}
}

impl<'a, 'tcx> MutVisitor<'tcx> for EraseRegions<'a, 'tcx> {
impl<'a, 'tcx> MutVisitor<'tcx> for EraseRegionsVisitor<'a, 'tcx> {
fn visit_mir(&mut self, mir: &mut Mir<'tcx>) {
self.erase_regions_return_ty(&mut mir.return_ty);
self.erase_regions_tys(mir.var_decls.iter_mut().map(|d| &mut d.ty));
Expand Down
6 changes: 0 additions & 6 deletions src/librustc_mir/transform/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,3 @@
pub mod simplify_cfg;
pub mod erase_regions;
mod util;

use rustc::mir::repr::Mir;

pub trait MirPass<'tcx> {
fn run_on_mir(&mut self, mir: &mut Mir<'tcx>);
}
6 changes: 3 additions & 3 deletions src/librustc_mir/transform/simplify_cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
use rustc::middle::const_eval::ConstVal;
use rustc::mir::repr::*;
use transform::util;
use transform::MirPass;
use rustc::mir::transform::MirPass;

pub struct SimplifyCfg;

Expand Down Expand Up @@ -118,8 +118,8 @@ impl SimplifyCfg {
}
}

impl<'tcx> MirPass<'tcx> for SimplifyCfg {
fn run_on_mir(&mut self, mir: &mut Mir<'tcx>) {
impl MirPass for SimplifyCfg {
fn run_on_mir<'tcx>(&mut self, mir: &mut Mir<'tcx>, _: &::rustc::middle::ty::ctxt<'tcx>) {
let mut changed = true;
while changed {
changed = self.simplify_branches(mir);
Expand Down
1 change: 1 addition & 0 deletions src/librustc_plugin/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@
extern crate rustc;
extern crate rustc_front;
extern crate rustc_metadata;
extern crate rustc_mir;

pub use self::registry::Registry;

Expand Down
Loading