* gcc/target.def (TARGET_HAS_IFUNC_P): New target hook.
authorkyukhin <kyukhin@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 27 Mar 2013 09:55:19 +0000 (09:55 +0000)
committerkyukhin <kyukhin@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 27 Mar 2013 09:55:19 +0000 (09:55 +0000)
        * 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@197156 138bc75d-0d04-0410-961f-82ee72b054a4

15 files changed:
gcc/ChangeLog
gcc/config.gcc
gcc/config/i386/i386.c
gcc/config/linux-android.c [new file with mode: 0644]
gcc/config/linux-android.h
gcc/config/linux-protos.h [new file with mode: 0644]
gcc/config/t-linux-android [new file with mode: 0644]
gcc/configure
gcc/configure.ac
gcc/doc/tm.texi
gcc/doc/tm.texi.in
gcc/target.def
gcc/targhooks.c
gcc/targhooks.h
gcc/varasm.c

index f8ae2ac..f00cb04 100644 (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
index 1a0be50..11af65f 100644 (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)
index b835c5d..030183c 100644 (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;
 }
 
diff --git a/gcc/config/linux-android.c b/gcc/config/linux-android.c
new file mode 100644 (file)
index 0000000..d6e47a7
--- /dev/null
@@ -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;
+}
index 2c87c84..831a19c 100644 (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
diff --git a/gcc/config/linux-protos.h b/gcc/config/linux-protos.h
new file mode 100644 (file)
index 0000000..3f926e5
--- /dev/null
@@ -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);
diff --git a/gcc/config/t-linux-android b/gcc/config/t-linux-android
new file mode 100644 (file)
index 0000000..6f9b033
--- /dev/null
@@ -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
index eac96cd..3db6a77 100755 (executable)
@@ -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`
index 40a1af7..e9ad74c 100644 (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
index cbbc82d..9f78ae4 100644 (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
index dfba947..b67df84 100644 (file)
@@ -11177,3 +11177,5 @@ memory model bits are allowed.
 @end deftypefn
 
 @hook TARGET_ATOMIC_TEST_AND_SET_TRUEVAL
+
+@hook TARGET_HAS_IFUNC_P
index 831cad8..3ad5870 100644 (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.  */
index 6c12a4a..61ca005 100644 (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.
 
index d23b352..0837c09 100644 (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);
index 6648103..2532d80 100644 (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