target.def (TARGET_HAS_IFUNC_P): New target hook.

* gcc/target.def (TARGET_HAS_IFUNC_P): New target hook.
        * gcc/doc/tm.texi.in (TARGET_HAS_IFUNC_P): New.
        * gcc/doc/tm.texi: Regenerate.
        * gcc/targhooks.h (default_has_ifunc_p): New.
        * gcc/targhooks.c (default_has_ifunc_p): Ditto.
        * gcc/config/linux-protos.h: New file.
        * gcc/config/linux-android.h (TARGET_HAS_IFUNC_P): Using version of
        this hook for linux which disables support of indirect functions in
        android.
        * gcc/config/linux-android.c: New file.
        * gcc/config/t-linux-android.c: Ditto.
        * gcc/config.gcc: Added new object file linux-android.o.
        * gcc/config/i386/i386.c (ix86_get_function_versions_dispatcher):
        Using TARGET_HAS_IFUNC hook instead of HAVE_GNU_INDIRECT_FUNCTION.
        * gcc/varasm.c (do_assemble_alias): Likewise.
        * configure.ac: Define HAVE_GNU_INDIRECT_FUNCTION as zero if the target
        doesn't support indirect functions.
        * configure: Regenerate.

From-SVN: r197156
This commit is contained in:
Alexander Ivchenko 2013-03-27 09:55:19 +00:00 committed by Kirill Yukhin
parent 78b4e425a6
commit 2f251a0535
15 changed files with 185 additions and 44 deletions

View File

@ -1,3 +1,24 @@
2013-03-27 Alexander Ivchenko <alexander.ivchenko@intel.com>
* gcc/target.def (TARGET_HAS_IFUNC_P): New target hook.
* gcc/doc/tm.texi.in (TARGET_HAS_IFUNC_P): New.
* gcc/doc/tm.texi: Regenerate.
* gcc/targhooks.h (default_has_ifunc_p): New.
* gcc/targhooks.c (default_has_ifunc_p): Ditto.
* gcc/config/linux-protos.h: New file.
* gcc/config/linux-android.h (TARGET_HAS_IFUNC_P): Using version of
this hook for linux which disables support of indirect functions in
android.
* gcc/config/linux-android.c: New file.
* gcc/config/t-linux-android.c: Ditto.
* gcc/config.gcc: Added new object file linux-android.o.
* gcc/config/i386/i386.c (ix86_get_function_versions_dispatcher):
Using TARGET_HAS_IFUNC hook instead of HAVE_GNU_INDIRECT_FUNCTION.
* gcc/varasm.c (do_assemble_alias): Likewise.
* configure.ac: Define HAVE_GNU_INDIRECT_FUNCTION as zero if the target
doesn't support indirect functions.
* configure: Regenerate.
2013-03-27 Bin Cheng <bin.cheng@arm.com>
PR target/56102

View File

@ -664,8 +664,11 @@ case ${target} in
# Add Android userspace support to Linux targets.
case $target in
*linux*)
tm_p_file="${tm_p_file} linux-protos.h"
tmake_file="${tmake_file} t-linux-android"
tm_file="$tm_file linux-android.h"
extra_options="$extra_options linux-android.opt"
extra_objs="$extra_objs linux-android.o"
;;
esac
# Enable compilation for Android by default for *android* targets.
@ -875,8 +878,9 @@ arm*-*-linux-*) # ARM GNU/Linux with ELF
tm_defines="${tm_defines} TARGET_BIG_ENDIAN_DEFAULT=1"
;;
esac
tmake_file="${tmake_file} arm/t-arm arm/t-arm-elf arm/t-bpabi arm/t-linux-eabi"
tm_file="$tm_file arm/bpabi.h arm/linux-eabi.h arm/aout.h vxworks-dummy.h arm/arm.h"
tmake_file="${tmake_file} arm/t-arm arm/t-arm-elf arm/t-bpabi arm/t-linux-eabi t-linux-android"
tm_file="$tm_file arm/bpabi.h arm/linux-eabi.h arm/aout.h arm/arm.h"
extra_objs="$extra_objs linux-android.o"
# Define multilib configuration for arm-linux-androideabi.
case ${target} in
*-androideabi)

View File

