mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-02-17 01:11:45 +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_dags (void *g, const char *filename);
|
||||||
void dump_dot_flow_live (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_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 expr_s;
|
||||||
struct type_s;
|
struct type_s;
|
||||||
|
struct dstring_s;
|
||||||
|
|
||||||
const char *optype_str (op_type_e type);
|
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 print_statement (statement_t *s);
|
||||||
void dump_dot_sblock (void *data, const char *fname);
|
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);
|
void print_sblock (sblock_t *sblock, const char *filename);
|
||||||
const char *operand_string (operand_t *op);
|
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[] = {
|
static flow_dot_t flow_dot_methods[] = {
|
||||||
{"", print_flow_node, print_flow_edge},
|
{"", print_flow_node, print_flow_edge},
|
||||||
{"dag", print_flow_node_dag, print_flow_edge_dag},
|
{"dag", print_flow_node_dag, print_flow_edge_dag},
|
||||||
{"live", print_flow_node_live, print_flow_edge},
|
{"live", print_flow_node_live, print_flow_edge},
|
||||||
{"reaching",print_flow_node_reaching, print_flow_edge},
|
{"reaching", print_flow_node_reaching, print_flow_edge},
|
||||||
|
{"statements", print_flow_node_statements, print_flow_edge_statements},
|
||||||
};
|
};
|
||||||
|
|
||||||
static void
|
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);
|
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");
|
dasprintf (dstr, "</tr>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
flow_sblock (dstring_t *dstr, sblock_t *sblock, int blockno)
|
dot_sblock (dstring_t *dstr, sblock_t *sblock, int blockno)
|
||||||
{
|
{
|
||||||
statement_t *s;
|
statement_t *s;
|
||||||
sblock_t **target;
|
|
||||||
sblock_t **target_list;
|
|
||||||
ex_label_t *l;
|
ex_label_t *l;
|
||||||
|
|
||||||
dasprintf (dstr, " sb_%p [shape=none,label=<\n", sblock);
|
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, " <td></td>\n");
|
||||||
dasprintf (dstr, " </tr>\n");
|
dasprintf (dstr, " </tr>\n");
|
||||||
dasprintf (dstr, " </table>>];\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) {
|
if (sblock->statements) {
|
||||||
statement_t *st = (statement_t *) sblock->tail;
|
statement_t *st = (statement_t *) sblock->tail;
|
||||||
if (sblock->next
|
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",
|
warning (st->expr, "%s may be used uninitialized",
|
||||||
def->name);
|
def->name);
|
||||||
} else {
|
} 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
|
// avoid repeat warnings in this node
|
||||||
|
|
Loading…
Reference in a new issue