This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Patch to improve flow dead code removal
- To: gcc-patches at gcc dot gnu dot org
- Subject: Patch to improve flow dead code removal
- From: John Wehle <john at feith dot com>
- Date: Wed, 25 Jul 2001 17:40:00 -0400 (EDT)
Currently dead code removal doesn't realize that it can cause
nop conditional jumps which if removed allow the CFG to be
further simplified and more dead code to be removed.
The patch passes make bootstrap and check on i386-unknown-solaris2.7.
It also passes make and check on powerpc-eabisim.
ChangeLog:
Thu Jul 12 14:38:01 EDT 2001 John Wehle (john@feith.com)
* basic-block.h (PROP_ALLOW_CFG_CHANGES): Define.
(PROP_FINAL): Include PROP_ALLOW_CFG_CHANGES.
(propagate_block): Update prototype.
* flow.c (update_life_info): Simplify the CFG and
recalculate the global regs which are alive when
removing dead code during a global update.
(propagate_block): Return non-zero if an INSN is
deleted.
Enjoy!
-- John Wehle
------------------8<------------------------8<------------------------
*** gcc/basic-block.h.ORIGINAL Tue Jul 17 17:59:51 2001
--- gcc/basic-block.h Fri Jul 20 23:08:13 2001
*************** enum update_life_extent
*** 532,539 ****
#define PROP_REG_INFO 4 /* Update regs_ever_live et al. */
#define PROP_KILL_DEAD_CODE 8 /* Remove dead code. */
#define PROP_SCAN_DEAD_CODE 16 /* Scan for dead code. */
! #define PROP_AUTOINC 32 /* Create autoinc mem references. */
! #define PROP_FINAL 63 /* All of the above. */
#define CLEANUP_EXPENSIVE 1 /* Do relativly expensive optimizations
except for edge forwarding */
--- 532,541 ----
#define PROP_REG_INFO 4 /* Update regs_ever_live et al. */
#define PROP_KILL_DEAD_CODE 8 /* Remove dead code. */
#define PROP_SCAN_DEAD_CODE 16 /* Scan for dead code. */
! #define PROP_ALLOW_CFG_CHANGES 32 /* Allow the CFG to be changed
! by dead code removal. */
! #define PROP_AUTOINC 64 /* Create autoinc mem references. */
! #define PROP_FINAL 127 /* All of the above. */
#define CLEANUP_EXPENSIVE 1 /* Do relativly expensive optimizations
except for edge forwarding */
*************** extern void life_analysis PARAMS ((rtx,
*** 556,562 ****
extern void update_life_info PARAMS ((sbitmap, enum update_life_extent,
int));
extern int count_or_remove_death_notes PARAMS ((sbitmap, int));
! extern void propagate_block PARAMS ((basic_block, regset, regset, regset,
int));
struct propagate_block_info;
--- 558,564 ----
extern void update_life_info PARAMS ((sbitmap, enum update_life_extent,
int));
extern int count_or_remove_death_notes PARAMS ((sbitmap, int));
! extern int propagate_block PARAMS ((basic_block, regset, regset, regset,
int));
struct propagate_block_info;
*** gcc/flow.c.ORIGINAL Wed Jul 18 18:47:58 2001
--- gcc/flow.c Fri Jul 20 23:08:13 2001
*************** update_life_info (blocks, extent, prop_f
*** 4106,4116 ****
tmp = INITIALIZE_REG_SET (tmp_head);
/* For a global update, we go through the relaxation process again. */
if (extent != UPDATE_LIFE_LOCAL)
{
! calculate_global_regs_live (blocks, blocks,
! prop_flags & PROP_SCAN_DEAD_CODE);
/* If asked, remove notes from the blocks we'll update. */
if (extent == UPDATE_LIFE_GLOBAL_RM_NOTES)
--- 4106,4150 ----
tmp = INITIALIZE_REG_SET (tmp_head);
+ /* Changes to the CFG are only allowed when
+ doing a global update for the entire CFG. */
+ if ((prop_flags & PROP_ALLOW_CFG_CHANGES)
+ && (extent == UPDATE_LIFE_LOCAL || blocks))
+ abort ();
+
/* For a global update, we go through the relaxation process again. */
if (extent != UPDATE_LIFE_LOCAL)
{
! for ( ; ; )
! {
! int changed = 0;
!
! calculate_global_regs_live (blocks, blocks,
! prop_flags & (PROP_SCAN_DEAD_CODE
! | PROP_ALLOW_CFG_CHANGES));
!
! if ((prop_flags & (PROP_KILL_DEAD_CODE | PROP_ALLOW_CFG_CHANGES))
! != (PROP_KILL_DEAD_CODE | PROP_ALLOW_CFG_CHANGES))
! break;
!
! /* Removing dead code may allow the CFG to be simplified which
! in turn may allow for further dead code detection / removal. */
! for (i = n_basic_blocks - 1; i >= 0; --i)
! {
! basic_block bb = BASIC_BLOCK (i);
!
! COPY_REG_SET (tmp, bb->global_live_at_end);
! changed |= propagate_block (bb, tmp, NULL, NULL,
! prop_flags & (PROP_SCAN_DEAD_CODE
! | PROP_KILL_DEAD_CODE));
! }
!
! if (! changed || ! try_optimize_cfg (CLEANUP_EXPENSIVE))
! break;
!
! delete_unreachable_blocks ();
! mark_critical_edges ();
! }
/* If asked, remove notes from the blocks we'll update. */
if (extent == UPDATE_LIFE_GLOBAL_RM_NOTES)
*************** free_propagate_block_info (pbi)
*** 5264,5272 ****
and cleared in COND_LOCAL_SET.
It is valid for LOCAL_SET and COND_LOCAL_SET to be the same set. In this
case, the resulting set will be equal to the union of the two sets that
! would otherwise be computed. */
! void
propagate_block (bb, live, local_set, cond_local_set, flags)
basic_block bb;
regset live;
--- 5298,5308 ----
and cleared in COND_LOCAL_SET.
It is valid for LOCAL_SET and COND_LOCAL_SET to be the same set. In this
case, the resulting set will be equal to the union of the two sets that
! would otherwise be computed.
! Return non-zero if an INSN is deleted (i.e. by dead code removal). */
!
! int
propagate_block (bb, live, local_set, cond_local_set, flags)
basic_block bb;
regset live;
*************** propagate_block (bb, live, local_set, co
*** 5276,5281 ****
--- 5312,5318 ----
{
struct propagate_block_info *pbi;
rtx insn, prev;
+ int changed;
pbi = init_propagate_block_info (bb, live, local_set, cond_local_set, flags);
*************** propagate_block (bb, live, local_set, co
*** 5291,5296 ****
--- 5328,5334 ----
/* Scan the block an insn at a time from end to beginning. */
+ changed = 0;
for (insn = bb->end;; insn = prev)
{
/* If this is a call to `setjmp' et al, warn if any
*************** propagate_block (bb, live, local_set, co
*** 5301,5312 ****
--- 5339,5353 ----
IOR_REG_SET (regs_live_at_setjmp, pbi->reg_live);
prev = propagate_one_insn (pbi, insn);
+ changed |= NEXT_INSN (prev) != insn;
if (insn == bb->head)
break;
}
free_propagate_block_info (pbi);
+
+ return changed;
}
/* Return 1 if X (the body of an insn, or part of it) is just dead stores
-------------------------------------------------------------------------
| Feith Systems | Voice: 1-215-646-8000 | Email: john@feith.com |
| John Wehle | Fax: 1-215-540-5495 | |
-------------------------------------------------------------------------