Re: [PATCH, PR61554] ICE during CCP

2014-06-24 Thread Chung-Lin Tang
On 2014/6/23 04:45 PM, Richard Biener wrote:
 On Mon, Jun 23, 2014 at 7:32 AM, Chung-Lin Tang clt...@codesourcery.com 
 wrote:
 Hi Richard,

 In this change:
 https://gcc.gnu.org/ml/gcc-patches/2014-06/msg01278.html

 where substitute_and_fold() was changed to use a dom walker, the calls
 to purge dead EH edges during the walk can alter the dom-tree, and have
 chaotic results; the testcase in PR 61554 has some blocks traversed
 twice during the walk, causing the segfault during CCP.

 The patch records the to-be-purged-for-dead-EH blocks in a similar
 manner like stmts_to_remove, and processes it after the walk. (another
 possible method would be using a bitmap to record the BBs + calling
 gimple_purge_all_dead_eh_edges...)
 
 Oops.
 
 Bootstrapped and tested on x86_64-linux, is this okay for trunk?
 
 Can you please use a bitmap and use gimple_purge_all_dead_eh_edges
 like tree-ssa-pre.c does?
 
 Also please add the reduced testcase from the PR to the g++.dg/torture
 
 Ok with that changes.
 
 Thanks,
 Richard.

Thanks for the review. Attached is what I committed. Testcase made by
Markus also added.

Thanks,
Chung-Lin

2014-06-24  Chung-Lin Tang  clt...@codesourcery.com

PR tree-optimization/61554
* tree-ssa-propagate.c: Include bitmap.h.
(substitute_and_fold_dom_walker): Add 'bitmap need_eh_cleanup'
member,
properly update constructor/destructor.
(substitute_and_fold_dom_walker::before_dom_children):
Remove call to gimple_purge_dead_eh_edges, add bb-index to
need_eh_cleaup instead.
(substitute_and_fold): Call gimple_purge_all_dead_eh_edges on
need_eh_cleanup.

Index: tree-ssa-propagate.c
===
--- tree-ssa-propagate.c	(revision 211927)
+++ tree-ssa-propagate.c	(working copy)
@@ -29,6 +29,7 @@
 #include function.h
 #include gimple-pretty-print.h
 #include dumpfile.h
+#include bitmap.h
 #include sbitmap.h
 #include tree-ssa-alias.h
 #include internal-fn.h
@@ -1031,8 +1032,13 @@ class substitute_and_fold_dom_walker : public dom_
   fold_fn (fold_fn_), do_dce (do_dce_), something_changed (false)
 {
   stmts_to_remove.create (0);
+  need_eh_cleanup = BITMAP_ALLOC (NULL);
 }
-~substitute_and_fold_dom_walker () { stmts_to_remove.release (); }
+~substitute_and_fold_dom_walker ()
+{
+  stmts_to_remove.release ();
+  BITMAP_FREE (need_eh_cleanup);
+}
 
 virtual void before_dom_children (basic_block);
 virtual void after_dom_children (basic_block) {}
@@ -1042,6 +1048,7 @@ class substitute_and_fold_dom_walker : public dom_
 bool do_dce;
 bool something_changed;
 vecgimple stmts_to_remove;
+bitmap need_eh_cleanup;
 };
 
 void
@@ -1144,7 +1151,7 @@ substitute_and_fold_dom_walker::before_dom_childre
 	  /* If we cleaned up EH information from the statement,
 	 remove EH edges.  */
 	  if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt))
