rustc_middle/mir/
generic_graph.rs1use gsgdt::{Edge, Graph, Node, NodeStyle};
2
3use crate::mir::*;
4
5pub(crate) fn mir_fn_to_generic_graph<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'_>) -> Graph {
7 let def_id = body.source.def_id();
8 let def_name = graphviz_safe_def_name(def_id);
9 let graph_name = format!("Mir_{def_name}");
10 let dark_mode = tcx.sess.opts.unstable_opts.graphviz_dark_mode;
11
12 let nodes: Vec<Node> = body
14 .basic_blocks
15 .iter_enumerated()
16 .map(|(block, _)| bb_to_graph_node(block, body, dark_mode))
17 .collect();
18
19 let mut edges = Vec::new();
21 for (source, _) in body.basic_blocks.iter_enumerated() {
22 let def_id = body.source.def_id();
23 let terminator = body[source].terminator();
24 let labels = terminator.kind.fmt_successor_labels();
25
26 for (target, label) in terminator.successors().zip(labels) {
27 let src = node(def_id, source);
28 let trg = node(def_id, target);
29 edges.push(Edge::new(src, trg, label.to_string()));
30 }
31 }
32
33 Graph::new(graph_name, nodes, edges)
34}
35
36fn bb_to_graph_node(block: BasicBlock, body: &Body<'_>, dark_mode: bool) -> Node {
37 let def_id = body.source.def_id();
38 let data = &body[block];
39 let label = node(def_id, block);
40
41 let (title, bgcolor) = if data.is_cleanup {
42 let color = if dark_mode { "royalblue" } else { "lightblue" };
43 (format!("{} (cleanup)", block.index()), color)
44 } else {
45 let color = if dark_mode { "dimgray" } else { "gray" };
46 (format!("{}", block.index()), color)
47 };
48
49 let style = NodeStyle { title_bg: Some(bgcolor.to_owned()), ..Default::default() };
50 let mut stmts: Vec<String> = data.statements.iter().map(|x| format!("{x:?}")).collect();
51
52 let mut terminator_head = String::new();
54 data.terminator().kind.fmt_head(&mut terminator_head).unwrap();
55 stmts.push(terminator_head);
56
57 Node::new(stmts, label, title, style)
58}
59
60pub fn graphviz_safe_def_name(def_id: DefId) -> String {
63 format!("{}_{}", def_id.krate.index(), def_id.index.index(),)
64}
65
66fn node(def_id: DefId, block: BasicBlock) -> String {
67 format!("bb{}__{}", block.index(), graphviz_safe_def_name(def_id))
68}