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] TRY_FINALLY vs CFG


While looking at a C++ problem yesterday, I noticed that the CFG had loops
in the FINALLY block of TRY_FINALLY constructs.  Going back to the source
showed no loops (of course).

The problem was how we add edges from the FINALLY block to the original
destinations of the TRY block.  If the TRY block reached the start of the
FINALLY block, then we'd create a loop in the FINALLY block.

At the same time I also noticed some easily factorable code in the
same area.

This patch fixes both problems.  It may marginally improve compile times
or runtimes for C++ code -- I haven't bothered trying to measure.


	* tree-cfg.c (make_edges): Factor out loop invariants from
	code to insert edges from the TRY to the FINALLY block.
	Avoid creating unnecessary edges from the end of the
	FINALLY block back to the start of the FINALLY block.
	
Index: tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-cfg.c,v
retrieving revision 1.1.4.89
diff -c -3 -p -r1.1.4.89 tree-cfg.c
*** tree-cfg.c	13 May 2003 19:35:47 -0000	1.1.4.89
--- tree-cfg.c	15 May 2003 13:29:21 -0000
*************** make_edges ()
*** 845,850 ****
--- 845,852 ----
    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);
+       basic_block finally_bb = first_exec_block (finally_p);
        tree *finally_last_p;
        basic_block last_bb;
        int bb;
*************** make_edges ()
*** 861,887 ****
  					      try_targets,
  					      &finally_last_p);
  
!       /* Examine each basic block within the TRY block.  */
!       EXECUTE_IF_SET_IN_BITMAP (try_blocks, 0, bb,
  	{
! 	  edge e;
! 
! 	  /* Look at each outgoing edge from the block.  */
! 	  for (e = BASIC_BLOCK (bb)->succ; e; e = e->succ_next)
  	    {
! 	      /* If the destination of this edge is not inside the
! 		 TRY block, then wire up an edge from this block to
! 		 the FINALLY block.  */
! 	      if (! bitmap_bit_p (try_blocks, e->dest->index))
! 	        {
! 		  tree *finally_p = &TREE_OPERAND (try_finally, 1);
! 		  basic_block finally_bb = first_exec_block (finally_p);
! 
! 		  if (finally_bb)
! 		    make_edge (BASIC_BLOCK (bb), finally_bb, EDGE_ABNORMAL);
! 		}
! 	    }
! 	});
  
        /* We need to know the last statement in the FINALLY so that
  	 we know where to wire up the additional outgoing edges from
--- 863,885 ----
  					      try_targets,
  					      &finally_last_p);
  
!       /* If the FINALLY is not empty, then we'll need to create some more
! 	 edges.  */
!       if (finally_bb)
  	{
! 	  /* Examine each basic block within the TRY block.  */
! 	  EXECUTE_IF_SET_IN_BITMAP (try_blocks, 0, bb,
  	    {
! 	      edge e;
! 
! 	      /* Look at each outgoing edge from the block, if the
! 		 destination of the edge is not inside the TRY block,
! 		 then wire up an edge from this block to the FINALLY block.  */
! 	      for (e = BASIC_BLOCK (bb)->succ; e; e = e->succ_next)
! 		if (! bitmap_bit_p (try_blocks, e->dest->index))
! 		  make_edge (BASIC_BLOCK (bb), finally_bb, EDGE_ABNORMAL);
! 	    });
! 	}
  
        /* We need to know the last statement in the FINALLY so that
  	 we know where to wire up the additional outgoing edges from
*************** make_edges ()
*** 900,909 ****
        if (last_bb)
  	EXECUTE_IF_AND_COMPL_IN_BITMAP (try_targets, try_blocks, 0, bb,
  	  {
! 	    basic_block b;
  
! 	    b = (bb == last_basic_block ? EXIT_BLOCK_PTR : BASIC_BLOCK (bb));
! 	    make_edge (last_bb, b, EDGE_ABNORMAL);
  	  });
  
        BITMAP_XFREE (dummy_bitmap);
--- 898,913 ----
        if (last_bb)
  	EXECUTE_IF_AND_COMPL_IN_BITMAP (try_targets, try_blocks, 0, bb,
  	  {
! 	    basic_block b
! 	      = (bb == last_basic_block ? EXIT_BLOCK_PTR : BASIC_BLOCK (bb));
  
! 	    /* Ignore original edges from the TRY block to the start of the
! 	       FINALLY block.  Failure to do so will create an unnecessary
! 	       loop within the FINALLY block since we create an edge from
! 	       the end of the FINALLY to the target of edges out of the
! 	       TRY block (ie the start of the FINALLY).  */
! 	    if (b->index != finally_bb->index)
! 	      make_edge (last_bb, b, EDGE_ABNORMAL);
  	  });
  
        BITMAP_XFREE (dummy_bitmap);






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