]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_middle/src/mir/generic_graph.rs
bump version to 1.81.0+dfsg1-2~bpo12+pve1
[rustc.git] / compiler / rustc_middle / src / mir / generic_graph.rs
CommitLineData
fc512014 1use gsgdt::{Edge, Graph, Node, NodeStyle};
fc512014 2use rustc_middle::mir::*;
fc512014
XL
3
4/// Convert an MIR function into a gsgdt Graph
5pub fn mir_fn_to_generic_graph<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'_>) -> Graph {
6 let def_id = body.source.def_id();
7 let def_name = graphviz_safe_def_name(def_id);
add651ee 8 let graph_name = format!("Mir_{def_name}");
064997fb 9 let dark_mode = tcx.sess.opts.unstable_opts.graphviz_dark_mode;
fc512014
XL
10
11 // Nodes
12 let nodes: Vec<Node> = body
f2b60f7d 13 .basic_blocks
fc512014
XL
14 .iter_enumerated()
15 .map(|(block, _)| bb_to_graph_node(block, body, dark_mode))
16 .collect();
17
18 // Edges
19 let mut edges = Vec::new();
f2b60f7d 20 for (source, _) in body.basic_blocks.iter_enumerated() {
fc512014
XL
21 let def_id = body.source.def_id();
22 let terminator = body[source].terminator();
23 let labels = terminator.kind.fmt_successor_labels();
24
923072b8 25 for (target, label) in terminator.successors().zip(labels) {
fc512014
XL
26 let src = node(def_id, source);
27 let trg = node(def_id, target);
28 edges.push(Edge::new(src, trg, label.to_string()));
29 }
30 }
31
32 Graph::new(graph_name, nodes, edges)
33}
34
35fn bb_to_graph_node(block: BasicBlock, body: &Body<'_>, dark_mode: bool) -> Node {
36 let def_id = body.source.def_id();
37 let data = &body[block];
38 let label = node(def_id, block);
39
40 let (title, bgcolor) = if data.is_cleanup {
41 let color = if dark_mode { "royalblue" } else { "lightblue" };
42 (format!("{} (cleanup)", block.index()), color)
43 } else {
44 let color = if dark_mode { "dimgray" } else { "gray" };
45 (format!("{}", block.index()), color)
46 };
47
48 let style = NodeStyle { title_bg: Some(bgcolor.to_owned()), ..Default::default() };
add651ee 49 let mut stmts: Vec<String> = data.statements.iter().map(|x| format!("{x:?}")).collect();
fc512014 50
5e7ed085 51 // add the terminator to the stmts, gsgdt can print it out separately
fc512014
XL
52 let mut terminator_head = String::new();
53 data.terminator().kind.fmt_head(&mut terminator_head).unwrap();
54 stmts.push(terminator_head);
55
56 Node::new(stmts, label, title, style)
57}
58
59// Must match `[0-9A-Za-z_]*`. This does not appear in the rendered graph, so
60// it does not have to be user friendly.
61pub fn graphviz_safe_def_name(def_id: DefId) -> String {
62 format!("{}_{}", def_id.krate.index(), def_id.index.index(),)
63}
64
65fn node(def_id: DefId, block: BasicBlock) -> String {
66 format!("bb{}__{}", block.index(), graphviz_safe_def_name(def_id))
67}