This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[tree-ssa] Patch to prevent incorrect edge splitting
- From: Andrew MacLeod <amacleod at redhat dot com>
- To: gcc-patches <gcc-patches at gcc dot gnu dot org>
- Date: 13 Jun 2003 14:14:47 -0400
- Subject: [tree-ssa] Patch to prevent incorrect edge splitting
As the Java folks found out, we incorrect split an edge occassionally
when there are abnormal edges coming out of a block. When we were
splitting the block, we were inserting the code in the wrong place.
We don't have to split an edge if a block only has one successor.
Instead we simply insert after the last stmt. This can be extended to
not split the edge if the block has only one non-abnormal edge. If
there is only one normal edge, we can still insert the stmt after the
last stmt in the block.
This patch implements that change. Bootstrapped on x86 and no testcase
regressions. In fact, it fixes one C++ testcase.
Andrew
* tree-cfg.c (bsi_commit_first_edge_insert): Only consider non-abnormal
edges when determining whether an edge needs to be split.
Index: tree-cfg.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-cfg.c,v
retrieving revision 1.1.4.105
diff -c -p -r1.1.4.105 tree-cfg.c
*** tree-cfg.c 12 Jun 2003 04:36:20 -0000 1.1.4.105
--- tree-cfg.c 13 Jun 2003 14:04:10 -0000
*************** bsi_commit_first_edge_insert (edge e, tr
*** 3824,3847 ****
basic_block src, dest, new_bb;
block_stmt_iterator bsi, tmp;
tree_stmt_iterator tsi;
! int single_exit, single_entry;
enum find_location_action location;
tree first, last, inserted_stmt, parent;
bb_ann_t ann;
first = last = NULL_TREE;
src = e->src;
dest = e->dest;
! single_exit = (src->succ->succ_next == NULL);
! single_entry = (dest->pred->pred_next == NULL);
/* If it is a single exit block, and it isn't the entry block, and the edge
is not abnormal, then insert at the end of the block, if we can. */
! if (single_exit
! && src != ENTRY_BLOCK_PTR
! && ((e->flags & EDGE_ABNORMAL)) == 0)
{
bsi = bsi_last (src);
/* If it is an empty block, simply insert after this bsi, and the new stmt
--- 3824,3859 ----
basic_block src, dest, new_bb;
block_stmt_iterator bsi, tmp;
tree_stmt_iterator tsi;
! int num_exit, num_entry;
enum find_location_action location;
tree first, last, inserted_stmt, parent;
bb_ann_t ann;
+ edge e2;
first = last = NULL_TREE;
src = e->src;
dest = e->dest;
! /* Cannot insert on an abnormal edge. */
! if (e->flags & EDGE_ABNORMAL)
! abort ();
!
! num_exit = num_entry = 0;
!
! /* Multiple successors on abnormal edges do not cause an edge to be split.
! A stmt can be inserted immediately following the last stmt in the block
! if there is only a single *normal* edge successor. */
! for (e2 = src->succ; e2; e2 = e2->succ_next)
! if (!(e2->flags & EDGE_ABNORMAL))
! num_exit++;
!
! for (e2 = dest->pred; e2; e2 = e2->pred_next)
! num_entry++;
/* If it is a single exit block, and it isn't the entry block, and the edge
is not abnormal, then insert at the end of the block, if we can. */
! if (num_exit == 1 && src != ENTRY_BLOCK_PTR)
{
bsi = bsi_last (src);
/* If it is an empty block, simply insert after this bsi, and the new stmt
*************** bsi_commit_first_edge_insert (edge e, tr
*** 3875,3881 ****
/* If it is a single entry destination, and it isn't the exit block, the new
stmt can be inserted at the beginning of the destination block. */
! if (single_entry && dest != EXIT_BLOCK_PTR)
{
bsi = bsi_start (dest);
/* If it is an empty block, simply insert after this bsi, and the new stmt
--- 3887,3893 ----
/* If it is a single entry destination, and it isn't the exit block, the new
stmt can be inserted at the beginning of the destination block. */
! if (num_entry == 1 && dest != EXIT_BLOCK_PTR)
{
bsi = bsi_start (dest);
/* If it is an empty block, simply insert after this bsi, and the new stmt