mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-29 02:03:53 +00:00
introduce PrettyPrintMirOptions
for cosmetic MIR dump options
initially starting with `-Z mir-include-spans` because we want them in the NLL mir dump pass
This commit is contained in:
parent
0d634185df
commit
c646b46b52
@ -44,8 +44,9 @@ pub(crate) fn codegen_fn<'tcx>(
|
|||||||
let _mir_guard = crate::PrintOnPanic(|| {
|
let _mir_guard = crate::PrintOnPanic(|| {
|
||||||
let mut buf = Vec::new();
|
let mut buf = Vec::new();
|
||||||
with_no_trimmed_paths!({
|
with_no_trimmed_paths!({
|
||||||
rustc_middle::mir::pretty::write_mir_fn(tcx, mir, &mut |_, _| Ok(()), &mut buf)
|
use rustc_middle::mir::pretty;
|
||||||
.unwrap();
|
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()
|
String::from_utf8_lossy(&buf).into_owned()
|
||||||
});
|
});
|
||||||
|
@ -43,8 +43,23 @@ pub enum PassWhere {
|
|||||||
AfterTerminator(BasicBlock),
|
AfterTerminator(BasicBlock),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If the session is properly configured, dumps a human-readable
|
/// Cosmetic options for pretty-printing the MIR contents, gathered from the CLI. Each pass can
|
||||||
/// representation of the mir into:
|
/// override these when dumping its own specific MIR information with [`dump_mir_with_options`].
|
||||||
|
#[derive(Copy, Clone)]
|
||||||
|
pub struct PrettyPrintMirOptions {
|
||||||
|
/// Whether to include extra comments, like span info. From `-Z mir-include-spans`.
|
||||||
|
pub include_extra_comments: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PrettyPrintMirOptions {
|
||||||
|
/// Create the default set of MIR pretty-printing options from the CLI flags.
|
||||||
|
pub fn from_cli(tcx: TyCtxt<'_>) -> Self {
|
||||||
|
Self { include_extra_comments: tcx.sess.opts.unstable_opts.mir_include_spans }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If the session is properly configured, dumps a human-readable representation of the MIR (with
|
||||||
|
/// default pretty-printing options) into:
|
||||||
///
|
///
|
||||||
/// ```text
|
/// ```text
|
||||||
/// rustc.node<node_id>.<pass_num>.<pass_name>.<disambiguator>
|
/// rustc.node<node_id>.<pass_num>.<pass_name>.<disambiguator>
|
||||||
@ -77,12 +92,40 @@ pub fn dump_mir<'tcx, F>(
|
|||||||
extra_data: F,
|
extra_data: F,
|
||||||
) where
|
) where
|
||||||
F: FnMut(PassWhere, &mut dyn io::Write) -> io::Result<()>,
|
F: FnMut(PassWhere, &mut dyn io::Write) -> io::Result<()>,
|
||||||
|
{
|
||||||
|
dump_mir_with_options(
|
||||||
|
tcx,
|
||||||
|
pass_num,
|
||||||
|
pass_name,
|
||||||
|
disambiguator,
|
||||||
|
body,
|
||||||
|
extra_data,
|
||||||
|
PrettyPrintMirOptions::from_cli(tcx),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If the session is properly configured, dumps a human-readable representation of the MIR, with
|
||||||
|
/// the given [pretty-printing options][PrettyPrintMirOptions].
|
||||||
|
///
|
||||||
|
/// See [`dump_mir`] for more details.
|
||||||
|
///
|
||||||
|
#[inline]
|
||||||
|
pub fn dump_mir_with_options<'tcx, F>(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
pass_num: bool,
|
||||||
|
pass_name: &str,
|
||||||
|
disambiguator: &dyn Display,
|
||||||
|
body: &Body<'tcx>,
|
||||||
|
extra_data: F,
|
||||||
|
options: PrettyPrintMirOptions,
|
||||||
|
) where
|
||||||
|
F: FnMut(PassWhere, &mut dyn io::Write) -> io::Result<()>,
|
||||||
{
|
{
|
||||||
if !dump_enabled(tcx, pass_name, body.source.def_id()) {
|
if !dump_enabled(tcx, pass_name, body.source.def_id()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dump_matched_mir_node(tcx, pass_num, pass_name, disambiguator, body, extra_data);
|
dump_matched_mir_node(tcx, pass_num, pass_name, disambiguator, body, extra_data, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dump_enabled(tcx: TyCtxt<'_>, pass_name: &str, def_id: DefId) -> bool {
|
pub fn dump_enabled(tcx: TyCtxt<'_>, pass_name: &str, def_id: DefId) -> bool {
|
||||||
@ -112,6 +155,7 @@ fn dump_matched_mir_node<'tcx, F>(
|
|||||||
disambiguator: &dyn Display,
|
disambiguator: &dyn Display,
|
||||||
body: &Body<'tcx>,
|
body: &Body<'tcx>,
|
||||||
mut extra_data: F,
|
mut extra_data: F,
|
||||||
|
options: PrettyPrintMirOptions,
|
||||||
) where
|
) where
|
||||||
F: FnMut(PassWhere, &mut dyn io::Write) -> io::Result<()>,
|
F: FnMut(PassWhere, &mut dyn io::Write) -> io::Result<()>,
|
||||||
{
|
{
|
||||||
@ -133,7 +177,7 @@ fn dump_matched_mir_node<'tcx, F>(
|
|||||||
writeln!(file)?;
|
writeln!(file)?;
|
||||||
extra_data(PassWhere::BeforeCFG, &mut file)?;
|
extra_data(PassWhere::BeforeCFG, &mut file)?;
|
||||||
write_user_type_annotations(tcx, body, &mut file)?;
|
write_user_type_annotations(tcx, body, &mut file)?;
|
||||||
write_mir_fn(tcx, body, &mut extra_data, &mut file)?;
|
write_mir_fn(tcx, body, &mut extra_data, &mut file, options)?;
|
||||||
extra_data(PassWhere::AfterCFG, &mut file)?;
|
extra_data(PassWhere::AfterCFG, &mut file)?;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -243,12 +287,15 @@ pub fn create_dump_file<'tcx>(
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Whole MIR bodies
|
// Whole MIR bodies
|
||||||
|
|
||||||
/// Write out a human-readable textual representation for the given MIR.
|
/// Write out a human-readable textual representation for the given MIR, with the default
|
||||||
|
/// [PrettyPrintMirOptions].
|
||||||
pub fn write_mir_pretty<'tcx>(
|
pub fn write_mir_pretty<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
single: Option<DefId>,
|
single: Option<DefId>,
|
||||||
w: &mut dyn io::Write,
|
w: &mut dyn io::Write,
|
||||||
) -> io::Result<()> {
|
) -> io::Result<()> {
|
||||||
|
let options = PrettyPrintMirOptions::from_cli(tcx);
|
||||||
|
|
||||||
writeln!(w, "// WARNING: This output format is intended for human consumers only")?;
|
writeln!(w, "// WARNING: This output format is intended for human consumers only")?;
|
||||||
writeln!(w, "// and is subject to change without notice. Knock yourself out.")?;
|
writeln!(w, "// and is subject to change without notice. Knock yourself out.")?;
|
||||||
|
|
||||||
@ -262,11 +309,11 @@ pub fn write_mir_pretty<'tcx>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
let render_body = |w: &mut dyn io::Write, body| -> io::Result<()> {
|
let render_body = |w: &mut dyn io::Write, body| -> io::Result<()> {
|
||||||
write_mir_fn(tcx, body, &mut |_, _| Ok(()), w)?;
|
write_mir_fn(tcx, body, &mut |_, _| Ok(()), w, options)?;
|
||||||
|
|
||||||
for body in tcx.promoted_mir(def_id) {
|
for body in tcx.promoted_mir(def_id) {
|
||||||
writeln!(w)?;
|
writeln!(w)?;
|
||||||
write_mir_fn(tcx, body, &mut |_, _| Ok(()), w)?;
|
write_mir_fn(tcx, body, &mut |_, _| Ok(()), w, options)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
};
|
};
|
||||||
@ -278,7 +325,7 @@ pub fn write_mir_pretty<'tcx>(
|
|||||||
writeln!(w, "// MIR FOR CTFE")?;
|
writeln!(w, "// MIR FOR CTFE")?;
|
||||||
// Do not use `render_body`, as that would render the promoteds again, but these
|
// Do not use `render_body`, as that would render the promoteds again, but these
|
||||||
// are shared between mir_for_ctfe and optimized_mir
|
// are shared between mir_for_ctfe and optimized_mir
|
||||||
write_mir_fn(tcx, tcx.mir_for_ctfe(def_id), &mut |_, _| Ok(()), w)?;
|
write_mir_fn(tcx, tcx.mir_for_ctfe(def_id), &mut |_, _| Ok(()), w, options)?;
|
||||||
} else {
|
} else {
|
||||||
let instance_mir = tcx.instance_mir(ty::InstanceKind::Item(def_id));
|
let instance_mir = tcx.instance_mir(ty::InstanceKind::Item(def_id));
|
||||||
render_body(w, instance_mir)?;
|
render_body(w, instance_mir)?;
|
||||||
@ -293,14 +340,15 @@ pub fn write_mir_fn<'tcx, F>(
|
|||||||
body: &Body<'tcx>,
|
body: &Body<'tcx>,
|
||||||
extra_data: &mut F,
|
extra_data: &mut F,
|
||||||
w: &mut dyn io::Write,
|
w: &mut dyn io::Write,
|
||||||
|
options: PrettyPrintMirOptions,
|
||||||
) -> io::Result<()>
|
) -> io::Result<()>
|
||||||
where
|
where
|
||||||
F: FnMut(PassWhere, &mut dyn io::Write) -> io::Result<()>,
|
F: FnMut(PassWhere, &mut dyn io::Write) -> io::Result<()>,
|
||||||
{
|
{
|
||||||
write_mir_intro(tcx, body, w)?;
|
write_mir_intro(tcx, body, w, options)?;
|
||||||
for block in body.basic_blocks.indices() {
|
for block in body.basic_blocks.indices() {
|
||||||
extra_data(PassWhere::BeforeBlock(block), w)?;
|
extra_data(PassWhere::BeforeBlock(block), w)?;
|
||||||
write_basic_block(tcx, block, body, extra_data, w)?;
|
write_basic_block(tcx, block, body, extra_data, w, options)?;
|
||||||
if block.index() + 1 != body.basic_blocks.len() {
|
if block.index() + 1 != body.basic_blocks.len() {
|
||||||
writeln!(w)?;
|
writeln!(w)?;
|
||||||
}
|
}
|
||||||
@ -321,6 +369,7 @@ fn write_scope_tree(
|
|||||||
w: &mut dyn io::Write,
|
w: &mut dyn io::Write,
|
||||||
parent: SourceScope,
|
parent: SourceScope,
|
||||||
depth: usize,
|
depth: usize,
|
||||||
|
options: PrettyPrintMirOptions,
|
||||||
) -> io::Result<()> {
|
) -> io::Result<()> {
|
||||||
let indent = depth * INDENT.len();
|
let indent = depth * INDENT.len();
|
||||||
|
|
||||||
@ -333,7 +382,7 @@ fn write_scope_tree(
|
|||||||
|
|
||||||
let indented_debug_info = format!("{0:1$}debug {2:?};", INDENT, indent, var_debug_info);
|
let indented_debug_info = format!("{0:1$}debug {2:?};", INDENT, indent, var_debug_info);
|
||||||
|
|
||||||
if tcx.sess.opts.unstable_opts.mir_include_spans {
|
if options.include_extra_comments {
|
||||||
writeln!(
|
writeln!(
|
||||||
w,
|
w,
|
||||||
"{0:1$} // in {2}",
|
"{0:1$} // in {2}",
|
||||||
@ -373,7 +422,7 @@ fn write_scope_tree(
|
|||||||
|
|
||||||
let local_name = if local == RETURN_PLACE { " return place" } else { "" };
|
let local_name = if local == RETURN_PLACE { " return place" } else { "" };
|
||||||
|
|
||||||
if tcx.sess.opts.unstable_opts.mir_include_spans {
|
if options.include_extra_comments {
|
||||||
writeln!(
|
writeln!(
|
||||||
w,
|
w,
|
||||||
"{0:1$} //{2} in {3}",
|
"{0:1$} //{2} in {3}",
|
||||||
@ -410,7 +459,7 @@ fn write_scope_tree(
|
|||||||
|
|
||||||
let indented_header = format!("{0:1$}scope {2}{3} {{", "", indent, child.index(), special);
|
let indented_header = format!("{0:1$}scope {2}{3} {{", "", indent, child.index(), special);
|
||||||
|
|
||||||
if tcx.sess.opts.unstable_opts.mir_include_spans {
|
if options.include_extra_comments {
|
||||||
if let Some(span) = span {
|
if let Some(span) = span {
|
||||||
writeln!(
|
writeln!(
|
||||||
w,
|
w,
|
||||||
@ -426,7 +475,7 @@ fn write_scope_tree(
|
|||||||
writeln!(w, "{indented_header}")?;
|
writeln!(w, "{indented_header}")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
write_scope_tree(tcx, body, scope_tree, w, child, depth + 1)?;
|
write_scope_tree(tcx, body, scope_tree, w, child, depth + 1, options)?;
|
||||||
writeln!(w, "{0:1$}}}", "", depth * INDENT.len())?;
|
writeln!(w, "{0:1$}}}", "", depth * INDENT.len())?;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -449,10 +498,11 @@ impl Debug for VarDebugInfo<'_> {
|
|||||||
|
|
||||||
/// Write out a human-readable textual representation of the MIR's `fn` type and the types of its
|
/// Write out a human-readable textual representation of the MIR's `fn` type and the types of its
|
||||||
/// local variables (both user-defined bindings and compiler temporaries).
|
/// local variables (both user-defined bindings and compiler temporaries).
|
||||||
pub fn write_mir_intro<'tcx>(
|
fn write_mir_intro<'tcx>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
body: &Body<'_>,
|
body: &Body<'_>,
|
||||||
w: &mut dyn io::Write,
|
w: &mut dyn io::Write,
|
||||||
|
options: PrettyPrintMirOptions,
|
||||||
) -> io::Result<()> {
|
) -> io::Result<()> {
|
||||||
write_mir_sig(tcx, body, w)?;
|
write_mir_sig(tcx, body, w)?;
|
||||||
writeln!(w, "{{")?;
|
writeln!(w, "{{")?;
|
||||||
@ -468,7 +518,7 @@ pub fn write_mir_intro<'tcx>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
write_scope_tree(tcx, body, &scope_tree, w, OUTERMOST_SOURCE_SCOPE, 1)?;
|
write_scope_tree(tcx, body, &scope_tree, w, OUTERMOST_SOURCE_SCOPE, 1, options)?;
|
||||||
|
|
||||||
// Add an empty line before the first block is printed.
|
// Add an empty line before the first block is printed.
|
||||||
writeln!(w)?;
|
writeln!(w)?;
|
||||||
@ -651,12 +701,13 @@ pub fn dump_mir_def_ids(tcx: TyCtxt<'_>, single: Option<DefId>) -> Vec<DefId> {
|
|||||||
// Basic blocks and their parts (statements, terminators, ...)
|
// Basic blocks and their parts (statements, terminators, ...)
|
||||||
|
|
||||||
/// Write out a human-readable textual representation for the given basic block.
|
/// Write out a human-readable textual representation for the given basic block.
|
||||||
pub fn write_basic_block<'tcx, F>(
|
fn write_basic_block<'tcx, F>(
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
block: BasicBlock,
|
block: BasicBlock,
|
||||||
body: &Body<'tcx>,
|
body: &Body<'tcx>,
|
||||||
extra_data: &mut F,
|
extra_data: &mut F,
|
||||||
w: &mut dyn io::Write,
|
w: &mut dyn io::Write,
|
||||||
|
options: PrettyPrintMirOptions,
|
||||||
) -> io::Result<()>
|
) -> io::Result<()>
|
||||||
where
|
where
|
||||||
F: FnMut(PassWhere, &mut dyn io::Write) -> io::Result<()>,
|
F: FnMut(PassWhere, &mut dyn io::Write) -> io::Result<()>,
|
||||||
@ -672,7 +723,7 @@ where
|
|||||||
for statement in &data.statements {
|
for statement in &data.statements {
|
||||||
extra_data(PassWhere::BeforeLocation(current_location), w)?;
|
extra_data(PassWhere::BeforeLocation(current_location), w)?;
|
||||||
let indented_body = format!("{INDENT}{INDENT}{statement:?};");
|
let indented_body = format!("{INDENT}{INDENT}{statement:?};");
|
||||||
if tcx.sess.opts.unstable_opts.mir_include_spans {
|
if options.include_extra_comments {
|
||||||
writeln!(
|
writeln!(
|
||||||
w,
|
w,
|
||||||
"{:A$} // {}{}",
|
"{:A$} // {}{}",
|
||||||
@ -689,9 +740,14 @@ where
|
|||||||
writeln!(w, "{indented_body}")?;
|
writeln!(w, "{indented_body}")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
write_extra(tcx, w, |visitor| {
|
write_extra(
|
||||||
|
tcx,
|
||||||
|
w,
|
||||||
|
|visitor| {
|
||||||
visitor.visit_statement(statement, current_location);
|
visitor.visit_statement(statement, current_location);
|
||||||
})?;
|
},
|
||||||
|
options,
|
||||||
|
)?;
|
||||||
|
|
||||||
extra_data(PassWhere::AfterLocation(current_location), w)?;
|
extra_data(PassWhere::AfterLocation(current_location), w)?;
|
||||||
|
|
||||||
@ -701,7 +757,7 @@ where
|
|||||||
// Terminator at the bottom.
|
// Terminator at the bottom.
|
||||||
extra_data(PassWhere::BeforeLocation(current_location), w)?;
|
extra_data(PassWhere::BeforeLocation(current_location), w)?;
|
||||||
let indented_terminator = format!("{0}{0}{1:?};", INDENT, data.terminator().kind);
|
let indented_terminator = format!("{0}{0}{1:?};", INDENT, data.terminator().kind);
|
||||||
if tcx.sess.opts.unstable_opts.mir_include_spans {
|
if options.include_extra_comments {
|
||||||
writeln!(
|
writeln!(
|
||||||
w,
|
w,
|
||||||
"{:A$} // {}{}",
|
"{:A$} // {}{}",
|
||||||
@ -718,9 +774,14 @@ where
|
|||||||
writeln!(w, "{indented_terminator}")?;
|
writeln!(w, "{indented_terminator}")?;
|
||||||
}
|
}
|
||||||
|
|
||||||
write_extra(tcx, w, |visitor| {
|
write_extra(
|
||||||
|
tcx,
|
||||||
|
w,
|
||||||
|
|visitor| {
|
||||||
visitor.visit_terminator(data.terminator(), current_location);
|
visitor.visit_terminator(data.terminator(), current_location);
|
||||||
})?;
|
},
|
||||||
|
options,
|
||||||
|
)?;
|
||||||
|
|
||||||
extra_data(PassWhere::AfterLocation(current_location), w)?;
|
extra_data(PassWhere::AfterLocation(current_location), w)?;
|
||||||
extra_data(PassWhere::AfterTerminator(block), w)?;
|
extra_data(PassWhere::AfterTerminator(block), w)?;
|
||||||
@ -1271,11 +1332,12 @@ fn write_extra<'tcx, F>(
|
|||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
write: &mut dyn io::Write,
|
write: &mut dyn io::Write,
|
||||||
mut visit_op: F,
|
mut visit_op: F,
|
||||||
|
options: PrettyPrintMirOptions,
|
||||||
) -> io::Result<()>
|
) -> io::Result<()>
|
||||||
where
|
where
|
||||||
F: FnMut(&mut ExtraComments<'tcx>),
|
F: FnMut(&mut ExtraComments<'tcx>),
|
||||||
{
|
{
|
||||||
if tcx.sess.opts.unstable_opts.mir_include_spans {
|
if options.include_extra_comments {
|
||||||
let mut extra_comments = ExtraComments { tcx, comments: vec![] };
|
let mut extra_comments = ExtraComments { tcx, comments: vec![] };
|
||||||
visit_op(&mut extra_comments);
|
visit_op(&mut extra_comments);
|
||||||
for comment in extra_comments.comments {
|
for comment in extra_comments.comments {
|
||||||
@ -1890,7 +1952,7 @@ pub(crate) fn pretty_print_const_value<'tcx>(
|
|||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
// Miscellaneous
|
// Miscellaneous
|
||||||
|
|
||||||
/// Calc converted u64 decimal into hex and return it's length in chars
|
/// Calc converted u64 decimal into hex and return its length in chars.
|
||||||
///
|
///
|
||||||
/// ```ignore (cannot-test-private-function)
|
/// ```ignore (cannot-test-private-function)
|
||||||
/// assert_eq!(1, hex_number_length(0));
|
/// assert_eq!(1, hex_number_length(0));
|
||||||
|
Loading…
Reference in New Issue
Block a user