Fix the dropping of the block after the merged if/goto.

The naive implementation of the if/goto merging was letting the old target
of the if get dropped because the block would lose its label and thus be
judged unreachable because the preceeding goto block was still in the list.
Instead, when the if/goto are "merged", mark the goto block as unreachable,
the following block as reachable, and break out of the analysis loop to
force the removal of the goto block. Since the dead block removal function
loops until no action is taken, all other dead blocks will be removed.
This commit is contained in:
Bill Currie 2012-05-04 10:02:02 +09:00
parent e866619de6
commit 8ddd58f951

View file

@ -1121,11 +1121,13 @@ remove_dead_blocks (sblock_t *blocks)
{
sblock_t *sblock;
int did_something;
int pass = 0;
if (!blocks)
return;
do {
debug (0, "dead block pass %d", pass++);
did_something = 0;
blocks->reachable = 1;
for (sblock = blocks; sblock->next; sblock = sblock->next) {
@ -1144,6 +1146,9 @@ remove_dead_blocks (sblock_t *blocks)
remove_label_from_dest (s->opb->o.label);
s->opb->o.label = sb->statements->opa->o.label;
invert_conditional (s);
sb->next->reachable = 1;
sb->reachable = 0;
break;
} else if (!is_goto (s) && !is_return (s)) {
sb->reachable = 1;
continue;