Skip to content

Commit

Permalink
Add -Zgraphviz_dark_mode
Browse files Browse the repository at this point in the history
Many developers use a dark theme with editors and IDEs, but this
typically doesn't extend to graphviz output.

When I bring up a MIR graphviz document, the white background is
strikingly bright. This new option changes the colors used for graphviz
output to work better in dark-themed UIs.
  • Loading branch information
richkadel committed Sep 9, 2020
1 parent 5099914 commit c19b237
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 11 deletions.
20 changes: 17 additions & 3 deletions compiler/rustc_graphviz/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -599,6 +599,7 @@ pub enum RenderOption {
NoNodeStyles,

Monospace,
DarkTheme,
}

/// Returns vec holding all the default render options.
Expand Down Expand Up @@ -630,10 +631,23 @@ where
writeln!(w, "digraph {} {{", g.graph_id().as_slice())?;

// Global graph properties
let mut graph_attrs = Vec::new();
let mut content_attrs = Vec::new();
if options.contains(&RenderOption::Monospace) {
writeln!(w, r#" graph[fontname="monospace"];"#)?;
writeln!(w, r#" node[fontname="monospace"];"#)?;
writeln!(w, r#" edge[fontname="monospace"];"#)?;
let font = r#"fontname="monospace""#;
graph_attrs.push(font);
content_attrs.push(font);
};
if options.contains(&RenderOption::DarkTheme) {
graph_attrs.push(r#"bgcolor="black""#);
content_attrs.push(r#"color="white""#);
content_attrs.push(r#"fontcolor="white""#);
}
if !(graph_attrs.is_empty() && content_attrs.is_empty()) {
writeln!(w, r#" graph[{}];"#, graph_attrs.join(" "))?;
let content_attrs_str = content_attrs.join(" ");
writeln!(w, r#" node[{}];"#, content_attrs_str)?;
writeln!(w, r#" edge[{}];"#, content_attrs_str)?;
}

for n in g.nodes().iter() {
Expand Down
6 changes: 5 additions & 1 deletion compiler/rustc_mir/src/dataflow/framework/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,7 +306,11 @@ where
let mut buf = Vec::new();

let graphviz = graphviz::Formatter::new(body, def_id, results, style);
dot::render_opts(&graphviz, &mut buf, &[dot::RenderOption::Monospace])?;
let mut render_opts = vec![dot::RenderOption::Monospace];
if tcx.sess.opts.debugging_opts.graphviz_dark_mode {
render_opts.push(dot::RenderOption::DarkTheme);
}
dot::render_opts(&graphviz, &mut buf, &render_opts)?;

if let Some(parent) = path.parent() {
fs::create_dir_all(parent)?;
Expand Down
29 changes: 22 additions & 7 deletions compiler/rustc_mir/src/util/graphviz.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,28 @@ where
writeln!(w, "{} {}Mir_{} {{", kind, cluster, def_name)?;

// Global graph properties
writeln!(w, r#" graph [fontname="monospace"];"#)?;
writeln!(w, r#" node [fontname="monospace"];"#)?;
writeln!(w, r#" edge [fontname="monospace"];"#)?;
let font = r#"fontname="monospace""#;
let mut graph_attrs = vec![font];
let mut content_attrs = vec![font];

let dark_mode = tcx.sess.opts.debugging_opts.graphviz_dark_mode;
if dark_mode {
graph_attrs.push(r#"bgcolor="black""#);
content_attrs.push(r#"color="white""#);
content_attrs.push(r#"fontcolor="white""#);
}

writeln!(w, r#" graph [{}];"#, graph_attrs.join(" "))?;
let content_attrs_str = content_attrs.join(" ");
writeln!(w, r#" node [{}];"#, content_attrs_str)?;
writeln!(w, r#" edge [{}];"#, content_attrs_str)?;

// Graph label
write_graph_label(tcx, def_id, body, w)?;

// Nodes
for (block, _) in body.basic_blocks().iter_enumerated() {
write_node(def_id, block, body, w)?;
write_node(def_id, block, body, dark_mode, w)?;
}

// Edges
Expand All @@ -84,6 +96,7 @@ where
pub fn write_node_label<W: Write, INIT, FINI>(
block: BasicBlock,
body: &Body<'_>,
dark_mode: bool,
w: &mut W,
num_cols: u32,
init: INIT,
Expand All @@ -100,8 +113,9 @@ where
// Basic block number at the top.
write!(
w,
r#"<tr><td {attrs} colspan="{colspan}">{blk}</td></tr>"#,
attrs = r#"bgcolor="gray" align="center""#,
r#"<tr><td bgcolor="{bgcolor}" {attrs} colspan="{colspan}">{blk}</td></tr>"#,
bgcolor = if dark_mode { "dimgray" } else { "gray" },
attrs = r#"align="center""#,
colspan = num_cols,
blk = block.index()
)?;
Expand Down Expand Up @@ -134,11 +148,12 @@ fn write_node<W: Write>(
def_id: DefId,
block: BasicBlock,
body: &Body<'_>,
dark_mode: bool,
w: &mut W,
) -> io::Result<()> {
// Start a new node with the label to follow, in one of DOT's pseudo-HTML tables.
write!(w, r#" {} [shape="none", label=<"#, node(def_id, block))?;
write_node_label(block, body, w, 1, |_| Ok(()), |_| Ok(()))?;
write_node_label(block, body, dark_mode, w, 1, |_| Ok(()), |_| Ok(()))?;
// Close the node label and the node itself.
writeln!(w, ">];")
}
Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_session/src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -907,6 +907,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
"force all crates to be `rustc_private` unstable (default: no)"),
fuel: Option<(String, u64)> = (None, parse_optimization_fuel, [TRACKED],
"set the optimization fuel quota for a crate"),
graphviz_dark_mode: bool = (false, parse_bool, [UNTRACKED],
"use dark-themed colors in graphviz output (default: no)"),
hir_stats: bool = (false, parse_bool, [UNTRACKED],
"print some statistics about AST and HIR (default: no)"),
human_readable_cgu_names: bool = (false, parse_bool, [TRACKED],
Expand Down

0 comments on commit c19b237

Please sign in to comment.