rs6000.c (rs6000_function_arg): Remove CALL_LIBCALL when returning call_cookie.
authorAlan Modra <amodra@gmail.com>
Fri, 22 Apr 2011 03:58:15 +0000 (13:28 +0930)
committerAlan Modra <amodra@gcc.gnu.org>
Fri, 22 Apr 2011 03:58:15 +0000 (13:28 +0930)
gcc/
* config/rs6000/rs6000.c (rs6000_function_arg): Remove CALL_LIBCALL
when returning call_cookie.
(rs6000_function_ok_for_sibcall): Allow sibcalls via function
pointers, to functions with no more vector args than the current
function, and some non-local calls for ABI_V4.
* config/rs6000/rs6000.md (sibcall_nonlocal_aix32,
sibcall_nonlocal_aix64): Combine to ..
(sibcall_nonlocal_aix<mode>): ..this.  Handle function pointer calls.
(sibcall_value_nonlocal_aix32, sibcall_value_nonlocal_aix64): Combine..
(sibcall_value_nonlocal_aix<mode>): ..likewise.
(*sibcall_nonlocal_sysv<mode>): Handle function pointer calls.
(sibcall_value_nonlocal_sysv<mode>): Likewise.  Correct call cookie
operand.
* config/rs6000/darwin.md (sibcall_nonlocal_darwin64,
sibcall_value_nonlocal_darwin64, sibcall_symbolic_64,
sibcall_value_symbolic_64): Delete.
gcc/testsuite/
* gcc.target/powerpc/ppc-pow.c: Allow for tail calls.

From-SVN: r172855

gcc/ChangeLog
gcc/config/rs6000/darwin.md
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/ppc-pow.c

index ce3df3d38a3453c5910ca3f6882fb47faee8555d..ec3b8d1ba8badb9dc8be9cd2c8749d889b9d992a 100644 (file)
@@ -1,3 +1,22 @@
+2011-04-22  Alan Modra  <amodra@gmail.com>
+
+       * config/rs6000/rs6000.c (rs6000_function_arg): Remove CALL_LIBCALL
+       when returning call_cookie.
+       (rs6000_function_ok_for_sibcall): Allow sibcalls via function
+       pointers, to functions with no more vector args than the current
+       function, and some non-local calls for ABI_V4.
+       * config/rs6000/rs6000.md (sibcall_nonlocal_aix32,
+       sibcall_nonlocal_aix64): Combine to ..
+       (sibcall_nonlocal_aix<mode>): ..this.  Handle function pointer calls.
+       (sibcall_value_nonlocal_aix32, sibcall_value_nonlocal_aix64): Combine..
+       (sibcall_value_nonlocal_aix<mode>): ..likewise.
+       (*sibcall_nonlocal_sysv<mode>): Handle function pointer calls.
+       (sibcall_value_nonlocal_sysv<mode>): Likewise.  Correct call cookie
+       operand.
+       * config/rs6000/darwin.md (sibcall_nonlocal_darwin64,
+       sibcall_value_nonlocal_darwin64, sibcall_symbolic_64,
+       sibcall_value_symbolic_64): Delete.
+
 2011-04-21  Xinliang David Li  <davidxl@google.com>
 
        * cgraph.h: Remove pid.
