diff mbox

Avoid cycles in the inline plan

Message ID 20150302203335.GC846@kam.mff.cuni.cz
State New
Headers show

Commit Message

Jan Hubicka March 2, 2015, 8:33 p.m. UTC
Hi,
in the testcase bellow we manage to produce cycle in inline plan because there is
indirectly recrusive function that appears called once.

I am having problems with the testcase. The second file outht to be compiled with
-O2, but it is not.  Is the dg-options in the LTO testsuite broken now or did I missed
something obvious?

The testcase excercises the new paths anyway (just does not ice) so I decided
to commit it as it is for now.

Bootstrapped/regtested x86_64-linux, commited.

Honza

	PR ipa/65130
	* ipa-inline.c (check_callers): Looks for recursion.
	(inline_to_all_callers): Give up on uninlinable or recursive edges.
	* ipa-inline-analysis.c (inline_summary_t::duplicate): Do not update
	summary of inline clones.
	(do_estimate_growth_1): Fix recursion check.

	* gcc.dg/lto/pr65130_0.c: New testcase.
	* gcc.dg/lto/pr65130_1.c: New testcase.

Comments

Richard Biener March 3, 2015, 8:37 a.m. UTC | #1
On Mon, 2 Mar 2015, Jan Hubicka wrote:

> Hi,
> in the testcase bellow we manage to produce cycle in inline plan because there is
> indirectly recrusive function that appears called once.
> 
> I am having problems with the testcase. The second file outht to be compiled with
> -O2, but it is not.  Is the dg-options in the LTO testsuite broken now or did I missed
> something obvious?

It works for me:

spawn /home/abuild/rguenther/trunk-g/gcc/testsuite/g++/../../xg++ 
-B/home/abuild/rguenther/trunk-g/gcc/testsuite/g++/../../ 
-fno-diagnostics-show-caret -fdiagnostics-color=never -nostdinc++ 
-I/abuild/rguenther/trunk-g/x86_64-unknown-linux-gnu/libstdc++-v3/include/x86_64-unknown-linux-gnu 
-I/abuild/rguenther/trunk-g/x86_64-unknown-linux-gnu/libstdc++-v3/include 
-I/space/rguenther/src/svn/trunk/libstdc++-v3/libsupc++ 
-I/space/rguenther/src/svn/trunk/libstdc++-v3/include/backward 
-I/space/rguenther/src/svn/trunk/libstdc++-v3/testsuite/util 
-fmessage-length=0 -flto -O0 -std=c++11 -O2 -c -o cp_lto_pr65276_1.o 
/space/rguenther/src/svn/trunk/gcc/testsuite/g++.dg/lto/pr65276_1.C^M

(it just appends -O2)

Richard.

