This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][alias-improvements] Fix ehcleanup pass fallout
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Cc: Jan Hubicka <jh at suse dot de>
- Date: Mon, 30 Mar 2009 17:19:03 +0200 (CEST)
- Subject: [PATCH][alias-improvements] Fix ehcleanup pass fallout
This makes sure not to leave dead SSA_NAMEs and immediate uses that
we are about to rename in statements. Otherwise if update_ssa
chooses to re-use the same SSA_NAME operands will not be re-built
and verify-ssa will fail.
This problem causes numerous ICEs in the libstdc++ testsuite on
the branch like
/space/rguenther/alias-improvements/libstdc++-v3/testsuite/ext/pb_ds/regression/tree_data_map_rand.cc:
In destructor 'virtual
__gnu_pbds::test::xml_result_set_regression_formatter::~xml_result_set_regression_formatter()':
/space/rguenther/alias-improvements/libstdc++-v3/testsuite/ext/pb_ds/regression/tree_data_map_rand.cc:71:
error: no immediate_use list
for SSA_NAME: .MEM_15(ab) in statement:
# .MEM_27 = VDEF <.MEM_15(ab)>
__base_dtor (D.78429_13);
/space/rguenther/alias-improvements/libstdc++-v3/testsuite/ext/pb_ds/regression/tree_data_map_rand.cc:71:
internal compiler error: verify_ssa failed
Please submit a full bug report,
with preprocessed source if appropriate.
See <http://gcc.gnu.org/bugs.html> for instructions.
I would expect this is not only an issue for virtual operands but
also real operands - but that case may be even more uncommon
(and there are no virtual operands on trunk at that stage).
I took the opportunity to document what we are trying to do in
cleanup_empty_eh (I hope I got it correct ;)).
Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to the
branch.
Richard.
2009-03-30 Richard Guenther <rguenther@suse.de>
* tree-eh.c (cleanup_empty_eh): Do not leave stale SSA_NAMEs
and immediate uses in statements.
Index: gcc/tree-eh.c
===================================================================
*** gcc/tree-eh.c (revision 145286)
--- gcc/tree-eh.c (working copy)
*************** cleanup_empty_eh (basic_block bb)
*** 2805,2812 ****
similar updating as jump threading does. */
for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
! mark_sym_for_renaming (SSA_NAME_VAR (PHI_RESULT (gsi_stmt (si))));
while ((e = ei_safe_edge (ei_start (bb->preds))))
{
basic_block src = e->src;
--- 2805,2833 ----
similar updating as jump threading does. */
for (si = gsi_start_phis (bb); !gsi_end_p (si); gsi_next (&si))
! {
! tree res = PHI_RESULT (gsi_stmt (si));
! gimple stmt;
! imm_use_iterator iter;
! use_operand_p use_p;
+ /* As we are going to delete this block we will release all
+ defs which makes the immediate uses on use stmts invalid.
+ Avoid that by replacing all uses with the bare variable
+ and updating the stmts. */
+ FOR_EACH_IMM_USE_STMT (stmt, iter, res)
+ {
+ FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
+ SET_USE (use_p, SSA_NAME_VAR (res));
+ update_stmt (stmt);
+ }
+ mark_sym_for_renaming (SSA_NAME_VAR (res));
+ }
+
+ /* We want to thread over the current receiver to the next reachable
+ one. Do so by deleting all outgoing EH edges from all
+ predecessors of the receiver block we are going to delete and
+ rebuild EH edges for them. */
while ((e = ei_safe_edge (ei_start (bb->preds))))
{
basic_block src = e->src;
*************** cleanup_empty_eh (basic_block bb)
*** 2824,2837 ****
if (!stmt_can_throw_internal (last_stmt (src)))
continue;
make_eh_edges (last_stmt (src));
! FOR_EACH_EDGE (e, ei, src->succs) if (e->flags & EDGE_EH)
! {
! dominance_info_invalidated = true;
! for (si = gsi_start_phis (e->dest); !gsi_end_p (si);
! gsi_next (&si))
! mark_sym_for_renaming (SSA_NAME_VAR
! (PHI_RESULT (gsi_stmt (si))));
! }
}
if (dump_file)
fprintf (dump_file, "Empty EH handler %i removed\n", region);
--- 2845,2861 ----
if (!stmt_can_throw_internal (last_stmt (src)))
continue;
make_eh_edges (last_stmt (src));
! /* Make sure to also rename symbols that feed into receivers
! that are now newly reachable from current src. */
! FOR_EACH_EDGE (e, ei, src->succs)
! if (e->flags & EDGE_EH)
! {
! dominance_info_invalidated = true;
! for (si = gsi_start_phis (e->dest); !gsi_end_p (si);
! gsi_next (&si))
! mark_sym_for_renaming (SSA_NAME_VAR
! (PHI_RESULT (gsi_stmt (si))));
! }
}
if (dump_file)
fprintf (dump_file, "Empty EH handler %i removed\n", region);