Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Expand NLL MIR dumps #129711

Merged
merged 5 commits into from
Aug 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ fn do_mir_borrowck<'tcx>(

// Dump MIR results into a file, if that is enabled. This let us
// write unit-tests, as well as helping with debugging.
nll::dump_mir_results(&infcx, body, &regioncx, &opt_closure_req);
nll::dump_nll_mir(&infcx, body, &regioncx, &opt_closure_req, &borrow_set);

// We also have a `#[rustc_regions]` annotation that causes us to dump
// information.
Expand Down
94 changes: 67 additions & 27 deletions compiler/rustc_borrowck/src/nll.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use polonius_engine::{Algorithm, Output};
use rustc_data_structures::fx::FxIndexMap;
use rustc_hir::def_id::LocalDefId;
use rustc_index::IndexSlice;
use rustc_middle::mir::pretty::{dump_mir_with_options, PrettyPrintMirOptions};
use rustc_middle::mir::{
create_dump_file, dump_enabled, dump_mir, Body, ClosureOutlivesSubject,
ClosureRegionRequirements, PassWhere, Promoted,
Expand All @@ -19,6 +20,7 @@ use rustc_mir_dataflow::impls::MaybeInitializedPlaces;
use rustc_mir_dataflow::move_paths::MoveData;
use rustc_mir_dataflow::points::DenseLocationMap;
use rustc_mir_dataflow::ResultsCursor;
use rustc_session::config::MirIncludeSpans;
use rustc_span::symbol::sym;

use crate::borrow_set::BorrowSet;
Expand Down Expand Up @@ -208,52 +210,90 @@ pub(crate) fn compute_regions<'cx, 'tcx>(
}
}

