From 8cbeddcc33cb842176b2ba6b8ffd5e8766efe6cc Mon Sep 17 00:00:00 2001
From: Martin Jambor <mjambor@suse.cz>
Date: Fri, 23 Jul 2010 18:31:48 +0200
Subject: [PATCH] re PR tree-optimization/44914 (ICE: in calc_dfs_tree, at
 dominance.c:395 with -fipa-sra -fnon-call-exceptions)

2010-07-23  Martin Jambor  <mjambor@suse.cz>

	PR tree-optimization/44914
	* tree-sra.c (sra_modify_function_body): Return true if CFG was
	changed, add purging dead eh edges.
	(ipa_sra_modify_function_body): Return true if CFG was changed,
	simplify purging dead eh edges.
	(modify_function): Return true if CFG was changed.
	(perform_intra_sra): Add TODO_cleanup_cfg to the return value if CFG
	was changed.
	(ipa_early_sra): Likewise.

	* testsuite/g++.dg/tree-ssa/pr44914.C:  New test.

From-SVN: r162468
---
 gcc/ChangeLog                           | 12 ++++++
 gcc/testsuite/ChangeLog                 |  5 +++
 gcc/testsuite/g++.dg/tree-ssa/pr44914.C | 20 ++++++++++
 gcc/tree-sra.c                          | 49 +++++++++++++++----------
 4 files changed, 67 insertions(+), 19 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/tree-ssa/pr44914.C

diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index adc38f49d2eb..e674f39ec13a 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,15 @@
+2010-07-23  Martin Jambor  <mjambor@suse.cz>
+
+	PR tree-optimization/44914
+	* tree-sra.c (sra_modify_function_body): Return true if CFG was
+	changed, add purging dead eh edges.
+	(ipa_sra_modify_function_body): Return true if CFG was changed,
+	simplify purging dead eh edges.
+	(modify_function): Return true if CFG was changed.
+	(perform_intra_sra): Add TODO_cleanup_cfg to the return value if CFG
+	was changed.
+	(ipa_early_sra): Likewise.
+
 2010-07-23  Jie Zhang  <jie@codesourcery.com>
 
 	PR target/44290
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 35923e208768..fd8615fffac0 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2010-07-23  Martin Jambor  <mjambor@suse.cz>
+
+	PR tree-optimization/44914
+	* g++.dg/tree-ssa/pr44914.C: New test.
+
 2010-07-23  Jie Zhang  <jie@codesourcery.com>
 
 	PR target/44290
diff --git a/gcc/testsuite/g++.dg/tree-ssa/pr44914.C b/gcc/testsuite/g++.dg/tree-ssa/pr44914.C
new file mode 100644
index 000000000000..57ca7e83f178
--- /dev/null
+++ b/gcc/testsuite/g++.dg/tree-ssa/pr44914.C
@@ -0,0 +1,20 @@
+/* { dg-do compile } */
+/* { dg-options "-O1 -fipa-sra -fnon-call-exceptions" } */
+
+struct A
+{
+  ~A () { }
+};
+
+struct B
+{
+  A a;
+  int i;
+  void f (int) { }
+  B ()
+  {
+    f (i);
+  }
+};
+
+B b;
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index 2bd9f97e1de3..fa567e54e8b6 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -2791,11 +2791,13 @@ sra_modify_assign (gimple *stmt, gimple_stmt_iterator *gsi)
 }
 
 /* Traverse the function body and all modifications as decided in
-   analyze_all_variable_accesses.  */
+   analyze_all_variable_accesses.  Return true iff the CFG has been
+   changed.  */
 
-static void
+static bool
 sra_modify_function_body (void)
 {
+  bool cfg_changed = false;
   basic_block bb;
 
   FOR_EACH_BB (bb)
@@ -2858,12 +2860,16 @@ sra_modify_function_body (void)
 	  if (modified)
 	    {
 	      update_stmt (stmt);
-	      maybe_clean_eh_stmt (stmt);
+	      if (maybe_clean_eh_stmt (stmt)
+		  && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
+		cfg_changed = true;
 	    }
 	  if (!deleted)
 	    gsi_next (&gsi);
 	}
     }
