From 8582e9de630ab4e7bcaa7bc4869b56044359332e Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Tue, 11 Dec 2012 11:31:55 +0900 Subject: [PATCH] Make it possible to dump statement blocks in a flow graph. Much nicer looking with proper back edges :). Not actually enabled, though. --- tools/qfcc/include/flow.h | 1 + tools/qfcc/include/statements.h | 2 + tools/qfcc/source/dot_flow.c | 73 +++++++++++++++++++++++++++++++-- tools/qfcc/source/dot_sblock.c | 15 +++++-- tools/qfcc/source/flow.c | 3 +- 5 files changed, 85 insertions(+), 9 deletions(-) diff --git a/tools/qfcc/include/flow.h b/tools/qfcc/include/flow.h index 4677c5e4d..7f1f25522 100644 --- a/tools/qfcc/include/flow.h +++ b/tools/qfcc/include/flow.h @@ -117,6 +117,7 @@ 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); void dump_dot_flow_reaching (void *g, const char *filename); +void dump_dot_flow_statements (void *g, const char *filename); //@} diff --git a/tools/qfcc/include/statements.h b/tools/qfcc/include/statements.h index 5013ed902..136f3726e 100644 --- a/tools/qfcc/include/statements.h +++ b/tools/qfcc/include/statements.h @@ -106,6 +106,7 @@ typedef struct sblock_s { struct expr_s; struct type_s; +struct dstring_s; const char *optype_str (op_type_e type); @@ -126,6 +127,7 @@ void statements_count_temps (sblock_t *sblock); void print_statement (statement_t *s); void dump_dot_sblock (void *data, const char *fname); +void dot_sblock (struct dstring_s *dstr, sblock_t *sblock, int blockno); void print_sblock (sblock_t *sblock, const char *filename); const char *operand_string (operand_t *op); diff --git a/tools/qfcc/source/dot_flow.c b/tools/qfcc/source/dot_flow.c index 1ae35b9dc..d75bbc7e5 100644 --- a/tools/qfcc/source/dot_flow.c +++ b/tools/qfcc/source/dot_flow.c @@ -224,11 +224,70 @@ print_flow_node_reaching (dstring_t *dstr, flowgraph_t *graph, } } +static void +print_flow_node_statements (dstring_t *dstr, flowgraph_t *graph, + flownode_t *node, int level) +{ + if (node->sblock) { + dot_sblock (dstr, node->sblock, node->id); + } else { + print_flow_node (dstr, graph, node, level); + } +} + +static void +print_flow_edge_statements (dstring_t *dstr, flowgraph_t *graph, + flowedge_t *edge, int level) +{ + int indent = level * 2 + 2; + int edge_num = edge - graph->edges; + flownode_t *h, *t; + const char *hpre = "fn_", *tpre = "fn_"; + 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; + } + if (t->sblock) { + tpre = "sb_"; + t = (flownode_t *) t->sblock; + } + if (h->sblock) { + hpre = "sb_"; + h = (flownode_t *) h->sblock; + } + dasprintf (dstr, "%*s", indent, ""); + dasprintf (dstr, "%s%p -> ", tpre, t); + dasprintf (dstr, "%s%p [%sstyle=%s,weight=%d", hpre, h, dir, style, + weight); + dasprintf (dstr, "];\n"); +} + 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}, - {"reaching",print_flow_node_reaching, print_flow_edge}, + {"", print_flow_node, print_flow_edge}, + {"dag", print_flow_node_dag, print_flow_edge_dag}, + {"live", print_flow_node_live, print_flow_edge}, + {"reaching", print_flow_node_reaching, print_flow_edge}, + {"statements", print_flow_node_statements, print_flow_edge_statements}, }; static void @@ -288,3 +347,9 @@ dump_dot_flow_reaching (void *g, const char *filename) { print_flowgraph (&flow_dot_methods[3], (flowgraph_t *) g, filename); } + +void +dump_dot_flow_statements (void *g, const char *filename) +{ + print_flowgraph (&flow_dot_methods[4], (flowgraph_t *) g, filename); +} diff --git a/tools/qfcc/source/dot_sblock.c b/tools/qfcc/source/dot_sblock.c index 120475eef..72b245efe 100644 --- a/tools/qfcc/source/dot_sblock.c +++ b/tools/qfcc/source/dot_sblock.c @@ -65,12 +65,10 @@ flow_statement (dstring_t *dstr, statement_t *s) dasprintf (dstr, "\n"); } -static void -flow_sblock (dstring_t *dstr, sblock_t *sblock, int blockno) +void +dot_sblock (dstring_t *dstr, sblock_t *sblock, int blockno) { statement_t *s; - sblock_t **target; - sblock_t **target_list; ex_label_t *l; dasprintf (dstr, " sb_%p [shape=none,label=<\n", sblock); @@ -94,6 +92,15 @@ flow_sblock (dstring_t *dstr, sblock_t *sblock, int blockno) dasprintf (dstr, " \n"); dasprintf (dstr, " \n"); dasprintf (dstr, " >];\n"); +} + +static void +flow_sblock (dstring_t *dstr, sblock_t *sblock, int blockno) +{ + sblock_t **target; + sblock_t **target_list; + + dot_sblock (dstr, sblock, blockno); if (sblock->statements) { statement_t *st = (statement_t *) sblock->tail; if (sblock->next diff --git a/tools/qfcc/source/flow.c b/tools/qfcc/source/flow.c index 30266c942..794411afa 100644 --- a/tools/qfcc/source/flow.c +++ b/tools/qfcc/source/flow.c @@ -631,7 +631,8 @@ flow_uninit_scan_statements (flownode_t *node, set_t *defs, set_t *uninit) warning (st->expr, "%s may be used uninitialized", def->name); } else { - bug (st->expr, "uninitialized temp"); + bug (st->expr, "st %d, uninitialized temp %s", + st->number, operand_string (var->op)); } } // avoid repeat warnings in this node