@ -29206,7 +29206,7 @@ make_name (tree decl, const char *suffix, bool make_unique)
return global_var_name;
}
#if defined (ASM_OUTPUT_TYPE_DIRECTIVE) && HAVE_GNU_INDIRECT_FUNCTION
#if defined (ASM_OUTPUT_TYPE_DIRECTIVE)
/* Make a dispatcher declaration for the multi-versioned function DECL.
Calls to DECL function will be replaced with calls to the dispatcher
@ -29277,12 +29277,6 @@ ix86_get_function_versions_dispatcher (void *decl)
tree dispatch_decl = NULL;
#if defined (ASM_OUTPUT_TYPE_DIRECTIVE) && HAVE_GNU_INDIRECT_FUNCTION
struct cgraph_function_version_info *it_v = NULL;
struct cgraph_node *dispatcher_node = NULL;
struct cgraph_function_version_info *dispatcher_version_info = NULL;
#endif
struct cgraph_function_version_info *default_version_info = NULL;
gcc_assert (fn != NULL && DECL_FUNCTION_VERSIONED (fn));
@ -29327,30 +29321,40 @@ ix86_get_function_versions_dispatcher (void *decl)
default_node = default_version_info->this_node;
#if defined (ASM_OUTPUT_TYPE_DIRECTIVE) && HAVE_GNU_INDIRECT_FUNCTION
/* Right now, the dispatching is done via ifunc. */
dispatch_decl = make_dispatcher_decl (default_node->symbol.decl);
dispatcher_node = cgraph_get_create_node (dispatch_decl);
gcc_assert (dispatcher_node != NULL);
dispatcher_node->dispatcher_function = 1;
dispatcher_version_info
= insert_new_cgraph_node_version (dispatcher_node);
dispatcher_version_info->next = default_version_info;
dispatcher_node->local.finalized = 1;
/* Set the dispatcher for all the versions. */
it_v = default_version_info;
while (it_v != NULL)
#if defined (ASM_OUTPUT_TYPE_DIRECTIVE)
if (targetm.has_ifunc_p ())
{
it_v->dispatcher_resolver = dispatch_decl;
it_v = it_v->next;
struct cgraph_function_version_info *it_v = NULL;
struct cgraph_node *dispatcher_node = NULL;
struct cgraph_function_version_info *dispatcher_version_info = NULL;
/* Right now, the dispatching is done via ifunc. */
dispatch_decl = make_dispatcher_decl (default_node->symbol.decl);
dispatcher_node = cgraph_get_create_node (dispatch_decl);
gcc_assert (dispatcher_node != NULL);
dispatcher_node->dispatcher_function = 1;
dispatcher_version_info
= insert_new_cgraph_node_version (dispatcher_node);
dispatcher_version_info->next = default_version_info;
dispatcher_node->local.finalized = 1;
/* Set the dispatcher for all the versions. */
it_v = default_version_info;
while (it_v != NULL)
{
it_v->dispatcher_resolver = dispatch_decl;
it_v = it_v->next;
}
}
#else
error_at (DECL_SOURCE_LOCATION (default_node->symbol.decl),
"multiversioning needs ifunc which is not supported "
"in this configuration");
else
#endif
{
error_at (DECL_SOURCE_LOCATION (default_node->symbol.decl),
"multiversioning needs ifunc which is not supported "
"on this target");
}
return dispatch_decl;
}

View File

@ -0,0 +1,33 @@
/* Functions for Linux Android as target machine for GNU C compiler.
Copyright (C) 2013.
Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "linux-protos.h"
/* Android does not support GNU indirect functions. */
bool
linux_android_has_ifunc_p (void)
{
return TARGET_ANDROID ? false : HAVE_GNU_INDIRECT_FUNCTION;
}

View File

@ -57,3 +57,6 @@
#define ANDROID_ENDFILE_SPEC \
"%{shared: crtend_so%O%s;: crtend_android%O%s}"
#undef TARGET_HAS_IFUNC_P
#define TARGET_HAS_IFUNC_P linux_android_has_ifunc_p

21
gcc/config/linux-protos.h Normal file
View File

