Patchwork [PR,45565] Update SSA after stmt redirection

login
register
mail settings
Submitter Martin Jambor
Date Sept. 23, 2010, 9:16 a.m.
Message ID <20100923091657.GA31666@virgil.arch.suse.de>
Download mbox | patch
Permalink /patch/65520/
State New
Headers show

Comments

Martin Jambor - Sept. 23, 2010, 9:16 a.m.
Hi,

the patch below fixes PR 45565 by updating SSA after inline transform
even if we don't inline anything and only redirect an edge.  I'm a bit
surprised this is necessary since we used to assert !need_ssa_update_p
in these cases
(http://gcc.gnu.org/ml/gcc-patches/2010-04/msg01012.html) ...but well,
in inline transform this does not matter.

Bootstrapped and tested on x86_64-linux.  OK for trunk?

Thanks,

Martin


2010-09-22  Martin Jambor  <mjambor@suse.cz>

	PR middle-end/45565
	* cgraphunit.c (cgraph_redirect_edge_call_stmt_to_callee): Return NULL
	if nothing is changed.
	* tree-inline.c (copy_bb): Handle that
	cgraph_redirect_edge_call_stmt_to_callee can return NULL.
	* ipa-inline.c (inline_transform): Update SSA if
	cgraph_redirect_edge_call_stmt_to_callee returns non-NULL.

	* testsuite/g++.dg/ipa/pr45565.C: New test.

Patch

Index: icln/gcc/cgraphunit.c
===================================================================
--- icln.orig/gcc/cgraphunit.c
+++ icln/gcc/cgraphunit.c
@@ -2113,7 +2113,8 @@  cgraph_materialize_clone (struct cgraph_
 }
 
 /* If necessary, change the function declaration in the call statement
-   associated with E so that it corresponds to the edge callee.  */
+   associated with E so that it corresponds to the edge callee.  Return the new
+   statement or NULL if nothing was changed.  */
 
 gimple
 cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *e)
@@ -2128,7 +2129,7 @@  cgraph_redirect_edge_call_stmt_to_callee
       || decl == e->callee->decl
       /* Don't update call from same body alias to the real function.  */
       || (decl && cgraph_get_node (decl) == cgraph_get_node (e->callee->decl)))
-    return e->call_stmt;
+    return NULL;
 
 #ifdef ENABLE_CHECKING
   if (decl)
Index: icln/gcc/ipa-inline.c
===================================================================
--- icln.orig/gcc/ipa-inline.c
+++ icln/gcc/ipa-inline.c
@@ -2161,7 +2161,8 @@  inline_transform (struct cgraph_node *no
 
   for (e = node->callees; e; e = e->next_callee)
     {
-      cgraph_redirect_edge_call_stmt_to_callee (e);
+      if (cgraph_redirect_edge_call_stmt_to_callee (e))
+	todo = TODO_update_ssa;
       if (!e->inline_failed || warn_inline)
         inline_p = true;
     }
@@ -2169,7 +2170,7 @@  inline_transform (struct cgraph_node *no
   if (inline_p)
     {
       timevar_push (TV_INTEGRATION);
-      todo = optimize_inline_calls (current_function_decl);
+      todo |= optimize_inline_calls (current_function_decl);
       timevar_pop (TV_INTEGRATION);
     }
   cfun->always_inline_functions_inlined = true;
Index: icln/gcc/tree-inline.c
===================================================================
--- icln.orig/gcc/tree-inline.c
+++ icln/gcc/tree-inline.c
@@ -1679,6 +1679,7 @@  copy_bb (copy_body_data *id, basic_block
 		  if (edge)
 		    {
 		      int edge_freq = edge->frequency;
+		      gimple n_stmt;
 		      edge = cgraph_clone_edge (edge, id->dst_node, stmt,
 					        gimple_uid (stmt),
 					        REG_BR_PROB_BASE, CGRAPH_FREQ_BASE,
@@ -1704,7 +1705,9 @@  copy_bb (copy_body_data *id, basic_block
 				   bb->frequency,
 				   copy_basic_block->frequency);
 			}
-		      stmt = cgraph_redirect_edge_call_stmt_to_callee (edge);
+		      n_stmt = cgraph_redirect_edge_call_stmt_to_callee (edge);
+		      if (n_stmt)
+			stmt = n_stmt;
 		    }
 		  break;
 
Index: icln/gcc/testsuite/g++.dg/ipa/pr45565.C
===================================================================
--- /dev/null
+++ icln/gcc/testsuite/g++.dg/ipa/pr45565.C
@@ -0,0 +1,28 @@ 
+// { dg-do compile }
+// { dg-options "-O -fno-toplevel-reorder -fno-inline -fipa-cp -fipa-cp-clone -fkeep-inline-functions" }
+
+template < typename Derived > struct AnyMatrixBase
+{
+};
+
+struct Matrix Random ();
+
+struct Matrix:AnyMatrixBase < Matrix >
+{
+  void bar ()
+  {
+    throw;
+  }
+  void foo (Matrix other)
+  {
+    bar ();
+    Matrix (AnyMatrixBase < Matrix > (Random ()));
+  }
+  template
+    < typename OtherDerived > Matrix (AnyMatrixBase < OtherDerived > other)
+  {
+    foo (other);
+  }
+};
+
+Matrix x (Random ());