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] More EH CFG cleanups


Whee.  It's taken a while, but here's the next EH CFG cleanup patch.

It's sole purpose is to remove unnecessary edges in the TRY block of
TRY_FINALLY_EXPRs.

To recap, for each edge which exits the TRY block of a TRY_FINALLY_EXPR
we create two new edges; one connects the TRY block to the start of the
FINALLY block the other connects the end of the FINALLY block to the
destination of the edge which exits the TRY block.

That's all fine and good, except that we never deleted the original edge
which exited the TRY block :-)

This patch eliminates those unwanted edges and fixes a couple latent bugs
exposed by removing those edges.

It should be a small, but measurable compile-time improvement for C++ code.
[ It used to give a much nicer improvement, but Diego's aliasing changes
  have largely subsumed the performance improvements I was seeing with 
  earlier versions of this patch. ]

This has (of course) been through the usual battery of tests on 
i686-pc-linux-gnu.


	* tree-cfg.c (make_edges): Remove fake edges before building
	extra edges for TRY_FINALLY_EXPRs.  Delete unnecessary edges
	leaving the TRY block in a TRY_FINALLY_EXPR.
	(find_contained_blocks): Don't consider statements in the CATCH
	clause of a TRY_CATCH_EXPR when noting the last statement in
	the block.
	* tree-dfa.c (remove_phi_arg): If we removed the last PHI argument,
	then remove the entire PHI node.
	* tree-ssa-dce.c (stmt_useful_p): Consider the other EH related
	nodes useful as well (TRY_FINALLY_EXPR, TRY_CATCH_EXPR, and
	EH_FILTER_EXPR).

Index: tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-cfg.c,v
retrieving revision 1.1.4.118
diff -c -3 -p -r1.1.4.118 tree-cfg.c
*** tree-cfg.c	24 Jun 2003 17:15:49 -0000	1.1.4.118
--- tree-cfg.c	25 Jun 2003 00:48:26 -0000
*************** static void
*** 831,837 ****
  make_edges (void)
  {
    basic_block bb;
!   unsigned int i;
  
    VARRAY_TREE_INIT (try_finallys, 10, "try finally block stack");
  
--- 831,837 ----
  make_edges (void)
  {
    basic_block bb;
!   int i;
  
    VARRAY_TREE_INIT (try_finallys, 10, "try finally block stack");
  
*************** make_edges (void)
*** 868,873 ****
--- 868,877 ----
  	make_edge (bb, successor_block (bb), 0);
      }
  
+   /* We do not care about fake edges, so remove any that the CFG
+      builder inserted for completeness.  */
+   remove_fake_edges ();
+ 
    /* Now go back to each TRY_FINALLY_EXPR and add the required special
       edges.
  
*************** make_edges (void)
*** 885,891 ****
       Also note this is overly conservative, many of the edges from the
       TRY to the FINALLY should be normal edges.  Similarly for the
       edges from the FINALLY to the TRY's original destination.  */
!   for (i = 0; i < VARRAY_ACTIVE_SIZE (try_finallys); i++)
      {
        tree try_finally = VARRAY_TREE (try_finallys, i);
        tree *finally_p = &TREE_OPERAND (try_finally, 1);
--- 889,895 ----
       Also note this is overly conservative, many of the edges from the
       TRY to the FINALLY should be normal edges.  Similarly for the
       edges from the FINALLY to the TRY's original destination.  */
!   for (i = VARRAY_ACTIVE_SIZE (try_finallys) - 1; i >= 0; i--)
      {
        tree try_finally = VARRAY_TREE (try_finallys, i);
        tree *finally_p = &TREE_OPERAND (try_finally, 1);
*************** make_edges (void)
*** 934,939 ****
--- 938,949 ----
  		       block.  */
  		    if (e->dest != finally_bb)
  		      make_edge (last_bb, e->dest, EDGE_ABNORMAL);
+ 
+ 		    /* If this is not one of the blocks we just
+ 		       created, then it can be removed it can never
+ 		       be executed.  */
+ 		    if (e->dest != finally_bb && e->src != last_bb)
+ 		      remove_edge (e);
  		  }
  	    });
  	}
