introduce mir_keys()
Each MIR key is a DefId that has MIR associated with it
This commit is contained in:
parent
ed1f26ddda
commit
0e5e2f3634
18 changed files with 132 additions and 141 deletions
|
@ -76,6 +76,7 @@ pub enum DepNode<D: Clone + Debug> {
|
||||||
BorrowCheck(D),
|
BorrowCheck(D),
|
||||||
RvalueCheck(D),
|
RvalueCheck(D),
|
||||||
Reachability,
|
Reachability,
|
||||||
|
MirKeys,
|
||||||
LateLintCheck,
|
LateLintCheck,
|
||||||
TransCrateItem(D),
|
TransCrateItem(D),
|
||||||
TransInlinedItem(D),
|
TransInlinedItem(D),
|
||||||
|
@ -202,6 +203,7 @@ impl<D: Clone + Debug> DepNode<D> {
|
||||||
Variance => Some(Variance),
|
Variance => Some(Variance),
|
||||||
PrivacyAccessLevels(k) => Some(PrivacyAccessLevels(k)),
|
PrivacyAccessLevels(k) => Some(PrivacyAccessLevels(k)),
|
||||||
Reachability => Some(Reachability),
|
Reachability => Some(Reachability),
|
||||||
|
MirKeys => Some(MirKeys),
|
||||||
LateLintCheck => Some(LateLintCheck),
|
LateLintCheck => Some(LateLintCheck),
|
||||||
TransWriteMetadata => Some(TransWriteMetadata),
|
TransWriteMetadata => Some(TransWriteMetadata),
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,5 @@ pub use self::graph::WorkProduct;
|
||||||
pub use self::query::DepGraphQuery;
|
pub use self::query::DepGraphQuery;
|
||||||
pub use self::safe::AssertDepGraphSafe;
|
pub use self::safe::AssertDepGraphSafe;
|
||||||
pub use self::safe::DepGraphSafe;
|
pub use self::safe::DepGraphSafe;
|
||||||
pub use self::visit::visit_all_bodies_in_krate;
|
|
||||||
pub use self::visit::visit_all_item_likes_in_krate;
|
pub use self::visit::visit_all_item_likes_in_krate;
|
||||||
pub use self::raii::DepTask;
|
pub use self::raii::DepTask;
|
||||||
|
|
|
@ -75,15 +75,3 @@ pub fn visit_all_item_likes_in_krate<'a, 'tcx, V, F>(tcx: TyCtxt<'a, 'tcx, 'tcx>
|
||||||
krate.visit_all_item_likes(&mut tracking_visitor)
|
krate.visit_all_item_likes(&mut tracking_visitor)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn visit_all_bodies_in_krate<'a, 'tcx, C>(tcx: TyCtxt<'a, 'tcx, 'tcx>, callback: C)
|
|
||||||
where C: Fn(/* body_owner */
|
|
||||||
DefId,
|
|
||||||
/* body id */
|
|
||||||
hir::BodyId)
|
|
||||||
{
|
|
||||||
let krate = tcx.hir.krate();
|
|
||||||
for &body_id in &krate.body_ids {
|
|
||||||
let body_owner_def_id = tcx.hir.body_owner_def_id(body_id);
|
|
||||||
callback(body_owner_def_id, body_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
|
|
||||||
use dep_graph::DepNode;
|
use dep_graph::DepNode;
|
||||||
use hir;
|
use hir;
|
||||||
|
use hir::def_id::LOCAL_CRATE;
|
||||||
use hir::map::DefPathData;
|
use hir::map::DefPathData;
|
||||||
use mir::{Mir, Promoted};
|
use mir::{Mir, Promoted};
|
||||||
use ty::TyCtxt;
|
use ty::TyCtxt;
|
||||||
|
@ -114,14 +115,9 @@ impl<'tcx, T: MirPass<'tcx>> MirMapPass<'tcx> for T {
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
hooks: &mut [Box<for<'s> MirPassHook<'s>>])
|
hooks: &mut [Box<for<'s> MirPassHook<'s>>])
|
||||||
{
|
{
|
||||||
let def_ids = tcx.maps.mir.borrow().keys();
|
for &def_id in tcx.mir_keys(LOCAL_CRATE).iter() {
|
||||||
for def_id in def_ids {
|
|
||||||
if !def_id.is_local() {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id));
|
let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id));
|
||||||
let mir = &mut tcx.maps.mir.borrow()[&def_id].borrow_mut();
|
let mir = &mut tcx.mir(def_id).borrow_mut();
|
||||||
tcx.dep_graph.write(DepNode::Mir(def_id));
|
tcx.dep_graph.write(DepNode::Mir(def_id));
|
||||||
|
|
||||||
let id = tcx.hir.as_local_node_id(def_id).unwrap();
|
let id = tcx.hir.as_local_node_id(def_id).unwrap();
|
||||||
|
|
|
@ -20,7 +20,7 @@ use session::CompileResult;
|
||||||
use ty::{self, CrateInherentImpls, Ty, TyCtxt};
|
use ty::{self, CrateInherentImpls, Ty, TyCtxt};
|
||||||
use ty::item_path;
|
use ty::item_path;
|
||||||
use ty::subst::Substs;
|
use ty::subst::Substs;
|
||||||
use util::nodemap::NodeSet;
|
use util::nodemap::{DefIdSet, NodeSet};
|
||||||
|
|
||||||
use rustc_data_structures::indexed_vec::IndexVec;
|
use rustc_data_structures::indexed_vec::IndexVec;
|
||||||
use std::cell::{RefCell, RefMut};
|
use std::cell::{RefCell, RefMut};
|
||||||
|
@ -270,8 +270,13 @@ impl<'tcx> QueryDescription for queries::reachable_set<'tcx> {
|
||||||
|
|
||||||
impl<'tcx> QueryDescription for queries::const_eval<'tcx> {
|
impl<'tcx> QueryDescription for queries::const_eval<'tcx> {
|
||||||
fn describe(tcx: TyCtxt, (def_id, _): (DefId, &'tcx Substs<'tcx>)) -> String {
|
fn describe(tcx: TyCtxt, (def_id, _): (DefId, &'tcx Substs<'tcx>)) -> String {
|
||||||
format!("const-evaluating `{}`",
|
format!("const-evaluating `{}`", tcx.item_path_str(def_id))
|
||||||
tcx.item_path_str(def_id))
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'tcx> QueryDescription for queries::mir_keys<'tcx> {
|
||||||
|
fn describe(_: TyCtxt, _: CrateNum) -> String {
|
||||||
|
format!("getting a list of all mir_keys")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -546,6 +551,11 @@ define_maps! { <'tcx>
|
||||||
/// (in the `RefCell` sense) to prevent accidental mutation.
|
/// (in the `RefCell` sense) to prevent accidental mutation.
|
||||||
[pub] mir: Mir(DefId) -> &'tcx RefCell<mir::Mir<'tcx>>,
|
[pub] mir: Mir(DefId) -> &'tcx RefCell<mir::Mir<'tcx>>,
|
||||||
|
|
||||||
|
/// Set of all the def-ids in this crate that have MIR associated with
|
||||||
|
/// them. This includes all the body owners, but also things like struct
|
||||||
|
/// constructors.
|
||||||
|
[] mir_keys: mir_keys(CrateNum) -> Rc<DefIdSet>,
|
||||||
|
|
||||||
/// Maps DefId's that have an associated Mir to the result
|
/// Maps DefId's that have an associated Mir to the result
|
||||||
/// of the MIR qualify_consts pass. The actual meaning of
|
/// of the MIR qualify_consts pass. The actual meaning of
|
||||||
/// the value isn't known except to the pass itself.
|
/// the value isn't known except to the pass itself.
|
||||||
|
@ -644,3 +654,7 @@ fn typeck_item_bodies_dep_node(_: CrateNum) -> DepNode<DefId> {
|
||||||
fn const_eval_dep_node((def_id, _): (DefId, &Substs)) -> DepNode<DefId> {
|
fn const_eval_dep_node((def_id, _): (DefId, &Substs)) -> DepNode<DefId> {
|
||||||
DepNode::ConstEval(def_id)
|
DepNode::ConstEval(def_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mir_keys(_: CrateNum) -> DepNode<DefId> {
|
||||||
|
DepNode::MirKeys
|
||||||
|
}
|
||||||
|
|
|
@ -2049,6 +2049,16 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||||
self.typeck_tables_of(self.hir.body_owner_def_id(body))
|
self.typeck_tables_of(self.hir.body_owner_def_id(body))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Returns an iterator of the def-ids for all body-owners in this
|
||||||
|
/// crate. If you would prefer to iterate over the bodies
|
||||||
|
/// themselves, you can do `self.hir.krate().body_ids.iter()`.
|
||||||
|
pub fn body_owners(self) -> impl Iterator<Item = DefId> + 'a {
|
||||||
|
self.hir.krate()
|
||||||
|
.body_ids
|
||||||
|
.iter()
|
||||||
|
.map(move |&body_id| self.hir.body_owner_def_id(body_id))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn expr_span(self, id: NodeId) -> Span {
|
pub fn expr_span(self, id: NodeId) -> Span {
|
||||||
match self.hir.find(id) {
|
match self.hir.find(id) {
|
||||||
Some(hir_map::NodeExpr(e)) => {
|
Some(hir_map::NodeExpr(e)) => {
|
||||||
|
@ -2331,7 +2341,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||||
/// Given the DefId of an item, returns its MIR, borrowed immutably.
|
/// Given the DefId of an item, returns its MIR, borrowed immutably.
|
||||||
/// Returns None if there is no MIR for the DefId
|
/// Returns None if there is no MIR for the DefId
|
||||||
pub fn maybe_item_mir(self, did: DefId) -> Option<Ref<'gcx, Mir<'gcx>>> {
|
pub fn maybe_item_mir(self, did: DefId) -> Option<Ref<'gcx, Mir<'gcx>>> {
|
||||||
if did.is_local() && !self.maps.mir.borrow().contains_key(&did) {
|
if did.is_local() && !self.mir_keys(LOCAL_CRATE).contains(&did) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2541,17 +2551,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
||||||
dep_graph::visit_all_item_likes_in_krate(self.global_tcx(), dep_node_fn, visitor);
|
dep_graph::visit_all_item_likes_in_krate(self.global_tcx(), dep_node_fn, visitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Invokes `callback` for each body in the krate. This will
|
|
||||||
/// create a read edge from `DepNode::Krate` to the current task;
|
|
||||||
/// it is meant to be run in the context of some global task like
|
|
||||||
/// `BorrowckCrate`. The callback would then create a task like
|
|
||||||
/// `BorrowckBody(DefId)` to process each individual item.
|
|
||||||
pub fn visit_all_bodies_in_krate<C>(self, callback: C)
|
|
||||||
where C: Fn(/* body_owner */ DefId, /* body id */ hir::BodyId),
|
|
||||||
{
|
|
||||||
dep_graph::visit_all_bodies_in_krate(self.global_tcx(), callback)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Looks up the span of `impl_did` if the impl is local; otherwise returns `Err`
|
/// Looks up the span of `impl_did` if the impl is local; otherwise returns `Err`
|
||||||
/// with the name of the crate containing the impl.
|
/// with the name of the crate containing the impl.
|
||||||
pub fn span_of_impl(self, impl_did: DefId) -> Result<Span, Symbol> {
|
pub fn span_of_impl(self, impl_did: DefId) -> Result<Span, Symbol> {
|
||||||
|
|
|
@ -63,9 +63,9 @@ pub struct LoanDataFlowOperator;
|
||||||
pub type LoanDataFlow<'a, 'tcx> = DataFlowContext<'a, 'tcx, LoanDataFlowOperator>;
|
pub type LoanDataFlow<'a, 'tcx> = DataFlowContext<'a, 'tcx, LoanDataFlowOperator>;
|
||||||
|
|
||||||
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
||||||
tcx.visit_all_bodies_in_krate(|body_owner_def_id, _body_id| {
|
for body_owner_def_id in tcx.body_owners() {
|
||||||
tcx.borrowck(body_owner_def_id);
|
tcx.borrowck(body_owner_def_id);
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn provide(providers: &mut Providers) {
|
pub fn provide(providers: &mut Providers) {
|
||||||
|
|
|
@ -41,7 +41,6 @@ use graphviz as dot;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
use std::iter;
|
|
||||||
use std::option;
|
use std::option;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
@ -999,22 +998,14 @@ fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session,
|
||||||
if let Some(nodeid) = nodeid {
|
if let Some(nodeid) = nodeid {
|
||||||
let def_id = tcx.hir.local_def_id(nodeid);
|
let def_id = tcx.hir.local_def_id(nodeid);
|
||||||
match ppm {
|
match ppm {
|
||||||
PpmMir => write_mir_pretty(tcx, iter::once(def_id), &mut out),
|
PpmMir => write_mir_pretty(tcx, Some(def_id), &mut out),
|
||||||
PpmMirCFG => write_mir_graphviz(tcx, iter::once(def_id), &mut out),
|
PpmMirCFG => write_mir_graphviz(tcx, Some(def_id), &mut out),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}?;
|
}?;
|
||||||
} else {
|
} else {
|
||||||
match ppm {
|
match ppm {
|
||||||
PpmMir => {
|
PpmMir => write_mir_pretty(tcx, None, &mut out),
|
||||||
write_mir_pretty(tcx,
|
PpmMirCFG => write_mir_graphviz(tcx, None, &mut out),
|
||||||
tcx.maps.mir.borrow().keys().into_iter(),
|
|
||||||
&mut out)
|
|
||||||
}
|
|
||||||
PpmMirCFG => {
|
|
||||||
write_mir_graphviz(tcx,
|
|
||||||
tcx.maps.mir.borrow().keys().into_iter(),
|
|
||||||
&mut out)
|
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}?;
|
}?;
|
||||||
}
|
}
|
||||||
|
|
|
@ -621,7 +621,12 @@ impl<'a, 'b: 'a, 'tcx: 'b> EntryBuilder<'a, 'b, 'tcx> {
|
||||||
|
|
||||||
fn encode_mir(&mut self, def_id: DefId) -> Option<Lazy<mir::Mir<'tcx>>> {
|
fn encode_mir(&mut self, def_id: DefId) -> Option<Lazy<mir::Mir<'tcx>>> {
|
||||||
debug!("EntryBuilder::encode_mir({:?})", def_id);
|
debug!("EntryBuilder::encode_mir({:?})", def_id);
|
||||||
self.tcx.maps.mir.borrow().get(&def_id).map(|mir| self.lazy(&*mir.borrow()))
|
if self.tcx.mir_keys(LOCAL_CRATE).contains(&def_id) {
|
||||||
|
let mir = self.tcx.item_mir(def_id);
|
||||||
|
Some(self.lazy(&mir))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encodes the inherent implementations of a structure, enumeration, or trait.
|
// Encodes the inherent implementations of a structure, enumeration, or trait.
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
//!
|
//!
|
||||||
//! This only considers direct calls
|
//! This only considers direct calls
|
||||||
|
|
||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
|
||||||
use rustc_data_structures::graph;
|
use rustc_data_structures::graph;
|
||||||
|
|
||||||
use rustc::mir::*;
|
use rustc::mir::*;
|
||||||
|
@ -31,16 +31,12 @@ impl CallGraph {
|
||||||
// FIXME: allow for construction of a callgraph that inspects
|
// FIXME: allow for construction of a callgraph that inspects
|
||||||
// cross-crate MIRs if available.
|
// cross-crate MIRs if available.
|
||||||
pub fn build<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>) -> CallGraph {
|
pub fn build<'a, 'tcx>(tcx: ty::TyCtxt<'a, 'tcx, 'tcx>) -> CallGraph {
|
||||||
let def_ids = tcx.maps.mir.borrow().keys();
|
|
||||||
|
|
||||||
let mut callgraph = CallGraph {
|
let mut callgraph = CallGraph {
|
||||||
node_map: DefIdMap(),
|
node_map: DefIdMap(),
|
||||||
graph: graph::Graph::new()
|
graph: graph::Graph::new()
|
||||||
};
|
};
|
||||||
|
|
||||||
for def_id in def_ids {
|
for &def_id in tcx.mir_keys(LOCAL_CRATE).iter() {
|
||||||
if !def_id.is_local() { continue; }
|
|
||||||
|
|
||||||
let idx = callgraph.add_node(def_id);
|
let idx = callgraph.add_node(def_id);
|
||||||
|
|
||||||
let mut call_visitor = CallVisitor {
|
let mut call_visitor = CallVisitor {
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
//! - `#[rustc_mir(pretty="file.mir")]`
|
//! - `#[rustc_mir(pretty="file.mir")]`
|
||||||
|
|
||||||
use build;
|
use build;
|
||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
|
||||||
use rustc::dep_graph::DepNode;
|
use rustc::dep_graph::DepNode;
|
||||||
use rustc::mir::Mir;
|
use rustc::mir::Mir;
|
||||||
use rustc::mir::transform::MirSource;
|
use rustc::mir::transform::MirSource;
|
||||||
|
@ -32,50 +32,67 @@ use rustc::ty::maps::Providers;
|
||||||
use rustc::ty::subst::Substs;
|
use rustc::ty::subst::Substs;
|
||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
|
use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap};
|
||||||
|
use rustc::util::nodemap::DefIdSet;
|
||||||
use syntax::abi::Abi;
|
use syntax::abi::Abi;
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use syntax_pos::Span;
|
use syntax_pos::Span;
|
||||||
|
|
||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
pub fn build_mir_for_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
pub fn build_mir_for_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
|
||||||
tcx.dep_graph.with_task(DepNode::MirKrate, tcx, (), build_mir_for_crate_task);
|
tcx.dep_graph.with_task(DepNode::MirKrate, tcx, (), build_mir_for_crate_task);
|
||||||
|
|
||||||
fn build_mir_for_crate_task<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, (): ()) {
|
fn build_mir_for_crate_task<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, (): ()) {
|
||||||
tcx.visit_all_bodies_in_krate(|body_owner_def_id, _body_id| {
|
for &body_owner_def_id in tcx.mir_keys(LOCAL_CRATE).iter() {
|
||||||
tcx.item_mir(body_owner_def_id);
|
tcx.item_mir(body_owner_def_id);
|
||||||
});
|
|
||||||
|
|
||||||
// Tuple struct/variant constructors don't have a BodyId, so we need
|
|
||||||
// to build them separately.
|
|
||||||
struct GatherCtors<'a, 'tcx: 'a> {
|
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>
|
|
||||||
}
|
}
|
||||||
impl<'a, 'tcx> Visitor<'tcx> for GatherCtors<'a, 'tcx> {
|
|
||||||
fn visit_variant_data(&mut self,
|
|
||||||
v: &'tcx hir::VariantData,
|
|
||||||
_: ast::Name,
|
|
||||||
_: &'tcx hir::Generics,
|
|
||||||
_: ast::NodeId,
|
|
||||||
_: Span) {
|
|
||||||
if let hir::VariantData::Tuple(_, node_id) = *v {
|
|
||||||
self.tcx.item_mir(self.tcx.hir.local_def_id(node_id));
|
|
||||||
}
|
|
||||||
intravisit::walk_struct_def(self, v)
|
|
||||||
}
|
|
||||||
fn nested_visit_map<'b>(&'b mut self) -> NestedVisitorMap<'b, 'tcx> {
|
|
||||||
NestedVisitorMap::None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tcx.hir.krate().visit_all_item_likes(&mut GatherCtors {
|
|
||||||
tcx: tcx
|
|
||||||
}.as_deep_visitor());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn provide(providers: &mut Providers) {
|
pub fn provide(providers: &mut Providers) {
|
||||||
providers.mir = build_mir;
|
providers.mir = build_mir;
|
||||||
|
providers.mir_keys = mir_keys;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mir_keys<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, krate: CrateNum)
|
||||||
|
-> Rc<DefIdSet> {
|
||||||
|
assert_eq!(krate, LOCAL_CRATE);
|
||||||
|
|
||||||
|
let mut set = DefIdSet();
|
||||||
|
|
||||||
|
// All body-owners have MIR associated with them.
|
||||||
|
set.extend(tcx.body_owners());
|
||||||
|
|
||||||
|
// Additionally, tuple struct/variant constructors have MIR, but
|
||||||
|
// they don't have a BodyId, so we need to build them separately.
|
||||||
|
struct GatherCtors<'a, 'tcx: 'a> {
|
||||||
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
|
set: &'a mut DefIdSet,
|
||||||
|
}
|
||||||
|
impl<'a, 'tcx> Visitor<'tcx> for GatherCtors<'a, 'tcx> {
|
||||||
|
fn visit_variant_data(&mut self,
|
||||||
|
v: &'tcx hir::VariantData,
|
||||||
|
_: ast::Name,
|
||||||
|
_: &'tcx hir::Generics,
|
||||||
|
_: ast::NodeId,
|
||||||
|
_: Span) {
|
||||||
|
if let hir::VariantData::Tuple(_, node_id) = *v {
|
||||||
|
self.set.insert(self.tcx.hir.local_def_id(node_id));
|
||||||
|
}
|
||||||
|
intravisit::walk_struct_def(self, v)
|
||||||
|
}
|
||||||
|
fn nested_visit_map<'b>(&'b mut self) -> NestedVisitorMap<'b, 'tcx> {
|
||||||
|
NestedVisitorMap::None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
tcx.hir.krate().visit_all_item_likes(&mut GatherCtors {
|
||||||
|
tcx: tcx,
|
||||||
|
set: &mut set,
|
||||||
|
}.as_deep_visitor());
|
||||||
|
|
||||||
|
Rc::new(set)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn build_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
|
fn build_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId)
|
||||||
|
|
|
@ -81,6 +81,6 @@ pub fn emit_mir<'a, 'tcx>(
|
||||||
{
|
{
|
||||||
let path = outputs.path(OutputType::Mir);
|
let path = outputs.path(OutputType::Mir);
|
||||||
let mut f = File::create(&path)?;
|
let mut f = File::create(&path)?;
|
||||||
mir_util::write_mir_pretty(tcx, tcx.maps.mir.borrow().keys().into_iter(), &mut f)?;
|
mir_util::write_mir_pretty(tcx, None, &mut f)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
//! Inlining pass for MIR functions
|
//! Inlining pass for MIR functions
|
||||||
|
|
||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
|
||||||
|
|
||||||
use rustc_data_structures::bitvec::BitVector;
|
use rustc_data_structures::bitvec::BitVector;
|
||||||
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
|
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
|
||||||
|
@ -58,24 +58,15 @@ impl<'tcx> MirMapPass<'tcx> for Inline {
|
||||||
tcx: tcx,
|
tcx: tcx,
|
||||||
};
|
};
|
||||||
|
|
||||||
let def_ids = tcx.maps.mir.borrow().keys();
|
for &def_id in tcx.mir_keys(LOCAL_CRATE).iter() {
|
||||||
for &def_id in &def_ids {
|
|
||||||
if !def_id.is_local() { continue; }
|
|
||||||
|
|
||||||
let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id));
|
let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id));
|
||||||
let mut mir = if let Some(mir) = tcx.maps.mir.borrow().get(&def_id) {
|
let mir = &tcx.item_mir(def_id);
|
||||||
mir.borrow_mut()
|
|
||||||
} else {
|
|
||||||
continue;
|
|
||||||
};
|
|
||||||
|
|
||||||
tcx.dep_graph.write(DepNode::Mir(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 src = MirSource::from_node(tcx, id);
|
let src = MirSource::from_node(tcx, id);
|
||||||
|
|
||||||
for hook in &mut *hooks {
|
for hook in &mut *hooks {
|
||||||
hook.on_mir_pass(tcx, src, &mut mir, self, false);
|
hook.on_mir_pass(tcx, src, mir, self, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -83,18 +74,15 @@ impl<'tcx> MirMapPass<'tcx> for Inline {
|
||||||
inliner.inline_scc(&callgraph, &scc);
|
inliner.inline_scc(&callgraph, &scc);
|
||||||
}
|
}
|
||||||
|
|
||||||
for def_id in def_ids {
|
for &def_id in tcx.mir_keys(LOCAL_CRATE).iter() {
|
||||||
if !def_id.is_local() { continue; }
|
|
||||||
|
|
||||||
let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id));
|
let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id));
|
||||||
let mut mir = tcx.maps.mir.borrow()[&def_id].borrow_mut();
|
let mir = &tcx.item_mir(def_id);
|
||||||
tcx.dep_graph.write(DepNode::Mir(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 src = MirSource::from_node(tcx, id);
|
let src = MirSource::from_node(tcx, id);
|
||||||
|
|
||||||
for hook in &mut *hooks {
|
for hook in &mut *hooks {
|
||||||
hook.on_mir_pass(tcx, src, &mut mir, self, true);
|
hook.on_mir_pass(tcx, src, mir, self, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,11 +188,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut caller_mir = {
|
let mut caller_mir = self.tcx.mir(callsite.caller).borrow_mut();
|
||||||
let map = self.tcx.maps.mir.borrow();
|
|
||||||
let mir = map.get(&callsite.caller).unwrap();
|
|
||||||
mir.borrow_mut()
|
|
||||||
};
|
|
||||||
|
|
||||||
let start = caller_mir.basic_blocks().len();
|
let start = caller_mir.basic_blocks().len();
|
||||||
|
|
||||||
|
@ -256,11 +240,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
|
||||||
let _task = self.tcx.dep_graph.in_task(DepNode::Mir(def_id));
|
let _task = self.tcx.dep_graph.in_task(DepNode::Mir(def_id));
|
||||||
self.tcx.dep_graph.write(DepNode::Mir(def_id));
|
self.tcx.dep_graph.write(DepNode::Mir(def_id));
|
||||||
|
|
||||||
let mut caller_mir = {
|
let mut caller_mir = self.tcx.mir(def_id).borrow_mut();
|
||||||
let map = self.tcx.maps.mir.borrow();
|
|
||||||
let mir = map.get(&def_id).unwrap();
|
|
||||||
mir.borrow_mut()
|
|
||||||
};
|
|
||||||
|
|
||||||
debug!("Running simplify cfg on {:?}", def_id);
|
debug!("Running simplify cfg on {:?}", def_id);
|
||||||
CfgSimplifier::new(&mut caller_mir).simplify();
|
CfgSimplifier::new(&mut caller_mir).simplify();
|
||||||
|
|
|
@ -19,7 +19,7 @@ use rustc_data_structures::indexed_vec::{IndexVec, Idx};
|
||||||
use rustc::dep_graph::DepNode;
|
use rustc::dep_graph::DepNode;
|
||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
use rustc::hir::map as hir_map;
|
use rustc::hir::map as hir_map;
|
||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
|
||||||
use rustc::hir::map::blocks::FnLikeNode;
|
use rustc::hir::map::blocks::FnLikeNode;
|
||||||
use rustc::traits::{self, Reveal};
|
use rustc::traits::{self, Reveal};
|
||||||
use rustc::ty::{self, TyCtxt, Ty, TypeFoldable};
|
use rustc::ty::{self, TyCtxt, Ty, TypeFoldable};
|
||||||
|
@ -946,12 +946,7 @@ impl<'tcx> MirMapPass<'tcx> for QualifyAndPromoteConstants {
|
||||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
hooks: &mut [Box<for<'s> MirPassHook<'s>>])
|
hooks: &mut [Box<for<'s> MirPassHook<'s>>])
|
||||||
{
|
{
|
||||||
let def_ids = tcx.maps.mir.borrow().keys();
|
for &def_id in tcx.mir_keys(LOCAL_CRATE).iter() {
|
||||||
for def_id in def_ids {
|
|
||||||
if !def_id.is_local() {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id));
|
let _task = tcx.dep_graph.in_task(DepNode::Mir(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 src = MirSource::from_node(tcx, id);
|
let src = MirSource::from_node(tcx, id);
|
||||||
|
@ -961,7 +956,7 @@ impl<'tcx> MirMapPass<'tcx> for QualifyAndPromoteConstants {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mir = &mut tcx.maps.mir.borrow()[&def_id].borrow_mut();
|
let mir = &mut tcx.mir(def_id).borrow_mut();
|
||||||
tcx.dep_graph.write(DepNode::Mir(def_id));
|
tcx.dep_graph.write(DepNode::Mir(def_id));
|
||||||
|
|
||||||
for hook in &mut *hooks {
|
for hook in &mut *hooks {
|
||||||
|
|
|
@ -18,14 +18,16 @@ use syntax::ast::NodeId;
|
||||||
|
|
||||||
use rustc_data_structures::indexed_vec::Idx;
|
use rustc_data_structures::indexed_vec::Idx;
|
||||||
|
|
||||||
|
use super::pretty::dump_mir_def_ids;
|
||||||
|
|
||||||
/// Write a graphviz DOT graph of a list of MIRs.
|
/// Write a graphviz DOT graph of a list of MIRs.
|
||||||
pub fn write_mir_graphviz<'a, 'b, 'tcx, W, I>(tcx: TyCtxt<'b, 'tcx, 'tcx>,
|
pub fn write_mir_graphviz<'a, 'tcx, W>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
iter: I,
|
single: Option<DefId>,
|
||||||
w: &mut W)
|
w: &mut W)
|
||||||
-> io::Result<()>
|
-> io::Result<()>
|
||||||
where W: Write, I: Iterator<Item=DefId>
|
where W: Write
|
||||||
{
|
{
|
||||||
for def_id in iter {
|
for def_id in dump_mir_def_ids(tcx, single) {
|
||||||
let nodeid = tcx.hir.as_local_node_id(def_id).unwrap();
|
let nodeid = tcx.hir.as_local_node_id(def_id).unwrap();
|
||||||
let mir = &tcx.item_mir(def_id);
|
let mir = &tcx.item_mir(def_id);
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
// except according to those terms.
|
// except according to those terms.
|
||||||
|
|
||||||
use rustc::hir;
|
use rustc::hir;
|
||||||
use rustc::hir::def_id::DefId;
|
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
|
||||||
use rustc::mir::*;
|
use rustc::mir::*;
|
||||||
use rustc::mir::transform::MirSource;
|
use rustc::mir::transform::MirSource;
|
||||||
use rustc::ty::TyCtxt;
|
use rustc::ty::TyCtxt;
|
||||||
|
@ -85,17 +85,16 @@ pub fn dump_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Write out a human-readable textual representation for the given MIR.
|
/// Write out a human-readable textual representation for the given MIR.
|
||||||
pub fn write_mir_pretty<'a, 'b, 'tcx, I>(tcx: TyCtxt<'b, 'tcx, 'tcx>,
|
pub fn write_mir_pretty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||||
iter: I,
|
single: Option<DefId>,
|
||||||
w: &mut Write)
|
w: &mut Write)
|
||||||
-> io::Result<()>
|
-> io::Result<()>
|
||||||
where I: Iterator<Item=DefId>, 'tcx: 'a
|
|
||||||
{
|
{
|
||||||
writeln!(w, "// WARNING: This output format is intended for human consumers only")?;
|
writeln!(w, "// WARNING: This output format is intended for human consumers only")?;
|
||||||
writeln!(w, "// and is subject to change without notice. Knock yourself out.")?;
|
writeln!(w, "// and is subject to change without notice. Knock yourself out.")?;
|
||||||
|
|
||||||
let mut first = true;
|
let mut first = true;
|
||||||
for def_id in iter.filter(DefId::is_local) {
|
for def_id in dump_mir_def_ids(tcx, single) {
|
||||||
let mir = &tcx.item_mir(def_id);
|
let mir = &tcx.item_mir(def_id);
|
||||||
|
|
||||||
if first {
|
if first {
|
||||||
|
@ -312,3 +311,11 @@ fn write_temp_decls(mir: &Mir, w: &mut Write) -> io::Result<()> {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn dump_mir_def_ids(tcx: TyCtxt, single: Option<DefId>) -> Vec<DefId> {
|
||||||
|
if let Some(i) = single {
|
||||||
|
vec![i]
|
||||||
|
} else {
|
||||||
|
tcx.mir_keys(LOCAL_CRATE).iter().cloned().collect()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
// completely accurate (some things might be counted twice, others missed).
|
// completely accurate (some things might be counted twice, others missed).
|
||||||
|
|
||||||
use rustc_const_math::{ConstUsize};
|
use rustc_const_math::{ConstUsize};
|
||||||
|
use rustc::hir::def_id::LOCAL_CRATE;
|
||||||
use rustc::middle::const_val::{ConstVal};
|
use rustc::middle::const_val::{ConstVal};
|
||||||
use rustc::mir::{AggregateKind, AssertMessage, BasicBlock, BasicBlockData};
|
use rustc::mir::{AggregateKind, AssertMessage, BasicBlock, BasicBlockData};
|
||||||
use rustc::mir::{Constant, Literal, Location, LocalDecl};
|
use rustc::mir::{Constant, Literal, Location, LocalDecl};
|
||||||
|
@ -44,10 +45,9 @@ pub fn print_mir_stats<'tcx, 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, title: &str) {
|
||||||
// For debugging instrumentation like this, we don't need to worry
|
// For debugging instrumentation like this, we don't need to worry
|
||||||
// about maintaining the dep graph.
|
// about maintaining the dep graph.
|
||||||
let _ignore = tcx.dep_graph.in_ignore();
|
let _ignore = tcx.dep_graph.in_ignore();
|
||||||
let mir_map = tcx.maps.mir.borrow();
|
for &def_id in tcx.mir_keys(LOCAL_CRATE).iter() {
|
||||||
for def_id in mir_map.keys() {
|
let mir = tcx.item_mir(def_id);
|
||||||
let mir = mir_map.get(&def_id).unwrap();
|
collector.visit_mir(&mir);
|
||||||
collector.visit_mir(&mir.borrow());
|
|
||||||
}
|
}
|
||||||
collector.print(title);
|
collector.print(title);
|
||||||
}
|
}
|
||||||
|
|
|
@ -640,9 +640,9 @@ pub fn check_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> CompileResult
|
||||||
fn typeck_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) -> CompileResult {
|
fn typeck_item_bodies<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, crate_num: CrateNum) -> CompileResult {
|
||||||
debug_assert!(crate_num == LOCAL_CRATE);
|
debug_assert!(crate_num == LOCAL_CRATE);
|
||||||
tcx.sess.track_errors(|| {
|
tcx.sess.track_errors(|| {
|
||||||
tcx.visit_all_bodies_in_krate(|body_owner_def_id, _body_id| {
|
for body_owner_def_id in tcx.body_owners() {
|
||||||
tcx.typeck_tables_of(body_owner_def_id);
|
tcx.typeck_tables_of(body_owner_def_id);
|
||||||
});
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue