PR 51469, Make gnu indirect functions always non-local

Submitted by Michael Meissner on Dec. 8, 2011, 10:29 p.m.

Details

Message ID 20111208222918.GA19135@ibm-tiger.the-meissners.org
State New
Headers show

Commit Message

Michael Meissner Dec. 8, 2011, 10:29 p.m.
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.

Comments

Richard Henderson Dec. 8, 2011, 11 p.m.
On 12/08/2011 02:29 PM, Michael Meissner wrote:
> 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.

Ok everywhere.


r~

Patch hide | download patch | download mbox

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))