diff options
author | amodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-04-22 03:58:15 +0000 |
---|---|---|
committer | amodra <amodra@138bc75d-0d04-0410-961f-82ee72b054a4> | 2011-04-22 03:58:15 +0000 |
commit | 0645b79d6625f5c5f1e34d3b55b0bfbbd41fbc69 (patch) | |
tree | d6860081e6a2a506b137d064f1efde41a7f0e3cf /gcc/config/rs6000/rs6000.c | |
parent | 9ea58440374b24631f156b145b4b98b207a15f85 (diff) | |
download | gcc-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
Diffstat (limited to 'gcc/config/rs6000/rs6000.c')
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 85 |
1 files changed, 58 insertions, 27 deletions
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; } |