summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoramodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4>2011-04-22 03:58:15 +0000
committeramodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4>2011-04-22 03:58:15 +0000
commit0645b79d6625f5c5f1e34d3b55b0bfbbd41fbc69 (patch)
treed6860081e6a2a506b137d064f1efde41a7f0e3cf
parent9ea58440374b24631f156b145b4b98b207a15f85 (diff)
downloadgcc-0645b79d6625f5c5f1e34d3b55b0bfbbd41fbc69.tar.gz
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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@172855 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog19
-rw-r--r--gcc/config/rs6000/darwin.md72
-rw-r--r--gcc/config/rs6000/rs6000.c85
-rw-r--r--gcc/config/rs6000/rs6000.md89
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.target/powerpc/ppc-pow.c4
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 <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.
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<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"
"*
{
@@ -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<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\";
@@ -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 <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
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)