Skip to content

Commit

Permalink
Some simple improvements to MIR pretty printing
Browse files Browse the repository at this point in the history
In short, this PR changes the MIR printer so that it:

* places an empty line between the MIR for each item
* does *not* write an empty line before the first BB when there are no
  var decls
* aligns the "// Scope" comments 50 chars in (makes the output more
  readable)
* prints the scope comments as "// scope N at ..." instead of "//
  Scope(N) at ..."
* prints a prettier scope tree:
 * no more unbalanced delimiters!
 * no more "Parent" entry (these convey no useful information)
 * drop the "Scope()" and just print scope IDs
 * no braces when the scope is empty
  • Loading branch information
jonas-schievink committed May 12, 2016
1 parent e88defe commit 96b178b
Showing 1 changed file with 55 additions and 22 deletions.
77 changes: 55 additions & 22 deletions src/librustc_mir/pretty.rs
Expand Up @@ -21,6 +21,8 @@ use syntax::ast::NodeId;
use syntax::codemap::Span;

const INDENT: &'static str = " ";
/// Alignment for lining up comments following MIR statements
const ALIGN: usize = 50;

/// If the session is properly configured, dumps a human-readable
/// representation of the mir into:
Expand Down Expand Up @@ -79,11 +81,20 @@ pub fn write_mir_pretty<'a, 'b, 'tcx, I>(tcx: TyCtxt<'b, 'tcx, 'tcx>,
-> io::Result<()>
where I: Iterator<Item=(&'a NodeId, &'a Mir<'tcx>)>, 'tcx: 'a
{
let mut first = true;
for (&id, mir) in iter {
if first {
first = false;
} else {
// Put empty lines between all items
writeln!(w, "")?;
}

let src = MirSource::from_node(tcx, id);
write_mir_fn(tcx, src, mir, w, None)?;

for (i, mir) in mir.promoted.iter().enumerate() {
writeln!(w, "")?;
write_mir_fn(tcx, MirSource::Promoted(id, i), mir, w, None)?;
}
}
Expand Down Expand Up @@ -131,6 +142,8 @@ pub fn write_mir_fn<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
.or_insert(vec![])
.push(ScopeId::new(index));
}

writeln!(w, "{}scope tree:", INDENT)?;
write_scope_tree(tcx, mir, auxiliary, &scope_tree, w, None, 1)?;

writeln!(w, "}}")?;
Expand All @@ -147,7 +160,7 @@ fn write_basic_block(tcx: TyCtxt,
let data = mir.basic_block_data(block);

// Basic block label at the top.
writeln!(w, "\n{}{:?}: {{", INDENT, block)?;
writeln!(w, "{}{:?}: {{", INDENT, block)?;

// List of statements in the middle.
let mut current_location = Location { block: block, statement_index: 0 };
Expand All @@ -165,25 +178,27 @@ fn write_basic_block(tcx: TyCtxt,
}
}

writeln!(w, "{0}{0}{1:?}; // {2}",
INDENT,
statement,
let indented_mir = format!("{0}{0}{1:?};", INDENT, statement);
writeln!(w, "{0:1$} // {2}",
indented_mir,
ALIGN,
comment(tcx, statement.scope, statement.span))?;

current_location.statement_index += 1;
}

// Terminator at the bottom.
writeln!(w, "{0}{0}{1:?}; // {2}",
INDENT,
data.terminator().kind,
let indented_terminator = format!("{0}{0}{1:?};", INDENT, data.terminator().kind);
writeln!(w, "{0:1$} // {2}",
indented_terminator,
ALIGN,
comment(tcx, data.terminator().scope, data.terminator().span))?;

writeln!(w, "{}}}", INDENT)
writeln!(w, "{}}}\n", INDENT)
}

fn comment(tcx: TyCtxt, scope: ScopeId, span: Span) -> String {
format!("Scope({}) at {}", scope.index(), tcx.sess.codemap().span_to_string(span))
format!("scope {} at {}", scope.index(), tcx.sess.codemap().span_to_string(span))
}

fn write_scope_tree(tcx: TyCtxt,
Expand All @@ -198,22 +213,28 @@ fn write_scope_tree(tcx: TyCtxt,
let indent = depth * INDENT.len();
let data = &mir.scopes[child];
assert_eq!(data.parent_scope, parent);
writeln!(w, "{0:1$}Scope({2}) {{", "", indent, child.index())?;
write!(w, "{0:1$}{2}", "", indent, child.index())?;

let indent = indent + INDENT.len();
if let Some(parent) = parent {
writeln!(w, "{0:1$}Parent: Scope({2})", "", indent, parent.index())?;
}

if let Some(auxiliary) = auxiliary {
let extent = auxiliary[child].extent;
let data = tcx.region_maps.code_extent_data(extent);
writeln!(w, "{0:1$}Extent: {2:?}", "", indent, data)?;
}

write_scope_tree(tcx, mir, auxiliary, scope_tree, w,
Some(child), depth + 1)?;
if scope_tree.get(&Some(child)).map(Vec::is_empty).unwrap_or(true) {
// No child scopes, skip the braces
writeln!(w, "")?;
} else {
writeln!(w, " {{")?;
write_scope_tree(tcx, mir, auxiliary, scope_tree, w,
Some(child), depth + 1)?;

writeln!(w, "{0:1$}}}", "", indent - INDENT.len())?;
}
}

Ok(())
}

Expand Down Expand Up @@ -261,13 +282,20 @@ fn write_mir_intro<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,

// User variable types (including the user's name in a comment).
for (i, var) in mir.var_decls.iter().enumerate() {
write!(w, "{}let ", INDENT)?;
if var.mutability == Mutability::Mut {
write!(w, "mut ")?;
}
writeln!(w, "{:?}: {}; // {} in {}",
Lvalue::Var(i as u32),
var.ty,
let mut_str = if var.mutability == Mutability::Mut {
"mut "
} else {
""
};

let indented_var = format!("{}let {}{:?}: {};",
INDENT,
mut_str,
Lvalue::Var(i as u32),
var.ty);
writeln!(w, "{0:1$} // \"{2}\" in {3}",
indented_var,
ALIGN,
var.name,
comment(tcx, var.scope, var.span))?;
}
Expand All @@ -277,5 +305,10 @@ fn write_mir_intro<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
writeln!(w, "{}let mut {:?}: {};", INDENT, Lvalue::Temp(i as u32), temp.ty)?;
}

// Wrote any declaration? Add an empty line before the first block is printed.
if !mir.var_decls.is_empty() || !mir.temp_decls.is_empty() {
writeln!(w, "")?;
}

Ok(())
}

0 comments on commit 96b178b

Please sign in to comment.