Generate MIR pass names for profiling on the fly and pass the body DefId as argument
This commit is contained in:
parent
f742d88326
commit
9624c30965
2 changed files with 47 additions and 4 deletions
|
@ -25,6 +25,7 @@ use rustc_target::abi::{FieldIdx, Size, VariantIdx};
|
||||||
|
|
||||||
use polonius_engine::Atom;
|
use polonius_engine::Atom;
|
||||||
pub use rustc_ast::Mutability;
|
pub use rustc_ast::Mutability;
|
||||||
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_data_structures::fx::FxHashSet;
|
use rustc_data_structures::fx::FxHashSet;
|
||||||
use rustc_data_structures::graph::dominators::Dominators;
|
use rustc_data_structures::graph::dominators::Dominators;
|
||||||
use rustc_index::{Idx, IndexSlice, IndexVec};
|
use rustc_index::{Idx, IndexSlice, IndexVec};
|
||||||
|
@ -35,6 +36,8 @@ use rustc_span::{Span, DUMMY_SP};
|
||||||
use either::Either;
|
use either::Either;
|
||||||
|
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
use std::cell::RefCell;
|
||||||
|
use std::collections::hash_map::Entry;
|
||||||
use std::fmt::{self, Debug, Display, Formatter, Write};
|
use std::fmt::{self, Debug, Display, Formatter, Write};
|
||||||
use std::ops::{Index, IndexMut};
|
use std::ops::{Index, IndexMut};
|
||||||
use std::{iter, mem};
|
use std::{iter, mem};
|
||||||
|
@ -97,6 +100,36 @@ impl<'tcx> HasLocalDecls<'tcx> for Body<'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
thread_local! {
|
||||||
|
static PASS_NAMES: RefCell<FxHashMap<&'static str, &'static str>> = {
|
||||||
|
RefCell::new(FxHashMap::default())
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Converts a MIR pass name into a snake case form to match the profiling naming style.
|
||||||
|
fn to_profiler_name(type_name: &'static str) -> &'static str {
|
||||||
|
PASS_NAMES.with(|names| match names.borrow_mut().entry(type_name) {
|
||||||
|
Entry::Occupied(e) => *e.get(),
|
||||||
|
Entry::Vacant(e) => {
|
||||||
|
let snake_case: String = type_name
|
||||||
|
.chars()
|
||||||
|
.flat_map(|c| {
|
||||||
|
if c.is_ascii_uppercase() {
|
||||||
|
vec!['_', c.to_ascii_lowercase()]
|
||||||
|
} else if c == '-' {
|
||||||
|
vec!['_']
|
||||||
|
} else {
|
||||||
|
vec![c]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
let result = &*String::leak(format!("mir_pass{}", snake_case));
|
||||||
|
e.insert(result);
|
||||||
|
result
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// A streamlined trait that you can implement to create a pass; the
|
/// A streamlined trait that you can implement to create a pass; the
|
||||||
/// pass will be named after the type, and it will consist of a main
|
/// pass will be named after the type, and it will consist of a main
|
||||||
/// loop that goes over each available MIR and applies `run_pass`.
|
/// loop that goes over each available MIR and applies `run_pass`.
|
||||||
|
@ -106,6 +139,10 @@ pub trait MirPass<'tcx> {
|
||||||
if let Some((_, tail)) = name.rsplit_once(':') { tail } else { name }
|
if let Some((_, tail)) = name.rsplit_once(':') { tail } else { name }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn profiler_name(&self) -> &'static str {
|
||||||
|
to_profiler_name(self.name())
|
||||||
|
}
|
||||||
|
|
||||||
/// Returns `true` if this pass is enabled with the current combination of compiler flags.
|
/// Returns `true` if this pass is enabled with the current combination of compiler flags.
|
||||||
fn is_enabled(&self, _sess: &Session) -> bool {
|
fn is_enabled(&self, _sess: &Session) -> bool {
|
||||||
true
|
true
|
||||||
|
|
|
@ -94,6 +94,8 @@ fn run_passes_inner<'tcx>(
|
||||||
let overridden_passes = &tcx.sess.opts.unstable_opts.mir_enable_passes;
|
let overridden_passes = &tcx.sess.opts.unstable_opts.mir_enable_passes;
|
||||||
trace!(?overridden_passes);
|
trace!(?overridden_passes);
|
||||||
|
|
||||||
|
let prof_arg = tcx.sess.prof.enabled().then(|| format!("{:?}", body.source.def_id()));
|
||||||
|
|
||||||
if !body.should_skip() {
|
if !body.should_skip() {
|
||||||
for pass in passes {
|
for pass in passes {
|
||||||
let name = pass.name();
|
let name = pass.name();
|
||||||
|
@ -121,10 +123,14 @@ fn run_passes_inner<'tcx>(
|
||||||
validate_body(tcx, body, format!("before pass {name}"));
|
validate_body(tcx, body, format!("before pass {name}"));
|
||||||
}
|
}
|
||||||
|
|
||||||
tcx.sess
|
if let Some(prof_arg) = &prof_arg {
|
||||||
.prof
|
tcx.sess
|
||||||
.generic_activity_with_arg("mir_pass", name)
|
.prof
|
||||||
.run(|| pass.run_pass(tcx, body));
|
.generic_activity_with_arg(pass.profiler_name(), &**prof_arg)
|
||||||
|
.run(|| pass.run_pass(tcx, body));
|
||||||
|
} else {
|
||||||
|
pass.run_pass(tcx, body);
|
||||||
|
}
|
||||||
|
|
||||||
if dump_enabled {
|
if dump_enabled {
|
||||||
dump_mir_for_pass(tcx, body, &name, true);
|
dump_mir_for_pass(tcx, body, &name, true);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue