re PR ipa/63470 (internal compiler error: in estimate_edge_growth, at ipa-inline...
authorJan Hubicka <hubicka@ucw.cz>
Mon, 12 Jan 2015 09:24:18 +0000 (10:24 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Mon, 12 Jan 2015 09:24:18 +0000 (09:24 +0000)
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.

From-SVN: r219451

gcc/ChangeLog
gcc/ipa-inline-analysis.c
gcc/ipa-prop.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/ipa/pr63470.C [new file with mode: 0644]

index 5331044514a21e22560afcb0f47932e4b2253818..29dab900e8c5119cc71e263825004fdead766c0d 100644 (file)
@@ -1,3 +1,11 @@
+2015-01-12  Jan Hubicka  <hubicka@ucw.cz>
+
+       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.
+
 2015-01-12  Chen Gang  <gang.chen.5i5j@gmail.com>
 
        PR ipa/64551
index 92858dad36049606130ce390233986488368f85c..ec91d8ec9af1fb8b7d55244072f54a809b3708ab 100644 (file)
@@ -1312,6 +1312,13 @@ inline_edge_duplication_hook (struct cgraph_edge *src,
   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 a96b2be44d1698b2db38d151c3445e6ea2f5b931..01f4111b097970906b27e468083e8d21cf25e7fe 100644 (file)
@@ -2737,7 +2737,20 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
                       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 @@ ipa_make_edge_direct_to_target (struct cgraph_edge *ie, tree target,
          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 b3b6b59091d2f8950823206f38a2350e85dac14c..937826612e76aa51f610a00ae61f897024cf460f 100644 (file)
@@ -1,3 +1,8 @@
+2015-01-12  Jan Hubicka  <hubicka@ucw.cz>
+
+       PR ipa/63470
+       * testsuite/g++.dg/ipa/pr63470.C: New testcase.
+
 2015-01-11  Janus Weil  <janus@gcc.gnu.org>
 
        PR fortran/63733
diff --git a/gcc/testsuite/g++.dg/ipa/pr63470.C b/gcc/testsuite/g++.dg/ipa/pr63470.C
new file mode 100644 (file)
index 0000000..e6fa73b
--- /dev/null
@@ -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;
+    }
+}