mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-18 15:01:41 +00:00
Do simple unreachable block analysis and dead block removal.
This commit is contained in:
parent
90a2738459
commit
9159daf99d
1 changed files with 69 additions and 0 deletions
|
@ -776,12 +776,81 @@ statement_slist (sblock_t *sblock, expr_t *e)
|
|||
return sblock;
|
||||
}
|
||||
|
||||
static void
|
||||
remove_label_from_dest (ex_label_t *label)
|
||||
{
|
||||
sblock_t *sblock;
|
||||
ex_label_t **l;
|
||||
|
||||
if (!label)
|
||||
return;
|
||||
|
||||
sblock = label->dest;
|
||||
for (l = &sblock->labels; *l; l = &(*l)->next) {
|
||||
if (*l == label) {
|
||||
*l = label->next;
|
||||
label->next = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
remove_dead_blocks (sblock_t *blocks)
|
||||
{
|
||||
sblock_t *sblock;
|
||||
int did_something;
|
||||
|
||||
if (!blocks)
|
||||
return;
|
||||
|
||||
do {
|
||||
did_something = 0;
|
||||
blocks->reachable = 1;
|
||||
for (sblock = blocks; sblock->next; sblock = sblock->next) {
|
||||
sblock_t *sb = sblock->next;
|
||||
statement_t *s;
|
||||
|
||||
if (sb->labels) {
|
||||
sb->reachable = 1;
|
||||
continue;
|
||||
}
|
||||
s = (statement_t *) sblock->tail;
|
||||
if (strcmp (s->opcode, "<GOTO>")
|
||||
&& strncmp (s->opcode, "<RETURN", 7)) {
|
||||
sb->reachable = 1;
|
||||
continue;
|
||||
}
|
||||
sb->reachable = 0;
|
||||
}
|
||||
for (sblock = blocks; sblock; sblock = sblock->next) {
|
||||
while (sblock->next && !sblock->next->reachable) {
|
||||
sblock_t *sb = sblock->next;
|
||||
statement_t *s;
|
||||
ex_label_t *label = 0;
|
||||
|
||||
notice (0, "removing dead block %p", sb);
|
||||
sblock->next = sb->next;
|
||||
s = (statement_t *) sblock->tail;
|
||||
if (!strcmp (s->opcode, "<GOTO>"))
|
||||
label = s->opa->o.label;
|
||||
else if (!strncmp (s->opcode, "<IF", 3))
|
||||
label = s->opb->o.label;
|
||||
remove_label_from_dest (label);
|
||||
did_something = 1;
|
||||
}
|
||||
}
|
||||
} while (did_something);
|
||||
}
|
||||
|
||||
sblock_t *
|
||||
make_statements (expr_t *e)
|
||||
{
|
||||
sblock_t *sblock = new_sblock ();
|
||||
// print_expr (e);
|
||||
statement_slist (sblock, e);
|
||||
// print_flow (sblock);
|
||||
remove_dead_blocks (sblock);
|
||||
// print_flow (sblock);
|
||||
return sblock;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue