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]
Other format: [Raw text]

[ tree-ssa] Eliminate more GOTO_EXPRs


I finally got around to dusting off the second part of my code to
eliminate useless gotos.

This patch allows us to identify and eliminate a goto to the next statement
when the next statement is at a higher level in the control nest.

ie, given something like this:

;; Function foo (foo)
        
foo ()
{
  void x = <<< error >>>;
  
  {     
    goto x;
  };
  x:;
}


We can easily see that once linearized the GOTO and its target label
will be consecutive in the instruction stream and the goto itself can
simply be removed.  This kind of thing happens all the time in our code.
The vast majority of the time the target label is an unnamed label and
removal of the goto will also likely allow us to remove the label
(once we're tracking label uses).

Note I don't expect this to really change the code we generate -- it's
more a matter of cleaning up the stuff we pass to the expanders so that
we don't have to expand more nodes than are really necessary.

[ I also noticed some minor sillyness in make_loop_expr_blocks that I
  went ahead and fixed.  Specifically we never use the passed in
  next_block_link value, so we might as well not pass it in to begin with.  ]

	* tree-cfg.c (make_loop_expr_blocks): Do not accept next_block_link
	as an argument, make it a local variable.  Callers changed.

	* tree-cfg.c (remove_useless_stmts_and_empty_vars): Eliminate
	GOTO_EXPRs which jump to the next statement occuring in an 
	outer control/block structure nest.

Index: tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-cfg.c,v
retrieving revision 1.1.4.92
diff -c -3 -p -r1.1.4.92 tree-cfg.c
*** tree-cfg.c	16 May 2003 15:55:31 -0000	1.1.4.92
--- tree-cfg.c	20 May 2003 18:27:06 -0000
*************** static void make_cond_expr_blocks	PARAMS
*** 82,88 ****
  static void make_catch_expr_blocks	PARAMS ((tree *, tree, basic_block));
  static void make_eh_filter_expr_blocks	PARAMS ((tree *, tree, basic_block));
  static void make_try_expr_blocks	PARAMS ((tree *, tree, basic_block));
! static void make_loop_expr_blocks	PARAMS ((tree *, tree, basic_block));
  static void make_switch_expr_blocks	PARAMS ((tree *, tree, basic_block));
  static basic_block make_bind_expr_blocks PARAMS ((tree *, tree, basic_block,
  						  tree));
--- 82,88 ----
  static void make_catch_expr_blocks	PARAMS ((tree *, tree, basic_block));
  static void make_eh_filter_expr_blocks	PARAMS ((tree *, tree, basic_block));
  static void make_try_expr_blocks	PARAMS ((tree *, tree, basic_block));
! static void make_loop_expr_blocks	PARAMS ((tree *, basic_block));
  static void make_switch_expr_blocks	PARAMS ((tree *, tree, basic_block));
  static basic_block make_bind_expr_blocks PARAMS ((tree *, tree, basic_block,
  						  tree));
*************** make_blocks (first_p, next_block_link, p
*** 325,331 ****
        append_stmt_to_bb (stmt_p, bb, parent_stmt);
  
        if (code == LOOP_EXPR)
! 	make_loop_expr_blocks (stmt_p, next_block_link, bb);
        else if (code == COND_EXPR)
  	make_cond_expr_blocks (stmt_p, next_block_link, bb);
        else if (code == SWITCH_EXPR)
--- 325,331 ----
        append_stmt_to_bb (stmt_p, bb, parent_stmt);
  
        if (code == LOOP_EXPR)
! 	make_loop_expr_blocks (stmt_p, bb);
        else if (code == COND_EXPR)
  	make_cond_expr_blocks (stmt_p, next_block_link, bb);
        else if (code == SWITCH_EXPR)
*************** make_blocks (first_p, next_block_link, p
*** 431,443 ****
     ENTRY is the block whose last statement is *LOOP_P.  */
  
  static void
! make_loop_expr_blocks (loop_p, next_block_link, entry)
       tree *loop_p;
-      tree next_block_link;
       basic_block entry;
  {
    tree_stmt_iterator si;
    tree loop = *loop_p;
    
    entry->flags |= BB_CONTROL_EXPR | BB_LOOP_CONTROL_EXPR;
  
--- 431,443 ----
     ENTRY is the block whose last statement is *LOOP_P.  */
  
  static void
! make_loop_expr_blocks (loop_p, entry)
       tree *loop_p;
       basic_block entry;
  {
    tree_stmt_iterator si;
    tree loop = *loop_p;
+   tree next_block_link;
    
    entry->flags |= BB_CONTROL_EXPR | BB_LOOP_CONTROL_EXPR;
  
*************** remove_useless_stmts_and_vars (first_p)
*** 1534,1544 ****
  	{
  	  tree_stmt_iterator tsi = i;
  
! 	  /* We can remove a GOTO_EXPR if the next tree statement is
! 	     the destination of the GOTO_EXPR.  */
  	  tsi_next (&tsi);
  	  if (! tsi_end_p (tsi))
  	    {
  	      tree label;
  
  	      label = tsi_stmt (tsi);
--- 1534,1546 ----
  	{
  	  tree_stmt_iterator tsi = i;
  
! 	  /* Step past the GOTO_EXPR statement.  */
  	  tsi_next (&tsi);
  	  if (! tsi_end_p (tsi))
  	    {
+ 	      /* If we are not at the end of this tree, then see if
+ 		 we are at the target label.  If so, then this jump
+ 		 is not needed.  */
  	      tree label;
  
  	      label = tsi_stmt (tsi);
*************** remove_useless_stmts_and_vars (first_p)
*** 1548,1553 ****
--- 1550,1580 ----
  		  repeat = 1;
  		  *stmt_p = build_empty_stmt ();
  		}
+ 	    }
+ 	  else
+ 	    {
+ 	      /* We are at the end of this tree, we may still have
+ 		 an unnecessary GOTO_EXPR if NEXT_BLOCK_LINK
+ 		 points to the target label.  */
+ 	      tree next_block_link = NEXT_BLOCK_LINK (*stmt_p);
+ 
+ 	      if (next_block_link)
+ 		{
+ 		  tree next_stmt;
+ 
+ 		  /* Get the statement at NEXT_BLOCK_LINK and see if it
+ 		     is our target label.  */
+ 		  next_stmt = tsi_stmt (tsi_start (&next_block_link));
+ 		  if (next_stmt
+ 		      && TREE_CODE (next_stmt) == LABEL_EXPR
+ 		      && (LABEL_EXPR_LABEL (next_stmt)
+ 			  == GOTO_DESTINATION (*stmt_p)))
+ 		    {
+ 		      repeat = 1;
+ 		      *stmt_p = build_empty_stmt ();
+ 		    }
+ 		}
+ 	      
  	    }
  	}
  







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