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]

[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);


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