-	gimple_purge_dead_eh_edges (bb);
+	bitmap_set_bit (need_eh_cleanup, bb-index);
 
 	  if (is_gimple_assign (stmt)
 	   (get_gimple_rhs_class (gimple_assign_rhs_code (stmt))
@@ -1235,6 +1242,9 @@ substitute_and_fold (ssa_prop_get_value_fn get_val
 	}
 }
 
+  if (!bitmap_empty_p (walker.need_eh_cleanup))
+gimple_purge_all_dead_eh_edges (walker.need_eh_cleanup);
+
   statistics_counter_event (cfun, Constants propagated,
 			prop_stats.num_const_prop);
   statistics_counter_event (cfun, Copies propagated,


Re: [PATCH, PR61554] ICE during CCP

2014-06-23 Thread Richard Biener
On Mon, Jun 23, 2014 at 7:32 AM, Chung-Lin Tang clt...@codesourcery.com wrote:
 Hi Richard,

 In this change:
 https://gcc.gnu.org/ml/gcc-patches/2014-06/msg01278.html

 where substitute_and_fold() was changed to use a dom walker, the calls
 to purge dead EH edges during the walk can alter the dom-tree, and have
 chaotic results; the testcase in PR 61554 has some blocks traversed
 twice during the walk, causing the segfault during CCP.

 The patch records the to-be-purged-for-dead-EH blocks in a similar
 manner like stmts_to_remove, and processes it after the walk. (another
 possible method would be using a bitmap to record the BBs + calling
 gimple_purge_all_dead_eh_edges...)

Oops.

 Bootstrapped and tested on x86_64-linux, is this okay for trunk?

Can you please use a bitmap and use gimple_purge_all_dead_eh_edges
like tree-ssa-pre.c does?

Also please add the reduced testcase from the PR to the g++.dg/torture

Ok with that changes.

Thanks,
Richard.

 Thanks,
 Chung-Lin

 2014-06-23  Chung-Lin Tang  clt...@codesourcery.com

 PR tree-optimization/61554
 * tree-ssa-propagate.c (substitute_and_fold_dom_walker):
 Add 'vecbasic_block bbs_to_purge_dead_eh_edges' member,
 properly update constructor/destructor.
 (substitute_and_fold_dom_walker::before_dom_children):
 Remove call to gimple_purge_dead_eh_edges, add bb to
 bbs_to_purge_dead_eh_edges instead.
 (substitute_and_fold): Call gimple_purge_dead_eh_edges for
 bbs recorded in bbs_to_purge_dead_eh_edges.


[PATCH, PR61554] ICE during CCP

2014-06-22 Thread Chung-Lin Tang
Hi Richard,

In this change:
https://gcc.gnu.org/ml/gcc-patches/2014-06/msg01278.html

where substitute_and_fold() was changed to use a dom walker, the calls
to purge dead EH edges during the walk can alter the dom-tree, and have
chaotic results; the testcase in PR 61554 has some blocks traversed
twice during the walk, causing the segfault during CCP.

The patch records the to-be-purged-for-dead-EH blocks in a similar
manner like stmts_to_remove, and processes it after the walk. (another
possible method would be using a bitmap to record the BBs + calling
gimple_purge_all_dead_eh_edges...)

Bootstrapped and tested on x86_64-linux, is this okay for trunk?

Thanks,
Chung-Lin

2014-06-23  Chung-Lin Tang  clt...@codesourcery.com

PR tree-optimization/61554
* tree-ssa-propagate.c (substitute_and_fold_dom_walker):
Add 'vecbasic_block bbs_to_purge_dead_eh_edges' member,
properly update constructor/destructor.
(substitute_and_fold_dom_walker::before_dom_children):
Remove call to gimple_purge_dead_eh_edges, add bb to
bbs_to_purge_dead_eh_edges instead.
(substitute_and_fold): Call gimple_purge_dead_eh_edges for
bbs recorded in bbs_to_purge_dead_eh_edges.
Index: tree-ssa-propagate.c
===
--- tree-ssa-propagate.c	(revision 211874)
+++ tree-ssa-propagate.c	(working copy)
@@ -1031,8 +1031,13 @@ class substitute_and_fold_dom_walker : public dom_
   fold_fn (fold_fn_), do_dce (do_dce_), something_changed (false)
 {
   stmts_to_remove.create (0);
+  bbs_to_purge_dead_eh_edges.create (0);
 }
-~substitute_and_fold_dom_walker () { stmts_to_remove.release (); }
+~substitute_and_fold_dom_walker ()
+{
+  stmts_to_remove.release ();
+  bbs_to_purge_dead_eh_edges.release ();
+}
 
 virtual void before_dom_children (basic_block);
 virtual void after_dom_children (basic_block) {}
@@ -1042,6 +1047,7 @@ class substitute_and_fold_dom_walker : public dom_
 bool do_dce;
 bool something_changed;
 vecgimple stmts_to_remove;
+vecbasic_block bbs_to_purge_dead_eh_edges;
 };
 
 void
@@ -1144,7 +1150,7 @@ substitute_and_fold_dom_walker::before_dom_childre
 	  /* If we cleaned up EH information from the statement,
 	 remove EH edges.  */
 	  if (maybe_clean_or_replace_eh_stmt (old_stmt, stmt))
-	gimple_purge_dead_eh_edges (bb);
+	bbs_to_purge_dead_eh_edges.safe_push (bb);
 
 	  if (is_gimple_assign (stmt)
 	   (get_gimple_rhs_class (gimple_assign_rhs_code (stmt))
@@ -1235,6 +1241,14 @@ substitute_and_fold (ssa_prop_get_value_fn get_val
 	}
 }
 
+  while (!walker.bbs_to_purge_dead_eh_edges.is_empty ())
+{
+  basic_block bb = walker.bbs_to_purge_dead_eh_edges.pop ();
+  gimple_purge_dead_eh_edges (bb);
+  if (dump_file  dump_flags  TDF_DETAILS)
+	fprintf (dump_file, Purge dead EH edges from bb %d\n, bb-index);
+}
+
   statistics_counter_event (cfun, Constants propagated,
 			prop_stats.num_const_prop);
   statistics_counter_event (cfun, Copies propagated,