[PATCH] PR 51469, Make gnu indirect functions always non-local

Michael Meissner meissner@linux.vnet.ibm.com
Thu Dec 8 22:29:00 GMT 2011


I noticed that most of the attr-ifunc tests were failing on the PowerPC.  I
tracked it down to the fact that in varasm.c the indirect function is
considered a local function.  On the powerpc in 64-bit mode or 32-bit mode
under AIX, a local function uses the same TOC value in r2 as the caller, so the
compiler can just implmenet a BL instruction.  For non-local functions, the
compiler issues BL followed by a NOP, which might be modified by the linker to
reload the TOC value into r2.  In the case of the indirect functions, the
linker needs to convert the call to always going through the PLT (procedure
linkage table), and it won't do the optimization if the BL is not followed by a
NOP.

This patch makes indirect functions always non-local, much like weak symbols
are.  Note, in the general case, the resolver function could potentially
resolve to a non-local function, so I feel this patch is correct for all ports.
I did a bootstrap and make check on the powerpc with no regressions, and the
attr-ifunc tests are fixed.  Is it ok to apply to the tree (and backport to
4.6)?

2011-12-08  Michael Meissner  <meissner@the-meissners.org>

	PR rtl-optimization/51469
	* varasm.c (default_binds_local_p_1): If the symbol is a gnu
	indirect function, mark the symbol as non-local.

Index: gcc/varasm.c
===================================================================
--- gcc/varasm.c	(revision 182092)
+++ gcc/varasm.c	(working copy)
@@ -6911,11 +6911,14 @@ default_binds_local_p_1 (const_tree exp,
   /* A non-decl is an entry in the constant pool.  */
   if (!DECL_P (exp))
     local_p = true;
-  /* Weakrefs may not bind locally, even though the weakref itself is
-     always static and therefore local.
-     FIXME: We can resolve this more curefuly by looking at the weakref
-     alias.  */
-  else if (lookup_attribute ("weakref", DECL_ATTRIBUTES (exp)))
+  /* Weakrefs may not bind locally, even though the weakref itself is always
+     static and therefore local.  Similarly, the resolver for ifunc functions
+     might resolve to a non-local function.
+     FIXME: We can resolve the weakref case more curefuly by looking at the
+     weakref alias.  */
+  else if (lookup_attribute ("weakref", DECL_ATTRIBUTES (exp))
+	   || (TREE_CODE (exp) == FUNCTION_DECL
+	       && lookup_attribute ("ifunc", DECL_ATTRIBUTES (exp))))
     local_p = false;
   /* Static variables are always local.  */
   else if (! TREE_PUBLIC (exp))

-- 
Michael Meissner, IBM
5 Technology Place Drive, M/S 2757, Westford, MA 01886-3141, USA
meissner@linux.vnet.ibm.com	fax +1 (978) 399-6899



More information about the Gcc-patches mailing list