mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-23 04:42:32 +00:00
Make it possible to dump statement blocks in a flow graph.
Much nicer looking with proper back edges :). Not actually enabled, though.
This commit is contained in:
parent
cd62755ce4
commit
8582e9de63
5 changed files with 85 additions and 9 deletions
|
@ -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);
|
||||
|
||||
//@}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -65,12 +65,10 @@ flow_statement (dstring_t *dstr, statement_t *s)
|
|||
dasprintf (dstr, "</tr>\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, " <td></td>\n");
|
||||
dasprintf (dstr, " </tr>\n");
|
||||
dasprintf (dstr, " </table>>];\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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue