Treat global variables as live at the end of a function.

.return and .param_N are not classed as global variables for data flow
analysis. .return is taken care of by return statements, and .param_N by
call statements.

With this, the menus work up to attempting to load the menu plist.
Something is corrupting zmalloc's blocks.
This commit is contained in:
Bill Currie 2012-11-19 17:21:35 +09:00
parent 0dea564cb4
commit 56103f9a38
6 changed files with 61 additions and 24 deletions

View file

@ -69,6 +69,7 @@ typedef struct flownode_s {
struct set_s *successors; ///< successors of this node
struct set_s *edges; ///< edges leaving this node to successor nodes
struct set_s *dom; ///< dominating nodes
struct set_s *global_vars; ///< global vars used by function
struct {
struct set_s *use;
struct set_s *def;
@ -102,7 +103,8 @@ void flow_analyze_statement (struct statement_s *s, struct set_s *use,
struct set_s *def, struct set_s *kill,
struct operand_s *operands[4]);
void flow_build_vars (struct function_s *func);
flowgraph_t *flow_build_graph (struct sblock_s *func);
flowgraph_t *flow_build_graph (struct sblock_s *sblock,
struct function_s *func);
void flow_del_graph (flowgraph_t *graph);
void flow_data_flow (flowgraph_t *graph);
struct sblock_s *flow_generate (flowgraph_t *graph);

View file

@ -89,6 +89,7 @@ typedef struct function_s {
*/
struct flowvar_s **vars;
int num_vars; ///< total number of variables referenced
struct set_s *global_vars;///< set indicating which vars are global
struct statement_s **statements;
int num_statements;
} function_t;

View file

@ -67,11 +67,11 @@ typedef struct symbol_s {
struct flowvar_s *flowvar;
struct daglabel_s *daglabel;///< dag label for this symbol
union {
int offset; ///< st_var (in a struct/union)
struct def_s *def; ///< st_var
struct ex_value_s *value; ///< st_const
struct expr_s *expr; ///< st_expr
struct function_s *func; ///< st_func
int offset; ///< sy_var (in a struct/union)
struct def_s *def; ///< sy_var
struct ex_value_s *value; ///< sy_const
struct expr_s *expr; ///< sy_expr
struct function_s *func; ///< sy_func
} s;
} symbol_t;

View file

@ -407,23 +407,26 @@ dag_create (flownode_t *flownode)
lx->expr = s->expr;
dagnode_attach_label (n, lx);
}
if (n->type == st_func
&& (!strncmp (n->label->opcode, "<CALL", 5)
|| !strncmp (n->label->opcode, "<RCALL", 6))) {
int start, end;
if (n->type == st_func) {
if (!strncmp (n->label->opcode, "<CALL", 5)
|| !strncmp (n->label->opcode, "<RCALL", 6)) {
int start, end;
if (!strncmp (n->label->opcode, "<CALL", 5)) {
start = 0;
end = 0;
if (n->label->opcode[5] != '>')
end = n->label->opcode[5] - '0';
} else {
start = 2;
end = n->label->opcode[6] - '0';
}
while (start < end) {
set_add (live_vars, start + 1);
start++;
if (!strncmp (n->label->opcode, "<CALL", 5)) {
start = 0;
end = 0;
if (n->label->opcode[5] != '>')
end = n->label->opcode[5] - '0';
} else {
start = 2;
end = n->label->opcode[6] - '0';
}
while (start < end) {
set_add (live_vars, start + 1);
start++;
}
} else if (!strncmp (n->label->opcode, "<RETURN", 7)) {
set_union (live_vars, flownode->global_vars);
}
}
}

View file

@ -160,6 +160,23 @@ delete_graph (flowgraph_t *graph)
free_graphs = graph;
}
static int
flowvar_is_global (flowvar_t *var)
{
symbol_t *sym;
def_t *def;
if (var->op->op_type != op_symbol)
return 0;
sym = var->op->o.symbol;
if (sym->sy_type != sy_var)
return 0;
def = sym->s.def;
if (def->local)
return 0;
return 1;
}
flowvar_t *
flow_get_var (operand_t *op)
{
@ -284,6 +301,12 @@ flow_build_vars (function_t *func)
add_operand (func, s->opc);
}
}
func->global_vars = set_new ();
// mark all global vars (except .return and .param_N)
for (i = num_flow_params; i < func->num_vars; i++) {
if (flowvar_is_global (func->vars[i]))
set_add (func->global_vars, i);
}
}
if (num_statements) {
func->statements = malloc (num_statements * sizeof (statement_t *));
@ -333,6 +356,13 @@ flow_live_vars (flowgraph_t *graph)
def = set_new ();
for (st = node->sblock->statements; st; st = st->next) {
flow_analyze_statement (st, stuse, stdef, 0, 0);
if (st->type == st_func && !strncmp (st->opcode, "<RETURN", 7)) {
set_t *global_vars = set_new ();
set_assign (global_vars, graph->func->global_vars);
live_set_use (global_vars, use, def);
set_delete (global_vars);
}
live_set_use (stuse, use, def);
live_set_def (stdef, use, def);
}
@ -799,7 +829,7 @@ flow_build_dfst (flowgraph_t *graph)
}
flowgraph_t *
flow_build_graph (sblock_t *sblock)
flow_build_graph (sblock_t *sblock, function_t *func)
{
flowgraph_t *graph;
flownode_t *node;
@ -819,6 +849,7 @@ flow_build_graph (sblock_t *sblock)
node->successors = set_new ();
node->edges = set_new ();
node->dom = set_new ();
node->global_vars = func->global_vars;
node->id = sb->number;
node->sblock = sb;
graph->nodes[node->id] = node;

View file

@ -644,7 +644,7 @@ emit_function (function_t *f, expr_t *e)
lineno_base = f->def->line;
f->sblock = make_statements (e);
flow_build_vars (f);
f->graph = flow_build_graph (f->sblock);
f->graph = flow_build_graph (f->sblock, f);
f->graph->func = f;
flow_data_flow (f->graph);
f->sblock = flow_generate (f->graph);