Move and rename statement related flow_is_* and flow_get_*

They really should have been in statements.[ch] in the first place
(actually, they sort of were: is_goto etc, so some redundant code has been
removed, too).
This commit is contained in:
Bill Currie 2012-11-30 14:06:52 +09:00
parent 086fd0f3c3
commit 93f53605ed
5 changed files with 93 additions and 111 deletions

View file

@ -99,12 +99,6 @@ typedef struct flowgraph_s {
} flowgraph_t;
flowvar_t *flow_get_var (struct operand_s *op);
int flow_is_cond (struct statement_s *s);
int flow_is_goto (struct statement_s *s);
int flow_is_jumpb (struct statement_s *s);
int flow_is_return (struct statement_s *s);
struct sblock_s *flow_get_target (struct statement_s *s);
struct sblock_s **flow_get_targetlist (struct statement_s *s);
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]);

View file

@ -112,6 +112,12 @@ operand_t *temp_operand (struct type_s *type);
sblock_t *new_sblock (void);
statement_t *new_statement (st_type_t type, const char *opcode,
struct expr_s *expr);
int statement_is_cond (statement_t *s);
int statement_is_goto (statement_t *s);
int statement_is_jumpb (statement_t *s);
int statement_is_return (statement_t *s);
sblock_t *statement_get_target (statement_t *s);
sblock_t **statement_get_targetlist (statement_t *s);
void sblock_add_statement (sblock_t *sblock, statement_t *statement);
sblock_t *make_statements (struct expr_s *expr);
void print_statement (statement_t *s);

View file

