------- Comment #7 from hubicka at ucw dot cz  2009-07-12 16:18 -------
Subject: Re:  [4.5 Regression] internal compiler error: verify_ssa error:
definition in block 5 does not dominate use in block 7

Hi,
there is interesting difficulty with this plan.

When we have something like

BB1: if (test) goto BB2 else BB3;
BB2:
BB3: A=PHI (0 from BB1, 1 from BB2)

we end up forwarding edge BB1->BB2 to BB3 resulting in wrong code
problem.  This is because how control dependency is formulated.
When visiting BB we first mark live its control dependent BBs (that
contains conditionals deciding if BB will be executed at all) and when
visiting PHI we mark control dependency BB of source BBs of edges
leading to PHI.

In this case control dependent BB2 is BB1, so we correctly mark the test
as neccesary, but we never mark BB2 as neccesary in any way.

I checked original Cytron formulation of the CD-DCE and it is not
forwarding edges of all branches, only of branches being removed just as
current mainline does.  I saw the forwarding of all branches on some
slides presenting CD-DCE but I am not sure if this can be cheaply done
correctly (one would need control dependence relation not only for BBs,
but also for edges, or implicit split edge BBs of every edge that leads
to PHI).

The following patch fixes ICE by implementing #2 from my previous comment.
Wihtout #1 we end up with some unnecesary virtuals being sent for
renaming (those virtuals that exist in otherwise empty BBs), but I doubt
it is that big deal.

I am regtesting&bootstrapping this fix.

Honza

Index: tree-ssa-dce.c
===================================================================
--- tree-ssa-dce.c      (revision 149499)
+++ tree-ssa-dce.c      (working copy)
@@ -1137,7 +1162,7 @@ eliminate_unnecessary_stmts (void)
       for (bb = ENTRY_BLOCK_PTR->next_bb; bb != EXIT_BLOCK_PTR; bb = next_bb)
        {
          next_bb = bb->next_bb;
-         if (!(bb->flags & BB_REACHABLE))
+         if (!TEST_BIT (bb_contains_live_stmts, bb->index))
            {
              for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next
(&gsi))
                if (!is_gimple_reg (gimple_phi_result (gsi_stmt (gsi))))
@@ -1159,8 +1184,11 @@ eliminate_unnecessary_stmts (void)
                    if (found)
                      mark_virtual_phi_result_for_renaming (gsi_stmt (gsi));
                  }
-             delete_basic_block (bb);
+             if (!(bb->flags & BB_REACHABLE))
+               delete_basic_block (bb);
            }
+         else
+           gcc_assert (bb->flags & BB_REACHABLE);
        }
     }
   FOR_EACH_BB (bb)


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=40676

Reply via email to