pub(super) fn dump_mir_results<'tcx>(
/// `-Zdump-mir=nll` dumps MIR annotated with NLL specific information:
/// - free regions
/// - inferred region values
/// - region liveness
/// - inference constraints and their causes
///
/// As well as graphviz `.dot` visualizations of:
/// - the region constraints graph
/// - the region SCC graph
pub(super) fn dump_nll_mir<'tcx>(
infcx: &BorrowckInferCtxt<'tcx>,
body: &Body<'tcx>,
regioncx: &RegionInferenceContext<'tcx>,
closure_region_requirements: &Option<ClosureRegionRequirements<'tcx>>,
borrow_set: &BorrowSet<'tcx>,
) {
if !dump_enabled(infcx.tcx, "nll", body.source.def_id()) {
let tcx = infcx.tcx;
if !dump_enabled(tcx, "nll", body.source.def_id()) {
return;
}

dump_mir(infcx.tcx, false, "nll", &0, body, |pass_where, out| {
match pass_where {
// Before the CFG, dump out the values for each region variable.
PassWhere::BeforeCFG => {
regioncx.dump_mir(infcx.tcx, out)?;
writeln!(out, "|")?;

if let Some(closure_region_requirements) = closure_region_requirements {
writeln!(out, "| Free Region Constraints")?;
for_each_region_constraint(
infcx.tcx,
closure_region_requirements,
&mut |msg| writeln!(out, "| {msg}"),
)?;
// We want the NLL extra comments printed by default in NLL MIR dumps (they were removed in
// #112346). Specifying `-Z mir-include-spans` on the CLI still has priority: for example,
// they're always disabled in mir-opt tests to make working with blessed dumps easier.
let options = PrettyPrintMirOptions {
include_extra_comments: matches!(
infcx.tcx.sess.opts.unstable_opts.mir_include_spans,
MirIncludeSpans::On | MirIncludeSpans::Nll
),
};
dump_mir_with_options(
tcx,
false,
"nll",
&0,
body,
|pass_where, out| {
match pass_where {
// Before the CFG, dump out the values for each region variable.
PassWhere::BeforeCFG => {
regioncx.dump_mir(tcx, out)?;
writeln!(out, "|")?;

if let Some(closure_region_requirements) = closure_region_requirements {
writeln!(out, "| Free Region Constraints")?;
for_each_region_constraint(tcx, closure_region_requirements, &mut |msg| {
writeln!(out, "| {msg}")
})?;
writeln!(out, "|")?;
}

if borrow_set.len() > 0 {
writeln!(out, "| Borrows")?;
for (borrow_idx, borrow_data) in borrow_set.iter_enumerated() {
writeln!(
out,
"| {:?}: issued at {:?} in {:?}",
borrow_idx, borrow_data.reserve_location, borrow_data.region
)?;
}
writeln!(out, "|")?;
}
}
}

PassWhere::BeforeLocation(_) => {}
PassWhere::BeforeLocation(_) => {}

PassWhere::AfterTerminator(_) => {}
PassWhere::AfterTerminator(_) => {}

PassWhere::BeforeBlock(_) | PassWhere::AfterLocation(_) | PassWhere::AfterCFG => {}
}
Ok(())
});
PassWhere::BeforeBlock(_) | PassWhere::AfterLocation(_) | PassWhere::AfterCFG => {}
}
Ok(())
},
options,
);

// Also dump the inference graph constraints as a graphviz file.
// Also dump the region constraint graph as a graphviz file.
let _: io::Result<()> = try {
let mut file = create_dump_file(infcx.tcx, "regioncx.all.dot", false, "nll", &0, body)?;
let mut file = create_dump_file(tcx, "regioncx.all.dot", false, "nll", &0, body)?;
regioncx.dump_graphviz_raw_constraints(&mut file)?;
};

// Also dump the inference graph constraints as a graphviz file.
// Also dump the region constraint SCC graph as a graphviz file.
let _: io::Result<()> = try {
let mut file = create_dump_file(infcx.tcx, "regioncx.scc.dot", false, "nll", &0, body)?;
let mut file = create_dump_file(tcx, "regioncx.scc.dot", false, "nll", &0, body)?;
regioncx.dump_graphviz_scc_constraints(&mut file)?;
};
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_borrowck/src/region_infer/graphviz.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
dot::render(&RawConstraints { regioncx: self }, &mut w)
}

/// Write out the region constraint graph.
/// Write out the region constraint SCC graph.
pub(crate) fn dump_graphviz_scc_constraints(&self, mut w: &mut dyn Write) -> io::Result<()> {
let mut nodes_per_scc: IndexVec<ConstraintSccIndex, _> =
self.constraint_sccs.all_sccs().map(|_| Vec::new()).collect();
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_codegen_cranelift/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,9 @@ pub(crate) fn codegen_fn<'tcx>(
let _mir_guard = crate::PrintOnPanic(|| {
let mut buf = Vec::new();
with_no_trimmed_paths!({
rustc_middle::mir::pretty::write_mir_fn(tcx, mir, &mut |_, _| Ok(()), &mut buf)
.unwrap();
use rustc_middle::mir::pretty;
let options = pretty::PrettyPrintMirOptions::from_cli(tcx);
pretty::write_mir_fn(tcx, mir, &mut |_, _| Ok(()), &mut buf, options).unwrap();
});
String::from_utf8_lossy(&buf).into_owned()
});
Expand Down
9 changes: 5 additions & 4 deletions compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ use rustc_session::config::{
CollapseMacroDebuginfo, CoverageLevel, CoverageOptions, DebugInfo, DumpMonoStatsFormat,
ErrorOutputType, ExternEntry, ExternLocation, Externs, FmtDebug, FunctionReturn,
InliningThreshold, Input, InstrumentCoverage, InstrumentXRay, LinkSelfContained,
LinkerPluginLto, LocationDetail, LtoCli, NextSolverConfig, OomStrategy, Options, OutFileName,
OutputType, OutputTypes, PAuthKey, PacRet, Passes, PatchableFunctionEntry, Polonius,
ProcMacroExecutionStrategy, Strip, SwitchWithOptPath, SymbolManglingVersion, WasiExecModel,
LinkerPluginLto, LocationDetail, LtoCli, MirIncludeSpans, NextSolverConfig, OomStrategy,
Options, OutFileName, OutputType, OutputTypes, PAuthKey, PacRet, Passes,
PatchableFunctionEntry, Polonius, ProcMacroExecutionStrategy, Strip, SwitchWithOptPath,
SymbolManglingVersion, WasiExecModel,
};
use rustc_session::lint::Level;
use rustc_session::search_paths::SearchPath;
Expand Down Expand Up @@ -705,7 +706,7 @@ fn test_unstable_options_tracking_hash() {
untracked!(ls, vec!["all".to_owned()]);
untracked!(macro_backtrace, true);
untracked!(meta_stats, true);
untracked!(mir_include_spans, true);
untracked!(mir_include_spans, MirIncludeSpans::On);
untracked!(nll_facts, true);
untracked!(no_analysis, true);
untracked!(no_leak_check, true);
Expand Down
Loading
Loading