Auto merge of #58103 - RalfJung:mir-shim-dump, r=eddyb
Make -Zdump-mir dump shims Fixes https://github.com/rust-lang/rust/issues/53532 by (a) making the MIR shim generation use the MIR pass infrastructure, and (b) fixing said infrastructure to handle the fallout. Cc @eddyb @oli-obk
This commit is contained in:
commit
de111e6367
28 changed files with 173 additions and 130 deletions
|
@ -371,8 +371,12 @@ impl<'hir> Map<'hir> {
|
||||||
let def_id = self.local_def_id(variant.node.data.id());
|
let def_id = self.local_def_id(variant.node.data.id());
|
||||||
Some(Def::Variant(def_id))
|
Some(Def::Variant(def_id))
|
||||||
}
|
}
|
||||||
Node::Field(_) |
|
Node::StructCtor(variant) => {
|
||||||
|
let def_id = self.local_def_id(variant.id());
|
||||||
|
Some(Def::StructCtor(def_id, def::CtorKind::from_hir(variant)))
|
||||||
|
}
|
||||||
Node::AnonConst(_) |
|
Node::AnonConst(_) |
|
||||||
|
Node::Field(_) |
|
||||||
Node::Expr(_) |
|
Node::Expr(_) |
|
||||||
Node::Stmt(_) |
|
Node::Stmt(_) |
|
||||||
Node::PathSegment(_) |
|
Node::PathSegment(_) |
|
||||||
|
@ -380,7 +384,6 @@ impl<'hir> Map<'hir> {
|
||||||
Node::TraitRef(_) |
|
Node::TraitRef(_) |
|
||||||
Node::Pat(_) |
|
Node::Pat(_) |
|
||||||
Node::Binding(_) |
|
Node::Binding(_) |
|
||||||
Node::StructCtor(_) |
|
|
||||||
Node::Lifetime(_) |
|
Node::Lifetime(_) |
|
||||||
Node::Visibility(_) |
|
Node::Visibility(_) |
|
||||||
Node::Block(_) |
|
Node::Block(_) |
|
||||||
|
|
|
@ -209,7 +209,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
|
||||||
|
|
||||||
fn dump_mir_results<'a, 'gcx, 'tcx>(
|
fn dump_mir_results<'a, 'gcx, 'tcx>(
|
||||||
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
|
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
|
||||||
source: MirSource,
|
source: MirSource<'tcx>,
|
||||||
mir: &Mir<'tcx>,
|
mir: &Mir<'tcx>,
|
||||||
regioncx: &RegionInferenceContext<'_>,
|
regioncx: &RegionInferenceContext<'_>,
|
||||||
closure_region_requirements: &Option<ClosureRegionRequirements<'_>>,
|
closure_region_requirements: &Option<ClosureRegionRequirements<'_>>,
|
||||||
|
|
|
@ -2427,8 +2427,13 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
|
||||||
pub struct TypeckMir;
|
pub struct TypeckMir;
|
||||||
|
|
||||||
impl MirPass for TypeckMir {
|
impl MirPass for TypeckMir {
|
||||||
fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, src: MirSource, mir: &mut Mir<'tcx>) {
|
fn run_pass<'a, 'tcx>(
|
||||||
let def_id = src.def_id;
|
&self,
|
||||||
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
|
src: MirSource<'tcx>,
|
||||||
|
mir: &mut Mir<'tcx>,
|
||||||
|
) {
|
||||||
|
let def_id = src.def_id();
|
||||||
debug!("run_pass: {:?}", def_id);
|
debug!("run_pass: {:?}", def_id);
|
||||||
|
|
||||||
// When NLL is enabled, the borrow checker runs the typeck
|
// When NLL is enabled, the borrow checker runs the typeck
|
||||||
|
|
|
@ -16,8 +16,10 @@ use syntax_pos::Span;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::iter;
|
use std::iter;
|
||||||
|
|
||||||
use crate::transform::{add_moves_for_packed_drops, add_call_guards};
|
use crate::transform::{
|
||||||
use crate::transform::{remove_noop_landing_pads, no_landing_pads, simplify};
|
add_moves_for_packed_drops, add_call_guards,
|
||||||
|
remove_noop_landing_pads, no_landing_pads, simplify, run_passes
|
||||||
|
};
|
||||||
use crate::util::elaborate_drops::{self, DropElaborator, DropStyle, DropFlagMode};
|
use crate::util::elaborate_drops::{self, DropElaborator, DropStyle, DropFlagMode};
|
||||||
use crate::util::patch::MirPatch;
|
use crate::util::patch::MirPatch;
|
||||||
|
|
||||||
|
@ -113,12 +115,15 @@ fn make_shim<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
debug!("make_shim({:?}) = untransformed {:?}", instance, result);
|
debug!("make_shim({:?}) = untransformed {:?}", instance, result);
|
||||||
add_moves_for_packed_drops::add_moves_for_packed_drops(
|
|
||||||
tcx, &mut result, instance.def_id());
|
run_passes(tcx, &mut result, instance, MirPhase::Const, &[
|
||||||
no_landing_pads::no_landing_pads(tcx, &mut result);
|
&add_moves_for_packed_drops::AddMovesForPackedDrops,
|
||||||
remove_noop_landing_pads::remove_noop_landing_pads(tcx, &mut result);
|
&no_landing_pads::NoLandingPads,
|
||||||
simplify::simplify_cfg(&mut result);
|
&remove_noop_landing_pads::RemoveNoopLandingPads,
|
||||||
add_call_guards::CriticalCallEdges.add_call_guards(&mut result);
|
&simplify::SimplifyCfg::new("make_shim"),
|
||||||
|
&add_call_guards::CriticalCallEdges,
|
||||||
|
]);
|
||||||
|
|
||||||
debug!("make_shim({:?}) = {:?}", instance, result);
|
debug!("make_shim({:?}) = {:?}", instance, result);
|
||||||
|
|
||||||
tcx.alloc_mir(result)
|
tcx.alloc_mir(result)
|
||||||
|
|
|
@ -33,7 +33,7 @@ pub use self::AddCallGuards::*;
|
||||||
impl MirPass for AddCallGuards {
|
impl MirPass for AddCallGuards {
|
||||||
fn run_pass<'a, 'tcx>(&self,
|
fn run_pass<'a, 'tcx>(&self,
|
||||||
_tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
_tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
_src: MirSource,
|
_src: MirSource<'tcx>,
|
||||||
mir: &mut Mir<'tcx>) {
|
mir: &mut Mir<'tcx>) {
|
||||||
self.add_call_guards(mir);
|
self.add_call_guards(mir);
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,11 +42,11 @@ pub struct AddMovesForPackedDrops;
|
||||||
impl MirPass for AddMovesForPackedDrops {
|
impl MirPass for AddMovesForPackedDrops {
|
||||||
fn run_pass<'a, 'tcx>(&self,
|
fn run_pass<'a, 'tcx>(&self,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
src: MirSource,
|
src: MirSource<'tcx>,
|
||||||
mir: &mut Mir<'tcx>)
|
mir: &mut Mir<'tcx>)
|
||||||
{
|
{
|
||||||
debug!("add_moves_for_packed_drops({:?} @ {:?})", src, mir.span);
|
debug!("add_moves_for_packed_drops({:?} @ {:?})", src, mir.span);
|
||||||
add_moves_for_packed_drops(tcx, mir, src.def_id);
|
add_moves_for_packed_drops(tcx, mir, src.def_id());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ fn may_have_reference<'a, 'gcx, 'tcx>(ty: Ty<'tcx>, tcx: TyCtxt<'a, 'gcx, 'tcx>)
|
||||||
impl MirPass for AddRetag {
|
impl MirPass for AddRetag {
|
||||||
fn run_pass<'a, 'tcx>(&self,
|
fn run_pass<'a, 'tcx>(&self,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
_src: MirSource,
|
_src: MirSource<'tcx>,
|
||||||
mir: &mut Mir<'tcx>)
|
mir: &mut Mir<'tcx>)
|
||||||
{
|
{
|
||||||
if !tcx.sess.opts.debugging_opts.mir_emit_retag {
|
if !tcx.sess.opts.debugging_opts.mir_emit_retag {
|
||||||
|
|
|
@ -35,7 +35,7 @@ pub struct DeleteAscribeUserType;
|
||||||
impl MirPass for CleanAscribeUserType {
|
impl MirPass for CleanAscribeUserType {
|
||||||
fn run_pass<'a, 'tcx>(&self,
|
fn run_pass<'a, 'tcx>(&self,
|
||||||
_tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
_tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
_source: MirSource,
|
_source: MirSource<'tcx>,
|
||||||
mir: &mut Mir<'tcx>) {
|
mir: &mut Mir<'tcx>) {
|
||||||
let mut delete = DeleteAscribeUserType;
|
let mut delete = DeleteAscribeUserType;
|
||||||
delete.visit_mir(mir);
|
delete.visit_mir(mir);
|
||||||
|
@ -69,7 +69,7 @@ pub struct DeleteFakeBorrows {
|
||||||
impl MirPass for CleanFakeReadsAndBorrows {
|
impl MirPass for CleanFakeReadsAndBorrows {
|
||||||
fn run_pass<'a, 'tcx>(&self,
|
fn run_pass<'a, 'tcx>(&self,
|
||||||
_tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
_tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
_source: MirSource,
|
_source: MirSource<'tcx>,
|
||||||
mir: &mut Mir<'tcx>) {
|
mir: &mut Mir<'tcx>) {
|
||||||
let mut delete_reads = DeleteAndRecordFakeReads::default();
|
let mut delete_reads = DeleteAndRecordFakeReads::default();
|
||||||
delete_reads.visit_mir(mir);
|
delete_reads.visit_mir(mir);
|
||||||
|
|
|
@ -30,7 +30,7 @@ pub struct ConstProp;
|
||||||
impl MirPass for ConstProp {
|
impl MirPass for ConstProp {
|
||||||
fn run_pass<'a, 'tcx>(&self,
|
fn run_pass<'a, 'tcx>(&self,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
source: MirSource,
|
source: MirSource<'tcx>,
|
||||||
mir: &mut Mir<'tcx>) {
|
mir: &mut Mir<'tcx>) {
|
||||||
// will be evaluated by miri and produce its errors there
|
// will be evaluated by miri and produce its errors there
|
||||||
if source.promoted.is_some() {
|
if source.promoted.is_some() {
|
||||||
|
@ -38,11 +38,11 @@ impl MirPass for ConstProp {
|
||||||
}
|
}
|
||||||
|
|
||||||
use rustc::hir::map::blocks::FnLikeNode;
|
use rustc::hir::map::blocks::FnLikeNode;
|
||||||
let node_id = tcx.hir().as_local_node_id(source.def_id)
|
let node_id = tcx.hir().as_local_node_id(source.def_id())
|
||||||
.expect("Non-local call to local provider is_const_fn");
|
.expect("Non-local call to local provider is_const_fn");
|
||||||
|
|
||||||
let is_fn_like = FnLikeNode::from_node(tcx.hir().get(node_id)).is_some();
|
let is_fn_like = FnLikeNode::from_node(tcx.hir().get(node_id)).is_some();
|
||||||
let is_assoc_const = match tcx.describe_def(source.def_id) {
|
let is_assoc_const = match tcx.describe_def(source.def_id()) {
|
||||||
Some(Def::AssociatedConst(_)) => true,
|
Some(Def::AssociatedConst(_)) => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
};
|
};
|
||||||
|
@ -50,11 +50,11 @@ impl MirPass for ConstProp {
|
||||||
// Only run const prop on functions, methods, closures and associated constants
|
// Only run const prop on functions, methods, closures and associated constants
|
||||||
if !is_fn_like && !is_assoc_const {
|
if !is_fn_like && !is_assoc_const {
|
||||||
// skip anon_const/statics/consts because they'll be evaluated by miri anyway
|
// skip anon_const/statics/consts because they'll be evaluated by miri anyway
|
||||||
trace!("ConstProp skipped for {:?}", source.def_id);
|
trace!("ConstProp skipped for {:?}", source.def_id());
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
trace!("ConstProp starting for {:?}", source.def_id);
|
trace!("ConstProp starting for {:?}", source.def_id());
|
||||||
|
|
||||||
// FIXME(oli-obk, eddyb) Optimize locals (or even local paths) to hold
|
// FIXME(oli-obk, eddyb) Optimize locals (or even local paths) to hold
|
||||||
// constants, instead of just checking for const-folding succeeding.
|
// constants, instead of just checking for const-folding succeeding.
|
||||||
|
@ -63,7 +63,7 @@ impl MirPass for ConstProp {
|
||||||
let mut optimization_finder = ConstPropagator::new(mir, tcx, source);
|
let mut optimization_finder = ConstPropagator::new(mir, tcx, source);
|
||||||
optimization_finder.visit_mir(mir);
|
optimization_finder.visit_mir(mir);
|
||||||
|
|
||||||
trace!("ConstProp done for {:?}", source.def_id);
|
trace!("ConstProp done for {:?}", source.def_id());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ struct ConstPropagator<'a, 'mir, 'tcx:'a+'mir> {
|
||||||
ecx: EvalContext<'a, 'mir, 'tcx, CompileTimeInterpreter<'a, 'mir, 'tcx>>,
|
ecx: EvalContext<'a, 'mir, 'tcx, CompileTimeInterpreter<'a, 'mir, 'tcx>>,
|
||||||
mir: &'mir Mir<'tcx>,
|
mir: &'mir Mir<'tcx>,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
source: MirSource,
|
source: MirSource<'tcx>,
|
||||||
places: IndexVec<Local, Option<Const<'tcx>>>,
|
places: IndexVec<Local, Option<Const<'tcx>>>,
|
||||||
can_const_prop: IndexVec<Local, bool>,
|
can_const_prop: IndexVec<Local, bool>,
|
||||||
param_env: ParamEnv<'tcx>,
|
param_env: ParamEnv<'tcx>,
|
||||||
|
@ -107,10 +107,10 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
|
||||||
fn new(
|
fn new(
|
||||||
mir: &'mir Mir<'tcx>,
|
mir: &'mir Mir<'tcx>,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
source: MirSource,
|
source: MirSource<'tcx>,
|
||||||
) -> ConstPropagator<'a, 'mir, 'tcx> {
|
) -> ConstPropagator<'a, 'mir, 'tcx> {
|
||||||
let param_env = tcx.param_env(source.def_id);
|
let param_env = tcx.param_env(source.def_id());
|
||||||
let ecx = mk_eval_cx(tcx, tcx.def_span(source.def_id), param_env);
|
let ecx = mk_eval_cx(tcx, tcx.def_span(source.def_id()), param_env);
|
||||||
ConstPropagator {
|
ConstPropagator {
|
||||||
ecx,
|
ecx,
|
||||||
mir,
|
mir,
|
||||||
|
@ -284,13 +284,13 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
Place::Promoted(ref promoted) => {
|
Place::Promoted(ref promoted) => {
|
||||||
let generics = self.tcx.generics_of(self.source.def_id);
|
let generics = self.tcx.generics_of(self.source.def_id());
|
||||||
if generics.requires_monomorphization(self.tcx) {
|
if generics.requires_monomorphization(self.tcx) {
|
||||||
// FIXME: can't handle code with generics
|
// FIXME: can't handle code with generics
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
let substs = Substs::identity_for_item(self.tcx, self.source.def_id);
|
let substs = Substs::identity_for_item(self.tcx, self.source.def_id());
|
||||||
let instance = Instance::new(self.source.def_id, substs);
|
let instance = Instance::new(self.source.def_id(), substs);
|
||||||
let cid = GlobalId {
|
let cid = GlobalId {
|
||||||
instance,
|
instance,
|
||||||
promoted: Some(promoted.0),
|
promoted: Some(promoted.0),
|
||||||
|
@ -358,10 +358,10 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
Rvalue::UnaryOp(op, ref arg) => {
|
Rvalue::UnaryOp(op, ref arg) => {
|
||||||
let def_id = if self.tcx.is_closure(self.source.def_id) {
|
let def_id = if self.tcx.is_closure(self.source.def_id()) {
|
||||||
self.tcx.closure_base_def_id(self.source.def_id)
|
self.tcx.closure_base_def_id(self.source.def_id())
|
||||||
} else {
|
} else {
|
||||||
self.source.def_id
|
self.source.def_id()
|
||||||
};
|
};
|
||||||
let generics = self.tcx.generics_of(def_id);
|
let generics = self.tcx.generics_of(def_id);
|
||||||
if generics.requires_monomorphization(self.tcx) {
|
if generics.requires_monomorphization(self.tcx) {
|
||||||
|
@ -398,10 +398,10 @@ impl<'a, 'mir, 'tcx> ConstPropagator<'a, 'mir, 'tcx> {
|
||||||
Rvalue::BinaryOp(op, ref left, ref right) => {
|
Rvalue::BinaryOp(op, ref left, ref right) => {
|
||||||
trace!("rvalue binop {:?} for {:?} and {:?}", op, left, right);
|
trace!("rvalue binop {:?} for {:?} and {:?}", op, left, right);
|
||||||
let right = self.eval_operand(right, source_info)?;
|
let right = self.eval_operand(right, source_info)?;
|
||||||
let def_id = if self.tcx.is_closure(self.source.def_id) {
|
let def_id = if self.tcx.is_closure(self.source.def_id()) {
|
||||||
self.tcx.closure_base_def_id(self.source.def_id)
|
self.tcx.closure_base_def_id(self.source.def_id())
|
||||||
} else {
|
} else {
|
||||||
self.source.def_id
|
self.source.def_id()
|
||||||
};
|
};
|
||||||
let generics = self.tcx.generics_of(def_id);
|
let generics = self.tcx.generics_of(def_id);
|
||||||
if generics.requires_monomorphization(self.tcx) {
|
if generics.requires_monomorphization(self.tcx) {
|
||||||
|
@ -608,7 +608,7 @@ impl<'b, 'a, 'tcx> Visitor<'tcx> for ConstPropagator<'b, 'a, 'tcx> {
|
||||||
let node_id = self
|
let node_id = self
|
||||||
.tcx
|
.tcx
|
||||||
.hir()
|
.hir()
|
||||||
.as_local_node_id(self.source.def_id)
|
.as_local_node_id(self.source.def_id())
|
||||||
.expect("some part of a failing const eval must be local");
|
.expect("some part of a failing const eval must be local");
|
||||||
use rustc::mir::interpret::EvalErrorKind::*;
|
use rustc::mir::interpret::EvalErrorKind::*;
|
||||||
let msg = match msg {
|
let msg = match msg {
|
||||||
|
|
|
@ -30,7 +30,7 @@ pub struct CopyPropagation;
|
||||||
impl MirPass for CopyPropagation {
|
impl MirPass for CopyPropagation {
|
||||||
fn run_pass<'a, 'tcx>(&self,
|
fn run_pass<'a, 'tcx>(&self,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
_source: MirSource,
|
_source: MirSource<'tcx>,
|
||||||
mir: &mut Mir<'tcx>) {
|
mir: &mut Mir<'tcx>) {
|
||||||
// We only run when the MIR optimization level is > 1.
|
// We only run when the MIR optimization level is > 1.
|
||||||
// This avoids a slow pass, and messing up debug info.
|
// This avoids a slow pass, and messing up debug info.
|
||||||
|
|
|
@ -8,7 +8,7 @@ pub struct Deaggregator;
|
||||||
impl MirPass for Deaggregator {
|
impl MirPass for Deaggregator {
|
||||||
fn run_pass<'a, 'tcx>(&self,
|
fn run_pass<'a, 'tcx>(&self,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
_source: MirSource,
|
_source: MirSource<'tcx>,
|
||||||
mir: &mut Mir<'tcx>) {
|
mir: &mut Mir<'tcx>) {
|
||||||
let (basic_blocks, local_decls) = mir.basic_blocks_and_local_decls_mut();
|
let (basic_blocks, local_decls) = mir.basic_blocks_and_local_decls_mut();
|
||||||
let local_decls = &*local_decls;
|
let local_decls = &*local_decls;
|
||||||
|
|
|
@ -20,7 +20,7 @@ impl MirPass for Marker {
|
||||||
|
|
||||||
fn run_pass<'a, 'tcx>(&self,
|
fn run_pass<'a, 'tcx>(&self,
|
||||||
_tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
_tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
_source: MirSource,
|
_source: MirSource<'tcx>,
|
||||||
_mir: &mut Mir<'tcx>)
|
_mir: &mut Mir<'tcx>)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ impl fmt::Display for Disambiguator {
|
||||||
pub fn on_mir_pass<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
pub fn on_mir_pass<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
pass_num: &dyn fmt::Display,
|
pass_num: &dyn fmt::Display,
|
||||||
pass_name: &str,
|
pass_name: &str,
|
||||||
source: MirSource,
|
source: MirSource<'tcx>,
|
||||||
mir: &Mir<'tcx>,
|
mir: &Mir<'tcx>,
|
||||||
is_after: bool) {
|
is_after: bool) {
|
||||||
if mir_util::dump_enabled(tcx, pass_name, source) {
|
if mir_util::dump_enabled(tcx, pass_name, source) {
|
||||||
|
|
|
@ -23,13 +23,13 @@ pub struct ElaborateDrops;
|
||||||
impl MirPass for ElaborateDrops {
|
impl MirPass for ElaborateDrops {
|
||||||
fn run_pass<'a, 'tcx>(&self,
|
fn run_pass<'a, 'tcx>(&self,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
src: MirSource,
|
src: MirSource<'tcx>,
|
||||||
mir: &mut Mir<'tcx>)
|
mir: &mut Mir<'tcx>)
|
||||||
{
|
{
|
||||||
debug!("elaborate_drops({:?} @ {:?})", src, mir.span);
|
debug!("elaborate_drops({:?} @ {:?})", src, mir.span);
|
||||||
|
|
||||||
let id = tcx.hir().as_local_node_id(src.def_id).unwrap();
|
let id = tcx.hir().as_local_node_id(src.def_id()).unwrap();
|
||||||
let param_env = tcx.param_env(src.def_id).with_reveal_all();
|
let param_env = tcx.param_env(src.def_id()).with_reveal_all();
|
||||||
let move_data = match MoveData::gather_moves(mir, tcx) {
|
let move_data = match MoveData::gather_moves(mir, tcx) {
|
||||||
Ok(move_data) => move_data,
|
Ok(move_data) => move_data,
|
||||||
Err((move_data, _move_errors)) => {
|
Err((move_data, _move_errors)) => {
|
||||||
|
|
|
@ -53,7 +53,7 @@ pub struct EraseRegions;
|
||||||
impl MirPass for EraseRegions {
|
impl MirPass for EraseRegions {
|
||||||
fn run_pass<'a, 'tcx>(&self,
|
fn run_pass<'a, 'tcx>(&self,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
_: MirSource,
|
_: MirSource<'tcx>,
|
||||||
mir: &mut Mir<'tcx>) {
|
mir: &mut Mir<'tcx>) {
|
||||||
EraseRegionsVisitor::new(tcx).visit_mir(mir);
|
EraseRegionsVisitor::new(tcx).visit_mir(mir);
|
||||||
}
|
}
|
||||||
|
|
|
@ -376,14 +376,14 @@ impl<'tcx> Visitor<'tcx> for StorageIgnored {
|
||||||
fn locals_live_across_suspend_points(
|
fn locals_live_across_suspend_points(
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
mir: &Mir<'tcx>,
|
mir: &Mir<'tcx>,
|
||||||
source: MirSource,
|
source: MirSource<'tcx>,
|
||||||
movable: bool,
|
movable: bool,
|
||||||
) -> (
|
) -> (
|
||||||
liveness::LiveVarSet<Local>,
|
liveness::LiveVarSet<Local>,
|
||||||
FxHashMap<BasicBlock, liveness::LiveVarSet<Local>>,
|
FxHashMap<BasicBlock, liveness::LiveVarSet<Local>>,
|
||||||
) {
|
) {
|
||||||
let dead_unwinds = BitSet::new_empty(mir.basic_blocks().len());
|
let dead_unwinds = BitSet::new_empty(mir.basic_blocks().len());
|
||||||
let node_id = tcx.hir().as_local_node_id(source.def_id).unwrap();
|
let node_id = tcx.hir().as_local_node_id(source.def_id()).unwrap();
|
||||||
|
|
||||||
// Calculate when MIR locals have live storage. This gives us an upper bound of their
|
// Calculate when MIR locals have live storage. This gives us an upper bound of their
|
||||||
// lifetimes.
|
// lifetimes.
|
||||||
|
@ -484,7 +484,7 @@ fn locals_live_across_suspend_points(
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compute_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
fn compute_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
source: MirSource,
|
source: MirSource<'tcx>,
|
||||||
upvars: Vec<Ty<'tcx>>,
|
upvars: Vec<Ty<'tcx>>,
|
||||||
interior: Ty<'tcx>,
|
interior: Ty<'tcx>,
|
||||||
movable: bool,
|
movable: bool,
|
||||||
|
@ -635,7 +635,7 @@ fn create_generator_drop_shim<'a, 'tcx>(
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
transform: &TransformVisitor<'a, 'tcx>,
|
transform: &TransformVisitor<'a, 'tcx>,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
source: MirSource,
|
source: MirSource<'tcx>,
|
||||||
gen_ty: Ty<'tcx>,
|
gen_ty: Ty<'tcx>,
|
||||||
mir: &Mir<'tcx>,
|
mir: &Mir<'tcx>,
|
||||||
drop_clean: BasicBlock) -> Mir<'tcx> {
|
drop_clean: BasicBlock) -> Mir<'tcx> {
|
||||||
|
@ -758,7 +758,7 @@ fn create_generator_resume_function<'a, 'tcx>(
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
transform: TransformVisitor<'a, 'tcx>,
|
transform: TransformVisitor<'a, 'tcx>,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
source: MirSource,
|
source: MirSource<'tcx>,
|
||||||
mir: &mut Mir<'tcx>) {
|
mir: &mut Mir<'tcx>) {
|
||||||
// Poison the generator when it unwinds
|
// Poison the generator when it unwinds
|
||||||
for block in mir.basic_blocks_mut() {
|
for block in mir.basic_blocks_mut() {
|
||||||
|
@ -869,7 +869,7 @@ fn create_cases<'a, 'tcx, F>(mir: &mut Mir<'tcx>,
|
||||||
impl MirPass for StateTransform {
|
impl MirPass for StateTransform {
|
||||||
fn run_pass<'a, 'tcx>(&self,
|
fn run_pass<'a, 'tcx>(&self,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
source: MirSource,
|
source: MirSource<'tcx>,
|
||||||
mir: &mut Mir<'tcx>) {
|
mir: &mut Mir<'tcx>) {
|
||||||
let yield_ty = if let Some(yield_ty) = mir.yield_ty {
|
let yield_ty = if let Some(yield_ty) = mir.yield_ty {
|
||||||
yield_ty
|
yield_ty
|
||||||
|
@ -880,7 +880,7 @@ impl MirPass for StateTransform {
|
||||||
|
|
||||||
assert!(mir.generator_drop.is_none());
|
assert!(mir.generator_drop.is_none());
|
||||||
|
|
||||||
let def_id = source.def_id;
|
let def_id = source.def_id();
|
||||||
|
|
||||||
// The first argument is the generator type passed by value
|
// The first argument is the generator type passed by value
|
||||||
let gen_ty = mir.local_decls.raw[1].ty;
|
let gen_ty = mir.local_decls.raw[1].ty;
|
||||||
|
|
|
@ -40,7 +40,7 @@ struct CallSite<'tcx> {
|
||||||
impl MirPass for Inline {
|
impl MirPass for Inline {
|
||||||
fn run_pass<'a, 'tcx>(&self,
|
fn run_pass<'a, 'tcx>(&self,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
source: MirSource,
|
source: MirSource<'tcx>,
|
||||||
mir: &mut Mir<'tcx>) {
|
mir: &mut Mir<'tcx>) {
|
||||||
if tcx.sess.opts.debugging_opts.mir_opt_level >= 2 {
|
if tcx.sess.opts.debugging_opts.mir_opt_level >= 2 {
|
||||||
Inliner { tcx, source }.run_pass(mir);
|
Inliner { tcx, source }.run_pass(mir);
|
||||||
|
@ -50,7 +50,7 @@ impl MirPass for Inline {
|
||||||
|
|
||||||
struct Inliner<'a, 'tcx: 'a> {
|
struct Inliner<'a, 'tcx: 'a> {
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
source: MirSource,
|
source: MirSource<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
||||||
|
@ -69,10 +69,10 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
||||||
|
|
||||||
let mut callsites = VecDeque::new();
|
let mut callsites = VecDeque::new();
|
||||||
|
|
||||||
let param_env = self.tcx.param_env(self.source.def_id);
|
let param_env = self.tcx.param_env(self.source.def_id());
|
||||||
|
|
||||||
// Only do inlining into fn bodies.
|
// Only do inlining into fn bodies.
|
||||||
let id = self.tcx.hir().as_local_node_id(self.source.def_id).unwrap();
|
let id = self.tcx.hir().as_local_node_id(self.source.def_id()).unwrap();
|
||||||
if self.tcx.hir().body_owner_kind(id).is_fn_or_closure() && self.source.promoted.is_none() {
|
if self.tcx.hir().body_owner_kind(id).is_fn_or_closure() && self.source.promoted.is_none() {
|
||||||
for (bb, bb_data) in caller_mir.basic_blocks().iter_enumerated() {
|
for (bb, bb_data) in caller_mir.basic_blocks().iter_enumerated() {
|
||||||
if let Some(callsite) = self.get_valid_function_call(bb,
|
if let Some(callsite) = self.get_valid_function_call(bb,
|
||||||
|
@ -274,7 +274,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
||||||
|
|
||||||
// FIXME: Give a bonus to functions with only a single caller
|
// FIXME: Give a bonus to functions with only a single caller
|
||||||
|
|
||||||
let param_env = tcx.param_env(self.source.def_id);
|
let param_env = tcx.param_env(self.source.def_id());
|
||||||
|
|
||||||
let mut first_block = true;
|
let mut first_block = true;
|
||||||
let mut cost = 0;
|
let mut cost = 0;
|
||||||
|
|
|
@ -13,7 +13,7 @@ pub struct InstCombine;
|
||||||
impl MirPass for InstCombine {
|
impl MirPass for InstCombine {
|
||||||
fn run_pass<'a, 'tcx>(&self,
|
fn run_pass<'a, 'tcx>(&self,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
_: MirSource,
|
_: MirSource<'tcx>,
|
||||||
mir: &mut Mir<'tcx>) {
|
mir: &mut Mir<'tcx>) {
|
||||||
// We only run when optimizing MIR (at any level).
|
// We only run when optimizing MIR (at any level).
|
||||||
if tcx.sess.opts.debugging_opts.mir_opt_level == 0 {
|
if tcx.sess.opts.debugging_opts.mir_opt_level == 0 {
|
||||||
|
|
|
@ -12,7 +12,7 @@ pub struct Lower128Bit;
|
||||||
impl MirPass for Lower128Bit {
|
impl MirPass for Lower128Bit {
|
||||||
fn run_pass<'a, 'tcx>(&self,
|
fn run_pass<'a, 'tcx>(&self,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
_src: MirSource,
|
_src: MirSource<'tcx>,
|
||||||
mir: &mut Mir<'tcx>) {
|
mir: &mut Mir<'tcx>) {
|
||||||
let debugging_override = tcx.sess.opts.debugging_opts.lower_128bit_ops;
|
let debugging_override = tcx.sess.opts.debugging_opts.lower_128bit_ops;
|
||||||
let target_default = tcx.sess.host.options.i128_lowering;
|
let target_default = tcx.sess.host.options.i128_lowering;
|
||||||
|
|
|
@ -2,7 +2,7 @@ use crate::borrow_check::nll::type_check;
|
||||||
use crate::build;
|
use crate::build;
|
||||||
use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
|
use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
|
||||||
use rustc::mir::{Mir, MirPhase, Promoted};
|
use rustc::mir::{Mir, MirPhase, Promoted};
|
||||||
use rustc::ty::TyCtxt;
|
use rustc::ty::{TyCtxt, InstanceDef};
|
||||||
use rustc::ty::query::Providers;
|
use rustc::ty::query::Providers;
|
||||||
use rustc::ty::steal::Steal;
|
use rustc::ty::steal::Steal;
|
||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
|
@ -104,20 +104,25 @@ fn mir_built<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Stea
|
||||||
|
|
||||||
/// Where a specific Mir comes from.
|
/// Where a specific Mir comes from.
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct MirSource {
|
pub struct MirSource<'tcx> {
|
||||||
pub def_id: DefId,
|
pub instance: InstanceDef<'tcx>,
|
||||||
|
|
||||||
/// If `Some`, this is a promoted rvalue within the parent function.
|
/// If `Some`, this is a promoted rvalue within the parent function.
|
||||||
pub promoted: Option<Promoted>,
|
pub promoted: Option<Promoted>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MirSource {
|
impl<'tcx> MirSource<'tcx> {
|
||||||
pub fn item(def_id: DefId) -> Self {
|
pub fn item(def_id: DefId) -> Self {
|
||||||
MirSource {
|
MirSource {
|
||||||
def_id,
|
instance: InstanceDef::Item(def_id),
|
||||||
promoted: None
|
promoted: None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn def_id(&self) -> DefId {
|
||||||
|
self.instance.def_id()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates a default name for the pass based on the name of the
|
/// Generates a default name for the pass based on the name of the
|
||||||
|
@ -141,14 +146,14 @@ pub trait MirPass {
|
||||||
|
|
||||||
fn run_pass<'a, 'tcx>(&self,
|
fn run_pass<'a, 'tcx>(&self,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
source: MirSource,
|
source: MirSource<'tcx>,
|
||||||
mir: &mut Mir<'tcx>);
|
mir: &mut Mir<'tcx>);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_passes(
|
pub fn run_passes(
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
mir: &mut Mir<'tcx>,
|
mir: &mut Mir<'tcx>,
|
||||||
def_id: DefId,
|
instance: InstanceDef<'tcx>,
|
||||||
mir_phase: MirPhase,
|
mir_phase: MirPhase,
|
||||||
passes: &[&dyn MirPass],
|
passes: &[&dyn MirPass],
|
||||||
) {
|
) {
|
||||||
|
@ -160,7 +165,7 @@ pub fn run_passes(
|
||||||
}
|
}
|
||||||
|
|
||||||
let source = MirSource {
|
let source = MirSource {
|
||||||
def_id,
|
instance,
|
||||||
promoted,
|
promoted,
|
||||||
};
|
};
|
||||||
let mut index = 0;
|
let mut index = 0;
|
||||||
|
@ -198,7 +203,7 @@ fn mir_const<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx Stea
|
||||||
let _ = tcx.unsafety_check_result(def_id);
|
let _ = tcx.unsafety_check_result(def_id);
|
||||||
|
|
||||||
let mut mir = tcx.mir_built(def_id).steal();
|
let mut mir = tcx.mir_built(def_id).steal();
|
||||||
run_passes(tcx, &mut mir, def_id, MirPhase::Const, &[
|
run_passes(tcx, &mut mir, InstanceDef::Item(def_id), MirPhase::Const, &[
|
||||||
// What we need to do constant evaluation.
|
// What we need to do constant evaluation.
|
||||||
&simplify::SimplifyCfg::new("initial"),
|
&simplify::SimplifyCfg::new("initial"),
|
||||||
&type_check::TypeckMir,
|
&type_check::TypeckMir,
|
||||||
|
@ -217,7 +222,7 @@ fn mir_validated<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut mir = tcx.mir_const(def_id).steal();
|
let mut mir = tcx.mir_const(def_id).steal();
|
||||||
run_passes(tcx, &mut mir, def_id, MirPhase::Validated, &[
|
run_passes(tcx, &mut mir, InstanceDef::Item(def_id), MirPhase::Validated, &[
|
||||||
// What we need to run borrowck etc.
|
// What we need to run borrowck etc.
|
||||||
&qualify_consts::QualifyAndPromoteConstants,
|
&qualify_consts::QualifyAndPromoteConstants,
|
||||||
&simplify::SimplifyCfg::new("qualify-consts"),
|
&simplify::SimplifyCfg::new("qualify-consts"),
|
||||||
|
@ -235,7 +240,7 @@ fn optimized_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut mir = tcx.mir_validated(def_id).steal();
|
let mut mir = tcx.mir_validated(def_id).steal();
|
||||||
run_passes(tcx, &mut mir, def_id, MirPhase::Optimized, &[
|
run_passes(tcx, &mut mir, InstanceDef::Item(def_id), MirPhase::Optimized, &[
|
||||||
// Remove all things not needed by analysis
|
// Remove all things not needed by analysis
|
||||||
&no_landing_pads::NoLandingPads,
|
&no_landing_pads::NoLandingPads,
|
||||||
&simplify_branches::SimplifyBranches::new("initial"),
|
&simplify_branches::SimplifyBranches::new("initial"),
|
||||||
|
|
|
@ -11,7 +11,7 @@ pub struct NoLandingPads;
|
||||||
impl MirPass for NoLandingPads {
|
impl MirPass for NoLandingPads {
|
||||||
fn run_pass<'a, 'tcx>(&self,
|
fn run_pass<'a, 'tcx>(&self,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
_: MirSource,
|
_: MirSource<'tcx>,
|
||||||
mir: &mut Mir<'tcx>) {
|
mir: &mut Mir<'tcx>) {
|
||||||
no_landing_pads(tcx, mir)
|
no_landing_pads(tcx, mir)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1159,7 +1159,7 @@ pub struct QualifyAndPromoteConstants;
|
||||||
impl MirPass for QualifyAndPromoteConstants {
|
impl MirPass for QualifyAndPromoteConstants {
|
||||||
fn run_pass<'a, 'tcx>(&self,
|
fn run_pass<'a, 'tcx>(&self,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
src: MirSource,
|
src: MirSource<'tcx>,
|
||||||
mir: &mut Mir<'tcx>) {
|
mir: &mut Mir<'tcx>) {
|
||||||
// There's not really any point in promoting errorful MIR.
|
// There's not really any point in promoting errorful MIR.
|
||||||
if mir.return_ty().references_error() {
|
if mir.return_ty().references_error() {
|
||||||
|
@ -1171,7 +1171,7 @@ impl MirPass for QualifyAndPromoteConstants {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let def_id = src.def_id;
|
let def_id = src.def_id();
|
||||||
let id = tcx.hir().as_local_node_id(def_id).unwrap();
|
let id = tcx.hir().as_local_node_id(def_id).unwrap();
|
||||||
let mut const_promoted_temps = None;
|
let mut const_promoted_temps = None;
|
||||||
let mode = match tcx.hir().body_owner_kind(id) {
|
let mode = match tcx.hir().body_owner_kind(id) {
|
||||||
|
|
|
@ -24,7 +24,7 @@ pub fn remove_noop_landing_pads<'a, 'tcx>(
|
||||||
impl MirPass for RemoveNoopLandingPads {
|
impl MirPass for RemoveNoopLandingPads {
|
||||||
fn run_pass<'a, 'tcx>(&self,
|
fn run_pass<'a, 'tcx>(&self,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
_src: MirSource,
|
_src: MirSource<'tcx>,
|
||||||
mir: &mut Mir<'tcx>) {
|
mir: &mut Mir<'tcx>) {
|
||||||
remove_noop_landing_pads(tcx, mir);
|
remove_noop_landing_pads(tcx, mir);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,8 +24,8 @@ pub struct SanityCheck;
|
||||||
|
|
||||||
impl MirPass for SanityCheck {
|
impl MirPass for SanityCheck {
|
||||||
fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
fn run_pass<'a, 'tcx>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
src: MirSource, mir: &mut Mir<'tcx>) {
|
src: MirSource<'tcx>, mir: &mut Mir<'tcx>) {
|
||||||
let def_id = src.def_id;
|
let def_id = src.def_id();
|
||||||
let id = tcx.hir().as_local_node_id(def_id).unwrap();
|
let id = tcx.hir().as_local_node_id(def_id).unwrap();
|
||||||
if !tcx.has_attr(def_id, "rustc_mir") {
|
if !tcx.has_attr(def_id, "rustc_mir") {
|
||||||
debug!("skipping rustc_peek::SanityCheck on {}", tcx.item_path_str(def_id));
|
debug!("skipping rustc_peek::SanityCheck on {}", tcx.item_path_str(def_id));
|
||||||
|
|
|
@ -59,7 +59,7 @@ impl MirPass for SimplifyCfg {
|
||||||
|
|
||||||
fn run_pass<'a, 'tcx>(&self,
|
fn run_pass<'a, 'tcx>(&self,
|
||||||
_tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
_tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
_src: MirSource,
|
_src: MirSource<'tcx>,
|
||||||
mir: &mut Mir<'tcx>) {
|
mir: &mut Mir<'tcx>) {
|
||||||
debug!("SimplifyCfg({:?}) - simplifying {:?}", self.label, mir);
|
debug!("SimplifyCfg({:?}) - simplifying {:?}", self.label, mir);
|
||||||
simplify_cfg(mir);
|
simplify_cfg(mir);
|
||||||
|
@ -298,7 +298,7 @@ pub struct SimplifyLocals;
|
||||||
impl MirPass for SimplifyLocals {
|
impl MirPass for SimplifyLocals {
|
||||||
fn run_pass<'a, 'tcx>(&self,
|
fn run_pass<'a, 'tcx>(&self,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
_: MirSource,
|
_: MirSource<'tcx>,
|
||||||
mir: &mut Mir<'tcx>) {
|
mir: &mut Mir<'tcx>) {
|
||||||
let mut marker = DeclMarker { locals: BitSet::new_empty(mir.local_decls.len()) };
|
let mut marker = DeclMarker { locals: BitSet::new_empty(mir.local_decls.len()) };
|
||||||
marker.visit_mir(mir);
|
marker.visit_mir(mir);
|
||||||
|
|
|
@ -21,7 +21,7 @@ impl MirPass for SimplifyBranches {
|
||||||
|
|
||||||
fn run_pass<'a, 'tcx>(&self,
|
fn run_pass<'a, 'tcx>(&self,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
_src: MirSource,
|
_src: MirSource<'tcx>,
|
||||||
mir: &mut Mir<'tcx>) {
|
mir: &mut Mir<'tcx>) {
|
||||||
for block in mir.basic_blocks_mut() {
|
for block in mir.basic_blocks_mut() {
|
||||||
let terminator = block.terminator_mut();
|
let terminator = block.terminator_mut();
|
||||||
|
|
|
@ -39,7 +39,7 @@ pub struct UniformArrayMoveOut;
|
||||||
impl MirPass for UniformArrayMoveOut {
|
impl MirPass for UniformArrayMoveOut {
|
||||||
fn run_pass<'a, 'tcx>(&self,
|
fn run_pass<'a, 'tcx>(&self,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
_src: MirSource,
|
_src: MirSource<'tcx>,
|
||||||
mir: &mut Mir<'tcx>) {
|
mir: &mut Mir<'tcx>) {
|
||||||
let mut patch = MirPatch::new(mir);
|
let mut patch = MirPatch::new(mir);
|
||||||
{
|
{
|
||||||
|
@ -161,7 +161,7 @@ pub struct RestoreSubsliceArrayMoveOut;
|
||||||
impl MirPass for RestoreSubsliceArrayMoveOut {
|
impl MirPass for RestoreSubsliceArrayMoveOut {
|
||||||
fn run_pass<'a, 'tcx>(&self,
|
fn run_pass<'a, 'tcx>(&self,
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
_src: MirSource,
|
_src: MirSource<'tcx>,
|
||||||
mir: &mut Mir<'tcx>) {
|
mir: &mut Mir<'tcx>) {
|
||||||
let mut patch = MirPatch::new(mir);
|
let mut patch = MirPatch::new(mir);
|
||||||
{
|
{
|
||||||
|
|
|
@ -307,7 +307,7 @@ fn block<'tcx, V: Idx>(
|
||||||
pub fn dump_mir<'a, 'tcx, V: Idx>(
|
pub fn dump_mir<'a, 'tcx, V: Idx>(
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
pass_name: &str,
|
pass_name: &str,
|
||||||
source: MirSource,
|
source: MirSource<'tcx>,
|
||||||
mir: &Mir<'tcx>,
|
mir: &Mir<'tcx>,
|
||||||
map: &impl LiveVariableMap<LiveVar = V>,
|
map: &impl LiveVariableMap<LiveVar = V>,
|
||||||
result: &LivenessResult<V>,
|
result: &LivenessResult<V>,
|
||||||
|
@ -317,7 +317,7 @@ pub fn dump_mir<'a, 'tcx, V: Idx>(
|
||||||
}
|
}
|
||||||
let node_path = item_path::with_forced_impl_filename_line(|| {
|
let node_path = item_path::with_forced_impl_filename_line(|| {
|
||||||
// see notes on #41697 below
|
// see notes on #41697 below
|
||||||
tcx.item_path_str(source.def_id)
|
tcx.item_path_str(source.def_id())
|
||||||
});
|
});
|
||||||
dump_matched_mir_node(tcx, pass_name, &node_path, source, mir, map, result);
|
dump_matched_mir_node(tcx, pass_name, &node_path, source, mir, map, result);
|
||||||
}
|
}
|
||||||
|
@ -326,14 +326,14 @@ fn dump_matched_mir_node<'a, 'tcx, V: Idx>(
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
pass_name: &str,
|
pass_name: &str,
|
||||||
node_path: &str,
|
node_path: &str,
|
||||||
source: MirSource,
|
source: MirSource<'tcx>,
|
||||||
mir: &Mir<'tcx>,
|
mir: &Mir<'tcx>,
|
||||||
map: &dyn LiveVariableMap<LiveVar = V>,
|
map: &dyn LiveVariableMap<LiveVar = V>,
|
||||||
result: &LivenessResult<V>,
|
result: &LivenessResult<V>,
|
||||||
) {
|
) {
|
||||||
let mut file_path = PathBuf::new();
|
let mut file_path = PathBuf::new();
|
||||||
file_path.push(Path::new(&tcx.sess.opts.debugging_opts.dump_mir_dir));
|
file_path.push(Path::new(&tcx.sess.opts.debugging_opts.dump_mir_dir));
|
||||||
let item_id = tcx.hir().as_local_node_id(source.def_id).unwrap();
|
let item_id = tcx.hir().as_local_node_id(source.def_id()).unwrap();
|
||||||
let file_name = format!("rustc.node{}{}-liveness.mir", item_id, pass_name);
|
let file_name = format!("rustc.node{}{}-liveness.mir", item_id, pass_name);
|
||||||
file_path.push(&file_name);
|
file_path.push(&file_name);
|
||||||
let _ = fs::File::create(&file_path).and_then(|mut file| {
|
let _ = fs::File::create(&file_path).and_then(|mut file| {
|
||||||
|
@ -348,7 +348,7 @@ fn dump_matched_mir_node<'a, 'tcx, V: Idx>(
|
||||||
|
|
||||||
pub fn write_mir_fn<'a, 'tcx, V: Idx>(
|
pub fn write_mir_fn<'a, 'tcx, V: Idx>(
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
src: MirSource,
|
src: MirSource<'tcx>,
|
||||||
mir: &Mir<'tcx>,
|
mir: &Mir<'tcx>,
|
||||||
map: &dyn LiveVariableMap<LiveVar = V>,
|
map: &dyn LiveVariableMap<LiveVar = V>,
|
||||||
w: &mut dyn Write,
|
w: &mut dyn Write,
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
use rustc::hir;
|
|
||||||
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
|
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
|
||||||
use rustc::mir::*;
|
use rustc::mir::*;
|
||||||
use rustc::mir::visit::Visitor;
|
use rustc::mir::visit::Visitor;
|
||||||
|
@ -69,7 +68,7 @@ pub fn dump_mir<'a, 'gcx, 'tcx, F>(
|
||||||
pass_num: Option<&dyn Display>,
|
pass_num: Option<&dyn Display>,
|
||||||
pass_name: &str,
|
pass_name: &str,
|
||||||
disambiguator: &dyn Display,
|
disambiguator: &dyn Display,
|
||||||
source: MirSource,
|
source: MirSource<'tcx>,
|
||||||
mir: &Mir<'tcx>,
|
mir: &Mir<'tcx>,
|
||||||
extra_data: F,
|
extra_data: F,
|
||||||
) where
|
) where
|
||||||
|
@ -81,7 +80,7 @@ pub fn dump_mir<'a, 'gcx, 'tcx, F>(
|
||||||
|
|
||||||
let node_path = item_path::with_forced_impl_filename_line(|| {
|
let node_path = item_path::with_forced_impl_filename_line(|| {
|
||||||
// see notes on #41697 below
|
// see notes on #41697 below
|
||||||
tcx.item_path_str(source.def_id)
|
tcx.item_path_str(source.def_id())
|
||||||
});
|
});
|
||||||
dump_matched_mir_node(
|
dump_matched_mir_node(
|
||||||
tcx,
|
tcx,
|
||||||
|
@ -98,7 +97,7 @@ pub fn dump_mir<'a, 'gcx, 'tcx, F>(
|
||||||
pub fn dump_enabled<'a, 'gcx, 'tcx>(
|
pub fn dump_enabled<'a, 'gcx, 'tcx>(
|
||||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
pass_name: &str,
|
pass_name: &str,
|
||||||
source: MirSource,
|
source: MirSource<'tcx>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
let filters = match tcx.sess.opts.debugging_opts.dump_mir {
|
let filters = match tcx.sess.opts.debugging_opts.dump_mir {
|
||||||
None => return false,
|
None => return false,
|
||||||
|
@ -106,7 +105,7 @@ pub fn dump_enabled<'a, 'gcx, 'tcx>(
|
||||||
};
|
};
|
||||||
let node_path = item_path::with_forced_impl_filename_line(|| {
|
let node_path = item_path::with_forced_impl_filename_line(|| {
|
||||||
// see notes on #41697 below
|
// see notes on #41697 below
|
||||||
tcx.item_path_str(source.def_id)
|
tcx.item_path_str(source.def_id())
|
||||||
});
|
});
|
||||||
filters.split('|').any(|or_filter| {
|
filters.split('|').any(|or_filter| {
|
||||||
or_filter.split('&').all(|and_filter| {
|
or_filter.split('&').all(|and_filter| {
|
||||||
|
@ -125,7 +124,7 @@ fn dump_matched_mir_node<'a, 'gcx, 'tcx, F>(
|
||||||
pass_name: &str,
|
pass_name: &str,
|
||||||
node_path: &str,
|
node_path: &str,
|
||||||
disambiguator: &dyn Display,
|
disambiguator: &dyn Display,
|
||||||
source: MirSource,
|
source: MirSource<'tcx>,
|
||||||
mir: &Mir<'tcx>,
|
mir: &Mir<'tcx>,
|
||||||
mut extra_data: F,
|
mut extra_data: F,
|
||||||
) where
|
) where
|
||||||
|
@ -151,7 +150,7 @@ fn dump_matched_mir_node<'a, 'gcx, 'tcx, F>(
|
||||||
let _: io::Result<()> = try {
|
let _: io::Result<()> = try {
|
||||||
let mut file =
|
let mut file =
|
||||||
create_dump_file(tcx, "dot", pass_num, pass_name, disambiguator, source)?;
|
create_dump_file(tcx, "dot", pass_num, pass_name, disambiguator, source)?;
|
||||||
write_mir_fn_graphviz(tcx, source.def_id, mir, &mut file)?;
|
write_mir_fn_graphviz(tcx, source.def_id(), mir, &mut file)?;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -165,7 +164,7 @@ fn dump_path(
|
||||||
pass_num: Option<&dyn Display>,
|
pass_num: Option<&dyn Display>,
|
||||||
pass_name: &str,
|
pass_name: &str,
|
||||||
disambiguator: &dyn Display,
|
disambiguator: &dyn Display,
|
||||||
source: MirSource,
|
source: MirSource<'tcx>,
|
||||||
) -> PathBuf {
|
) -> PathBuf {
|
||||||
let promotion_id = match source.promoted {
|
let promotion_id = match source.promoted {
|
||||||
Some(id) => format!("-{:?}", id),
|
Some(id) => format!("-{:?}", id),
|
||||||
|
@ -184,13 +183,32 @@ fn dump_path(
|
||||||
let mut file_path = PathBuf::new();
|
let mut file_path = PathBuf::new();
|
||||||
file_path.push(Path::new(&tcx.sess.opts.debugging_opts.dump_mir_dir));
|
file_path.push(Path::new(&tcx.sess.opts.debugging_opts.dump_mir_dir));
|
||||||
|
|
||||||
let item_name = tcx.hir()
|
let item_name = tcx
|
||||||
.def_path(source.def_id)
|
.def_path(source.def_id())
|
||||||
.to_filename_friendly_no_crate();
|
.to_filename_friendly_no_crate();
|
||||||
|
// All drop shims have the same DefId, so we have to add the type
|
||||||
|
// to get unique file names.
|
||||||
|
let shim_disambiguator = match source.instance {
|
||||||
|
ty::InstanceDef::DropGlue(_, Some(ty)) => {
|
||||||
|
// Unfortunately, pretty-printed typed are not very filename-friendly.
|
||||||
|
// We dome some filtering.
|
||||||
|
let mut s = ".".to_owned();
|
||||||
|
s.extend(ty.to_string()
|
||||||
|
.chars()
|
||||||
|
.filter_map(|c| match c {
|
||||||
|
' ' => None,
|
||||||
|
':' => Some('_'),
|
||||||
|
c => Some(c)
|
||||||
|
}));
|
||||||
|
s
|
||||||
|
}
|
||||||
|
_ => String::new(),
|
||||||
|
};
|
||||||
|
|
||||||
let file_name = format!(
|
let file_name = format!(
|
||||||
"rustc.{}{}{}.{}.{}.{}",
|
"rustc.{}{}{}{}.{}.{}.{}",
|
||||||
item_name,
|
item_name,
|
||||||
|
shim_disambiguator,
|
||||||
promotion_id,
|
promotion_id,
|
||||||
pass_num,
|
pass_num,
|
||||||
pass_name,
|
pass_name,
|
||||||
|
@ -213,7 +231,7 @@ pub(crate) fn create_dump_file(
|
||||||
pass_num: Option<&dyn Display>,
|
pass_num: Option<&dyn Display>,
|
||||||
pass_name: &str,
|
pass_name: &str,
|
||||||
disambiguator: &dyn Display,
|
disambiguator: &dyn Display,
|
||||||
source: MirSource,
|
source: MirSource<'tcx>,
|
||||||
) -> io::Result<fs::File> {
|
) -> io::Result<fs::File> {
|
||||||
let file_path = dump_path(tcx, extension, pass_num, pass_name, disambiguator, source);
|
let file_path = dump_path(tcx, extension, pass_num, pass_name, disambiguator, source);
|
||||||
if let Some(parent) = file_path.parent() {
|
if let Some(parent) = file_path.parent() {
|
||||||
|
@ -253,7 +271,7 @@ pub fn write_mir_pretty<'a, 'gcx, 'tcx>(
|
||||||
for (i, mir) in mir.promoted.iter_enumerated() {
|
for (i, mir) in mir.promoted.iter_enumerated() {
|
||||||
writeln!(w, "")?;
|
writeln!(w, "")?;
|
||||||
let src = MirSource {
|
let src = MirSource {
|
||||||
def_id,
|
instance: ty::InstanceDef::Item(def_id),
|
||||||
promoted: Some(i),
|
promoted: Some(i),
|
||||||
};
|
};
|
||||||
write_mir_fn(tcx, src, mir, &mut |_, _| Ok(()), w)?;
|
write_mir_fn(tcx, src, mir, &mut |_, _| Ok(()), w)?;
|
||||||
|
@ -264,7 +282,7 @@ pub fn write_mir_pretty<'a, 'gcx, 'tcx>(
|
||||||
|
|
||||||
pub fn write_mir_fn<'a, 'gcx, 'tcx, F>(
|
pub fn write_mir_fn<'a, 'gcx, 'tcx, F>(
|
||||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
src: MirSource,
|
src: MirSource<'tcx>,
|
||||||
mir: &Mir<'tcx>,
|
mir: &Mir<'tcx>,
|
||||||
extra_data: &mut F,
|
extra_data: &mut F,
|
||||||
w: &mut dyn Write,
|
w: &mut dyn Write,
|
||||||
|
@ -528,7 +546,7 @@ fn write_scope_tree(
|
||||||
/// local variables (both user-defined bindings and compiler temporaries).
|
/// local variables (both user-defined bindings and compiler temporaries).
|
||||||
pub fn write_mir_intro<'a, 'gcx, 'tcx>(
|
pub fn write_mir_intro<'a, 'gcx, 'tcx>(
|
||||||
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||||
src: MirSource,
|
src: MirSource<'tcx>,
|
||||||
mir: &Mir<'_>,
|
mir: &Mir<'_>,
|
||||||
w: &mut dyn Write,
|
w: &mut dyn Write,
|
||||||
) -> io::Result<()> {
|
) -> io::Result<()> {
|
||||||
|
@ -570,45 +588,49 @@ pub fn write_mir_intro<'a, 'gcx, 'tcx>(
|
||||||
|
|
||||||
fn write_mir_sig(
|
fn write_mir_sig(
|
||||||
tcx: TyCtxt<'_, '_, '_>,
|
tcx: TyCtxt<'_, '_, '_>,
|
||||||
src: MirSource,
|
src: MirSource<'tcx>,
|
||||||
mir: &Mir<'_>,
|
mir: &Mir<'_>,
|
||||||
w: &mut dyn Write,
|
w: &mut dyn Write,
|
||||||
) -> io::Result<()> {
|
) -> io::Result<()> {
|
||||||
let id = tcx.hir().as_local_node_id(src.def_id).unwrap();
|
use rustc::hir::def::Def;
|
||||||
let body_owner_kind = tcx.hir().body_owner_kind(id);
|
|
||||||
match (body_owner_kind, src.promoted) {
|
trace!("write_mir_sig: {:?}", src.instance);
|
||||||
(_, Some(i)) => write!(w, "{:?} in", i)?,
|
let descr = tcx.describe_def(src.def_id());
|
||||||
(hir::BodyOwnerKind::Closure, _) |
|
let is_function = match descr {
|
||||||
(hir::BodyOwnerKind::Fn, _) => write!(w, "fn")?,
|
Some(Def::Fn(_)) | Some(Def::Method(_)) | Some(Def::StructCtor(..)) => true,
|
||||||
(hir::BodyOwnerKind::Const, _) => write!(w, "const")?,
|
_ => tcx.is_closure(src.def_id()),
|
||||||
(hir::BodyOwnerKind::Static(hir::MutImmutable), _) => write!(w, "static")?,
|
};
|
||||||
(hir::BodyOwnerKind::Static(hir::MutMutable), _) => write!(w, "static mut")?,
|
match (descr, src.promoted) {
|
||||||
|
(_, Some(i)) => write!(w, "{:?} in ", i)?,
|
||||||
|
(Some(Def::StructCtor(..)), _) => write!(w, "struct ")?,
|
||||||
|
(Some(Def::Const(_)), _) => write!(w, "const ")?,
|
||||||
|
(Some(Def::Static(_, /*is_mutbl*/false)), _) => write!(w, "static ")?,
|
||||||
|
(Some(Def::Static(_, /*is_mutbl*/true)), _) => write!(w, "static mut ")?,
|
||||||
|
(_, _) if is_function => write!(w, "fn ")?,
|
||||||
|
(None, _) => {}, // things like anon const, not an item
|
||||||
|
_ => bug!("Unexpected def description {:?}", descr),
|
||||||
}
|
}
|
||||||
|
|
||||||
item_path::with_forced_impl_filename_line(|| {
|
item_path::with_forced_impl_filename_line(|| {
|
||||||
// see notes on #41697 elsewhere
|
// see notes on #41697 elsewhere
|
||||||
write!(w, " {}", tcx.item_path_str(src.def_id))
|
write!(w, "{}", tcx.item_path_str(src.def_id()))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
match (body_owner_kind, src.promoted) {
|
if src.promoted.is_none() && is_function {
|
||||||
(hir::BodyOwnerKind::Closure, None) |
|
write!(w, "(")?;
|
||||||
(hir::BodyOwnerKind::Fn, None) => {
|
|
||||||
write!(w, "(")?;
|
|
||||||
|
|
||||||
// fn argument types.
|
// fn argument types.
|
||||||
for (i, arg) in mir.args_iter().enumerate() {
|
for (i, arg) in mir.args_iter().enumerate() {
|
||||||
if i != 0 {
|
if i != 0 {
|
||||||
write!(w, ", ")?;
|
write!(w, ", ")?;
|
||||||
}
|
|
||||||
write!(w, "{:?}: {}", Place::Local(arg), mir.local_decls[arg].ty)?;
|
|
||||||
}
|
}
|
||||||
|
write!(w, "{:?}: {}", Place::Local(arg), mir.local_decls[arg].ty)?;
|
||||||
|
}
|
||||||
|
|
||||||
write!(w, ") -> {}", mir.return_ty())?;
|
write!(w, ") -> {}", mir.return_ty())?;
|
||||||
}
|
} else {
|
||||||
(hir::BodyOwnerKind::Const, _) | (hir::BodyOwnerKind::Static(_), _) | (_, Some(_)) => {
|
assert_eq!(mir.arg_count, 0);
|
||||||
assert_eq!(mir.arg_count, 0);
|
write!(w, ": {} =", mir.return_ty())?;
|
||||||
write!(w, ": {} =", mir.return_ty())?;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(yield_ty) = mir.yield_ty {
|
if let Some(yield_ty) = mir.yield_ty {
|
||||||
|
@ -616,6 +638,9 @@ fn write_mir_sig(
|
||||||
writeln!(w, "yields {}", yield_ty)?;
|
writeln!(w, "yields {}", yield_ty)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
write!(w, " ")?;
|
||||||
|
// Next thing that gets printed is the opening {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue