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] Fix tree-cfg.c latent bug


Some pending work exposed a problem with our implementation of
move_outgoing_edges (which is used when linearizing COND_EXPRs).

Specifically  if the THEN and ELSE arms of the COND_EXPR have a
common destination which has a PHI node, then we can end up with 
a PHI node with a NULL edge argument.  This in turn causes the
out-of-ssa pass some grief.

Luckily the fix is pretty simple.  In the case where make_edge returns
NULL, we merely delete the original edge form the THEN/ELSE block as
we already have an edge from the COND_EXPR to the target block.

This removal should be done with ssa_remove_edge since we want to
remove the PHI arguments associated with the edge from the THEN/ELSE
clause to the target block.

	* tree-cfg.c (move_outgoing_edges): Correctly handle case where
	an edge already exists from BB1 to BB2's successor.

Index: tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-cfg.c,v
retrieving revision 1.1.4.135
diff -c -3 -p -r1.1.4.135 tree-cfg.c
*** tree-cfg.c	25 Jul 2003 12:28:23 -0000	1.1.4.135
--- tree-cfg.c	28 Jul 2003 16:51:26 -0000
*************** move_outgoing_edges (basic_block bb1, ba
*** 4458,4476 ****
        old_edge = bb2->succ;
        new_edge = make_edge (bb1, old_edge->dest, old_edge->flags);
  
!       /* Update PHI nodes at BB2's successor.  The arguments that used to
! 	 come from BB2 now come from BB1.  */
!       for (phi = phi_nodes (old_edge->dest); phi; phi = TREE_CHAIN (phi))
  	{
! 	  int i;
! 	  for (i = 0; i < PHI_NUM_ARGS (phi); i++)
! 	    if (PHI_ARG_EDGE (phi, i) == old_edge)
! 	      PHI_ARG_EDGE (phi, i) = new_edge;
  	}
  
-       /* Note that we shouldn't call ssa_remove_edge here because we've
- 	 already dealt with PHI nodes.  */
-       remove_edge (old_edge);
      }
  
    /* BB2's dominator children are now BB1's.  Also, remove BB2 as a
--- 4458,4490 ----
        old_edge = bb2->succ;
        new_edge = make_edge (bb1, old_edge->dest, old_edge->flags);
  
!       /* If make_edge created a new edge, then we need to update the PHI
! 	 node at BB2's successor.  The arguments that used to come from
! 	 BB2 now come from BB1.
! 
! 	 If make_edge did not create a new edge, then we already had an
! 	 edge from BB1 to BB2's successor.  In this case we want to
! 	 remove the edge and remove its alternative from BB2's successor's
! 	 PHI nodes, hence we use ssa_remove_edge.  */
!       if (new_edge)
! 	{
! 	  for (phi = phi_nodes (old_edge->dest); phi; phi = TREE_CHAIN (phi))
! 	    {
! 	      int i;
! 	      for (i = 0; i < PHI_NUM_ARGS (phi); i++)
! 		if (PHI_ARG_EDGE (phi, i) == old_edge)
! 		  PHI_ARG_EDGE (phi, i) = new_edge;
! 	    }
! 
! 	  /* Note that we shouldn't call ssa_remove_edge here because we've
! 	     already dealt with PHI nodes.  */
! 	  remove_edge (old_edge);
! 	}
!       else
  	{
! 	  ssa_remove_edge (old_edge);
  	}
  
      }
  
    /* BB2's dominator children are now BB1's.  Also, remove BB2 as a













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