Skip to content

Commit

Permalink
Rollup merge of #105286 - willcrichton:maximal-hir-to-mir-coverage, r…
Browse files Browse the repository at this point in the history
…=cjgillot

Add -Z maximal-hir-to-mir-coverage flag

This PR adds a new unstable flag `-Z maximal-hir-to-mir-coverage` that changes the behavior of `maybe_lint_level_root_bounded`, pursuant to [a discussion on Zulip](https://rust-lang.zulipchat.com/#narrow/stream/131828-t-compiler/topic/Mapping.20MIR.20to.20HIR). When enabled, this function will not search upwards for a lint root, but rather immediately return the provided HIR node ID. This change increases the granularity of the mapping between MIR locations and HIR nodes inside the `SourceScopeLocalData` data structures. This increase in granularity is useful for rustc consumers like [Flowistry](https://github.com/willcrichton/flowistry) that rely on getting source-mapping information about the MIR CFG that is as precise as possible.

A test `maximal_mir_to_hir_coverage.rs` has been added to verify that this flag does not break anything.

r? `@cjgillot`

cc `@gavinleroy`
  • Loading branch information
matthiaskrgr authored Dec 6, 2022
2 parents 967085e + d595884 commit c699b05
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 32 deletions.
1 change: 1 addition & 0 deletions compiler/rustc_interface/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -747,6 +747,7 @@ fn test_unstable_options_tracking_hash() {
tracked!(link_only, true);
tracked!(llvm_plugins, vec![String::from("plugin_name")]);
tracked!(location_detail, LocationDetail { file: true, line: false, column: false });
tracked!(maximal_hir_to_mir_coverage, true);
tracked!(merge_functions, Some(MergeFunctions::Disabled));
tracked!(mir_emit_retag, true);
tracked!(mir_enable_passes, vec![("DestProp".to_string(), false)]);
Expand Down
20 changes: 6 additions & 14 deletions compiler/rustc_mir_build/src/build/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -948,20 +948,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
original_source_scope: SourceScope,
pattern_span: Span,
) {
let tcx = self.tcx;
let current_root = tcx.maybe_lint_level_root_bounded(arg_hir_id, self.hir_id);
let parent_root = tcx.maybe_lint_level_root_bounded(
self.source_scopes[original_source_scope]
.local_data
.as_ref()
.assert_crate_local()
.lint_root,
self.hir_id,
);
if current_root != parent_root {
self.source_scope =
self.new_source_scope(pattern_span, LintLevel::Explicit(current_root), None);
}
let parent_id = self.source_scopes[original_source_scope]
.local_data
.as_ref()
.assert_crate_local()
.lint_root;
self.maybe_new_source_scope(pattern_span, None, arg_hir_id, parent_id);
}

fn get_unit_temp(&mut self) -> Place<'tcx> {
Expand Down
56 changes: 38 additions & 18 deletions compiler/rustc_mir_build/src/build/scope.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ use std::mem;

use crate::build::{BlockAnd, BlockAndExtension, BlockFrame, Builder, CFG};
use rustc_data_structures::fx::FxHashMap;
use rustc_hir::HirId;
use rustc_index::vec::IndexVec;
use rustc_middle::middle::region;
use rustc_middle::mir::*;
Expand Down Expand Up @@ -567,25 +568,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
F: FnOnce(&mut Builder<'a, 'tcx>) -> BlockAnd<R>,
{
let source_scope = self.source_scope;
let tcx = self.tcx;
if let LintLevel::Explicit(current_hir_id) = lint_level {
// Use `maybe_lint_level_root_bounded` with `root_lint_level` as a bound
// to avoid adding Hir dependencies on our parents.
// We estimate the true lint roots here to avoid creating a lot of source scopes.

let parent_root = tcx.maybe_lint_level_root_bounded(
self.source_scopes[source_scope].local_data.as_ref().assert_crate_local().lint_root,
self.hir_id,
);
let current_root = tcx.maybe_lint_level_root_bounded(current_hir_id, self.hir_id);

if parent_root != current_root {
self.source_scope = self.new_source_scope(
region_scope.1.span,
LintLevel::Explicit(current_root),
None,
);
}
let parent_id =
self.source_scopes[source_scope].local_data.as_ref().assert_crate_local().lint_root;
self.maybe_new_source_scope(region_scope.1.span, None, current_hir_id, parent_id);
}
self.push_scope(region_scope);
let mut block;
Expand Down Expand Up @@ -758,6 +744,40 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
))
}

