diff mbox

PR ipa/63470 (zero sized call_stmt)

Message ID 20150112090925.GB29799@kam.mff.cuni.cz
State New
Headers show

Commit Message

Jan Hubicka Jan. 12, 2015, 9:09 a.m. UTC
Hi,
this ICE is caused by double updating in ipa-prop that reduces call stmt size
once when it becomes speculative and again when it is turned to direct.  Fixed
by the following patch that makes updating to happen while duplication so
ipa-prop needs to care only about case it turned real indirect call into
direct.

Bootstrapped/regtested x86_64-linux, will commit it shortly.

Honza

	PR ipa/63470
	* ipa-inline-analysis.c (inline_edge_duplication_hook): Adjust
	cost when edge becomes direct.
	* ipa-prop.c (make_edge_direct): Do not adjust when speculation
	is resolved or when introducing new speculation.

	* testsuite/g++.dg/ipa/pr63470.C: New testcase.
diff mbox

Patch

Index: ipa-inline-analysis.c
===================================================================
--- ipa-inline-analysis.c	(revision 219430)
+++ ipa-inline-analysis.c	(working copy)
@@ -1312,6 +1312,13 @@ 
   info->predicate = NULL;
   edge_set_predicate (dst, srcinfo->predicate);
   info->param = srcinfo->param.copy ();
+  if (!dst->indirect_unknown_callee && src->indirect_unknown_callee)
+    {
+      info->call_stmt_size -= (eni_size_weights.indirect_call_cost
+			       - eni_size_weights.call_cost);
+      info->call_stmt_time -= (eni_time_weights.indirect_call_cost
+			       - eni_time_weights.call_cost);
+    }
 }
 
 
Index: ipa-prop.c
===================================================================
--- ipa-prop.c	(revision 219430)
+++ ipa-prop.c	(working copy)
@@ -2737,7 +2737,20 @@ 
 		       ie->caller->name (), callee->name ());
     }
   if (!speculative)
-    ie = ie->make_direct (callee);
+    {
+      struct cgraph_edge *orig = ie;
+      ie = ie->make_direct (callee);
+      /* If we resolved speculative edge the cost is already up to date
+	 for direct call (adjusted by inline_edge_duplication_hook).  */
+      if (ie == orig)
+	{
+	  es = inline_edge_summary (ie);
+	  es->call_stmt_size -= (eni_size_weights.indirect_call_cost
+				 - eni_size_weights.call_cost);
+	  es->call_stmt_time -= (eni_time_weights.indirect_call_cost
+				 - eni_time_weights.call_cost);
+	}
+    }
   else
     {
       if (!callee->can_be_discarded_p ())
@@ -2747,14 +2760,10 @@ 
 	  if (alias)
 	    callee = alias;
 	}
+      /* make_speculative will update ie's cost to direct call cost. */
       ie = ie->make_speculative
 	     (callee, ie->count * 8 / 10, ie->frequency * 8 / 10);
     }
-  es = inline_edge_summary (ie);
-  es->call_stmt_size -= (eni_size_weights.indirect_call_cost
-			 - eni_size_weights.call_cost);
-  es->call_stmt_time -= (eni_time_weights.indirect_call_cost
-			 - eni_time_weights.call_cost);
 
   return ie;
 }
Index: testsuite/g++.dg/ipa/pr63470.C
===================================================================
--- testsuite/g++.dg/ipa/pr63470.C	(revision 0)
+++ testsuite/g++.dg/ipa/pr63470.C	(revision 0)
@@ -0,0 +1,54 @@ 
+/* PR ipa/63470.C */
+/* { dg-do compile } */
+/* { dg-options "-O2 -finline-functions" } */
+
+class A
+{
+public:
+  virtual bool m_fn1 ();
+  virtual const char **m_fn2 (int);
+  virtual int m_fn3 ();
+};
+class FTjackSupport : A
+{
+  ~FTjackSupport ();
+  bool m_fn1 ();
+  bool m_fn4 ();
+  const char **
+  m_fn2 (int)
+  {
+  }
+  int _inited;
+  int *_jackClient;
+  int _activePathCount;
+}
+
+* a;
+void fn1 (...);
+void fn2 (void *);
+int fn3 (int *);
+FTjackSupport::~FTjackSupport () { m_fn4 (); }
+
+bool
+FTjackSupport::m_fn1 ()
+{
+  if (!_jackClient)
+    return 0;
+  for (int i=0; _activePathCount; ++i)
+    if (m_fn2 (i))
+      fn2 (a);
+  if (m_fn3 ())
+    fn2 (a);
+  if (fn3 (_jackClient))
+    fn1 (0);
+}
+
+bool
+FTjackSupport::m_fn4 ()
+{
+  if (_inited && _jackClient)
+    {
+      m_fn1 ();
+      return 0;
+    }
+}