Rollup merge of #70511 - ecstatic-morse:mir-dataflow-graphviz, r=davidtwco

Add `-Z dump-mir-dataflow` flag for dumping dataflow results visualization

Previously, to visualize the results of a MIR dataflow pass, one had to add a `#[rustc_mir(borrowck_graphviz_postflow)]` attribute to functions of interest. However, there is no way to specify this attribute on closures and generators, so it was impossible to view results for these MIR bodies.

This PR adds a flag, `-Z dump-mir-dataflow`, which will output the dataflow results for any functions specified in `-Z dump-mir` to the output directory specified by `-Z dump-mir-dir`. This behavior is modeled on the `-Z dump-mir-graphviz` flag.
This commit is contained in:
Mazdak Farrokhzad 2020-04-01 14:32:12 +02:00 committed by GitHub
commit 84a4633880
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 30 additions and 7 deletions

View File

@ -562,6 +562,8 @@ fn test_debugging_options_tracking_hash() {
assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
opts.debugging_opts.dump_mir_graphviz = true;
assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
opts.debugging_opts.dump_mir_dataflow = true;
assert_eq!(reference.dep_tracking_hash(), opts.dep_tracking_hash());
// Make sure changing a [TRACKED] option changes the hash
opts = reference.clone();

View File

@ -317,7 +317,7 @@ pub(super) fn dump_mir_results<'a, 'tcx>(
regioncx: &RegionInferenceContext<'_>,
closure_region_requirements: &Option<ClosureRegionRequirements<'_>>,
) {
if !mir_util::dump_enabled(infcx.tcx, "nll", source) {
if !mir_util::dump_enabled(infcx.tcx, "nll", source.def_id()) {
return;
}

View File

@ -15,6 +15,7 @@
use super::graphviz;
use super::{Analysis, GenKillAnalysis, GenKillSet, Results};
use crate::util::pretty::dump_enabled;
/// A solver for dataflow problems.
pub struct Engine<'a, 'tcx, A>
@ -400,12 +401,25 @@ fn write_graphviz_results<A>(
let attrs = match RustcMirAttrs::parse(tcx, def_id) {
Ok(attrs) => attrs,
// Invalid `rustc_mir` attrs will be reported using `span_err`.
// Invalid `rustc_mir` attrs are reported in `RustcMirAttrs::parse`
Err(()) => return Ok(()),
};
let path = match attrs.output_path(A::NAME) {
Some(path) => path,
None if tcx.sess.opts.debugging_opts.dump_mir_dataflow
&& dump_enabled(tcx, A::NAME, def_id) =>
{
let mut path = PathBuf::from(&tcx.sess.opts.debugging_opts.dump_mir_dir);
let item_name = ty::print::with_forced_impl_filename_line(|| {
tcx.def_path(def_id).to_filename_friendly_no_crate()
});
path.push(format!("rustc.{}.{}.dot", item_name, A::NAME));
path
}
None => return Ok(()),
};
@ -430,7 +444,12 @@ fn write_graphviz_results<A>(
let graphviz = graphviz::Formatter::new(body, def_id, results, &mut *formatter);
dot::render_opts(&graphviz, &mut buf, &[dot::RenderOption::Monospace])?;
if let Some(parent) = path.parent() {
fs::create_dir_all(parent)?;
}
fs::write(&path, buf)?;
Ok(())
}

View File

@ -46,7 +46,7 @@ pub fn on_mir_pass<'tcx>(
body: &Body<'tcx>,
is_after: bool,
) {
if mir_util::dump_enabled(tcx, pass_name, source) {
if mir_util::dump_enabled(tcx, pass_name, source.def_id()) {
mir_util::dump_mir(
tcx,
Some(pass_num),

View File

@ -265,7 +265,7 @@ pub fn dump_mir<'tcx>(
body: &Body<'tcx>,
result: &LivenessResult,
) {
if !dump_enabled(tcx, pass_name, source) {
if !dump_enabled(tcx, pass_name, source.def_id()) {
return;
}
let node_path = ty::print::with_forced_impl_filename_line(|| {

View File

@ -78,21 +78,21 @@ pub fn dump_mir<'tcx, F>(
) where
F: FnMut(PassWhere, &mut dyn Write) -> io::Result<()>,
{
if !dump_enabled(tcx, pass_name, source) {
if !dump_enabled(tcx, pass_name, source.def_id()) {
return;
}
dump_matched_mir_node(tcx, pass_num, pass_name, disambiguator, source, body, extra_data);
}
pub fn dump_enabled<'tcx>(tcx: TyCtxt<'tcx>, pass_name: &str, source: MirSource<'tcx>) -> bool {
pub fn dump_enabled<'tcx>(tcx: TyCtxt<'tcx>, pass_name: &str, def_id: DefId) -> bool {
let filters = match tcx.sess.opts.debugging_opts.dump_mir {
None => return false,
Some(ref filters) => filters,
};
let node_path = ty::print::with_forced_impl_filename_line(|| {
// see notes on #41697 below
tcx.def_path_str(source.def_id())
tcx.def_path_str(def_id)
});
filters.split('|').any(|or_filter| {
or_filter.split('&').all(|and_filter| {

View File

@ -835,6 +835,8 @@ fn parse_symbol_mangling_version(
"the directory the MIR is dumped into"),
dump_mir_graphviz: bool = (false, parse_bool, [UNTRACKED],
"in addition to `.mir` files, create graphviz `.dot` files"),
dump_mir_dataflow: bool = (false, parse_bool, [UNTRACKED],
"in addition to `.mir` files, create graphviz `.dot` files with dataflow results"),
dump_mir_exclude_pass_number: bool = (false, parse_bool, [UNTRACKED],
"if set, exclude the pass number when dumping MIR (used in tests)"),
mir_emit_retag: bool = (false, parse_bool, [TRACKED],