> The testcase excercises the new paths anyway (just does not ice) so I decided
> to commit it as it is for now.
> 
> Bootstrapped/regtested x86_64-linux, commited.
> 
> Honza
> 
> 	PR ipa/65130
> 	* ipa-inline.c (check_callers): Looks for recursion.
> 	(inline_to_all_callers): Give up on uninlinable or recursive edges.
> 	* ipa-inline-analysis.c (inline_summary_t::duplicate): Do not update
> 	summary of inline clones.
> 	(do_estimate_growth_1): Fix recursion check.
> 
> 	* gcc.dg/lto/pr65130_0.c: New testcase.
> 	* gcc.dg/lto/pr65130_1.c: New testcase.
> Index: ipa-inline.c
> ===================================================================
> --- ipa-inline.c	(revision 221122)
> +++ ipa-inline.c	(working copy)
> @@ -952,6 +952,8 @@ check_callers (struct cgraph_node *node,
>  	 return true;
>         if (!can_inline_edge_p (e, true))
>           return true;
> +       if (e->recursive_p ())
> +	 return true;
>         if (!(*(bool *)has_hot_call) && e->maybe_hot_p ())
>  	 *(bool *)has_hot_call = true;
>       }
> @@ -2094,6 +2096,15 @@ inline_to_all_callers (struct cgraph_nod
>      {
>        struct cgraph_node *caller = node->callers->caller;
>  
> +      if (!can_inline_edge_p (node->callers, true)
> +	  || node->callers->recursive_p ())
> +	{
> +	  if (dump_file)
> +	    fprintf (dump_file, "Uninlinable call found; giving up.\n");
> +	  *num_calls = 0;
> +	  return false;
> +	}
> +
>        if (dump_file)
>  	{
>  	  fprintf (dump_file,
> Index: testsuite/gcc.dg/lto/pr65130_0.c
> ===================================================================
> --- testsuite/gcc.dg/lto/pr65130_0.c	(revision 0)
> +++ testsuite/gcc.dg/lto/pr65130_0.c	(revision 0)
> @@ -0,0 +1,19 @@
> +/* { dg-lto-do link } */
> +/* { dg-lto-options { { -flto -O1 -fdevirtualize } } } */
> +extern void fn3 (void); 
> +
> +void fn2(void) 
> +{ 
> +  fn3(); 
> +}
> +
> +void fn1(void) 
> +{ 
> +  fn2(); 
> +}
> +
> +void fn4(void) 
> +{ 
> +  fn2(); 
> +}
> +
> Index: testsuite/gcc.dg/lto/pr65130_1.c
> ===================================================================
> --- testsuite/gcc.dg/lto/pr65130_1.c	(revision 0)
> +++ testsuite/gcc.dg/lto/pr65130_1.c	(revision 0)
> @@ -0,0 +1,17 @@
> +/* { dg-options "-O2 -fdevirtualize" } */
> +extern void fn1(void);
> +extern void fn4 (void); 
> +
> +int a; 
> +
> +void fn3(void) 
> +{
> +  for (; a;)
> +    fn4();
> +}
> +
> +int main() {
> +  fn1();
> +  return 0;
> +}
> +
> Index: ipa-inline-analysis.c
> ===================================================================
> --- ipa-inline-analysis.c	(revision 221122)
> +++ ipa-inline-analysis.c	(working copy)
> @@ -1291,7 +1291,8 @@ inline_summary_t::duplicate (cgraph_node
>  	  set_hint_predicate (&info->array_index, p);
>  	}
>      }
> -  inline_update_overall_summary (dst);
> +  if (!dst->global.inlined_to)
> +    inline_update_overall_summary (dst);
>  }
>  
>  
> @@ -3924,10 +3925,11 @@ do_estimate_growth_1 (struct cgraph_node
>            continue;
>  	}
>  
> -      if (e->caller == d->node
> -	  || (e->caller->global.inlined_to
> -	      && e->caller->global.inlined_to == d->node))
> -	d->self_recursive = true;
> +      if (e->recursive_p ())
> +	{
> +	  d->self_recursive = true;
> +	  continue;
> +	}
>        d->growth += estimate_edge_growth (e);
>      }
>    return false;
> 
>
diff mbox

Patch

Index: ipa-inline.c
===================================================================
--- ipa-inline.c	(revision 221122)
+++ ipa-inline.c	(working copy)
@@ -952,6 +952,8 @@  check_callers (struct cgraph_node *node,
 	 return true;
        if (!can_inline_edge_p (e, true))
          return true;
+       if (e->recursive_p ())
+	 return true;
        if (!(*(bool *)has_hot_call) && e->maybe_hot_p ())
 	 *(bool *)has_hot_call = true;
      }
@@ -2094,6 +2096,15 @@  inline_to_all_callers (struct cgraph_nod
     {
       struct cgraph_node *caller = node->callers->caller;
 
+      if (!can_inline_edge_p (node->callers, true)
+	  || node->callers->recursive_p ())
+	{
+	  if (dump_file)
+	    fprintf (dump_file, "Uninlinable call found; giving up.\n");
+	  *num_calls = 0;
+	  return false;
+	}
+
       if (dump_file)
 	{
 	  fprintf (dump_file,
Index: testsuite/gcc.dg/lto/pr65130_0.c
===================================================================
--- testsuite/gcc.dg/lto/pr65130_0.c	(revision 0)
+++ testsuite/gcc.dg/lto/pr65130_0.c	(revision 0)
@@ -0,0 +1,19 @@ 
+/* { dg-lto-do link } */
+/* { dg-lto-options { { -flto -O1 -fdevirtualize } } } */
+extern void fn3 (void); 
+
+void fn2(void) 
+{ 
+  fn3(); 
+}
+
+void fn1(void) 
+{ 
+  fn2(); 
+}
+
+void fn4(void) 
+{ 
+  fn2(); 
+}
+
Index: testsuite/gcc.dg/lto/pr65130_1.c
===================================================================
--- testsuite/gcc.dg/lto/pr65130_1.c	(revision 0)
+++ testsuite/gcc.dg/lto/pr65130_1.c	(revision 0)
@@ -0,0 +1,17 @@ 
+/* { dg-options "-O2 -fdevirtualize" } */
+extern void fn1(void);
+extern void fn4 (void); 
+
+int a; 
+
+void fn3(void) 
+{
+  for (; a;)
+    fn4();
+}
+
+int main() {
+  fn1();
+  return 0;
+}
+
Index: ipa-inline-analysis.c
===================================================================
--- ipa-inline-analysis.c	(revision 221122)
+++ ipa-inline-analysis.c	(working copy)
@@ -1291,7 +1291,8 @@  inline_summary_t::duplicate (cgraph_node
 	  set_hint_predicate (&info->array_index, p);
 	}
     }
-  inline_update_overall_summary (dst);
+  if (!dst->global.inlined_to)
+    inline_update_overall_summary (dst);
 }
 
 
@@ -3924,10 +3925,11 @@  do_estimate_growth_1 (struct cgraph_node
           continue;
 	}
 
-      if (e->caller == d->node
-	  || (e->caller->global.inlined_to
-	      && e->caller->global.inlined_to == d->node))
-	d->self_recursive = true;
+      if (e->recursive_p ())
+	{
+	  d->self_recursive = true;
+	  continue;
+	}
       d->growth += estimate_edge_growth (e);
     }
   return false;