From 401f66999f930fde26fe1d5602371b319ddd9f25 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Fri, 22 Apr 2011 13:28:15 +0930 Subject: [PATCH] rs6000.c (rs6000_function_arg): Remove CALL_LIBCALL when returning call_cookie. 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): ..this. Handle function pointer calls. (sibcall_value_nonlocal_aix32, sibcall_value_nonlocal_aix64): Combine.. (sibcall_value_nonlocal_aix): ..likewise. (*sibcall_nonlocal_sysv): Handle function pointer calls. (sibcall_value_nonlocal_sysv): 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 | 19 +++++ gcc/config/rs6000/darwin.md | 72 +---------------- gcc/config/rs6000/rs6000.c | 85 ++++++++++++++------- gcc/config/rs6000/rs6000.md | 89 +++++++++------------- gcc/testsuite/ChangeLog | 4 + gcc/testsuite/gcc.target/powerpc/ppc-pow.c | 4 +- 6 files changed, 118 insertions(+), 155 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ce3df3d38a3..ec3b8d1ba8b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,22 @@ +2011-04-22 Alan Modra + + * 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): ..this. Handle function pointer calls. + (sibcall_value_nonlocal_aix32, sibcall_value_nonlocal_aix64): Combine.. + (sibcall_value_nonlocal_aix): ..likewise. + (*sibcall_nonlocal_sysv): Handle function pointer calls. + (sibcall_value_nonlocal_sysv): 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 * cgraph.h: Remove pid. diff --git a/gcc/config/rs6000/darwin.md b/gcc/config/rs6000/darwin.md index 6b192777945..e811822223a 100644 --- a/gcc/config/rs6000/darwin.md +++ b/gcc/config/rs6000/darwin.md @@ -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")]) diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 4f095a26207..e98b5f39b59 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -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; } diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 89836d7d632..586e9e4a83b 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -12963,68 +12963,43 @@ [(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" + [(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" [(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" - [(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" "* { @@ -13034,7 +13009,9 @@ 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\"; @@ -13042,8 +13019,8 @@ 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" "") @@ -13068,23 +13045,25 @@ (define_insn "*sibcall_value_nonlocal_sysv" [(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\"; @@ -13092,8 +13071,8 @@ 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))] diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 304ecb695ca..da59b77a5db 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2011-04-22 Alan Modra + + * gcc.target/powerpc/ppc-pow.c: Allow for tail calls. + 2011-04-21 Thomas Koenig PR fortran/48405 diff --git a/gcc/testsuite/gcc.target/powerpc/ppc-pow.c b/gcc/testsuite/gcc.target/powerpc/ppc-pow.c index 1255d5c5966..e88125c1d98 100644 --- a/gcc/testsuite/gcc.target/powerpc/ppc-pow.c +++ b/gcc/testsuite/gcc.target/powerpc/ppc-pow.c @@ -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) -- 2.30.2