Skip to content

Commit fd884a0

Browse files
committed
Reduce cost of no-op dump_mir.
`dump_mir_for_pass` and `dump_mir_for_phase_change` do some allocations even when `-Zdump-mir` isn't used, and the cost is enough to be noticeable. This commit rearranges things to avoid the cost. - `dump_mir` now dumps MIR unconditionally. - The new `maybe_dump_mir` functions dumps MIR if `-Zdump-mir` is set appropriately. - `dump_enabled` is replaced with `pass_name_matches_dump_filters`, which just does the second part of the test. - Most places use `maybe_dump_mir`, but `dump_mir_for_pass` and `dump_mir_for_phase_change` do their own tests to avoid the allocations in the common cases where no MIR dumping occurs. This is not the most elegant code ever written, but hopefully it's good enough. I also tried using closures for `pass_num` and `pass_name` but that ended up being uglier than this approach.
1 parent 2585bce commit fd884a0

File tree

9 files changed

+83
-45
lines changed

9 files changed

+83
-45
lines changed

compiler/rustc_borrowck/src/nll.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,9 @@ use rustc_data_structures::vec_map::VecMap;
66
use rustc_hir::def_id::LocalDefId;
77
use rustc_index::vec::IndexVec;
88
use rustc_infer::infer::InferCtxt;
9-
use rustc_middle::mir::{create_dump_file, dump_enabled, dump_mir, PassWhere};
9+
use rustc_middle::mir::{
10+
create_dump_file, dump_mir, maybe_dump_mir, pass_name_matches_dump_filters, PassWhere,
11+
};
1012
use rustc_middle::mir::{
1113
BasicBlock, Body, ClosureOutlivesSubject, ClosureRegionRequirements, LocalKind, Location,
1214
Promoted,
@@ -73,7 +75,7 @@ pub(crate) fn replace_regions_in_mir<'tcx>(
7375
// Replace all remaining regions with fresh inference variables.
7476
renumber::renumber_mir(infcx, body, promoted);
7577

76-
dump_mir(infcx.tcx, None, "renumber", &0, body, |_, _| Ok(()));
78+
maybe_dump_mir(infcx.tcx, None, "renumber", &0, body, |_, _| Ok(()));
7779

7880
universal_regions
7981
}
@@ -327,11 +329,16 @@ pub(super) fn dump_mir_results<'tcx>(
327329
regioncx: &RegionInferenceContext<'tcx>,
328330
closure_region_requirements: &Option<ClosureRegionRequirements<'_>>,
329331
) {
330-
if !dump_enabled(infcx.tcx, "nll", body.source.def_id()) {
332+
let pass_name = "nll";
333+
if let Some(filters) = &infcx.tcx.sess.opts.unstable_opts.dump_mir
334+
&& pass_name_matches_dump_filters(infcx.tcx, filters, pass_name, body.source.def_id())
335+
{
336+
// continue
337+
} else {
331338
return;
332-
}
339+
};
333340

334-
dump_mir(infcx.tcx, None, "nll", &0, body, |pass_where, out| {
341+
dump_mir(infcx.tcx, None, pass_name, &0, body, |pass_where, out| {
335342
match pass_where {
336343
// Before the CFG, dump out the values for each region variable.
337344
PassWhere::BeforeCFG => {

compiler/rustc_middle/src/mir/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ pub mod visit;
7272
pub use self::generic_graph::graphviz_safe_def_name;
7373
pub use self::graphviz::write_mir_graphviz;
7474
pub use self::pretty::{
75-
create_dump_file, display_allocation, dump_enabled, dump_mir, write_mir_pretty, PassWhere,
75+
create_dump_file, display_allocation, dump_mir, maybe_dump_mir, pass_name_matches_dump_filters,
76+
write_mir_pretty, PassWhere,
7677
};
7778

7879
/// Types for locals

compiler/rustc_middle/src/mir/pretty.rs

+23-7
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ pub enum PassWhere {
7272
/// - `foo & nll | bar & typeck` == match if `foo` and `nll` both appear in the name
7373
/// or `typeck` and `bar` both appear in the name.
7474
#[inline]
75-
pub fn dump_mir<'tcx, F>(
75+
pub fn maybe_dump_mir<'tcx, F>(
7676
tcx: TyCtxt<'tcx>,
7777
pass_num: Option<&dyn Display>,
7878
pass_name: &str,
@@ -82,17 +82,33 @@ pub fn dump_mir<'tcx, F>(
8282
) where
8383
F: FnMut(PassWhere, &mut dyn Write) -> io::Result<()>,
8484
{
85-
if !dump_enabled(tcx, pass_name, body.source.def_id()) {
86-
return;
85+
if let Some(filters) = &tcx.sess.opts.unstable_opts.dump_mir {
86+
if pass_name_matches_dump_filters(tcx, filters, pass_name, body.source.def_id()) {
87+
dump_mir(tcx, pass_num, pass_name, disambiguator, body, extra_data);
88+
}
8789
}
90+
}
8891

92+
pub fn dump_mir<'tcx, F>(
93+
tcx: TyCtxt<'tcx>,
94+
pass_num: Option<&dyn Display>,
95+
pass_name: &str,
96+
disambiguator: &dyn Display,
97+
body: &Body<'tcx>,
98+
extra_data: F,
99+
) where
100+
F: FnMut(PassWhere, &mut dyn Write) -> io::Result<()>,
101+
{
102+
// njn: inline this
89103
dump_matched_mir_node(tcx, pass_num, pass_name, disambiguator, body, extra_data);
90104
}
91105

92-
pub fn dump_enabled<'tcx>(tcx: TyCtxt<'tcx>, pass_name: &str, def_id: DefId) -> bool {
93-
let Some(ref filters) = tcx.sess.opts.unstable_opts.dump_mir else {
94-
return false;
95-
};
106+
pub fn pass_name_matches_dump_filters<'tcx>(
107+
tcx: TyCtxt<'tcx>,
108+
filters: &str,
109+
pass_name: &str,
110+
def_id: DefId,
111+
) -> bool {
96112
// see notes on #41697 below
97113
let node_path = ty::print::with_forced_impl_filename_line!(tcx.def_path_str(def_id));
98114
filters.split('|').any(|or_filter| {

compiler/rustc_mir_dataflow/src/framework/engine.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use rustc_hir::def_id::DefId;
1515
use rustc_index::bit_set::BitSet;
1616
use rustc_index::vec::{Idx, IndexVec};
1717
use rustc_middle::mir::{self, traversal, BasicBlock};
18-
use rustc_middle::mir::{create_dump_file, dump_enabled};
18+
use rustc_middle::mir::{create_dump_file, pass_name_matches_dump_filters};
1919
use rustc_middle::ty::TyCtxt;
2020
use rustc_span::symbol::{sym, Symbol};
2121

@@ -292,7 +292,8 @@ where
292292
}
293293

294294
None if tcx.sess.opts.unstable_opts.dump_mir_dataflow
295-
&& dump_enabled(tcx, A::NAME, def_id) =>
295+
&& let Some(filters) = &tcx.sess.opts.unstable_opts.dump_mir
296+
&& pass_name_matches_dump_filters(tcx, filters, A::NAME, def_id) =>
296297
{
297298
create_dump_file(
298299
tcx,

compiler/rustc_mir_dataflow/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#![feature(associated_type_defaults)]
22
#![feature(box_patterns)]
33
#![feature(exact_size_is_empty)]
4+
#![feature(if_let_guard)]
5+
#![feature(let_chains)]
46
#![feature(min_specialization)]
57
#![feature(once_cell)]
68
#![feature(stmt_expr_attributes)]

compiler/rustc_mir_transform/src/coverage/mod.rs

+8-2
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use rustc_index::vec::IndexVec;
2020
use rustc_middle::hir;
2121
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
2222
use rustc_middle::mir::coverage::*;
23-
use rustc_middle::mir::dump_enabled;
23+
use rustc_middle::mir::pass_name_matches_dump_filters;
2424
use rustc_middle::mir::{
2525
self, BasicBlock, BasicBlockData, Coverage, SourceInfo, Statement, StatementKind, Terminator,
2626
TerminatorKind,
@@ -159,7 +159,13 @@ impl<'a, 'tcx> Instrumentor<'a, 'tcx> {
159159
let mut graphviz_data = debug::GraphvizData::new();
160160
let mut debug_used_expressions = debug::UsedExpressions::new();
161161

162-
let dump_mir = dump_enabled(tcx, self.pass_name, def_id);
162+
let dump_mir = if let Some(filters) = &tcx.sess.opts.unstable_opts.dump_mir
163+
&& pass_name_matches_dump_filters(tcx, filters, self.pass_name, def_id)
164+
{
165+
true
166+
} else {
167+
false
168+
};
163169
let dump_graphviz = dump_mir && tcx.sess.opts.unstable_opts.dump_mir_graphviz;
164170
let dump_spanview = dump_mir && tcx.sess.opts.unstable_opts.dump_mir_spanview.is_some();
165171

compiler/rustc_mir_transform/src/dest_prop.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ use std::collections::hash_map::{Entry, OccupiedEntry};
132132
use crate::MirPass;
133133
use rustc_data_structures::fx::FxHashMap;
134134
use rustc_index::bit_set::BitSet;
135-
use rustc_middle::mir::{dump_mir, PassWhere};
135+
use rustc_middle::mir::{maybe_dump_mir, PassWhere};
136136
use rustc_middle::mir::{
137137
traversal, BasicBlock, Body, InlineAsmOperand, Local, LocalKind, Location, Operand, Place,
138138
Rvalue, Statement, StatementKind, TerminatorKind,
@@ -787,7 +787,7 @@ fn dest_prop_mir_dump<'body, 'tcx>(
787787
round: usize,
788788
) {
789789
let mut reachable = None;
790-
dump_mir(tcx, None, "DestinationPropagation-dataflow", &round, body, |pass_where, w| {
790+
maybe_dump_mir(tcx, None, "DestinationPropagation-dataflow", &round, body, |pass_where, w| {
791791
let reachable = reachable.get_or_insert_with(|| traversal::reachable_as_bitset(body));
792792

793793
match pass_where {

compiler/rustc_mir_transform/src/generator.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ use rustc_hir::lang_items::LangItem;
6060
use rustc_hir::GeneratorKind;
6161
use rustc_index::bit_set::{BitMatrix, BitSet, GrowableBitSet};
6262
use rustc_index::vec::{Idx, IndexVec};
63-
use rustc_middle::mir::dump_mir;
63+
use rustc_middle::mir::maybe_dump_mir;
6464
use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor};
6565
use rustc_middle::mir::*;
6666
use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt};
@@ -1000,7 +1000,7 @@ fn create_generator_drop_shim<'tcx>(
10001000
// unrelated code from the resume part of the function
10011001
simplify::remove_dead_blocks(tcx, &mut body);
10021002

1003-
dump_mir(tcx, None, "generator_drop", &0, &body, |_, _| Ok(()));
1003+
maybe_dump_mir(tcx, None, "generator_drop", &0, &body, |_, _| Ok(()));
10041004

10051005
body
10061006
}
@@ -1171,7 +1171,7 @@ fn create_generator_resume_function<'tcx>(
11711171
// unrelated code from the drop part of the function
11721172
simplify::remove_dead_blocks(tcx, body);
11731173

1174-
dump_mir(tcx, None, "generator_resume", &0, body, |_, _| Ok(()));
1174+
maybe_dump_mir(tcx, None, "generator_resume", &0, body, |_, _| Ok(()));
11751175
}
11761176

11771177
fn insert_clean_drop(body: &mut Body<'_>) -> BasicBlock {
@@ -1394,14 +1394,14 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
13941394
// This is expanded to a drop ladder in `elaborate_generator_drops`.
13951395
let drop_clean = insert_clean_drop(body);
13961396

1397-
dump_mir(tcx, None, "generator_pre-elab", &0, body, |_, _| Ok(()));
1397+
maybe_dump_mir(tcx, None, "generator_pre-elab", &0, body, |_, _| Ok(()));
13981398

13991399
// Expand `drop(generator_struct)` to a drop ladder which destroys upvars.
14001400
// If any upvars are moved out of, drop elaboration will handle upvar destruction.
14011401
// However we need to also elaborate the code generated by `insert_clean_drop`.
14021402
elaborate_generator_drops(tcx, body);
14031403

1404-
dump_mir(tcx, None, "generator_post-transform", &0, body, |_, _| Ok(()));
1404+
maybe_dump_mir(tcx, None, "generator_post-transform", &0, body, |_, _| Ok(()));
14051405

14061406
// Create a copy of our MIR and use it to create the drop shim for the generator
14071407
let drop_shim = create_generator_drop_shim(tcx, &transform, gen_ty, body, drop_clean);

compiler/rustc_mir_transform/src/pass_manager.rs

+26-21
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::borrow::Cow;
22

3-
use rustc_middle::mir::{self, Body, MirPhase, RuntimePhase};
3+
use rustc_middle::mir::{self, pass_name_matches_dump_filters, Body, MirPhase, RuntimePhase};
44
use rustc_middle::ty::TyCtxt;
55
use rustc_session::Session;
66

@@ -166,27 +166,32 @@ pub fn dump_mir_for_pass<'tcx>(
166166
pass_name: &str,
167167
is_after: bool,
168168
) {
169-
let phase_index = body.phase.phase_index();
170-
171-
mir::dump_mir(
172-
tcx,
173-
Some(&format_args!("{:03}-{:03}", phase_index, body.pass_count)),
174-
pass_name,
175-
if is_after { &"after" } else { &"before" },
176-
body,
177-
|_, _| Ok(()),
178-
);
169+
if let Some(filters) = &tcx.sess.opts.unstable_opts.dump_mir {
170+
if pass_name_matches_dump_filters(tcx, filters, pass_name, body.source.def_id()) {
171+
mir::dump_mir(
172+
tcx,
173+
Some(&format_args!("{:03}-{:03}", body.phase.phase_index(), body.pass_count)),
174+
pass_name,
175+
if is_after { &"after" } else { &"before" },
176+
body,
177+
|_, _| Ok(()),
178+
);
179+
}
180+
}
179181
}
180182

181183
pub fn dump_mir_for_phase_change<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
182-
let phase_index = body.phase.phase_index();
183-
184-
mir::dump_mir(
185-
tcx,
186-
Some(&format_args!("{:03}-000", phase_index)),
187-
&format!("{}", body.phase),
188-
&"after",
189-
body,
190-
|_, _| Ok(()),
191-
)
184+
if let Some(filters) = &tcx.sess.opts.unstable_opts.dump_mir {
185+
let pass_name = &format!("{}", body.phase);
186+
if pass_name_matches_dump_filters(tcx, filters, pass_name, body.source.def_id()) {
187+
mir::dump_mir(
188+
tcx,
189+
Some(&format_args!("{:03}-000", body.phase.phase_index())),
190+
pass_name,
191+
&"after",
192+
body,
193+
|_, _| Ok(()),
194+
)
195+
}
196+
}
192197
}

0 commit comments

Comments
 (0)