@ -0,0 +1,21 @@
/* Prototypes.
Copyright (C) 2013.
Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
extern bool linux_android_has_ifunc_p (void);

View File

@ -0,0 +1,23 @@
# Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2013
# Free Software Foundation, Inc.
#
# This file is part of GCC.
#
# GCC is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GCC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GCC; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>.
linux-android.o: $(srcdir)/config/linux-android.c $(CONFIG_H) $(SYSTEM_H) \
coretypes.h $(TM_H) $(TM_P_H)
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
$(srcdir)/config/linux-android.c

9
gcc/configure vendored
View File

@ -22055,11 +22055,14 @@ else
enable_gnu_indirect_function="$default_gnu_indirect_function"
fi
if test x$enable_gnu_indirect_function = xyes; then
$as_echo "#define HAVE_GNU_INDIRECT_FUNCTION 1" >>confdefs.h
gif=`if test x$enable_gnu_indirect_function = xyes; then echo 1; else echo 0; fi`
cat >>confdefs.h <<_ACEOF
#define HAVE_GNU_INDIRECT_FUNCTION $gif
_ACEOF
fi
if test $in_tree_ld != yes ; then
ld_ver=`$gcc_cv_ld --version 2>/dev/null | sed 1q`

View File

@ -2299,10 +2299,11 @@ AC_ARG_ENABLE(gnu-indirect-function,
Valid choices are 'yes' and 'no'.]) ;;
esac],
[enable_gnu_indirect_function="$default_gnu_indirect_function"])
if test x$enable_gnu_indirect_function = xyes; then
AC_DEFINE(HAVE_GNU_INDIRECT_FUNCTION, 1,
[Define if your system supports gnu indirect functions.])
fi
gif=`if test x$enable_gnu_indirect_function = xyes; then echo 1; else echo 0; fi`
AC_DEFINE_UNQUOTED(HAVE_GNU_INDIRECT_FUNCTION, $gif,
[Define if your system supports gnu indirect functions.])
changequote(,)dnl
if test $in_tree_ld != yes ; then

View File

@ -11341,3 +11341,9 @@ memory model bits are allowed.
@deftypevr {Target Hook} {unsigned char} TARGET_ATOMIC_TEST_AND_SET_TRUEVAL
This value should be set if the result written by @code{atomic_test_and_set} is not exactly 1, i.e. the @code{bool} @code{true}.
@end deftypevr
@deftypefn {Target Hook} bool TARGET_HAS_IFUNC_P (void)
It returns true if the target supports GNU indirect functions.
The support includes the assembler, linker and dynamic linker.
The default value of this hook is based on target's libc.
@end deftypefn

View File

@ -11177,3 +11177,5 @@ memory model bits are allowed.
@end deftypefn
@hook TARGET_ATOMIC_TEST_AND_SET_TRUEVAL
@hook TARGET_HAS_IFUNC_P

View File

@ -1518,6 +1518,15 @@ DEFHOOK
bool, (const_rtx x),
default_use_anchors_for_symbol_p)
/* True if target supports indirect functions. */
DEFHOOK
(has_ifunc_p,
"It returns true if the target supports GNU indirect functions.\n\
The support includes the assembler, linker and dynamic linker.\n\
The default value of this hook is based on target's libc.",
bool, (void),
default_has_ifunc_p)
/* True if it is OK to do sibling call optimization for the specified
call expression EXP. DECL will be the called function, or NULL if
this is an indirect call. */

View File

@ -450,6 +450,14 @@ default_fixed_point_supported_p (void)
return ENABLE_FIXED_POINT;
}
/* True if the target supports GNU indirect functions. */
bool
default_has_ifunc_p (void)
{
return HAVE_GNU_INDIRECT_FUNCTION;
}
/* NULL if INSN insn is valid within a low-overhead loop, otherwise returns
an error message.

View File

@ -72,6 +72,8 @@ extern bool targhook_float_words_big_endian (void);
extern bool default_decimal_float_supported_p (void);
extern bool default_fixed_point_supported_p (void);
extern bool default_has_ifunc_p (void);
extern const char * default_invalid_within_doloop (const_rtx);
extern tree default_builtin_vectorized_function (tree, tree, tree);

View File

@ -5489,14 +5489,15 @@ do_assemble_alias (tree decl, tree target)
}
if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (decl)))
{
#if defined (ASM_OUTPUT_TYPE_DIRECTIVE) && HAVE_GNU_INDIRECT_FUNCTION
ASM_OUTPUT_TYPE_DIRECTIVE
(asm_out_file, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)),
IFUNC_ASM_TYPE);
#else
error_at (DECL_SOURCE_LOCATION (decl),
"ifunc is not supported in this configuration");
#if defined (ASM_OUTPUT_TYPE_DIRECTIVE)
if (targetm.has_ifunc_p ())
ASM_OUTPUT_TYPE_DIRECTIVE
(asm_out_file, IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)),
IFUNC_ASM_TYPE);
else
#endif
error_at (DECL_SOURCE_LOCATION (decl),
"ifunc is not supported on this target");
}
# ifdef ASM_OUTPUT_DEF_FROM_DECLS