index 6b1927779451ab3515a3905cac9094a6259ac6f6..e811822223a6f08ea7a5fda48c82ac2d32902689 100644 (file)
@@ -1,5 +1,5 @@
 /* Machine description patterns for PowerPC running Darwin (Mac OS X).
-   Copyright (C) 2004, 2005, 2007, 2010 Free Software Foundation, Inc.
+   Copyright (C) 2004, 2005, 2007, 2010, 2011 Free Software Foundation, Inc.
    Contributed by Apple Computer Inc.
 
 This file is part of GCC.
@@ -370,73 +370,3 @@ You should have received a copy of the GNU General Public License
 }
   [(set_attr "type" "branch,branch")
    (set_attr "length" "4,8")])
-
-(define_insn "*sibcall_nonlocal_darwin64"
-  [(call (mem:SI (match_operand:DI 0 "symbol_ref_operand" "s,s"))
-        (match_operand 1 "" ""))
-   (use (match_operand 2 "immediate_operand" "O,n"))
-   (use (reg:SI 65))
-   (return)]
-  "(DEFAULT_ABI == ABI_DARWIN)
-   && (INTVAL (operands[2]) & CALL_LONG) == 0"
-{
-  return "b %z0";
-}
-  [(set_attr "type" "branch,branch")
-   (set_attr "length" "4,8")])
-
-(define_insn "*sibcall_value_nonlocal_darwin64"
-  [(set (match_operand 0 "" "")
-       (call (mem:SI (match_operand:DI 1 "symbol_ref_operand" "s,s"))
-             (match_operand 2 "" "")))
-   (use (match_operand:SI 3 "immediate_operand" "O,n"))
-   (use (reg:SI 65))
-   (return)]
-  "(DEFAULT_ABI == ABI_DARWIN)
-   && (INTVAL (operands[3]) & CALL_LONG) == 0"
-  "*
-{
-  return \"b %z1\";
-}"
-  [(set_attr "type" "branch,branch")
-   (set_attr "length" "4,8")])
-
-
-(define_insn "*sibcall_symbolic_64"
-  [(call (mem:SI (match_operand:DI 0 "call_operand" "s,c")) ; 64
-        (match_operand 1 "" ""))
-   (use (match_operand 2 "" ""))
-   (use (reg:SI 65))
-   (return)]
-  "TARGET_64BIT && DEFAULT_ABI == ABI_DARWIN"
-  "*
-{
-  switch (which_alternative)
-    {
-      case 0:  return \"b %z0\";
-      case 1:  return \"b%T0\";
-      default:  gcc_unreachable ();
-    }
-}"
-  [(set_attr "type" "branch")
-   (set_attr "length" "4")])
-
-(define_insn "*sibcall_value_symbolic_64"
-  [(set (match_operand 0 "" "")
-       (call (mem:SI (match_operand:DI 1 "call_operand" "s,c"))
-             (match_operand 2 "" "")))
-   (use (match_operand:SI 3 "" ""))
-   (use (reg:SI 65))
-   (return)]
-  "TARGET_64BIT && DEFAULT_ABI == ABI_DARWIN"
-  "*
-{
-  switch (which_alternative)
-    {
-      case 0:  return \"b %z1\";
-      case 1:  return \"b%T1\";
-      default:  gcc_unreachable ();
-    }
-}"
-  [(set_attr "type" "branch")
-   (set_attr "length" "4")])
index 4f095a26207f3487a8b9db19063edffc326c62ba..e98b5f39b599cdd0922302e7165932967aaff1fd 100644 (file)
@@ -19307,39 +19307,70 @@ rs6000_return_addr (int count, rtx frame)
   return get_hard_reg_initial_val (Pmode, LR_REGNO);
 }
 
-/* Say whether a function is a candidate for sibcall handling or not.
-   We do not allow indirect calls to be optimized into sibling calls.
-   Also, we can't do it if there are any vector parameters; there's
-   nowhere to put the VRsave code so it works; note that functions with
-   vector parameters are required to have a prototype, so the argument
-   type info must be available here.  (The tail recursion case can work
-   with vector parameters, but there's no way to distinguish here.) */
+/* Say whether a function is a candidate for sibcall handling or not.  */
+
 static bool
-rs6000_function_ok_for_sibcall (tree decl, tree exp ATTRIBUTE_UNUSED)
+rs6000_function_ok_for_sibcall (tree decl, tree exp)
 {
-  tree type;
+  tree fntype;
+
   if (decl)
+    fntype = TREE_TYPE (decl);
+  else
+    fntype = TREE_TYPE (TREE_TYPE (CALL_EXPR_FN (exp)));
+
+  /* We can't do it if the called function has more vector parameters
+     than the current function; there's nowhere to put the VRsave code.  */
+  if (TARGET_ALTIVEC_ABI
+      && TARGET_ALTIVEC_VRSAVE
+      && !(decl && decl == current_function_decl))
     {
-      if (TARGET_ALTIVEC_VRSAVE)
-       {
-         for (type = TYPE_ARG_TYPES (TREE_TYPE (decl));
-              type; type = TREE_CHAIN (type))
-           {
-             if (TREE_CODE (TREE_VALUE (type)) == VECTOR_TYPE)
-               return false;
-           }
-       }
-      if (DEFAULT_ABI == ABI_DARWIN
-         || ((*targetm.binds_local_p) (decl)
-             && (DEFAULT_ABI != ABI_AIX || !DECL_EXTERNAL (decl))))
-       {
-         tree attr_list = TYPE_ATTRIBUTES (TREE_TYPE (decl));
+      function_args_iterator args_iter;
+      tree type;
+      int nvreg = 0;
+
+      /* Functions with vector parameters are required to have a
+        prototype, so the argument type info must be available
+        here.  */
+      FOREACH_FUNCTION_ARGS(fntype, type, args_iter)
+       if (TREE_CODE (type) == VECTOR_TYPE
+           && (ALTIVEC_VECTOR_MODE (TYPE_MODE (type))
+               || VSX_VECTOR_MODE (TYPE_MODE (type))))
+         nvreg++;
+
+      FOREACH_FUNCTION_ARGS(TREE_TYPE (current_function_decl), type, args_iter)
+       if (TREE_CODE (type) == VECTOR_TYPE
+           && (ALTIVEC_VECTOR_MODE (TYPE_MODE (type))
+               || VSX_VECTOR_MODE (TYPE_MODE (type))))
+         nvreg--;
+
+      if (nvreg > 0)
+       return false;
+    }
 
-         if (!lookup_attribute ("longcall", attr_list)
-             || lookup_attribute ("shortcall", attr_list))
-           return true;
-       }
+  /* Under the AIX ABI we can't allow calls to non-local functions,
+     because the callee may have a different TOC pointer to the
+     caller and there's no way to ensure we restore the TOC when we
+     return.  With the secure-plt SYSV ABI we can't make non-local
+     calls when -fpic/PIC because the plt call stubs use r30.  */
+  if (DEFAULT_ABI == ABI_DARWIN
+      || (DEFAULT_ABI == ABI_AIX
+         && decl
+         && !DECL_EXTERNAL (decl)
+         && (*targetm.binds_local_p) (decl))
+      || (DEFAULT_ABI == ABI_V4
+         && (!TARGET_SECURE_PLT
+             || !flag_pic
+             || (decl
+                 && (*targetm.binds_local_p) (decl)))))
+    {
+      tree attr_list = TYPE_ATTRIBUTES (fntype);
+
+      if (!lookup_attribute ("longcall", attr_list)
+         || lookup_attribute ("shortcall", attr_list))
+       return true;
     }
+
   return false;
 }
 
