This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Patch to improve flow dead code removal


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  |                         |
-------------------------------------------------------------------------


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]