Allow flownodes and sblocks to be numbered independently.

The numbering will need to be independent when unreachable nodes are
removed.
This commit is contained in:
Bill Currie 2012-12-19 16:08:10 +09:00
parent 9d35ca607f
commit c7ae58d7a3
2 changed files with 14 additions and 10 deletions

View file

@ -99,6 +99,7 @@ typedef struct sblock_s {
struct sblock_s *next; struct sblock_s *next;
struct reloc_s *relocs; struct reloc_s *relocs;
struct ex_label_s *labels; struct ex_label_s *labels;
struct flownode_s *flownode;///< flow node for this block
int offset; ///< offset of first statement of block int offset; ///< offset of first statement of block
int reachable; int reachable;
int number; ///< number of this block in flow graph int number; ///< number of this block in flow graph

View file

@ -1062,6 +1062,8 @@ flow_make_node (sblock_t *sblock, int id, function_t *func)
node->global_vars = func->global_vars; node->global_vars = func->global_vars;
node->id = id; node->id = id;
node->sblock = sblock; node->sblock = sblock;
if (sblock)
sblock->flownode = node;
node->graph = func->graph; node->graph = func->graph;
// Mark the node as unreachable. flow_build_dfst() will mark reachable // Mark the node as unreachable. flow_build_dfst() will mark reachable
// nodes with a value >= 0 // nodes with a value >= 0
@ -1085,11 +1087,11 @@ flow_build_graph (function_t *func)
graph->func = func; graph->func = func;
func->graph = graph; func->graph = graph;
for (sb = sblock; sb; sb = sb->next) for (sb = sblock; sb; sb = sb->next)
sb->number = graph->num_nodes++; graph->num_nodes++;
// + 2 for the uninitialized dummy head block and the live dummy end block // + 2 for the uninitialized dummy head block and the live dummy end block
graph->nodes = malloc ((graph->num_nodes + 2) * sizeof (flownode_t *)); graph->nodes = malloc ((graph->num_nodes + 2) * sizeof (flownode_t *));
for (sb = sblock; sb; sb = sb->next) for (i = 0, sb = sblock; sb; i++, sb = sb->next)
graph->nodes[sb->number] = flow_make_node (sb, sb->number, func); graph->nodes[i] = flow_make_node (sb, i, func);
// Create the dummy node for detecting uninitialized variables // Create the dummy node for detecting uninitialized variables
node = flow_make_node (0, graph->num_nodes, func); node = flow_make_node (0, graph->num_nodes, func);
graph->nodes[graph->num_nodes] = node; graph->nodes[graph->num_nodes] = node;
@ -1107,19 +1109,20 @@ flow_build_graph (function_t *func)
//NOTE: if st is null (the sblock has no statements), statement_is_* //NOTE: if st is null (the sblock has no statements), statement_is_*
//will return false //will return false
//FIXME jump/jumpb //FIXME jump/jumpb
if (statement_is_goto (st)) { if (statement_is_goto (st) || statement_is_jumpb (st)) {
// sb's next is never followed. // sb's next is never followed.
set_add (node->successors, statement_get_target (st)->number);
} else if (statement_is_jumpb (st)) {
target_list = statement_get_targetlist (st); target_list = statement_get_targetlist (st);
for (target = target_list; *target; target++) for (target = target_list; *target; target++)
set_add (node->successors, (*target)->number); set_add (node->successors, (*target)->flownode->id);
free (target_list); free (target_list);
} else if (statement_is_cond (st)) { } else if (statement_is_cond (st)) {
// branch: either sb's next or the conditional statment's // branch: either sb's next or the conditional statment's
// target will be followed. // target will be followed.
set_add (node->successors, sb->next->number); set_add (node->successors, sb->next->flownode->id);
set_add (node->successors, statement_get_target (st)->number); target_list = statement_get_targetlist (st);
for (target = target_list; *target; target++)
set_add (node->successors, (*target)->flownode->id);
free (target_list);
} else if (statement_is_return (st)) { } else if (statement_is_return (st)) {
// exit from function (dead end) // exit from function (dead end)
// however, make the exit dummy block the node's successor // however, make the exit dummy block the node's successor
@ -1128,7 +1131,7 @@ flow_build_graph (function_t *func)
// there is no flow-control statement in sb, so sb's next // there is no flow-control statement in sb, so sb's next
// must be followed // must be followed
if (sb->next) { if (sb->next) {
set_add (node->successors, sb->next->number); set_add (node->successors, sb->next->flownode->id);
} else { } else {
bug (0, "code drops off the end of the function"); bug (0, "code drops off the end of the function");
// this shouldn't happen // this shouldn't happen