Avoid cycles in the inline plan

Jan Hubicka hubicka@ucw.cz
Mon Mar 2 20:33:00 GMT 2015


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.
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;



More information about the Gcc-patches mailing list