From bedde023076a19eb081639732af7b21d234dc396 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 21 Nov 2012 13:43:03 +0900 Subject: [PATCH] Make flow graphs with dags easier to read. The node contents are now the dag rather than the dag being attached to the node. --- tools/qfcc/include/dags.h | 2 +- tools/qfcc/source/dot_dag.c | 15 +++++-- tools/qfcc/source/dot_flow.c | 80 +++++++++++++++++++++++++----------- 3 files changed, 69 insertions(+), 28 deletions(-) diff --git a/tools/qfcc/include/dags.h b/tools/qfcc/include/dags.h index 7cefa98ec..6dc3f5f1c 100644 --- a/tools/qfcc/include/dags.h +++ b/tools/qfcc/include/dags.h @@ -92,7 +92,7 @@ typedef struct dag_s { } dag_t; const char *daglabel_string (daglabel_t *label); -void print_dag (struct dstring_s *dstr, dag_t *dag); +void print_dag (struct dstring_s *dstr, dag_t *dag, const char *label); /** Make a dag for a single basic block. diff --git a/tools/qfcc/source/dot_dag.c b/tools/qfcc/source/dot_dag.c index 224e82a84..21f15050e 100644 --- a/tools/qfcc/source/dot_dag.c +++ b/tools/qfcc/source/dot_dag.c @@ -68,8 +68,8 @@ print_root_nodes (dstring_t *dstr, dag_t *dag) node_iter = set_next (node_iter)) { dagnode_t *node = dag->nodes[node_iter->member]; print_node_def (dstr, node); - dasprintf (dstr, " dag_%p ->dagnode_%p [style=invis];\n", dag, - node); + dasprintf (dstr, " dag_enter_%p ->dagnode_%p [style=invis];\n", + dag, node); } dasprintf (dstr, " }\n"); } @@ -130,17 +130,24 @@ print_node (dstring_t *dstr, dag_t *dag, dagnode_t *node) dasprintf (dstr, " \n"); dasprintf (dstr, " >];\n"); } + if (set_is_empty (node->edges)) + dasprintf (dstr, + " \"dagnode_%p\" -> \"dag_leave_%p\" [style=invis];\n", + node, dag); } void -print_dag (dstring_t *dstr, dag_t *dag) +print_dag (dstring_t *dstr, dag_t *dag, const char *label) { int i; dasprintf (dstr, " subgraph cluster_dag_%p {\n", dag); - dasprintf (dstr, " dag_%p [label=\"\", style=invis];\n", dag); + if (label) + dasprintf (dstr, " label=\"%s\";\n", label); + dasprintf (dstr, " dag_enter_%p [label=\"\", style=invis];\n", dag); print_root_nodes (dstr, dag); print_child_nodes (dstr, dag); for (i = 0; i < dag->num_nodes; i++) print_node (dstr, dag, dag->nodes[i]); + dasprintf (dstr, " dag_leave_%p [label=\"\", style=invis];\n", dag); dasprintf (dstr, " }\n"); } diff --git a/tools/qfcc/source/dot_flow.c b/tools/qfcc/source/dot_flow.c index 6f61bdf49..3a7e8309c 100644 --- a/tools/qfcc/source/dot_flow.c +++ b/tools/qfcc/source/dot_flow.c @@ -67,8 +67,12 @@ print_flow_node (dstring_t *dstr, flowgraph_t *graph, flownode_t *node, //dasprintf (dstr, "%*s rank=same;\n", indent, ""); indent += 2; } - dasprintf (dstr, "%*s\"fn_%p\" [label=\"%d (%d)\"];\n", indent, "", node, - node->id, node->dfn); + if (node->dag) { + print_dag (dstr, node->dag, va ("%d (%d)", node->id, node->dfn)); + } else { + dasprintf (dstr, "%*s\"fn_%p\" [label=\"%d (%d)\"];\n", indent, "", + node, node->id, node->dfn); + } if (live) { dasprintf (dstr, "%*slv_%p [shape=none,label=<\n", indent, "", node); dasprintf (dstr, "%*snumber, html_string(operand_string (var->op))); } dasprintf (dstr, "%*s
>];\n", indent + 2, ""); - dasprintf (dstr, "%*sfn_%p -> lv_%p " - //"[constraint=false,style=dashed,weight=10];\n", - "[style=dashed,weight=10];\n", - indent, "", node, node); + if (node->dag) { + dasprintf (dstr, "%*sdag_enter_%p -> lv_%p " + //"[constraint=false,style=dashed,weight=10];\n", + "[style=dashed,weight=10,ltail=cluster_dag_%p];\n", + indent, "", node->dag, node, node->dag); + } else { + dasprintf (dstr, "%*sfn_%p -> lv_%p " + //"[constraint=false,style=dashed,weight=10];\n", + "[style=dashed,weight=10];\n", + indent, "", node, node); + } indent -= 2; dasprintf (dstr, "%*s}\n", indent, ""); } - if (node->dag) { - dasprintf (dstr, " fn_%p -> dag_%p [lhead=cluster_dag_%p];\n", node, - node->dag, node->dag); - print_dag (dstr, node->dag); - } } static void @@ -102,28 +108,56 @@ print_flow_edges (dstring_t *dstr, flowgraph_t *graph, int level) int i; flowedge_t *edge; flownode_t *t, *h; + const char *tpref; + const char *hpref; const char *style; + const char *dir; int weight; for (i = 0; i < graph->num_edges; i++) { edge = &graph->edges[i]; t = graph->nodes[edge->tail]; h = graph->nodes[edge->head]; - if (t->dfn < h->dfn) { + if (t->dfn >= h->dfn) { + flownode_t *temp; + temp = h; + h = t; + t = temp; + + tpref = "enter"; + hpref = "leave"; + dir = "dir=back,"; + style = "dashed"; + weight = 0; + } else if (set_is_member (graph->dfst, i)) { + tpref = "leave"; + hpref = "enter"; + dir = ""; + style = "bold"; + weight = 10; + } else { + tpref = "leave"; + hpref = "enter"; + dir = ""; style = "solid"; weight = 0; - if (set_is_member (graph->dfst, i)) { - style = "bold"; - weight = 10; - } - dasprintf (dstr, - "%*s\"fn_%p\" -> \"fn_%p\" [style=%s,weight=%d];\n", - indent, "", t, h, style, weight); - } else { - dasprintf (dstr, - "%*s\"fn_%p\" -> \"fn_%p\" [dir=back, style=dashed];\n", - indent, "", h, t); } + dasprintf (dstr, "%*s", indent, ""); + if (t->dag) + dasprintf (dstr, "dag_%s_%p -> ", tpref, t->dag); + else + dasprintf (dstr, "fn_%p -> ", t); + if (h->dag) + dasprintf (dstr, "dag_%s_%p [%sstyle=%s,weight=%d", + hpref, h->dag, dir, style, weight); + else + dasprintf (dstr, "fn_%p [%sstyle=%s,weight=%d", + h, dir, style, weight); + if (t->dag) + dasprintf (dstr, ",ltail=cluster_dag_%p", t->dag); + if (h->dag) + dasprintf (dstr, ",lhead=cluster_dag_%p", h->dag); + dasprintf (dstr, "];\n"); } }