/// Possibly creates a new source scope if `current_root` and `parent_root`
/// are different, or if -Zmaximal-hir-to-mir-coverage is enabled.
pub(crate) fn maybe_new_source_scope(
&mut self,
span: Span,
safety: Option<Safety>,
current_id: HirId,
parent_id: HirId,
) {
let (current_root, parent_root) =
if self.tcx.sess.opts.unstable_opts.maximal_hir_to_mir_coverage {
// Some consumers of rustc need to map MIR locations back to HIR nodes. Currently the
// the only part of rustc that tracks MIR -> HIR is the `SourceScopeLocalData::lint_root`
// field that tracks lint levels for MIR locations. Normally the number of source scopes
// is limited to the set of nodes with lint annotations. The -Zmaximal-hir-to-mir-coverage
// flag changes this behavior to maximize the number of source scopes, increasing the
// granularity of the MIR->HIR mapping.
(current_id, parent_id)
} else {
// Use `maybe_lint_level_root_bounded` with `self.hir_id` as a bound
// to avoid adding Hir dependencies on our parents.
// We estimate the true lint roots here to avoid creating a lot of source scopes.
(
self.tcx.maybe_lint_level_root_bounded(current_id, self.hir_id),
self.tcx.maybe_lint_level_root_bounded(parent_id, self.hir_id),
)
};

if current_root != parent_root {
let lint_level = LintLevel::Explicit(current_root);
self.source_scope = self.new_source_scope(span, lint_level, safety);
}
}

/// Creates a new source scope, nested in the current one.
pub(crate) fn new_source_scope(
&mut self,
Expand Down
3 changes: 3 additions & 0 deletions compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1382,6 +1382,9 @@ options! {
"list the symbols defined by a library crate (default: no)"),
macro_backtrace: bool = (false, parse_bool, [UNTRACKED],
"show macro backtraces (default: no)"),
maximal_hir_to_mir_coverage: bool = (false, parse_bool, [TRACKED],
"save as much information as possible about the correspondence between MIR and HIR \
as source scopes (default: no)"),
merge_functions: Option<MergeFunctions> = (None, parse_merge_functions, [TRACKED],
"control the operation of the MergeFunctions LLVM pass, taking \
the same values as the target option of the same name"),
Expand Down
1 change: 1 addition & 0 deletions src/test/rustdoc-ui/z-help.stdout
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@
-Z location-detail=val -- what location details should be tracked when using caller_location, either `none`, or a comma separated list of location details, for which valid options are `file`, `line`, and `column` (default: `file,line,column`)
-Z ls=val -- list the symbols defined by a library crate (default: no)
-Z macro-backtrace=val -- show macro backtraces (default: no)
-Z maximal-hir-to-mir-coverage=val -- save as much information as possible about the correspondence between MIR and HIR as source scopes (default: no)
-Z merge-functions=val -- control the operation of the MergeFunctions LLVM pass, taking the same values as the target option of the same name
-Z meta-stats=val -- gather metadata statistics (default: no)
-Z mir-emit-retag=val -- emit Retagging MIR statements, interpreted e.g., by miri; implies -Zmir-opt-level=0 (default: no)
Expand Down
10 changes: 10 additions & 0 deletions src/test/ui/maximal_mir_to_hir_coverage.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// compile-flags: -Zmaximal-hir-to-mir-coverage
// run-pass

// Just making sure this flag is accepted and doesn't crash the compiler

fn main() {
let x = 1;
let y = x + 1;
println!("{y}");
}

0 comments on commit c699b05

Please sign in to comment.