Patchwork Redirect recursive calls in IPA-SRA

login
register
mail settings
Submitter Martin Jambor
Date June 28, 2010, 1:28 p.m.
Message ID <20100628132823.GB4383@virgil.arch.suse.de>
Download mbox | patch
Permalink /patch/57140/
State New
Headers show

Comments

Martin Jambor - June 28, 2010, 1:28 p.m.
Hi,

the patch I committed to make IPA-SRA clone the functions it modifies
has a serious flaw in it because I did not notice that
cgraph_function_versioning no longer redirects the recursive calls and
so when they were present, the old functions were left around and, to
make matters worse still, were not optimized by the rest of the early
passes pipeline.

The following patch changes that by redirecting them by hand when we
modify callers of the current function and making the code dealing
with recursive calls actually properly recognize those.

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

Thanks,

Martin


2010-06-26  Martin Jambor  <mjambor@suse.cz>

	* tree-sra.c (convert_callers): New parameter, change fndecls of
	recursive calls.
	(modify_function): Pass the old decl to convert_callers.

	* testsuite/gcc.dg/ipa/ipa-sra-6.c: New test.
Jan Hubicka - June 28, 2010, 1:31 p.m.
> 2010-06-26  Martin Jambor  <mjambor@suse.cz>
> 
> 	* tree-sra.c (convert_callers): New parameter, change fndecls of
> 	recursive calls.
> 	(modify_function): Pass the old decl to convert_callers.
> 
> 	* testsuite/gcc.dg/ipa/ipa-sra-6.c: New test.
OK,
thanks.
Honza

Patch

Index: mine/gcc/testsuite/gcc.dg/ipa/ipa-sra-6.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ mine/gcc/testsuite/gcc.dg/ipa/ipa-sra-6.c	2010-06-27 11:27:45.000000000 +0200
@@ -0,0 +1,32 @@ 
+/* { dg-do compile } */
+/* { dg-options "-O2 -fipa-sra -fdump-tree-eipa_sra-slim"  } */
+
+struct bovid
+{
+  float a;
+  int b;
+  struct bovid *next;
+};
+
+static int
+__attribute__((noinline))
+foo (struct bovid *cow, int i)
+{
+  i++;
+  if (cow->next)
+    foo (cow->next, i);
+  return i;
+}
+
+int main (int argc, char *argv[])
+{
+  struct bovid cow;
+
+  cow.a = 7.4;
+  cow.b = 6;
+  cow.next = (struct bovid *) 0;
+
+  return foo (&cow, 0);
+}
+
+/* { dg-final { scan-tree-dump-times "foo " 1 "eipa_sra"  } } */
Index: mine/gcc/tree-sra.c
===================================================================
--- mine.orig/gcc/tree-sra.c	2010-06-26 23:50:14.000000000 +0200
+++ mine/gcc/tree-sra.c	2010-06-26 23:56:16.000000000 +0200
@@ -4167,7 +4167,8 @@  all_callers_have_enough_arguments_p (str
 /* Convert all callers of NODE to pass parameters as given in ADJUSTMENTS.  */
 
 static void
-convert_callers (struct cgraph_node *node, ipa_parm_adjustment_vec adjustments)
+convert_callers (struct cgraph_node *node, tree old_decl,
+		 ipa_parm_adjustment_vec adjustments)
 {
   tree old_cur_fndecl = current_function_decl;
   struct cgraph_edge *cs;
@@ -4214,10 +4215,11 @@  convert_callers (struct cgraph_node *nod
 	  if (gimple_code (stmt) != GIMPLE_CALL)
 	    continue;
 	  call_fndecl = gimple_call_fndecl (stmt);
-	  if (call_fndecl && cgraph_get_node (call_fndecl) == node)
+	  if (call_fndecl == old_decl)
 	    {
 	      if (dump_file)
 		fprintf (dump_file, "Adjusting recursive call");
+	      gimple_call_set_fndecl (stmt, node->decl);
 	      ipa_modify_call_arguments (NULL, stmt, adjustments);
 	    }
 	}
@@ -4256,7 +4258,7 @@  modify_function (struct cgraph_node *nod
   ipa_modify_formal_parameters (current_function_decl, adjustments, "ISRA");
   ipa_sra_modify_function_body (adjustments);
   sra_ipa_reset_debug_stmts (adjustments);
-  convert_callers (new_node, adjustments);
+  convert_callers (new_node, node->decl, adjustments);
   cgraph_make_node_local (new_node);
   return;
 }