(take 2) [RFA:] Fix g77.f-torture/compile/970915-0.f, -Os verify_local_live_at_start, MMIX
Hans-Peter Nilsson
hp@bitrange.com
Tue Apr 16 18:52:00 GMT 2002
On Tue, 16 Apr 2002, Hans-Peter Nilsson wrote:
> The computed regsets are different from the start; they don't
> change with subsequent calls to update_life_info:
Ignore that, it was confused.
The inconsistency happens in that same first call to
update_live_info, the code *after* the loop that updates global
liveness and deletes dead code. flow.c:~693:
...
if (blocks)
{
EXECUTE_IF_SET_IN_SBITMAP (blocks, 0, i,
{
basic_block bb = BASIC_BLOCK (i);
COPY_REG_SET (tmp, bb->global_live_at_end);
propagate_block (bb, tmp, NULL, NULL, prop_flags);
if (extent == UPDATE_LIFE_LOCAL)
verify_local_live_at_start (tmp, bb);
});
}
else
{
for (i = n_basic_blocks - 1; i >= 0; --i)
{
basic_block bb = BASIC_BLOCK (i);
COPY_REG_SET (tmp, bb->global_live_at_end);
propagate_block (bb, tmp, NULL, NULL, prop_flags);
if (extent == UPDATE_LIFE_LOCAL)
verify_local_live_at_start (tmp, bb);
}
}
...
(blocks is NULL here). propagate_block is here called with the
original flags. It removes another hunk of dead stores (that
now fits below the capping on processed mems). But, it *does
not update global liveness, which has changed by deleting the
dead store that was the only user of the presumed alive (but
incorrectly due to capping) register*. As you noticed, the
inconsistency is spotted later on in an UPDATE_LIFE_LOCAL call
(same code above).
Now, what's the best way to have global liveness up to date? I
can think of two choices: mask out PROP_SCAN_DEAD_CODE |
PROP_KILL_DEAD_CODE so that liveness doesn't change, or call
calculate_global_regs_live if something changed. The latter
seems unclean; for one thing it duplicates the dead-code killing
in the first loop. I'll go with masking out those flags. It
solves the problem at hand. I changed both if-arms; the first
doesn't trig for this case, but it looked wrong and inconsistent
not to fix it. As a not strictly necessary improvement for
removal of the resulting dead code, ignoring the return value
from cleanup_cfg should be safe (first hunk; should have done
this in my first patch if I hadn't misinterpreted BB_DIRTY).
This solution should also be safe for 3.1; I'll check there too.
Ok trunk and branch if this passes (bootstrapping and checking
on the various cross-targets I listed for my first patch)?
* flow.c (update_life_info): Ignore return value of cleanup_cfg.
Mask out PROP_SCAN_DEAD_CODE | PROP_KILL_DEAD_CODE in
propagate_block calls after relaxation loop.
Index: flow.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/flow.c,v
retrieving revision 1.514
diff -p -c -r1.514 flow.c
*** flow.c 12 Apr 2002 07:52:02 -0000 1.514
--- flow.c 17 Apr 2002 01:41:48 -0000
*************** update_life_info (blocks, extent, prop_f
*** 677,684 ****
| PROP_KILL_DEAD_CODE));
}
! if (! changed || ! cleanup_cfg (CLEANUP_EXPENSIVE))
break;
}
/* If asked, remove notes from the blocks we'll update. */
--- 677,690 ----
| PROP_KILL_DEAD_CODE));
}
! if (! changed)
break;
+
+ /* We repeat regardless of what cleanup_cfg says. If there were
+ instructions deleted above, that might have been only a
+ partial improvement (see MAX_MEM_SET_LIST_LEN usage).
+ Further improvement may be possible. */
+ cleanup_cfg (CLEANUP_EXPENSIVE);
}
/* If asked, remove notes from the blocks we'll update. */
*************** update_life_info (blocks, extent, prop_f
*** 696,703 ****
{
basic_block bb = BASIC_BLOCK (i);
COPY_REG_SET (tmp, bb->global_live_at_end);
! propagate_block (bb, tmp, NULL, NULL, prop_flags);
if (extent == UPDATE_LIFE_LOCAL)
verify_local_live_at_start (tmp, bb);
--- 702,712 ----
{
basic_block bb = BASIC_BLOCK (i);
+ /* See below about the masking out of flags. */
COPY_REG_SET (tmp, bb->global_live_at_end);
! propagate_block (bb, tmp, NULL, NULL,
! prop_flags & ~(PROP_SCAN_DEAD_CODE
! | PROP_KILL_DEAD_CODE));
if (extent == UPDATE_LIFE_LOCAL)
verify_local_live_at_start (tmp, bb);
*************** update_life_info (blocks, extent, prop_f
*** 710,716 ****
basic_block bb = BASIC_BLOCK (i);
COPY_REG_SET (tmp, bb->global_live_at_end);
! propagate_block (bb, tmp, NULL, NULL, prop_flags);
if (extent == UPDATE_LIFE_LOCAL)
verify_local_live_at_start (tmp, bb);
--- 719,732 ----
basic_block bb = BASIC_BLOCK (i);
COPY_REG_SET (tmp, bb->global_live_at_end);
!
! /* Don't pass PROP_SCAN_DEAD_CODE or PROP_KILL_DEAD_CODE here,
! since removing or pretending to remove dead code can affect
! global register liveness, which is supposed to be finalized
! for this call at this point. */
! propagate_block (bb, tmp, NULL, NULL,
! prop_flags & ~(PROP_SCAN_DEAD_CODE
! | PROP_KILL_DEAD_CODE));
if (extent == UPDATE_LIFE_LOCAL)
verify_local_live_at_start (tmp, bb);
brgds, H-P
More information about the Gcc-patches
mailing list