@ -97,11 +97,11 @@ flow_sblock (dstring_t *dstr, sblock_t *sblock, int blockno)
if (sblock->statements) {
statement_t *st = (statement_t *) sblock->tail;
if (sblock->next
&& !flow_is_goto (st)
&& !flow_is_jumpb (st)
&& !flow_is_return (st))
&& !statement_is_goto (st)
&& !statement_is_jumpb (st)
&& !statement_is_return (st))
dasprintf (dstr, " sb_%p:e -> sb_%p:s;\n", sblock, sblock->next);
if ((target_list = flow_get_targetlist (st))) {
if ((target_list = statement_get_targetlist (st))) {
for (target = target_list; *target; target++)
dasprintf (dstr, " sb_%p:e -> sb_%p:s [label=\"%s\"];\n",
sblock, *target, st->opcode);

View file

@ -639,78 +639,6 @@ flow_generate (flowgraph_t *graph)
return code;
}
int
flow_is_cond (statement_t *s)
{
if (!s)
return 0;
return !strncmp (s->opcode, "<IF", 3);
}
int
flow_is_goto (statement_t *s)
{
if (!s)
return 0;
return !strcmp (s->opcode, "<GOTO>");
}
int
flow_is_jumpb (statement_t *s)
{
if (!s)
return 0;
return !strcmp (s->opcode, "<JUMPB>");
}
int
flow_is_return (statement_t *s)
{
if (!s)
return 0;
return !strncmp (s->opcode, "<RETURN", 7);
}
sblock_t *
flow_get_target (statement_t *s)
{
if (flow_is_cond (s))
return s->opb->o.label->dest;
if (flow_is_goto (s))
return s->opa->o.label->dest;
return 0;
}
sblock_t **
flow_get_targetlist (statement_t *s)
{
sblock_t **target_list;
int count = 0, i;
def_t *table = 0;
expr_t *e;
if (flow_is_cond (s)) {
count = 1;
} else if (flow_is_goto (s)) {
count = 1;
} else if (flow_is_jumpb (s)) {
table = s->opa->o.alias->o.symbol->s.def; //FIXME check!!!
count = table->type->t.array.size;
}
target_list = malloc ((count + 1) * sizeof (sblock_t *));
target_list[count] = 0;
if (flow_is_cond (s)) {
target_list[0] = flow_get_target (s);
} else if (flow_is_goto (s)) {
target_list[0] = flow_get_target (s);
} else if (flow_is_jumpb (s)) {
e = table->initializer->e.block.head; //FIXME check!!!
for (i = 0; i < count; e = e->next, i++)
target_list[i] = e->e.labelref.label->dest;
}
return target_list;
}
static void
flow_add_op_var (set_t *set, operand_t *op)
{
@ -1040,23 +968,23 @@ flow_build_graph (sblock_t *sblock, function_t *func)
st = 0;
if (sb->statements)
st = (statement_t *) sb->tail;
//NOTE: if st is null (the sblock has no statements), flow_is_* will
//return false
//NOTE: if st is null (the sblock has no statements), statement_is_*
//will return false
//FIXME jump/jumpb
if (flow_is_goto (st)) {
if (statement_is_goto (st)) {
// sb's next is never followed.
set_add (node->successors, flow_get_target (st)->number);
} else if (flow_is_jumpb (st)) {
target_list = flow_get_targetlist (st);
set_add (node->successors, statement_get_target (st)->number);
} else if (statement_is_jumpb (st)) {
target_list = statement_get_targetlist (st);
for (target = target_list; *target; target++)
set_add (node->successors, (*target)->number);
free (target_list);
} else if (flow_is_cond (st)) {
} else if (statement_is_cond (st)) {
// branch: either sb's next or the conditional statment's
// target will be followed.
set_add (node->successors, sb->next->number);
set_add (node->successors, flow_get_target (st)->number);
} else if (flow_is_return (st)) {
set_add (node->successors, statement_get_target (st)->number);
} else if (statement_is_return (st)) {
// exit from function (dead end)
} else {
// there is no flow-control statement in sb, so sb's next

View file

@ -368,22 +368,76 @@ convert_op (int op)
}
}
static int
is_goto (statement_t *s)
int
statement_is_cond (statement_t *s)
{
if (!s)
return 0;
return !strncmp (s->opcode, "<IF", 3);
}
int
statement_is_goto (statement_t *s)
{
if (!s)
return 0;
return !strcmp (s->opcode, "<GOTO>");
}
static int
is_return (statement_t *s)
int
statement_is_jumpb (statement_t *s)
{
if (!s)
return 0;
return !strcmp (s->opcode, "<JUMPB>");
}
int
statement_is_return (statement_t *s)
{
if (!s)
return 0;
return !strncmp (s->opcode, "<RETURN", 7);
}
static int
is_conditional (statement_t *s)
sblock_t *
statement_get_target (statement_t *s)
{
return !strncmp (s->opcode, "<IF", 3);
if (statement_is_cond (s))
return s->opb->o.label->dest;
if (statement_is_goto (s))
return s->opa->o.label->dest;
return 0;
}
sblock_t **
statement_get_targetlist (statement_t *s)
{
sblock_t **target_list;
int count = 0, i;
def_t *table = 0;
expr_t *e;
if (statement_is_cond (s)) {
count = 1;
} else if (statement_is_goto (s)) {
count = 1;
} else if (statement_is_jumpb (s)) {
table = s->opa->o.alias->o.symbol->s.def; //FIXME check!!!
count = table->type->t.array.size;
}
target_list = malloc ((count + 1) * sizeof (sblock_t *));
target_list[count] = 0;
if (statement_is_cond (s)) {
target_list[0] = statement_get_target (s);
} else if (statement_is_goto (s)) {
target_list[0] = statement_get_target (s);
} else if (statement_is_jumpb (s)) {
e = table->initializer->e.block.head; //FIXME check!!!
for (i = 0; i < count; e = e->next, i++)
target_list[i] = e->e.labelref.label->dest;
}
return target_list;
}
static void
@ -1208,14 +1262,14 @@ thread_jumps (sblock_t *blocks)
if (!sblock->statements)
continue;
s = (statement_t *) sblock->tail;
if (is_goto (s))
if (statement_is_goto (s))
label = &s->opa->o.label;
else if (is_conditional (s))
else if (statement_is_cond (s))
label = &s->opb->o.label;
else
continue;
for (l = *label;
l->dest->statements && is_goto (l->dest->statements);
l->dest->statements && statement_is_goto (l->dest->statements);
l = l->dest->statements->opa->o.label) {
}
if (l != *label) {
@ -1223,7 +1277,7 @@ thread_jumps (sblock_t *blocks)
l->used++;
*label = l;
}
if (is_goto (s) && (*label)->dest == sblock->next) {
if (statement_is_goto (s) && (*label)->dest == sblock->next) {
statement_t **p;
unuse_label (*label);
for (p = &sblock->statements; *p != s; p = &(*p)->next)
@ -1287,7 +1341,7 @@ merge_blocks (sblock_t *blocks)
if (!sblock->statements)
continue;
s = (statement_t *) sblock->tail;
if (!is_goto (s))
if (!statement_is_goto (s))
continue;
dest = s->opa->o.label->dest;
// The destination block must not be the current block
@ -1312,7 +1366,7 @@ merge_blocks (sblock_t *blocks)
if (!sb->statements)
continue;
s = (statement_t *) sb->tail;
if (!is_goto (s) && !is_return (s))
if (!statement_is_goto (s) && !statement_is_return (s))
continue;
// desination block is reachable only via goto of the current block
if (!dest->next)
@ -1351,8 +1405,8 @@ remove_dead_blocks (sblock_t *blocks)
continue;
}
s = (statement_t *) sblock->tail;
if (is_conditional (s)
&& sb->statements && is_goto (sb->statements)
if (statement_is_cond (s)
&& sb->statements && statement_is_goto (sb->statements)
&& s->opb->o.label->dest == sb->next) {
debug (0, "merging if/goto %p %p", sblock, sb);
unuse_label (s->opb->o.label);
@ -1363,7 +1417,7 @@ remove_dead_blocks (sblock_t *blocks)
for (sb = sb->next; sb; sb = sb->next)
sb->reachable = 1;
break;
} else if (!is_goto (s) && !is_return (s)) {
} else if (!statement_is_goto (s) && !statement_is_return (s)) {
sb->reachable = 1;
continue;
}
@ -1379,9 +1433,9 @@ remove_dead_blocks (sblock_t *blocks)
if (sb->statements) {
s = (statement_t *) sb->tail;
if (is_goto (s))
if (statement_is_goto (s))
label = s->opa->o.label;
else if (is_conditional (s))
else if (statement_is_cond (s))
label = s->opb->o.label;
}
unuse_label (label);
@ -1408,9 +1462,9 @@ check_final_block (sblock_t *sblock)
sblock = sblock->next;
if (sblock->statements) {
s = (statement_t *) sblock->tail;
if (is_goto (s))
if (statement_is_goto (s))
return; // the end of function is the end of a loop
if (is_return (s))
if (statement_is_return (s))
return;
}
if (current_func->sym->type->t.func.type != &type_void)