simplify the MirPass traits and passes dramatically
Overall goal: reduce the amount of context a mir pass needs so that it resembles a query. - The hooks are no longer "threaded down" to the pass, but rather run automatically from the top-level (we also thread down the current pass number, so that the files are sorted better). - The hook now receives a *single* callback, rather than a callback per-MIR. - The traits are no longer lifetime parameters, which moved to the methods -- given that we required `for<'tcx>` objecs, there wasn't much point to that. - Several passes now store a `String` instead of a `&'l str` (again, no point).
This commit is contained in:
parent
11b6b0663a
commit
46b342fbc0
@ -50,6 +50,12 @@ impl<A, B> DepGraphSafe for (A, B)
|
||||
{
|
||||
}
|
||||
|
||||
/// Shared ref to dep-graph-safe stuff should still be dep-graph-safe.
|
||||
impl<'a, A> DepGraphSafe for &'a A
|
||||
where A: DepGraphSafe,
|
||||
{
|
||||
}
|
||||
|
||||
/// No data here! :)
|
||||
impl DepGraphSafe for () {
|
||||
}
|
||||
|
@ -18,7 +18,6 @@ use syntax::ast::NodeId;
|
||||
use util::common::time;
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::fmt;
|
||||
|
||||
/// Where a specific Mir comes from.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
@ -73,59 +72,61 @@ impl<'a, 'tcx> MirSource {
|
||||
|
||||
/// Various information about pass.
|
||||
pub trait Pass {
|
||||
// fn should_run(Session) to check if pass should run?
|
||||
fn name<'a>(&self) -> Cow<'static, str> {
|
||||
let name = unsafe { ::std::intrinsics::type_name::<Self>() };
|
||||
if let Some(tail) = name.rfind(":") {
|
||||
Cow::from(&name[tail+1..])
|
||||
} else {
|
||||
Cow::from(name)
|
||||
}
|
||||
fn name<'a>(&'a self) -> Cow<'a, str> {
|
||||
default_name::<Self>()
|
||||
}
|
||||
fn disambiguator<'a>(&'a self) -> Option<Box<fmt::Display+'a>> { None }
|
||||
|
||||
fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>);
|
||||
}
|
||||
|
||||
/// A pass which inspects the whole Mir map.
|
||||
pub trait MirMapPass<'tcx>: Pass {
|
||||
fn run_pass<'a>(
|
||||
&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
hooks: &mut [Box<for<'s> MirPassHook<'s>>]);
|
||||
/// Generates a default name for the pass based on the name of the
|
||||
/// type `T`.
|
||||
pub fn default_name<T: ?Sized>() -> Cow<'static, str> {
|
||||
let name = unsafe { ::std::intrinsics::type_name::<T>() };
|
||||
if let Some(tail) = name.rfind(":") {
|
||||
Cow::from(&name[tail+1..])
|
||||
} else {
|
||||
Cow::from(name)
|
||||
}
|
||||
}
|
||||
|
||||
pub trait MirPassHook<'tcx>: Pass {
|
||||
fn on_mir_pass<'a>(
|
||||
&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
src: MirSource,
|
||||
mir: &Mir<'tcx>,
|
||||
pass: &Pass,
|
||||
is_after: bool
|
||||
);
|
||||
pub trait PassHook {
|
||||
fn on_mir_pass<'a, 'tcx>(&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
pass: &Pass,
|
||||
pass_num: usize,
|
||||
is_after: bool);
|
||||
}
|
||||
|
||||
/// A pass which inspects Mir of functions in isolation.
|
||||
pub trait MirPass<'tcx>: Pass {
|
||||
fn run_pass<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
src: MirSource, mir: &mut Mir<'tcx>);
|
||||
/// A streamlined trait that you can implement to create a pass; the
|
||||
/// pass will be named after the type, and it will consist of a main
|
||||
/// loop that goes over each available MIR and applies `run_pass`.
|
||||
pub trait MirPass {
|
||||
fn name<'a>(&'a self) -> Cow<'a, str> {
|
||||
default_name::<Self>()
|
||||
}
|
||||
|
||||
fn run_pass<'a, 'tcx>(&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>(&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
hooks: &mut [Box<for<'s> MirPassHook<'s>>])
|
||||
{
|
||||
impl<T: MirPass> Pass for T {
|
||||
fn name<'a>(&'a self) -> Cow<'a, str> {
|
||||
MirPass::name(self)
|
||||
}
|
||||
|
||||
fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
||||
for &def_id in tcx.mir_keys(LOCAL_CRATE).iter() {
|
||||
run_hooks(tcx, hooks, self, false);
|
||||
run_map_pass_task(tcx, self, def_id);
|
||||
run_hooks(tcx, hooks, self, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn run_map_pass_task<'a, 'tcx, T: MirPass<'tcx>>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
pass: &T,
|
||||
def_id: DefId) {
|
||||
fn run_map_pass_task<'a, 'tcx, T: MirPass>(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");
|
||||
@ -138,36 +139,11 @@ fn run_map_pass_task<'a, 'tcx, T: MirPass<'tcx>>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
}
|
||||
}
|
||||
|
||||
/// 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, source, &mir, pass, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A manager for MIR passes.
|
||||
pub struct Passes {
|
||||
passes: Vec<Box<for<'tcx> MirMapPass<'tcx>>>,
|
||||
pass_hooks: Vec<Box<for<'tcx> MirPassHook<'tcx>>>,
|
||||
plugin_passes: Vec<Box<for<'tcx> MirMapPass<'tcx>>>
|
||||
passes: Vec<Box<Pass>>,
|
||||
pass_hooks: Vec<Box<PassHook>>,
|
||||
plugin_passes: Vec<Box<Pass>>
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Passes {
|
||||
@ -181,27 +157,34 @@ impl<'a, 'tcx> Passes {
|
||||
}
|
||||
|
||||
pub fn run_passes(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
||||
let Passes { ref mut passes, ref mut plugin_passes, ref mut pass_hooks } = *self;
|
||||
for pass in plugin_passes.iter_mut().chain(passes.iter_mut()) {
|
||||
time(tcx.sess.time_passes(), &*pass.name(),
|
||||
|| pass.run_pass(tcx, pass_hooks));
|
||||
// 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 hook in &self.pass_hooks {
|
||||
hook.on_mir_pass(tcx, &**pass, pass_num, false);
|
||||
}
|
||||
|
||||
time(tcx.sess.time_passes(), &*pass.name(), || pass.run_pass(tcx));
|
||||
|
||||
for hook in &self.pass_hooks {
|
||||
hook.on_mir_pass(tcx, &**pass, pass_num, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Pushes a built-in pass.
|
||||
pub fn push_pass(&mut self, pass: Box<for<'b> MirMapPass<'b>>) {
|
||||
pub fn push_pass(&mut self, pass: Box<Pass>) {
|
||||
self.passes.push(pass);
|
||||
}
|
||||
|
||||
/// Pushes a pass hook.
|
||||
pub fn push_hook(&mut self, hook: Box<for<'b> MirPassHook<'b>>) {
|
||||
pub fn push_hook(&mut self, hook: Box<PassHook>) {
|
||||
self.pass_hooks.push(hook);
|
||||
}
|
||||
}
|
||||
|
||||
/// Copies the plugin passes.
|
||||
impl ::std::iter::Extend<Box<for<'a> MirMapPass<'a>>> for Passes {
|
||||
fn extend<I: IntoIterator<Item=Box<for <'a> MirMapPass<'a>>>>(&mut self, it: I) {
|
||||
impl ::std::iter::Extend<Box<Pass>> for Passes {
|
||||
fn extend<I: IntoIterator<Item=Box<Pass>>>(&mut self, it: I) {
|
||||
self.plugin_passes.extend(it);
|
||||
}
|
||||
}
|
||||
|
@ -1003,6 +1003,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
|
||||
"dump MIR state at various points in translation"),
|
||||
dump_mir_dir: Option<String> = (None, parse_opt_string, [UNTRACKED],
|
||||
"the directory the MIR is dumped into"),
|
||||
dump_mir_exclude_pass_number: bool = (false, parse_bool, [UNTRACKED],
|
||||
"if set, exclude the pass number when dumping MIR (used in tests)"),
|
||||
perf_stats: bool = (false, parse_bool, [UNTRACKED],
|
||||
"print some performance-related statistics"),
|
||||
hir_stats: bool = (false, parse_bool, [UNTRACKED],
|
||||
|
@ -16,7 +16,7 @@ use super::{drop_flag_effects_for_location, on_lookup_result_bits};
|
||||
use super::MoveDataParamEnv;
|
||||
use rustc::ty::{self, TyCtxt};
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::transform::{Pass, MirPass, MirSource};
|
||||
use rustc::mir::transform::{MirPass, MirSource};
|
||||
use rustc::middle::const_val::ConstVal;
|
||||
use rustc::util::nodemap::FxHashMap;
|
||||
use rustc_data_structures::indexed_set::IdxSetBuf;
|
||||
@ -32,9 +32,11 @@ use std::u32;
|
||||
|
||||
pub struct ElaborateDrops;
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for ElaborateDrops {
|
||||
fn run_pass<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
src: MirSource, mir: &mut Mir<'tcx>)
|
||||
impl MirPass for ElaborateDrops {
|
||||
fn run_pass<'a, 'tcx>(&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
src: MirSource,
|
||||
mir: &mut Mir<'tcx>)
|
||||
{
|
||||
debug!("elaborate_drops({:?} @ {:?})", src, mir.span);
|
||||
match src {
|
||||
@ -74,8 +76,6 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops {
|
||||
}
|
||||
}
|
||||
|
||||
impl Pass for ElaborateDrops {}
|
||||
|
||||
/// Return the set of basic blocks whose unwind edges are known
|
||||
/// to not be reachable, because they are `drop` terminators
|
||||
/// that can't drop anything.
|
||||
|
@ -979,8 +979,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
|
||||
passes.push_pass(box mir::transform::simplify::SimplifyCfg::new("initial"));
|
||||
passes.push_pass(box mir::transform::type_check::TypeckMir);
|
||||
passes.push_pass(box mir::transform::qualify_consts::QualifyAndPromoteConstants);
|
||||
passes.push_pass(
|
||||
box mir::transform::simplify_branches::SimplifyBranches::new("initial"));
|
||||
passes.push_pass(box mir::transform::simplify_branches::SimplifyBranches::new("initial"));
|
||||
passes.push_pass(box mir::transform::simplify::SimplifyCfg::new("qualify-consts"));
|
||||
// And run everything.
|
||||
passes.run_passes(tcx);
|
||||
|
@ -192,7 +192,7 @@ fn build_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
|
||||
mem::transmute::<Mir, Mir<'tcx>>(mir)
|
||||
};
|
||||
|
||||
mir_util::dump_mir(tcx, "mir_map", &0, src, &mir);
|
||||
mir_util::dump_mir(tcx, 0, "mir_map", &0, src, &mir);
|
||||
|
||||
tcx.alloc_mir(mir)
|
||||
})
|
||||
@ -251,7 +251,7 @@ fn create_constructor_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mem::transmute::<Mir, Mir<'tcx>>(mir)
|
||||
};
|
||||
|
||||
mir_util::dump_mir(tcx, "mir_map", &0, src, &mir);
|
||||
mir_util::dump_mir(tcx, 0, "mir_map", &0, src, &mir);
|
||||
|
||||
tcx.alloc_mir(mir)
|
||||
})
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::transform::{MirPass, MirSource, Pass};
|
||||
use rustc::mir::transform::{MirPass, MirSource};
|
||||
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
|
||||
|
||||
pub struct AddCallGuards;
|
||||
@ -35,8 +35,11 @@ pub struct AddCallGuards;
|
||||
*
|
||||
*/
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for AddCallGuards {
|
||||
fn run_pass<'a>(&self, _tcx: TyCtxt<'a, 'tcx, 'tcx>, _src: MirSource, mir: &mut Mir<'tcx>) {
|
||||
impl MirPass for AddCallGuards {
|
||||
fn run_pass<'a, 'tcx>(&self,
|
||||
_tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
_src: MirSource,
|
||||
mir: &mut Mir<'tcx>) {
|
||||
add_call_guards(mir);
|
||||
}
|
||||
}
|
||||
@ -82,5 +85,3 @@ pub fn add_call_guards(mir: &mut Mir) {
|
||||
|
||||
mir.basic_blocks_mut().extend(new_blocks);
|
||||
}
|
||||
|
||||
impl Pass for AddCallGuards {}
|
||||
|
@ -30,7 +30,7 @@
|
||||
//! future.
|
||||
|
||||
use rustc::mir::{Constant, Local, LocalKind, Location, Lvalue, Mir, Operand, Rvalue, StatementKind};
|
||||
use rustc::mir::transform::{MirPass, MirSource, Pass};
|
||||
use rustc::mir::transform::{MirPass, MirSource};
|
||||
use rustc::mir::visit::MutVisitor;
|
||||
use rustc::ty::TyCtxt;
|
||||
use util::def_use::DefUseAnalysis;
|
||||
@ -38,13 +38,11 @@ use transform::qualify_consts;
|
||||
|
||||
pub struct CopyPropagation;
|
||||
|
||||
impl Pass for CopyPropagation {}
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for CopyPropagation {
|
||||
fn run_pass<'a>(&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
source: MirSource,
|
||||
mir: &mut Mir<'tcx>) {
|
||||
impl MirPass for CopyPropagation {
|
||||
fn run_pass<'a, 'tcx>(&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
source: MirSource,
|
||||
mir: &mut Mir<'tcx>) {
|
||||
match source {
|
||||
MirSource::Const(_) => {
|
||||
// Don't run on constants, because constant qualification might reject the
|
||||
|
@ -10,16 +10,16 @@
|
||||
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::transform::{MirPass, MirSource, Pass};
|
||||
use rustc::mir::transform::{MirPass, MirSource};
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
|
||||
pub struct Deaggregator;
|
||||
|
||||
impl Pass for Deaggregator {}
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for Deaggregator {
|
||||
fn run_pass<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
source: MirSource, mir: &mut Mir<'tcx>) {
|
||||
impl MirPass for Deaggregator {
|
||||
fn run_pass<'a, 'tcx>(&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));
|
||||
debug!("running on: {:?}", node_path);
|
||||
|
@ -10,70 +10,71 @@
|
||||
|
||||
//! This pass just dumps MIR at a specified point.
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::fmt;
|
||||
use std::fs::File;
|
||||
use std::io;
|
||||
|
||||
use rustc::hir::def_id::LOCAL_CRATE;
|
||||
use rustc::session::config::{OutputFilenames, OutputType};
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::transform::{Pass, MirPass, MirPassHook, MirSource};
|
||||
use rustc::mir::transform::{Pass, PassHook, MirSource};
|
||||
use util as mir_util;
|
||||
|
||||
pub struct Marker<'a>(pub &'a str);
|
||||
pub struct Marker(pub &'static str);
|
||||
|
||||
impl<'b, 'tcx> MirPass<'tcx> for Marker<'b> {
|
||||
fn run_pass<'a>(&self, _tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
_src: MirSource, _mir: &mut Mir<'tcx>)
|
||||
{}
|
||||
impl Pass for Marker {
|
||||
fn name<'a>(&'a self) -> Cow<'a, str> {
|
||||
Cow::Borrowed(self.0)
|
||||
}
|
||||
|
||||
fn run_pass<'a, 'tcx>(&self, _tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
||||
// no-op
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b> Pass for Marker<'b> {
|
||||
fn name(&self) -> ::std::borrow::Cow<'static, str> { String::from(self.0).into() }
|
||||
}
|
||||
|
||||
pub struct Disambiguator<'a> {
|
||||
pass: &'a Pass,
|
||||
pub struct Disambiguator {
|
||||
is_after: bool
|
||||
}
|
||||
|
||||
impl<'a> fmt::Display for Disambiguator<'a> {
|
||||
impl fmt::Display for Disambiguator {
|
||||
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
|
||||
let title = if self.is_after { "after" } else { "before" };
|
||||
if let Some(fmt) = self.pass.disambiguator() {
|
||||
write!(formatter, "{}-{}", fmt, title)
|
||||
} else {
|
||||
write!(formatter, "{}", title)
|
||||
}
|
||||
write!(formatter, "{}", title)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DumpMir;
|
||||
|
||||
impl<'tcx> MirPassHook<'tcx> for DumpMir {
|
||||
fn on_mir_pass<'a>(
|
||||
impl PassHook for DumpMir {
|
||||
fn on_mir_pass<'a, 'tcx>(
|
||||
&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
src: MirSource,
|
||||
mir: &Mir<'tcx>,
|
||||
pass: &Pass,
|
||||
pass_num: usize,
|
||||
is_after: bool)
|
||||
{
|
||||
mir_util::dump_mir(
|
||||
tcx,
|
||||
&*pass.name(),
|
||||
&Disambiguator {
|
||||
pass: pass,
|
||||
is_after: is_after
|
||||
},
|
||||
src,
|
||||
mir
|
||||
);
|
||||
// No dump filters enabled.
|
||||
if tcx.sess.opts.debugging_opts.dump_mir.is_none() {
|
||||
return;
|
||||
}
|
||||
|
||||
for &def_id in tcx.mir_keys(LOCAL_CRATE).iter() {
|
||||
let id = tcx.hir.as_local_node_id(def_id).unwrap();
|
||||
let source = MirSource::from_node(tcx, id);
|
||||
let mir = tcx.item_mir(def_id);
|
||||
mir_util::dump_mir(
|
||||
tcx,
|
||||
pass_num,
|
||||
&*pass.name(),
|
||||
&Disambiguator { is_after },
|
||||
source,
|
||||
&mir
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'b> Pass for DumpMir {}
|
||||
|
||||
pub fn emit_mir<'a, 'tcx>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
outputs: &OutputFilenames)
|
||||
|
@ -16,7 +16,7 @@ use rustc::ty::subst::Substs;
|
||||
use rustc::ty::{Ty, TyCtxt, ClosureSubsts};
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::visit::MutVisitor;
|
||||
use rustc::mir::transform::{MirPass, MirSource, Pass};
|
||||
use rustc::mir::transform::{MirPass, MirSource};
|
||||
|
||||
struct EraseRegionsVisitor<'a, 'tcx: 'a> {
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
@ -69,11 +69,11 @@ impl<'a, 'tcx> MutVisitor<'tcx> for EraseRegionsVisitor<'a, 'tcx> {
|
||||
|
||||
pub struct EraseRegions;
|
||||
|
||||
impl Pass for EraseRegions {}
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for EraseRegions {
|
||||
fn run_pass<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
_: MirSource, mir: &mut Mir<'tcx>) {
|
||||
impl MirPass for EraseRegions {
|
||||
fn run_pass<'a, 'tcx>(&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
_: MirSource,
|
||||
mir: &mut Mir<'tcx>) {
|
||||
EraseRegionsVisitor::new(tcx).visit_mir(mir);
|
||||
}
|
||||
}
|
||||
|
@ -10,7 +10,7 @@
|
||||
|
||||
//! Inlining pass for MIR functions
|
||||
|
||||
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
|
||||
use rustc::hir::def_id::DefId;
|
||||
|
||||
use rustc_data_structures::bitvec::BitVector;
|
||||
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
|
||||
@ -18,7 +18,7 @@ use rustc_data_structures::graph;
|
||||
|
||||
use rustc::dep_graph::DepNode;
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::transform::{self, MirMapPass, MirPassHook, MirSource, Pass};
|
||||
use rustc::mir::transform::{MirSource, Pass};
|
||||
use rustc::mir::visit::*;
|
||||
use rustc::traits;
|
||||
use rustc::ty::{self, Ty, TyCtxt};
|
||||
@ -42,12 +42,8 @@ const UNKNOWN_SIZE_COST: usize = 10;
|
||||
|
||||
pub struct Inline;
|
||||
|
||||
impl<'tcx> MirMapPass<'tcx> for Inline {
|
||||
fn run_pass<'a>(
|
||||
&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
hooks: &mut [Box<for<'s> MirPassHook<'s>>]) {
|
||||
|
||||
impl Pass for Inline {
|
||||
fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
||||
if tcx.sess.opts.debugging_opts.mir_opt_level < 2 { return; }
|
||||
|
||||
let _ignore = tcx.dep_graph.in_ignore();
|
||||
@ -58,18 +54,12 @@ impl<'tcx> MirMapPass<'tcx> for Inline {
|
||||
tcx: tcx,
|
||||
};
|
||||
|
||||
transform::run_hooks(tcx, hooks, self, false);
|
||||
|
||||
for scc in callgraph.scc_iter() {
|
||||
inliner.inline_scc(&callgraph, &scc);
|
||||
}
|
||||
|
||||
transform::run_hooks(tcx, hooks, self, true);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Pass for Inline { }
|
||||
|
||||
struct Inliner<'a, 'tcx: 'a> {
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
}
|
||||
|
@ -11,7 +11,7 @@
|
||||
//! Performs various peephole optimizations.
|
||||
|
||||
use rustc::mir::{Location, Lvalue, Mir, Operand, ProjectionElem, Rvalue, Local};
|
||||
use rustc::mir::transform::{MirPass, MirSource, Pass};
|
||||
use rustc::mir::transform::{MirPass, MirSource};
|
||||
use rustc::mir::visit::{MutVisitor, Visitor};
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc::util::nodemap::FxHashSet;
|
||||
@ -20,13 +20,11 @@ use std::mem;
|
||||
|
||||
pub struct InstCombine;
|
||||
|
||||
impl Pass for InstCombine {}
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for InstCombine {
|
||||
fn run_pass<'a>(&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
_: MirSource,
|
||||
mir: &mut Mir<'tcx>) {
|
||||
impl MirPass for InstCombine {
|
||||
fn run_pass<'a, 'tcx>(&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
_: MirSource,
|
||||
mir: &mut Mir<'tcx>) {
|
||||
// We only run when optimizing MIR (at any level).
|
||||
if tcx.sess.opts.debugging_opts.mir_opt_level == 0 {
|
||||
return
|
||||
|
@ -14,10 +14,25 @@
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::visit::MutVisitor;
|
||||
use rustc::mir::transform::{Pass, MirPass, MirSource};
|
||||
use rustc::mir::transform::{MirPass, MirSource};
|
||||
|
||||
pub struct NoLandingPads;
|
||||
|
||||
impl MirPass for NoLandingPads {
|
||||
fn run_pass<'a, 'tcx>(&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
_: MirSource,
|
||||
mir: &mut Mir<'tcx>) {
|
||||
no_landing_pads(tcx, mir)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn no_landing_pads<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, mir: &mut Mir<'tcx>) {
|
||||
if tcx.sess.no_landing_pads() {
|
||||
NoLandingPads.visit_mir(mir);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> MutVisitor<'tcx> for NoLandingPads {
|
||||
fn visit_terminator(&mut self,
|
||||
bb: BasicBlock,
|
||||
@ -41,18 +56,3 @@ impl<'tcx> MutVisitor<'tcx> for NoLandingPads {
|
||||
self.super_terminator(bb, terminator, location);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn no_landing_pads<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, mir: &mut Mir<'tcx>) {
|
||||
if tcx.sess.no_landing_pads() {
|
||||
NoLandingPads.visit_mir(mir);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for NoLandingPads {
|
||||
fn run_pass<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
_: MirSource, mir: &mut Mir<'tcx>) {
|
||||
no_landing_pads(tcx, mir)
|
||||
}
|
||||
}
|
||||
|
||||
impl Pass for NoLandingPads {}
|
||||
|
@ -27,7 +27,7 @@ use rustc::ty::cast::CastTy;
|
||||
use rustc::ty::maps::Providers;
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::traversal::ReversePostorder;
|
||||
use rustc::mir::transform::{Pass, MirMapPass, MirPassHook, MirSource};
|
||||
use rustc::mir::transform::{Pass, MirSource};
|
||||
use rustc::mir::visit::{LvalueContext, Visitor};
|
||||
use rustc::middle::lang_items;
|
||||
use syntax::abi::Abi;
|
||||
@ -939,12 +939,9 @@ fn qualify_const_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
|
||||
pub struct QualifyAndPromoteConstants;
|
||||
|
||||
impl Pass for QualifyAndPromoteConstants {}
|
||||
|
||||
impl<'tcx> MirMapPass<'tcx> for QualifyAndPromoteConstants {
|
||||
fn run_pass<'a>(&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
hooks: &mut [Box<for<'s> MirPassHook<'s>>])
|
||||
impl Pass for QualifyAndPromoteConstants {
|
||||
fn run_pass<'a, 'tcx>(&self,
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>)
|
||||
{
|
||||
for &def_id in tcx.mir_keys(LOCAL_CRATE).iter() {
|
||||
let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id));
|
||||
@ -959,20 +956,15 @@ impl<'tcx> MirMapPass<'tcx> for QualifyAndPromoteConstants {
|
||||
let mir = &mut tcx.mir(def_id).borrow_mut();
|
||||
tcx.dep_graph.write(DepNode::Mir(def_id));
|
||||
|
||||
for hook in &mut *hooks {
|
||||
hook.on_mir_pass(tcx, src, mir, self, false);
|
||||
}
|
||||
self.run_pass(tcx, src, mir);
|
||||
for hook in &mut *hooks {
|
||||
hook.on_mir_pass(tcx, src, mir, self, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> QualifyAndPromoteConstants {
|
||||
fn run_pass<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
src: MirSource, mir: &mut Mir<'tcx>) {
|
||||
impl<'a, 'tcx> QualifyAndPromoteConstants {
|
||||
fn run_pass(&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);
|
||||
let mode = match src {
|
||||
|
@ -41,15 +41,15 @@ use rustc_data_structures::bitvec::BitVector;
|
||||
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::transform::{MirPass, MirSource, Pass};
|
||||
use rustc::mir::transform::{MirPass, MirSource};
|
||||
use rustc::mir::visit::{MutVisitor, Visitor, LvalueContext};
|
||||
use std::fmt;
|
||||
use std::borrow::Cow;
|
||||
|
||||
pub struct SimplifyCfg<'a> { label: &'a str }
|
||||
pub struct SimplifyCfg { label: String }
|
||||
|
||||
impl<'a> SimplifyCfg<'a> {
|
||||
pub fn new(label: &'a str) -> Self {
|
||||
SimplifyCfg { label: label }
|
||||
impl SimplifyCfg {
|
||||
pub fn new(label: &str) -> Self {
|
||||
SimplifyCfg { label: format!("SimplifyCfg-{}", label) }
|
||||
}
|
||||
}
|
||||
|
||||
@ -61,22 +61,20 @@ pub fn simplify_cfg(mir: &mut Mir) {
|
||||
mir.basic_blocks_mut().raw.shrink_to_fit();
|
||||
}
|
||||
|
||||
impl<'l, 'tcx> MirPass<'tcx> for SimplifyCfg<'l> {
|
||||
fn run_pass<'a>(&self, _tcx: TyCtxt<'a, 'tcx, 'tcx>, _src: MirSource, mir: &mut Mir<'tcx>) {
|
||||
impl MirPass for SimplifyCfg {
|
||||
fn name<'a>(&'a self) -> Cow<'a, str> {
|
||||
Cow::Borrowed(&self.label)
|
||||
}
|
||||
|
||||
fn run_pass<'a, 'tcx>(&self,
|
||||
_tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
_src: MirSource,
|
||||
mir: &mut Mir<'tcx>) {
|
||||
debug!("SimplifyCfg({:?}) - simplifying {:?}", self.label, mir);
|
||||
simplify_cfg(mir);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'l> Pass for SimplifyCfg<'l> {
|
||||
fn disambiguator<'a>(&'a self) -> Option<Box<fmt::Display+'a>> {
|
||||
Some(Box::new(self.label))
|
||||
}
|
||||
|
||||
// avoid calling `type_name` - it contains `<'static>`
|
||||
fn name(&self) -> ::std::borrow::Cow<'static, str> { "SimplifyCfg".into() }
|
||||
}
|
||||
|
||||
pub struct CfgSimplifier<'a, 'tcx: 'a> {
|
||||
basic_blocks: &'a mut IndexVec<BasicBlock, BasicBlockData<'tcx>>,
|
||||
pred_count: IndexVec<BasicBlock, u32>
|
||||
@ -315,12 +313,11 @@ pub fn remove_dead_blocks(mir: &mut Mir) {
|
||||
|
||||
pub struct SimplifyLocals;
|
||||
|
||||
impl Pass for SimplifyLocals {
|
||||
fn name(&self) -> ::std::borrow::Cow<'static, str> { "SimplifyLocals".into() }
|
||||
}
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for SimplifyLocals {
|
||||
fn run_pass<'a>(&self, _: TyCtxt<'a, 'tcx, 'tcx>, _: MirSource, mir: &mut Mir<'tcx>) {
|
||||
impl MirPass for SimplifyLocals {
|
||||
fn run_pass<'a, 'tcx>(&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
|
||||
|
@ -12,21 +12,28 @@
|
||||
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc::middle::const_val::ConstVal;
|
||||
use rustc::mir::transform::{MirPass, MirSource, Pass};
|
||||
use rustc::mir::transform::{MirPass, MirSource};
|
||||
use rustc::mir::*;
|
||||
|
||||
use std::fmt;
|
||||
use std::borrow::Cow;
|
||||
|
||||
pub struct SimplifyBranches<'a> { label: &'a str }
|
||||
pub struct SimplifyBranches { label: String }
|
||||
|
||||
impl<'a> SimplifyBranches<'a> {
|
||||
pub fn new(label: &'a str) -> Self {
|
||||
SimplifyBranches { label: label }
|
||||
impl SimplifyBranches {
|
||||
pub fn new(label: &str) -> Self {
|
||||
SimplifyBranches { label: format!("SimplifyBranches-{}", label) }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'l, 'tcx> MirPass<'tcx> for SimplifyBranches<'l> {
|
||||
fn run_pass<'a>(&self, _tcx: TyCtxt<'a, 'tcx, 'tcx>, _src: MirSource, mir: &mut Mir<'tcx>) {
|
||||
impl MirPass for SimplifyBranches {
|
||||
fn name<'a>(&'a self) -> Cow<'a, str> {
|
||||
Cow::Borrowed(&self.label)
|
||||
}
|
||||
|
||||
fn run_pass<'a, 'tcx>(&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 {
|
||||
@ -60,11 +67,3 @@ impl<'l, 'tcx> MirPass<'tcx> for SimplifyBranches<'l> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'l> Pass for SimplifyBranches<'l> {
|
||||
fn disambiguator<'a>(&'a self) -> Option<Box<fmt::Display+'a>> {
|
||||
Some(Box::new(self.label))
|
||||
}
|
||||
|
||||
// avoid calling `type_name` - it contains `<'static>`
|
||||
fn name(&self) -> ::std::borrow::Cow<'static, str> { "SimplifyBranches".into() }
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ use rustc::ty::{self, Ty, TyCtxt, TypeVariants};
|
||||
use rustc::middle::const_val::ConstVal;
|
||||
use rustc::mir::*;
|
||||
use rustc::mir::tcx::LvalueTy;
|
||||
use rustc::mir::transform::{MirPass, MirSource, Pass};
|
||||
use rustc::mir::transform::{MirPass, MirSource};
|
||||
use rustc::mir::visit::Visitor;
|
||||
use std::fmt;
|
||||
use syntax::ast;
|
||||
@ -737,9 +737,11 @@ impl TypeckMir {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> MirPass<'tcx> for TypeckMir {
|
||||
fn run_pass<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
src: MirSource, mir: &mut Mir<'tcx>) {
|
||||
impl MirPass for TypeckMir {
|
||||
fn run_pass<'a, 'tcx>(&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);
|
||||
debug!("run_pass: {}", tcx.item_path_str(def_id));
|
||||
@ -765,6 +767,3 @@ impl<'tcx> MirPass<'tcx> for TypeckMir {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
impl Pass for TypeckMir {
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ const ALIGN: usize = 40;
|
||||
/// representation of the mir into:
|
||||
///
|
||||
/// ```text
|
||||
/// rustc.node<node_id>.<pass_name>.<disambiguator>
|
||||
/// rustc.node<node_id>.<pass_num>.<pass_name>.<disambiguator>
|
||||
/// ```
|
||||
///
|
||||
/// Output from this function is controlled by passing `-Z dump-mir=<filter>`,
|
||||
@ -39,15 +39,16 @@ const ALIGN: usize = 40;
|
||||
/// that can appear in the pass-name or the `item_path_str` for the given
|
||||
/// node-id. If any one of the substrings match, the data is dumped out.
|
||||
pub fn dump_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
pass_num: usize,
|
||||
pass_name: &str,
|
||||
disambiguator: &Display,
|
||||
src: MirSource,
|
||||
source: MirSource,
|
||||
mir: &Mir<'tcx>) {
|
||||
let filters = match tcx.sess.opts.debugging_opts.dump_mir {
|
||||
None => return,
|
||||
Some(ref filters) => filters,
|
||||
};
|
||||
let node_id = src.item_id();
|
||||
let node_id = source.item_id();
|
||||
let node_path = tcx.item_path_str(tcx.hir.local_def_id(node_id));
|
||||
let is_matched =
|
||||
filters.split("&")
|
||||
@ -60,26 +61,47 @@ pub fn dump_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
return;
|
||||
}
|
||||
|
||||
let promotion_id = match src {
|
||||
dump_matched_mir_node(tcx, pass_num, pass_name, &node_path, disambiguator, source, mir);
|
||||
for (index, promoted_mir) in mir.promoted.iter_enumerated() {
|
||||
let promoted_source = MirSource::Promoted(source.item_id(), index);
|
||||
dump_matched_mir_node(tcx, pass_num, pass_name, &node_path, disambiguator,
|
||||
promoted_source, promoted_mir);
|
||||
}
|
||||
}
|
||||
|
||||
fn dump_matched_mir_node<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
pass_num: usize,
|
||||
pass_name: &str,
|
||||
node_path: &str,
|
||||
disambiguator: &Display,
|
||||
source: MirSource,
|
||||
mir: &Mir<'tcx>) {
|
||||
let promotion_id = match source {
|
||||
MirSource::Promoted(_, id) => format!("-{:?}", id),
|
||||
_ => String::new()
|
||||
};
|
||||
|
||||
let pass_num = if tcx.sess.opts.debugging_opts.dump_mir_exclude_pass_number {
|
||||
format!("")
|
||||
} else {
|
||||
format!(".{:03}", pass_num)
|
||||
};
|
||||
|
||||
let mut file_path = PathBuf::new();
|
||||
if let Some(ref file_dir) = tcx.sess.opts.debugging_opts.dump_mir_dir {
|
||||
let p = Path::new(file_dir);
|
||||
file_path.push(p);
|
||||
};
|
||||
let file_name = format!("rustc.node{}{}.{}.{}.mir",
|
||||
node_id, promotion_id, pass_name, disambiguator);
|
||||
let file_name = format!("rustc.node{}{}{}.{}.{}.mir",
|
||||
source.item_id(), promotion_id, pass_num, pass_name, disambiguator);
|
||||
file_path.push(&file_name);
|
||||
let _ = fs::File::create(&file_path).and_then(|mut file| {
|
||||
writeln!(file, "// MIR for `{}`", node_path)?;
|
||||
writeln!(file, "// node_id = {}", node_id)?;
|
||||
writeln!(file, "// source = {:?}", source)?;
|
||||
writeln!(file, "// pass_name = {}", pass_name)?;
|
||||
writeln!(file, "// disambiguator = {}", disambiguator)?;
|
||||
writeln!(file, "")?;
|
||||
write_mir_fn(tcx, src, mir, &mut file)?;
|
||||
write_mir_fn(tcx, source, mir, &mut file)?;
|
||||
Ok(())
|
||||
});
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ fn main() {
|
||||
}
|
||||
|
||||
// END RUST SOURCE
|
||||
// START rustc.node4.SimplifyCfg.initial-after.mir
|
||||
// START rustc.node4.SimplifyCfg-initial.after.mir
|
||||
// bb0: {
|
||||
// StorageLive(_1);
|
||||
// _1 = const false;
|
||||
@ -82,4 +82,4 @@ fn main() {
|
||||
// StorageDead(_1);
|
||||
// return;
|
||||
// }
|
||||
// END rustc.node4.SimplifyCfg.initial-after.mir
|
||||
// END rustc.node4.SimplifyCfg-initial.after.mir
|
||||
|
@ -21,7 +21,7 @@ fn main() {
|
||||
}
|
||||
|
||||
// END RUST SOURCE
|
||||
// START rustc.node4.SimplifyCfg.initial-after.mir
|
||||
// START rustc.node4.SimplifyCfg-initial.after.mir
|
||||
// bb0: {
|
||||
// StorageLive(_1);
|
||||
// _1 = const false;
|
||||
@ -48,4 +48,4 @@ fn main() {
|
||||
// _2 = ();
|
||||
// goto -> bb1;
|
||||
// }
|
||||
// END rustc.node4.SimplifyCfg.initial-after.mir
|
||||
// END rustc.node4.SimplifyCfg-initial.after.mir
|
||||
|
@ -15,13 +15,13 @@ fn main() {
|
||||
}
|
||||
|
||||
// END RUST SOURCE
|
||||
// START rustc.node4.SimplifyBranches.initial-before.mir
|
||||
// START rustc.node4.SimplifyBranches-initial.before.mir
|
||||
// bb0: {
|
||||
// switchInt(const false) -> [0u8: bb2, otherwise: bb1];
|
||||
// }
|
||||
// END rustc.node4.SimplifyBranches.initial-before.mir
|
||||
// START rustc.node4.SimplifyBranches.initial-after.mir
|
||||
// END rustc.node4.SimplifyBranches-initial.before.mir
|
||||
// START rustc.node4.SimplifyBranches-initial.after.mir
|
||||
// bb0: {
|
||||
// goto -> bb2;
|
||||
// }
|
||||
// END rustc.node4.SimplifyBranches.initial-after.mir
|
||||
// END rustc.node4.SimplifyBranches-initial.after.mir
|
||||
|
@ -1402,18 +1402,16 @@ actual:\n\
|
||||
}
|
||||
}
|
||||
MirOpt => {
|
||||
args.extend(["-Z",
|
||||
"dump-mir=all",
|
||||
"-Z",
|
||||
"mir-opt-level=3",
|
||||
"-Z"]
|
||||
args.extend(["-Zdump-mir=all",
|
||||
"-Zmir-opt-level=3",
|
||||
"-Zdump-mir-exclude-pass-number"]
|
||||
.iter()
|
||||
.map(|s| s.to_string()));
|
||||
|
||||
|
||||
let mir_dump_dir = self.get_mir_dump_dir();
|
||||
create_dir_all(mir_dump_dir.as_path()).unwrap();
|
||||
let mut dir_opt = "dump-mir-dir=".to_string();
|
||||
let mut dir_opt = "-Zdump-mir-dir=".to_string();
|
||||
dir_opt.push_str(mir_dump_dir.to_str().unwrap());
|
||||
debug!("dir_opt: {:?}", dir_opt);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user