*************** make_edges (void)
*** 943,952 ****
  
    try_finallys = NULL;
  
-   /* We do not care about fake edges, so remove any that the CFG
-      builder inserted for completeness.  */
-   remove_fake_edges ();
- 
    /* Clean up the graph and warn for unreachable code.  */
    cleanup_tree_cfg ();
  }
--- 953,958 ----
*************** find_contained_blocks (tree *stmt_p, bit
*** 998,1005 ****
  	{
  	  find_contained_blocks (&EH_FILTER_FAILURE (stmt), my_blocks, last_p);
  	}
!       else if (code == TRY_CATCH_EXPR
! 	       || code == TRY_FINALLY_EXPR
  	       || code == COMPOUND_EXPR)
  	{
  	  find_contained_blocks (&TREE_OPERAND (stmt, 0), my_blocks, last_p);
--- 1004,1027 ----
  	{
  	  find_contained_blocks (&EH_FILTER_FAILURE (stmt), my_blocks, last_p);
  	}
!       else if (code == TRY_CATCH_EXPR)
! 	{
! 	  tree *save_last_p;
! 	  find_contained_blocks (&TREE_OPERAND (stmt, 0), my_blocks, last_p);
! 
! 	  /* We do not want to include statements in the CATCH block
! 	     when determining the last executed statement.  FIXME,
! 	     what would probably work better would be a to include
! 	     an empty block at the end of each FINALLY block and
! 	     use it as the last statement.
! 
! 	     I worry that we do the wrong thing with ELSE clauses,
! 	     and other control structures.  */
! 	  save_last_p = *last_p;
! 	  find_contained_blocks (&TREE_OPERAND (stmt, 1), my_blocks, last_p);
! 	  *last_p = save_last_p;
! 	}
!       else if (code == TRY_FINALLY_EXPR
  	       || code == COMPOUND_EXPR)
  	{
  	  find_contained_blocks (&TREE_OPERAND (stmt, 0), my_blocks, last_p);
Index: tree-dfa.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-dfa.c,v
retrieving revision 1.1.4.122
diff -c -3 -p -r1.1.4.122 tree-dfa.c
*** tree-dfa.c	24 Jun 2003 02:13:57 -0000	1.1.4.122
--- tree-dfa.c	25 Jun 2003 00:48:29 -0000
*************** remove_phi_arg (tree phi, basic_block bl
*** 823,828 ****
--- 823,834 ----
        if (src_bb == block)
  	{
  	  remove_phi_arg_num (phi, i);
+ 
+ 	  /* If we removed the last PHI argument, then go ahead and
+ 	     remove the PHI node.  */
+ 	  if (PHI_NUM_ARGS (phi) == 0)
+ 	    remove_phi_node (phi, NULL, bb_for_stmt (phi));
+ 
  	  return;
  	}
      }
Index: tree-ssa-dce.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-ssa-dce.c,v
retrieving revision 1.1.2.43
diff -c -3 -p -r1.1.2.43 tree-ssa-dce.c
*** tree-ssa-dce.c	16 Jun 2003 18:54:00 -0000	1.1.2.43
--- tree-ssa-dce.c	25 Jun 2003 00:48:29 -0000
*************** stmt_useful_p (tree stmt)
*** 275,280 ****
--- 275,283 ----
        || (TREE_CODE (stmt) == CALL_EXPR)
        || ((TREE_CODE (stmt) == MODIFY_EXPR)
  	  && (TREE_CODE (TREE_OPERAND (stmt, 1)) == CALL_EXPR))
+       || (TREE_CODE (stmt) == TRY_CATCH_EXPR)
+       || (TREE_CODE (stmt) == TRY_FINALLY_EXPR)
+       || (TREE_CODE (stmt) == EH_FILTER_EXPR)
        || (TREE_CODE (stmt) == CATCH_EXPR))
      return true;
  






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