+
+  return cfg_changed;
 }
 
 /* Generate statements initializing scalar replacements of parts of function
@@ -2923,7 +2929,10 @@ perform_intra_sra (void)
   if (!analyze_all_variable_accesses ())
     goto out;
 
-  sra_modify_function_body ();
+  if (sra_modify_function_body ())
+    ret = TODO_update_ssa | TODO_cleanup_cfg;
+  else
+    ret = TODO_update_ssa;
   initialize_parameter_reductions ();
 
   statistics_counter_event (cfun, "Scalar replacements created",
@@ -2937,8 +2946,6 @@ perform_intra_sra (void)
   statistics_counter_event (cfun, "Separate LHS and RHS handling",
 			    sra_stats.separate_lhs_rhs_handling);
 
-  ret = TODO_update_ssa;
-
  out:
   sra_deinitialize ();
   return ret;
@@ -4064,17 +4071,17 @@ sra_ipa_modify_assign (gimple *stmt_ptr, gimple_stmt_iterator *gsi,
 }
 
 /* Traverse the function body and all modifications as described in
-   ADJUSTMENTS.  */
+   ADJUSTMENTS.  Return true iff the CFG has been changed.  */
 
-static void
+static bool
 ipa_sra_modify_function_body (ipa_parm_adjustment_vec adjustments)
 {
+  bool cfg_changed = false;
   basic_block bb;
 
   FOR_EACH_BB (bb)
     {
       gimple_stmt_iterator gsi;
-      bool bb_changed = false;
 
       for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
 	replace_removed_params_ssa_names (gsi_stmt (gsi), adjustments);
@@ -4136,15 +4143,16 @@ ipa_sra_modify_function_body (ipa_parm_adjustment_vec adjustments)
 
 	  if (modified)
 	    {
-	      bb_changed = true;
 	      update_stmt (stmt);
-	      maybe_clean_eh_stmt (stmt);
+	      if (maybe_clean_eh_stmt (stmt)
+		  && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
+		cfg_changed = true;
 	    }
 	  gsi_next (&gsi);
 	}
-      if (bb_changed)
-	gimple_purge_dead_eh_edges (bb);
     }
+
+  return cfg_changed;
 }
 
 /* Call gimple_debug_bind_reset_value on all debug statements describing
@@ -4260,13 +4268,14 @@ convert_callers (struct cgraph_node *node, tree old_decl,
 }
 
 /* Perform all the modification required in IPA-SRA for NODE to have parameters
-   as given in ADJUSTMENTS.  */
+   as given in ADJUSTMENTS.  Return true iff the CFG has been changed.  */
 
-static void
+static bool
 modify_function (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
 {
   struct cgraph_node *new_node;
   struct cgraph_edge *cs;
+  bool cfg_changed;
   VEC (cgraph_edge_p, heap) * redirect_callers;
   int node_callers;
 
@@ -4287,11 +4296,11 @@ modify_function (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
   push_cfun (DECL_STRUCT_FUNCTION (new_node->decl));
 
   ipa_modify_formal_parameters (current_function_decl, adjustments, "ISRA");
-  ipa_sra_modify_function_body (adjustments);
+  cfg_changed = ipa_sra_modify_function_body (adjustments);
   sra_ipa_reset_debug_stmts (adjustments);
   convert_callers (new_node, node->decl, adjustments);
   cgraph_make_node_local (new_node);
-  return;
+  return cfg_changed;
 }
 
 /* Return false the function is apparently unsuitable for IPA-SRA based on it's
@@ -4415,9 +4424,11 @@ ipa_early_sra (void)
   if (dump_file)
     ipa_dump_param_adjustments (dump_file, adjustments, current_function_decl);
 
-  modify_function (node, adjustments);
+  if (modify_function (node, adjustments))
+    ret = TODO_update_ssa | TODO_cleanup_cfg;
+  else
+    ret = TODO_update_ssa;
   VEC_free (ipa_parm_adjustment_t, heap, adjustments);
-  ret = TODO_update_ssa;
 
   statistics_counter_event (cfun, "Unused parameters deleted",
 			    sra_stats.deleted_unused_parameters);
-- 
GitLab