Add live variable info to flow graph dumps.

Things are a little bogus, but at least the bogosity is visible :)
This commit is contained in:
Bill Currie 2012-11-06 18:26:08 +09:00
parent 8817c4a1c2
commit cd224c00d4
4 changed files with 31 additions and 8 deletions

View file

@ -44,6 +44,7 @@ typedef struct flowvar_s {
struct flowvar_s *next; ///< for ALLOC
struct set_s *use; ///< set of statements that use this var
struct set_s *define; ///< set of statements that define this var
struct operand_s *op; ///< an operand using this var
int number; ///< number of variable in func's ref list
} flowvar_t;
@ -79,6 +80,7 @@ typedef struct flownode_s {
typedef struct flowgraph_s {
struct flowgraph_s *next; ///< for ALLOC
struct function_s *func; ///< function to which this graph is attached
flownode_t **nodes; ///< array of nodes in the graph
int num_nodes;
flowedge_t *edges; ///< array of all edges in the graph
@ -98,7 +100,7 @@ struct sblock_s **flow_get_targetlist (struct statement_s *s);
void flow_build_vars (struct function_s *func);
flowgraph_t *flow_build_graph (struct sblock_s *func);
void flow_del_graph (flowgraph_t *graph);
void flow_data_flow (struct function_s *func);
void flow_data_flow (flowgraph_t *graph);
void print_flowgraph (flowgraph_t *graph, const char *filename);

View file

@ -45,17 +45,37 @@
#include "dags.h"
#include "flow.h"
#include "function.h"
#include "expr.h"
#include "set.h"
#include "statements.h"
#include "strpool.h"
static void
print_flow_node (dstring_t *dstr, flownode_t *node, int level)
print_flow_node (dstring_t *dstr, flowgraph_t *graph, flownode_t *node,
int level)
{
int indent = level * 2 + 2;
set_iter_t *var_iter;
flowvar_t *var;
dasprintf (dstr, "%*s\"fn_%p\" [label=\"%d (%d)\"];\n", indent, "", node,
node->id, node->dfn);
if (node->live_vars.out && !set_is_empty (node->live_vars.out)) {
dasprintf (dstr, "%*slv_%p [shape=none,label=<\n", indent, "", node);
dasprintf (dstr, "%*s<table border=\"0\" cellborder=\"1\" "
"cellspacing=\"0\">\n", indent + 2, "");
dasprintf (dstr, "%*s<tr><td>Live Vars</td></tr>\n", indent + 4, "");
for (var_iter = set_first (node->live_vars.out); var_iter;
var_iter = set_next (var_iter)) {
var = graph->func->vars[var_iter->member];
dasprintf (dstr, "%*s<tr><td>(%d) %s</td></tr>\n", indent + 4, "",
var->number, html_string(operand_string (var->op)));
}
dasprintf (dstr, "%*s</table>>];\n", indent + 2, "");
dasprintf (dstr, "%*sfn_%p -> lv_%p [constraint=false,style=dashed];\n",
indent, "", node, node);
}
}
static void
@ -102,7 +122,7 @@ print_flowgraph (flowgraph_t *graph, const char *filename)
dasprintf (dstr, " rankdir=TB;\n");
dasprintf (dstr, " compound=true;\n");
for (i = 0; i < graph->num_nodes; i++) {
print_flow_node (dstr, graph->nodes[i], 0);
print_flow_node (dstr, graph, graph->nodes[i], 0);
}
print_flow_edges (dstr, graph, 0);
dasprintf (dstr, "}\n");

View file

@ -204,6 +204,7 @@ add_operand (function_t *func, operand_t *op)
// added to the list of variables referenced by the function.
if (var && var->number == -1) {
var->number = func->num_vars++;
var->op = op;
func->vars[var->number] = var;
}
}
@ -266,9 +267,8 @@ live_set_def (flowvar_t *var, set_t *use, set_t *def)
}
static void
flow_live_vars (function_t *func)
flow_live_vars (flowgraph_t *graph)
{
flowgraph_t *graph = func->graph;
int i, j;
flownode_t *node;
set_t *use;
@ -318,9 +318,9 @@ flow_live_vars (function_t *func)
}
void
flow_data_flow (function_t *func)
flow_data_flow (flowgraph_t *graph)
{
flow_live_vars (func);
flow_live_vars (graph);
}
int

View file

@ -645,7 +645,8 @@ emit_function (function_t *f, expr_t *e)
f->sblock = make_statements (e);
flow_build_vars (f);
f->graph = flow_build_graph (f->sblock);
flow_data_flow (f);
f->graph->func = f;
flow_data_flow (f->graph);
if (options.block_dot.flow)
print_flowgraph (f->graph, nva ("%s.%s.%s.dot", GETSTR (pr.source_file),
f->name, "flow"));