This is the mail archive of the gcc@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]
Other format: [Raw text]

[tree-ssa] Improve eliminate_useless_stmts_and_vars [Was Re: Dead-code elimination can't remove string copy insns? ]


In message <20030513170722.GA7112@tornado.toronto.redhat.com>, Diego Novillo wr
ites:
 >On Tue, May 13, 2003 at 09:40:33AM -0700, Zack Weinberg wrote:
 >
 >> gcc.dg/const-elim-1.c.  On an x86, compile it with -march=i386 -O2;
 >> rs6000-ibm-aix5 and arm-elf also show the problem.
 >> 
 >Yup, tree-ssa handles it.  The original program in GIMPLE form is
 >on the left.  The optimized version is on the right (we still
 >don't linearize GOTO_EXPRs).
Here's the patch to allow us to eliminate the unnecessary GOTOs in
const-elim-1.c.

	* tree-cfg.c (cleanup_tree_cfg): Update comments.   Set repeat
	anytime we remove a control structure.

Index: tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-cfg.c,v
retrieving revision 1.1.4.88
diff -c -3 -p -r1.1.4.88 tree-cfg.c
*** tree-cfg.c	13 May 2003 02:16:38 -0000	1.1.4.88
--- tree-cfg.c	13 May 2003 18:36:20 -0000
*************** cleanup_tree_cfg ()
*** 1382,1395 ****
  
       * Empty statement nodes are removed
  
       * Some unnecessary BIND_EXPRs are removed
  
     Clearly more work could be done.  The trick is doing the analysis
     and removal fast enough to be a net improvement in compile times. 
  
     Note that when we remove a control structure such as a COND_EXPR
!    or BIND_EXPR, we will need to repeat this optimization pass to
!    ensure we eliminate all the useless code.  */
    
  int
  remove_useless_stmts_and_vars (first_p)
--- 1382,1399 ----
  
       * Empty statement nodes are removed
  
+      * Unnecessary TRY_FINALLY and TRY_CATCH blocks are removed
+ 
+      * Unnecessary COND_EXPRs are removed
+ 
       * Some unnecessary BIND_EXPRs are removed
  
     Clearly more work could be done.  The trick is doing the analysis
     and removal fast enough to be a net improvement in compile times. 
  
     Note that when we remove a control structure such as a COND_EXPR
!    BIND_EXPR, or TRY block, we will need to repeat this optimization pass
!    to ensure we eliminate all the useless code.  */
    
  int
  remove_useless_stmts_and_vars (first_p)
*************** remove_useless_stmts_and_vars (first_p)
*** 1436,1451 ****
  	     label in one arm.  If the label has since become unreachable
  	     then we may be able to zap the entire conditional here.
  
! 	     If this causes us to replace the COND_EXPR with an
! 	     empty statement, then we will need to repeat this pass.  */
  	  if (integer_nonzerop (cond) && IS_EMPTY_STMT (else_clause))
! 	    *stmt_p = then_clause;
  	  if (integer_zerop (cond) && IS_EMPTY_STMT (then_clause))
! 	    *stmt_p = else_clause;
! 
! 	  /* This can happen if both arms were ultimately empty.  */
! 	  if (IS_EMPTY_STMT (*stmt_p))
! 	    repeat = 1;
  	}
        else if (code == SWITCH_EXPR)
  	repeat |= remove_useless_stmts_and_vars (&SWITCH_BODY (*stmt_p));
--- 1440,1457 ----
  	     label in one arm.  If the label has since become unreachable
  	     then we may be able to zap the entire conditional here.
  
! 	     If so, replace the COND_EXPR and set up to repeat this
! 	     optimization pass.  */
  	  if (integer_nonzerop (cond) && IS_EMPTY_STMT (else_clause))
! 	    {
! 	      *stmt_p = then_clause;
! 	       repeat = 1;
! 	    }
  	  if (integer_zerop (cond) && IS_EMPTY_STMT (then_clause))
! 	    {
! 	      *stmt_p = else_clause;
! 	       repeat = 1;
! 	    }
  	}
        else if (code == SWITCH_EXPR)
  	repeat |= remove_useless_stmts_and_vars (&SWITCH_BODY (*stmt_p));
