re PR middle-end/56727 (Recursive call goes through the PLT unnecessarily)
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
This commit is contained in:
parent
d5c125ca0c
commit
325fe81618
5 changed files with 82 additions and 0 deletions
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
23
gcc/testsuite/gcc.dg/pr56727-1.c
Normal file
23
gcc/testsuite/gcc.dg/pr56727-1.c
Normal file
|
@ -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);
|
||||
}
|
16
gcc/testsuite/gcc.dg/pr56727-2.c
Normal file
16
gcc/testsuite/gcc.dg/pr56727-2.c
Normal file
|
@ -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);
|
||||
}
|
Loading…
Add table
Reference in a new issue