Skip to content
Snippets Groups Projects
Commit 8290d912 authored by Russel Arbore's avatar Russel Arbore
Browse files

Create .dot graph

parent 4c57cb06
No related branches found
No related tags found
No related merge requests found
use crate::*;
use std::collections::HashMap;
pub fn write_dot<W: std::fmt::Write>(module: &Module, w: &mut W) -> std::fmt::Result {
write!(w, "digraph \"Module\" {{\n")?;
for i in 0..module.functions.len() {
let function = &module.functions[i];
write_function(i, function, &module.constants, w)?;
}
write!(w, "}}")?;
Ok(())
}
fn write_function<W: std::fmt::Write>(
i: usize,
function: &Function,
constants: &Vec<Constant>,
w: &mut W,
) -> std::fmt::Result {
let mut visited = HashMap::default();
for j in 0..function.nodes.len() {
visited = write_node(i, j, &function.nodes, constants, visited, w)?.1;
}
Ok(())
}
fn write_node<W: std::fmt::Write>(
i: usize,
j: usize,
nodes: &Vec<Node>,
constants: &Vec<Constant>,
mut visited: HashMap<NodeID, String>,
w: &mut W,
) -> Result<(String, HashMap<NodeID, String>), std::fmt::Error> {
let id = NodeID::new(j);
if visited.contains_key(&id) {
Ok((visited.get(&id).unwrap().clone(), visited))
} else {
let node = &nodes[j];
let name = format!("{}_{}_{}", get_string_node_kind(node), i, j);
visited.insert(NodeID::new(j), name.clone());
let visited = match node {
Node::Start => {
write!(w, "{} [label=\"start\"];\n", name)?;
visited
}
Node::Return { control, value } => {
let (control_name, visited) =
write_node(i, control.idx(), nodes, constants, visited, w)?;
let (value_name, visited) =
write_node(i, value.idx(), nodes, constants, visited, w)?;
write!(w, "{} [label=\"return\"];\n", name)?;
write!(w, "{} -> {};\n", control_name, name)?;
write!(w, "{} -> {};\n", value_name, name)?;
visited
}
Node::Parameter { index } => {
write!(w, "{} [label=\"param #{}\"];\n", name, index)?;
visited
}
Node::Constant { id } => {
write!(w, "{} [label=\"{:?}\"];\n", name, constants[id.idx()])?;
visited
}
Node::Add {
control,
left,
right,
} => {
let (control_name, visited) =
write_node(i, control.idx(), nodes, constants, visited, w)?;
let (left_name, visited) = write_node(i, left.idx(), nodes, constants, visited, w)?;
let (right_name, visited) =
write_node(i, right.idx(), nodes, constants, visited, w)?;
write!(w, "{} [label=\"add\"];\n", name)?;
write!(w, "{} -> {};\n", control_name, name)?;
write!(w, "{} -> {};\n", left_name, name)?;
write!(w, "{} -> {};\n", right_name, name)?;
visited
}
_ => todo!(),
};
Ok((visited.get(&id).unwrap().clone(), visited))
}
}
fn get_string_node_kind(node: &Node) -> &'static str {
match node {
Node::Start => "start",
Node::Region { preds: _ } => "region",
Node::If {
control: _,
cond: _,
} => "if",
Node::Fork {
control: _,
factor: _,
} => "fork",
Node::Join {
control: _,
factor: _,
} => "join",
Node::Phi {
control: _,
data: _,
} => "phi",
Node::Return {
control: _,
value: _,
} => "return",
Node::Parameter { index: _ } => "parameter",
Node::Constant { id: _ } => "constant",
Node::Add {
control: _,
left: _,
right: _,
} => "add",
Node::Sub {
control: _,
left: _,
right: _,
} => "sub",
Node::Mul {
control: _,
left: _,
right: _,
} => "mul",
Node::Div {
control: _,
left: _,
right: _,
} => "div",
Node::Call { args: _ } => "call",
}
}
......@@ -101,7 +101,7 @@ pub enum Node {
},
}
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct FunctionID(u32);
impl FunctionID {
......@@ -114,7 +114,7 @@ impl FunctionID {
}
}
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct NodeID(u32);
impl NodeID {
......@@ -127,7 +127,7 @@ impl NodeID {
}
}
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ConstantID(u32);
impl ConstantID {
......@@ -140,7 +140,7 @@ impl ConstantID {
}
}
#[derive(Debug, Clone, Copy)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct TypeID(u32);
impl TypeID {
......
pub mod dot;
pub mod ir;
pub mod parse;
pub use crate::dot::*;
pub use crate::ir::*;
pub use crate::parse::*;
......@@ -287,5 +287,8 @@ mod tests {
let module =
parse("fn add(x: i32, y: i32) -> i32 c = constant(i8, 5) r = return(start, w) w = add(start, z, c) z = add(start, x, y)");
println!("{:?}", module);
let mut dot = String::new();
write_dot(&module, &mut dot).unwrap();
println!("{}", dot);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment