rs6000 sibcall test

Alan Modra
Sun Sep 8 01:43:00 GMT 2002

On Sat, Sep 07, 2002 at 07:53:36PM -0700, Richard Henderson wrote:
> On Fri, Sep 06, 2002 at 11:47:04PM +0930, Alan Modra wrote:
> > Fired that off too quickly.  My explanation covers why we need to
> > use binds_local_p, not why TREE_ASM_WRITTEN is necessary.  So
> > back to that question again..
> The only explanation must be that the assumption of
> branch in range.  If the linker takes care of that,
> you're fine.  It doesn't on Alpha.

Thanks for the explanation!  In that case, I think we want the following.

	* config/rs6000/rs6000.c (function_ok_for_sibcall): Use binds_local_p.
	Respect longcall attributes.

This is a bug fix, so a reasonable candidate for inclusion in 3.3.

Index: gcc/config/rs6000/rs6000.c
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.371
diff -u -p -r1.371 rs6000.c
--- gcc/config/rs6000/rs6000.c	7 Sep 2002 00:19:27 -0000	1.371
+++ gcc/config/rs6000/rs6000.c	8 Sep 2002 08:12:10 -0000
@@ -9503,8 +9505,14 @@ function_ok_for_sibcall (fndecl)
-	  || (TREE_ASM_WRITTEN (fndecl) && !flag_pic) || !TREE_PUBLIC (fndecl))
-        return 1;
+	  || (*targetm.binds_local_p) (fndecl))
+	{
+	  tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (fndecl));
+	  if (!lookup_attribute ("longcall", attr_list)
+	      || lookup_attribute ("shortcall", attr_list))
+	    return 1;
+	}
   return 0;

Just for the record, David pointed out another case where sibling calls
in PowerPC64 shared libs could go awry.  If "f1" in a shared lib calls
a local function "f2", then allowing the tail call optimisation from
"f2" to a global function "f3" will cause Horrible Things to happen.
The problem is that the f1 to f2 call _doesn't_ go via a stub, the toc
pointer isn't saved or restored (because f1 and f2 have the same toc
pointer), and when f3 returns (all the way back to f1) we may have a
different toc pointer.  Boom.

With a little extra linker support on powerpc64-linux, we can do

calling func   called func   sibling call OK
   any            local           yes
   local          global          no
   global         global          yes

ie. the last line is an extra case not allowed by this patch.
After 3.3 branches, maybe..

Alan Modra
IBM OzLabs - Linux Technology Centre

More information about the Gcc-patches mailing list