When a register is set outside of a loop and referenced inside, update_life_info can't figure out that the set is dead because the loop appears to still use the register according to the lifeness information which is propagated circularily around the loop. delete_trivially_dead_insns can detect that such sets are dead, and thus remove them. However, it does not update the liveness information. This leads to a checking ICE when doing the next global update. The gcc 3.2 version of this patch (short version) for this problem looks like this: 2004-05-17 J"orn Rennecke <joern.rennecke@superh.com> * cse.c (basic-block.h): #include. (trivially_dead_nonlocal_regs): New variable. (note_dead_set): New function. (delete_trivially_dead_insns): If life info is available, update it. The patch in its current form is conceptually dependent on the patch for gcc/18992 being applied first and also has some bits to support highpart liveness information optimizations. It is about 100 lines of unidiff. If someone is prepared to review the patch, I can extract an independent patch against the then-current mainline.
Test case??? There are many other problems with delete_trivially_dead_insns, unsurprisingly, so maybe the whole thing should be revisited and reconsidered :-/
Subject: Re: delete_trivially_dead_insns fails to update the liveness information steven at gcc dot gnu dot org wrote: >------- Additional Comments From steven at gcc dot gnu dot org 2005-01-15 12:29 ------- >Test case??? > I had a test case for this, but this wouldn't reproduce the problem on mainline because most of the functionality of delete_trivially_dead_insns has been disabled by a clumsy patch; see PR 18992 . > >There are many other problems with delete_trivially_dead_insns, unsurprisingly, >so maybe the whole thing should be revisited and reconsidered :-/ > What other problems are there with delete_trivially_dead_insns? As far as I am aware, delete_trivially_dead_insns only needed maitenance when the semantics of the rtl was changed (e.g. adding exceptions), it was called in new contexts (e.g. after flow), or a previous modification wasn't (quite) right / sufficient. In terms of time and code complexity versus optimization result, I think delete_trivially_dead_insns compares quite favourably with running a full data flow and dead code elimination pass.
A patch is here: http://gcc.gnu.org/ml/gcc-patches/2004-06/msg00774.html The size of this patch can also be reduced by setting update_live_p in delete_trivially_dead_insns like this: bool update_life_p = EXIT_BLOCK_PTR->global_live_at_start != NULL;
There will be no more delete_trivially_dead_insns when the dataflow branch is merged.
delete_trivially_dead_insns is gone now that the dataflow branch has been merged in. So closing as won't fix.