diff --git a/tools/qfcc/include/flow.h b/tools/qfcc/include/flow.h index b021549c4..17cc0fc1b 100644 --- a/tools/qfcc/include/flow.h +++ b/tools/qfcc/include/flow.h @@ -109,7 +109,9 @@ void flow_del_graph (flowgraph_t *graph); void flow_data_flow (flowgraph_t *graph); struct sblock_s *flow_generate (flowgraph_t *graph); -void print_flowgraph (flowgraph_t *graph, const char *filename); +void dump_dot_flow (void *g, const char *filename); +void dump_dot_flow_dags (void *g, const char *filename); +void dump_dot_flow_live (void *g, const char *filename); //@} diff --git a/tools/qfcc/source/dot_flow.c b/tools/qfcc/source/dot_flow.c index 3a7e8309c..141db49ac 100644 --- a/tools/qfcc/source/dot_flow.c +++ b/tools/qfcc/source/dot_flow.c @@ -51,11 +51,131 @@ #include "statements.h" #include "strpool.h" +typedef struct { + const char *type; + void (*print_node) (dstring_t *, flowgraph_t *, flownode_t *, int); + void (*print_edge) (dstring_t *, flowgraph_t *, flowedge_t *, int); +} flow_dot_t; + static void print_flow_node (dstring_t *dstr, flowgraph_t *graph, flownode_t *node, int level) { int indent = level * 2 + 2; + + dasprintf (dstr, "%*s\"fn_%p\" [label=\"%d (%d)\"];\n", indent, "", + node, node->id, node->dfn); +} + +static void +print_flow_edge (dstring_t *dstr, flowgraph_t *graph, flowedge_t *edge, + int level) +{ + int indent = level * 2 + 2; + int edge_num = edge - graph->edges; + flownode_t *t, *h; + const char *style; + const char *dir; + int weight; + + t = graph->nodes[edge->tail]; + h = graph->nodes[edge->head]; + if (t->dfn >= h->dfn) { + flownode_t *temp; + temp = h; + h = t; + t = temp; + + dir = "dir=back,"; + style = "dashed"; + weight = 0; + } else if (set_is_member (graph->dfst, edge_num)) { + dir = ""; + style = "bold"; + weight = 10; + } else { + dir = ""; + style = "solid"; + weight = 0; + } + dasprintf (dstr, "%*s", indent, ""); + dasprintf (dstr, "fn_%p -> ", t); + dasprintf (dstr, "fn_%p [%sstyle=%s,weight=%d", h, dir, style, weight); + dasprintf (dstr, "];\n"); +} + +static void +print_flow_node_dag (dstring_t *dstr, flowgraph_t *graph, flownode_t *node, + int level) +{ + if (node->dag) + print_dag (dstr, node->dag, va ("%d (%d)", node->id, node->dfn)); + else + print_flow_node (dstr, graph, node, level); +} + +static void +print_flow_edge_dag (dstring_t *dstr, flowgraph_t *graph, flowedge_t *edge, + int level) +{ + int indent = level * 2 + 2; + int edge_num = edge - graph->edges; + flownode_t *t, *h; + const char *tpref; + const char *hpref; + const char *style; + const char *dir; + int weight; + + t = graph->nodes[edge->tail]; + h = graph->nodes[edge->head]; + 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, edge_num)) { + tpref = "leave"; + hpref = "enter"; + dir = ""; + style = "bold"; + weight = 10; + } else { + tpref = "leave"; + hpref = "enter"; + dir = ""; + style = "solid"; + weight = 0; + } + 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"); +} + +static void +print_flow_node_live (dstring_t *dstr, flowgraph_t *graph, flownode_t *node, + int level) +{ + int indent = level * 2 + 2; set_iter_t *var_iter; flowvar_t *var; int live; @@ -63,21 +183,11 @@ print_flow_node (dstring_t *dstr, flowgraph_t *graph, flownode_t *node, live = node->live_vars.out && !set_is_empty (node->live_vars.out); if (live) { - dasprintf (dstr, "%*ssubgraph sub_%p {\n", indent, "", node); - //dasprintf (dstr, "%*s rank=same;\n", indent, ""); - indent += 2; - } - 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, "%*sfn_%p [shape=none,label=<\n", indent, "", node); dasprintf (dstr, "%*s\n", indent + 2, ""); - dasprintf (dstr, "%*s\n", indent + 4, ""); + dasprintf (dstr, "%*s\n", indent + 4, "", + node->id, node->dfn); for (var_iter = set_first (node->live_vars.out); var_iter; var_iter = set_next (var_iter)) { var = graph->func->vars[var_iter->member]; @@ -85,97 +195,34 @@ print_flow_node (dstring_t *dstr, flowgraph_t *graph, flownode_t *node, var->number, html_string(operand_string (var->op))); } dasprintf (dstr, "%*s
Live Vars
%d (%d)
>];\n", indent + 2, ""); - 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, ""); + } else { + print_flow_node (dstr, graph, node, level); } } +static flow_dot_t flow_dot_methods[] = { + {"", print_flow_node, print_flow_edge}, + {"dag", print_flow_node_dag, print_flow_edge_dag}, + {"live", print_flow_node_live, print_flow_edge}, +}; + static void -print_flow_edges (dstring_t *dstr, flowgraph_t *graph, int level) -{ - int indent = level * 2 + 2; - 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) { - 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; - } - 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"); - } -} - -void -print_flowgraph (flowgraph_t *graph, const char *filename) +print_flowgraph (flow_dot_t *method, flowgraph_t *graph, const char *filename) { int i; dstring_t *dstr = dstring_newstr(); - dasprintf (dstr, "digraph flowgraph_%p {\n", graph); + dasprintf (dstr, "digraph flowgraph_%s_%p {\n", method->type, graph); dasprintf (dstr, " layout=dot;\n"); dasprintf (dstr, " clusterrank=local;\n"); dasprintf (dstr, " rankdir=TB;\n"); dasprintf (dstr, " compound=true;\n"); for (i = 0; i < graph->num_nodes; i++) { - print_flow_node (dstr, graph, graph->nodes[i], 0); + method->print_node (dstr, graph, graph->nodes[i], 0); + } + for (i = 0; i < graph->num_edges; i++) { + method->print_edge (dstr, graph, &graph->edges[i], 0); } - print_flow_edges (dstr, graph, 0); dasprintf (dstr, "}\n"); if (filename) { @@ -189,3 +236,21 @@ print_flowgraph (flowgraph_t *graph, const char *filename) } dstring_delete (dstr); } + +void +dump_dot_flow (void *g, const char *filename) +{ + print_flowgraph (&flow_dot_methods[0], (flowgraph_t *) g, filename); +} + +void +dump_dot_flow_dags (void *g, const char *filename) +{ + print_flowgraph (&flow_dot_methods[1], (flowgraph_t *) g, filename); +} + +void +dump_dot_flow_live (void *g, const char *filename) +{ + print_flowgraph (&flow_dot_methods[2], (flowgraph_t *) g, filename); +} diff --git a/tools/qfcc/source/flow.c b/tools/qfcc/source/flow.c index b1a024e78..6bbd44705 100644 --- a/tools/qfcc/source/flow.c +++ b/tools/qfcc/source/flow.c @@ -76,12 +76,6 @@ static struct { }; static const int num_flow_params = sizeof(flow_params)/sizeof(flow_params[0]); -static void -dump_dot_flow (void *data, const char *fname) -{ - print_flowgraph ((flowgraph_t *) data, fname); -} - static flowvar_t * new_flowvar (void) { @@ -575,7 +569,7 @@ flow_build_dags (flowgraph_t *graph) node->dag = dag_create (node); } //if (options.block_dot.dags) - // dump_dot ("dags", graph, dump_dot_flow); + // dump_dot ("dags", graph, dump_dot_flow_dags); } void