index 89836d7d63213990a49562cff5066996a2d6d193..586e9e4a83b29d9d67468a43b296d3d0a5fbe3db 100644 (file)
   [(set_attr "type" "branch")
    (set_attr "length" "4,8")])
 
-(define_insn "*sibcall_nonlocal_aix32"
-  [(call (mem:SI (match_operand:SI 0 "symbol_ref_operand" "s"))
-        (match_operand 1 "" "g"))
-   (use (match_operand:SI 2 "immediate_operand" "O"))
-   (use (reg:SI LR_REGNO))
-   (return)]
-  "TARGET_32BIT
-   && DEFAULT_ABI == ABI_AIX
-   && (INTVAL (operands[2]) & CALL_LONG) == 0"
-  "b %z0"
-  [(set_attr "type" "branch")
-   (set_attr "length" "4")])
-
-(define_insn "*sibcall_nonlocal_aix64"
-  [(call (mem:SI (match_operand:DI 0 "symbol_ref_operand" "s"))
-        (match_operand 1 "" "g"))
-   (use (match_operand:SI 2 "immediate_operand" "O"))
+(define_insn "*sibcall_nonlocal_aix<mode>"
+  [(call (mem:SI (match_operand:P 0 "call_operand" "s,c"))
+        (match_operand 1 "" "g,g"))
+   (use (match_operand:SI 2 "immediate_operand" "O,O"))
    (use (reg:SI LR_REGNO))
    (return)]
-  "TARGET_64BIT
-   && DEFAULT_ABI == ABI_AIX
+  "DEFAULT_ABI == ABI_AIX
    && (INTVAL (operands[2]) & CALL_LONG) == 0"
-  "b %z0"
-  [(set_attr "type" "branch")
-   (set_attr "length" "4")])
-
-(define_insn "*sibcall_value_nonlocal_aix32"
-  [(set (match_operand 0 "" "")
-       (call (mem:SI (match_operand:SI 1 "symbol_ref_operand" "s"))
-             (match_operand 2 "" "g")))
-   (use (match_operand:SI 3 "immediate_operand" "O"))
-   (use (reg:SI LR_REGNO))
-   (return)]
-  "TARGET_32BIT
-   && DEFAULT_ABI == ABI_AIX
-   && (INTVAL (operands[3]) & CALL_LONG) == 0"
-  "b %z1"
+  "@
+   b %z0
+   b%T0"
   [(set_attr "type" "branch")
    (set_attr "length" "4")])
 
-(define_insn "*sibcall_value_nonlocal_aix64"
+(define_insn "*sibcall_value_nonlocal_aix<mode>"
   [(set (match_operand 0 "" "")
-       (call (mem:SI (match_operand:DI 1 "symbol_ref_operand" "s"))
-             (match_operand 2 "" "g")))
-   (use (match_operand:SI 3 "immediate_operand" "O"))
+       (call (mem:SI (match_operand:P 1 "call_operand" "s,c"))
+             (match_operand 2 "" "g,g")))
+   (use (match_operand:SI 3 "immediate_operand" "O,O"))
    (use (reg:SI LR_REGNO))
    (return)]
-  "TARGET_64BIT
-   && DEFAULT_ABI == ABI_AIX
+  "DEFAULT_ABI == ABI_AIX
    && (INTVAL (operands[3]) & CALL_LONG) == 0"
-  "b %z1"
+  "@
+   b %z1
+   b%T1"
   [(set_attr "type" "branch")
    (set_attr "length" "4")])
 
 (define_insn "*sibcall_nonlocal_sysv<mode>"
-  [(call (mem:SI (match_operand:P 0 "symbol_ref_operand" "s,s"))
+  [(call (mem:SI (match_operand:P 0 "call_operand" "s,s,c,c"))
         (match_operand 1 "" ""))
-   (use (match_operand 2 "immediate_operand" "O,n"))
+   (use (match_operand 2 "immediate_operand" "O,n,O,n"))
    (use (reg:SI LR_REGNO))
    (return)]
   "(DEFAULT_ABI == ABI_DARWIN
-     || DEFAULT_ABI == ABI_V4)
+    || DEFAULT_ABI == ABI_V4)
    && (INTVAL (operands[2]) & CALL_LONG) == 0"
   "*
 {
   else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
     output_asm_insn (\"creqv 6,6,6\", operands);
 
-  if (DEFAULT_ABI == ABI_V4 && flag_pic)
+  if (which_alternative >= 2)
+    return \"b%T0\";
+  else if (DEFAULT_ABI == ABI_V4 && flag_pic)
     {
       gcc_assert (!TARGET_SECURE_PLT);
       return \"b %z0@plt\";
   else
     return \"b %z0\";
 }"
-  [(set_attr "type" "branch,branch")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "branch")
+   (set_attr "length" "4,8,4,8")])
 
 (define_expand "sibcall_value"
   [(parallel [(set (match_operand 0 "register_operand" "")
 
 (define_insn "*sibcall_value_nonlocal_sysv<mode>"
   [(set (match_operand 0 "" "")
-       (call (mem:SI (match_operand:P 1 "symbol_ref_operand" "s,s"))
+       (call (mem:SI (match_operand:P 1 "call_operand" "s,s,c,c"))
              (match_operand 2 "" "")))
-   (use (match_operand:SI 3 "immediate_operand" "O,n"))
+   (use (match_operand:SI 3 "immediate_operand" "O,n,O,n"))
    (use (reg:SI LR_REGNO))
    (return)]
   "(DEFAULT_ABI == ABI_DARWIN
-       || DEFAULT_ABI == ABI_V4)
+    || DEFAULT_ABI == ABI_V4)
    && (INTVAL (operands[3]) & CALL_LONG) == 0"
   "*
 {
-  if (INTVAL (operands[2]) & CALL_V4_SET_FP_ARGS)
+  if (INTVAL (operands[3]) & CALL_V4_SET_FP_ARGS)
     output_asm_insn (\"crxor 6,6,6\", operands);
 
-  else if (INTVAL (operands[2]) & CALL_V4_CLEAR_FP_ARGS)
+  else if (INTVAL (operands[3]) & CALL_V4_CLEAR_FP_ARGS)
     output_asm_insn (\"creqv 6,6,6\", operands);
 
-  if (DEFAULT_ABI == ABI_V4 && flag_pic)
+  if (which_alternative >= 2)
+    return \"b%T1\";
+  else if (DEFAULT_ABI == ABI_V4 && flag_pic)
     {
       gcc_assert (!TARGET_SECURE_PLT);
       return \"b %z1@plt\";
   else
     return \"b %z1\";
 }"
-  [(set_attr "type" "branch,branch")
-   (set_attr "length" "4,8")])
+  [(set_attr "type" "branch")
+   (set_attr "length" "4,8,4,8")])
 
 (define_expand "sibcall_epilogue"
   [(use (const_int 0))]
index 304ecb695ca4e0e94da8c3fdfb6344dc140f6393..da59b77a5dbd561fdc9417867db60d54fbd83e17 100644 (file)
@@ -1,3 +1,7 @@
+2011-04-22  Alan Modra  <amodra@gmail.com>
+
+       * gcc.target/powerpc/ppc-pow.c: Allow for tail calls.
+
 2011-04-21  Thomas Koenig  <tkoenig@gcc.gnu.org>
 
        PR fortran/48405
index 1255d5c5966ffaef4f6930580de147bc6bc72d38..e88125c1d98a96db97db6d7b25d1049f4220d795 100644 (file)
@@ -2,8 +2,8 @@
 /* { dg-options "-O2 -ffast-math -mcpu=power6" } */
 /* { dg-final { scan-assembler-times "fsqrt" 3 } } */
 /* { dg-final { scan-assembler-times "fmul" 1 } } */
-/* { dg-final { scan-assembler-times "bl pow" 1 } } */
-/* { dg-final { scan-assembler-times "bl sqrt" 1 } } */
+/* { dg-final { scan-assembler-times "bl? pow" 1 } } */
+/* { dg-final { scan-assembler-times "bl? sqrt" 1 } } */
 
 double
 do_pow_0_75_default (double a)