Skip to content

Commit

Permalink
Refactor DOT graph printing of IR
Browse files Browse the repository at this point in the history
  • Loading branch information
hansihe committed Feb 25, 2020
1 parent f4995ca commit bb38750
Show file tree
Hide file tree
Showing 7 changed files with 353 additions and 43 deletions.
3 changes: 2 additions & 1 deletion libeir_ir/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ libeir_diagnostics = { path = "../libeir_diagnostics" }
libeir_util_datastructures = { path = "../util/libeir_util_datastructures" }
libeir_util_parse = { path = "../util/libeir_util_parse" }
libeir_util_number = { path = "../util/libeir_util_number" }
libeir_util_dot_graph = { path = "../util/libeir_util_dot_graph" }

string-intern = { version = "0.1.7", default-features = false }
pretty = "0.3.3"
pretty = "0.7"
lazy_static = "1.2.0"
itertools = "0.8.0"

Expand Down
8 changes: 8 additions & 0 deletions libeir_ir/src/function/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ use super::{ Block, Const, PrimOp, Location };
pub struct Value(u32);
entity_impl!(Value, "value");

use libeir_util_dot_graph::NodeId;
impl NodeId for Value {
fn make_id(&self, out: &mut String) {
use std::fmt::Write;
write!(out, "{}", self).unwrap();
}
}

#[derive(Debug, Clone)]
pub struct ValueData {
pub(crate) kind: ValueKind,
Expand Down
59 changes: 17 additions & 42 deletions libeir_ir/src/text/dot_printer.rs
Original file line number Diff line number Diff line change
@@ -1,67 +1,42 @@
use crate::Function;
use super::printer::{ ToEirTextFun, ToEirTextContext };

use petgraph::visit::{ Dfs, IntoNeighbors };

const DOT_BREAK: &str = "<br align=\"left\" />";
use libeir_util_dot_graph::GraphPrinter;

fn format_label(label: &str) -> String {
label
.replace("{", "\\{")
.replace("}", "\\}")
.replace("|", "\\|")
.replace(">", "&lt;")
.replace("<", "&gt;")
.replace("&", "&amp;")
.replace("\"", "&quot;")
.replace("\n", DOT_BREAK)
}

use std::io::Write;
use petgraph::visit::{ Dfs, IntoNeighbors };

#[allow(clippy::write_with_newline)]
pub fn function_to_dot(fun: &Function, w: &mut dyn Write) -> ::std::io::Result<()> {
pub fn function_into_graph_printer<O>(fun: &Function, g: &mut GraphPrinter<O>)
where
O: std::fmt::Write,
{
let mut to_eir_ctx = ToEirTextContext::new();

write!(w, "digraph g {{\n")?;
write!(w, "node [labeljust=\"l\", shape=record, fontname=\"Courier New\"]\n")?;
write!(w, "edge [fontname=\"Courier New\" ]\n\n")?;

let fun_name = format_label(&format!("{}", fun.ident()));
write!(w, "entry [ label=<entry|fun: {}> ];\n",
fun_name)?;
write!(w, "entry -> blk_{};\n\n", fun.block_entry())?;

let mut buf = Vec::new();

write!(w, "constants [ label=<")?;
super::printer::print_constants(&mut to_eir_ctx, fun, 0, &mut buf)?;
super::printer::print_constants(&mut to_eir_ctx, fun, 0, &mut buf).unwrap();
let text = std::str::from_utf8(&buf).unwrap();
let text = format_label(text);
write!(w, "{}", text)?;
write!(w, "> ];\n")?;
g.node("constants", text);

let block_graph = fun.block_graph();
let mut block_dfs = Dfs::new(&block_graph, fun.block_entry());

while let Some(block) = block_dfs.next(&block_graph) {
write!(w, "blk_{} [ label=<", block)?;
let block_val = fun.block_value(block);

buf.clear();
block.to_eir_text_fun(&mut to_eir_ctx, fun, 0, &mut buf).unwrap();
let text = std::str::from_utf8(&buf).unwrap();
let text = format_label(text);
write!(w, "{}", text)?;

write!(w, "> ];\n")?;
g.node(block_val, text);

for out in block_graph.neighbors(block) {
write!(w, "blk_{} -> blk_{};\n", block, out)?;
let out_val = fun.block_value(out);
g.edge(block_val, out_val, "");
}

write!(w, "\n")?;
}
}

write!(w, "}}\n")?;
Ok(())
pub fn function_to_dot(fun: &Function) -> String {
let mut g = GraphPrinter::new();
function_into_graph_printer(fun, &mut g);
g.finish().unwrap()
}
4 changes: 4 additions & 0 deletions tools/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,9 @@ libeir_diagnostics = { path = "../libeir_diagnostics" }
libeir_syntax_erl = { path = "../libeir_syntax_erl" }
libeir_passes = { path = "../libeir_passes" }
libeir_ir = { path = "../libeir_ir" }
libeir_util_parse = { path = "../util/libeir_util_parse" }
libeir_util_parse_listing = { path = "../util/libeir_util_parse_listing" }

clap = "2.33.0"
log = "0.4"
fern = "0.5"
9 changes: 9 additions & 0 deletions util/libeir_util_dot_graph/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "libeir_util_dot_graph"
version = "0.1.0"
authors = ["Hans Elias B. Josephsen <[email protected]>"]
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
Loading

0 comments on commit bb38750

Please sign in to comment.