------- 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