re PR middle-end/56727 (Recursive call goes through the PLT unnecessarily)
authorYury Gribov <tetra2005@gmail.com>
Fri, 21 Jul 2017 19:48:51 +0000 (19:48 +0000)
committerYury Gribov <ygribov@gcc.gnu.org>
Fri, 21 Jul 2017 19:48:51 +0000 (19:48 +0000)
2017-07-21  Yury Gribov  <tetra2005@gmail.com>

PR middle-end/56727
* ipa-visibility (function_and_variable_visibility): Convert
recursive PLT call to direct call if appropriate.

* gcc.dg/pr56727-1.c: New test.
* gcc.dg/pr56727-2.c: New test.

From-SVN: r250442

gcc/ChangeLog
gcc/ipa-visibility.c
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/pr56727-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/pr56727-2.c [new file with mode: 0644]

index 2033b33789f440bec7de59b2be0466c1fe1329f9..55937a8a34439174b41d30554fcf247acaf73be3 100644 (file)
@@ -1,3 +1,9 @@
+2017-07-21  Yury Gribov  <tetra2005@gmail.com>
+
+       PR middle-end/56727
+       * ipa-visibility (function_and_variable_visibility): Convert
+       recursive PLT call to direct call if appropriate.
+
 2017-07-21  Andrew Pinski  <apinski@cavium.com>
 
        * tree-ssa-sccvn.c (vn_nary_op_eq): Check BIT_INSERT_EXPR's
index 17186e9d2e6156df07108ed3df6c5cced555b113..21321703dbbc3329d1a25b18e8a20b49160c8267 100644 (file)
@@ -83,6 +83,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "cgraph.h"
 #include "calls.h"
 #include "varasm.h"
+#include "ipa-utils.h"
 
 /* Return true when NODE can not be local. Worker for cgraph_local_node_p.  */
 
@@ -617,6 +618,36 @@ function_and_variable_visibility (bool whole_program)
   /* All aliases should be procssed at this point.  */
   gcc_checking_assert (!alias_pairs || !alias_pairs->length ());
 
+  FOR_EACH_DEFINED_FUNCTION (node)
+    {
+      if (node->get_availability () != AVAIL_INTERPOSABLE
+         || DECL_EXTERNAL (node->decl)
+         || node->has_aliases_p ())
+       continue;
+
+      cgraph_node *alias = 0;
+      for (cgraph_edge *e = node->callees; e; e = e->next_callee)
+       {
+         /* Recursive function calls usually can't be interposed.  */
+
+         if (!e->recursive_p ())
+           continue;
+
+         if (!alias)
+           { 
+             alias = dyn_cast<cgraph_node *> (node->noninterposable_alias ());
+             gcc_assert (alias && alias != node);
+           }
+
+         e->redirect_callee (alias);
+         if (gimple_has_body_p (e->caller->decl))
+           { 
+             push_cfun (DECL_STRUCT_FUNCTION (e->caller->decl));
+             e->redirect_call_stmt_to_callee ();
+             pop_cfun (); 
+           }
+       }
+    }
   FOR_EACH_FUNCTION (node)
     {
       int flags = flags_from_decl_or_type (node->decl);
index 530a4abc1a7ca901c1bd6d1006daca770221e381..6ee65b15e974b7c0603e920e2de09e9da18bdc25 100644 (file)
@@ -1,3 +1,9 @@
+2017-07-21  Yury Gribov  <tetra2005@gmail.com>
+
+       PR middle-end/56727
+       * gcc.dg/pr56727-1.c: New test.
+       * gcc.dg/pr56727-2.c: New test.
+
 2017-07-21  Steven Munroe  <munroesj@gcc.gnu.org>
 
        * gcc.target/powerpc/mmx-check.h: New file.
diff --git a/gcc/testsuite/gcc.dg/pr56727-1.c b/gcc/testsuite/gcc.dg/pr56727-1.c
new file mode 100644 (file)
index 0000000..ffc1335
--- /dev/null
@@ -0,0 +1,23 @@
+/* { dg-do compile { target fpic } } */
+/* { dg-options "-O2 -fPIC" } */
+/* { dg-final { scan-assembler-not "@(PLT|plt)" { target i?86-*-* x86_64-*-* powerpc*-*-* } } } */
+
+#define define_func(type) \
+  void f_ ## type (type b) { f_ ## type (0); } \
+  void __attribute__((noinline, noclone)) f_noinline_ ## type (type b) \
+  { f_noinline_ ## type (0); }
+
+define_func(char)
+define_func(short)
+define_func(int)
+define_func(long)
+
+int foo(int n)
+{
+  return (n == 1 || n == 2) ? 1 : foo(n-1) * foo(n-2);
+}
+
+int __attribute__((noinline, noclone)) foo_noinline(int n)
+{
+  return (n == 1 || n == 2) ? 1 : foo_noinline(n-1) * foo_noinline(n-2);
+}
diff --git a/gcc/testsuite/gcc.dg/pr56727-2.c b/gcc/testsuite/gcc.dg/pr56727-2.c
new file mode 100644 (file)
index 0000000..a285d57
--- /dev/null
@@ -0,0 +1,16 @@
+/* { dg-do compile { target fpic } } */
+/* { dg-options "-O2 -fPIC" } */
+/* { dg-final { scan-assembler "@(PLT|plt)" { target i?86-*-* x86_64-*-* powerpc*-*-* } } } */
+
+__attribute__((noinline, noclone))
+void f (short b)
+{
+  f (0);
+}
+
+static void g (short) __attribute__ ((alias ("f")));
+
+void h ()
+{
+  g (0);
+}