Skip to content

Commit

Permalink
Unrolled build for rust-lang#129711
Browse files Browse the repository at this point in the history
Rollup merge of rust-lang#129711 - lqd:nll-mir-dumps, r=compiler-errors

Expand NLL MIR dumps

This PR is a first step to clean up and expand NLL MIR dumps:
- by restoring the "mir-include-spans" comments which are useful for `-Zdump-mir=nll`
- by adding the list of borrows to NLL MIR dumps, where they are introduced in the CFG and in which region

Comments in MIR dumps were turned off in rust-lang#112346, but as shown in rust-lang#114652 they were still useful for us working with NLL MIR dumps. So this PR pulls `-Z mir-include-spans` into its own options struct, so that passes dumping MIR can override them if need be. The rest of the compiler is not affected, only the "nll" pass dumps have these comments enabled again. The CLI still has priority when specifying the flag, so that we can explicitly turn them off in the `mir-opt` tests to keep blessed dumps easier to work with (which was one of the points of rust-lang#112346).

Then, as part of a couple steps to improve NLL/polonius MIR dumps and `.dot` visualizations, I've also added the list of borrows and where they're introduced. I'm doing all this to help debug some polonius scope issues in my prototype location-sensitive analysis :3. I'll probably add member constraints soon.
  • Loading branch information
rust-timer authored Aug 31, 2024
2 parents 9649706 + dff3d35 commit fe4f400
Show file tree
Hide file tree
Showing 12 changed files with 214 additions and 64 deletions.
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

0 comments on commit fe4f400

Please sign in to comment.