*************** remove_useless_stmts_and_vars (first_p)
*** 1463,1479 ****
                                                                                  
  	     If the body of a TRY_CATCH is empty and the handler is
  	     empty (it had no reachable code either), then we can
! 	     emit an empty statement without the enclosing TRY_CATCH.  */
  	  if (IS_EMPTY_STMT (TREE_OPERAND (*stmt_p, 0)))
  	    {
  	      if (code == TRY_FINALLY_EXPR
  		  || IS_EMPTY_STMT (TREE_OPERAND (*stmt_p, 1)))
! 		*stmt_p = TREE_OPERAND (*stmt_p, 1);
! 
! 	      /* If we replaced this statement with an empty statement,
! 		 then we'll need to repeat this optimization.  */
! 	      if (IS_EMPTY_STMT (*stmt_p))
! 		repeat = 1;
  	    }
  	}
        else if (code == BIND_EXPR)
--- 1469,1486 ----
                                                                                  
  	     If the body of a TRY_CATCH is empty and the handler is
  	     empty (it had no reachable code either), then we can
! 	     emit an empty statement without the enclosing TRY_CATCH.
! 
! 	     In both cases we want to apply this optimization pass
! 	     again.  */
  	  if (IS_EMPTY_STMT (TREE_OPERAND (*stmt_p, 0)))
  	    {
  	      if (code == TRY_FINALLY_EXPR
  		  || IS_EMPTY_STMT (TREE_OPERAND (*stmt_p, 1)))
! 		{
! 		  *stmt_p = TREE_OPERAND (*stmt_p, 1);
! 		  repeat = 1;
! 		}
  	    }
  	}
        else if (code == BIND_EXPR)
*************** remove_useless_stmts_and_vars (first_p)
*** 1485,1491 ****
  	  /* If the BIND_EXPR has no variables, then we can pull everything
  	     up one level and remove the BIND_EXPR, unless this is the
  	     toplevel BIND_EXPR for the current function or an inlined
! 	     function.  */
  	  block = BIND_EXPR_BLOCK (*stmt_p);
    	  if (BIND_EXPR_VARS (*stmt_p) == NULL_TREE
  	      && *stmt_p != DECL_SAVED_TREE (current_function_decl)
--- 1492,1501 ----
  	  /* If the BIND_EXPR has no variables, then we can pull everything
  	     up one level and remove the BIND_EXPR, unless this is the
  	     toplevel BIND_EXPR for the current function or an inlined
! 	     function. 
! 
! 	     When this situation occurs we will want to apply this
! 	     optimization again.  */
  	  block = BIND_EXPR_BLOCK (*stmt_p);
    	  if (BIND_EXPR_VARS (*stmt_p) == NULL_TREE
  	      && *stmt_p != DECL_SAVED_TREE (current_function_decl)
*************** remove_useless_stmts_and_vars (first_p)
*** 1493,1505 ****
  		  || ! BLOCK_ABSTRACT_ORIGIN (block)
  		  || (TREE_CODE (BLOCK_ABSTRACT_ORIGIN (block))
  		      != FUNCTION_DECL)))
! 	    *stmt_p = BIND_EXPR_BODY (*stmt_p);
! 
! 	  /* If we removed the BIND_EXPR completely and were left with
! 	     an empty statement, then we'll need to repeat this
! 	     optimization.  */
! 	  if (IS_EMPTY_STMT (*stmt_p))
! 	    repeat = 1;
  	}
        else if (code == GOTO_EXPR)
  	{
--- 1503,1512 ----
  		  || ! BLOCK_ABSTRACT_ORIGIN (block)
  		  || (TREE_CODE (BLOCK_ABSTRACT_ORIGIN (block))
  		      != FUNCTION_DECL)))
! 	    {
! 	      *stmt_p = BIND_EXPR_BODY (*stmt_p);
! 	      repeat = 1;
! 	    }
  	}
        else if (code == GOTO_EXPR)
  	{



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