diff options
author | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-04-16 13:21:38 +0000 |
---|---|---|
committer | rguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4> | 2010-04-16 13:21:38 +0000 |
commit | 4debfcfc2011ada93fe865e36272fd8b0fb83ba5 (patch) | |
tree | 640a4ede30c1f4cf1f9690d68ebfea15522967e3 /gcc/tree-tailcall.c | |
parent | a66fa75e35be553181a0cf64126f7eb068872b58 (diff) | |
download | gcc-4debfcfc2011ada93fe865e36272fd8b0fb83ba5.tar.gz |
2010-04-16 Richard Guenther <rguenther@suse.de>
PR tree-optimization/43572
* tree-ssa-alias.h (call_may_clobber_ref_p): Declare.
* tree-ssa-alias.c (call_may_clobber_ref_p): Export.
* tree-flow.h (is_call_clobbered): Remove.
* tree-flow-inline.h (is_call_clobbered): Likewise.
* tree-dfa.c (dump_variable): Do not dump call clobber state.
* tree-nrv.c (dest_safe_for_nrv_p): Use the alias oracle.
(execute_return_slot_opt): Adjust.
* tree-tailcall.c (suitable_for_tail_opt_p): Remove
check for call clobbered vars here.
(find_tail_calls): Move tailcall verification to the
proper place.
* gcc.dg/tree-ssa/tailcall-5.c: New testcase.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@158418 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/tree-tailcall.c')
-rw-r--r-- | gcc/tree-tailcall.c | 44 |
1 files changed, 11 insertions, 33 deletions
diff --git a/gcc/tree-tailcall.c b/gcc/tree-tailcall.c index e0d3f4844e9..ca3dffadc75 100644 --- a/gcc/tree-tailcall.c +++ b/gcc/tree-tailcall.c @@ -130,32 +130,9 @@ static void find_tail_calls (basic_block, struct tailcall **); static bool suitable_for_tail_opt_p (void) { - referenced_var_iterator rvi; - tree var; - if (cfun->stdarg) return false; - /* No local variable nor structure field should escape to callees. */ - FOR_EACH_REFERENCED_VAR (var, rvi) - { - if (!is_global_var (var) - /* ??? We do not have a suitable predicate for escaping to - callees. With IPA-PTA the following might be incorrect. - We want to catch - foo { - int i; - bar (&i); - foo (); - } - where bar might store &i somewhere and in the next - recursion should not be able to tell if it got the - same (with tail-recursion applied) or a different - address. */ - && is_call_clobbered (var)) - return false; - } - return true; } /* Returns false when the function is not suitable for tail call optimization @@ -387,6 +364,8 @@ find_tail_calls (basic_block bb, struct tailcall **ret) tree m, a; basic_block abb; size_t idx; + tree var; + referenced_var_iterator rvi; if (!single_succ_p (bb)) return; @@ -442,8 +421,7 @@ find_tail_calls (basic_block bb, struct tailcall **ret) func = gimple_call_fndecl (call); if (func == current_function_decl) { - tree arg, var; - referenced_var_iterator rvi; + tree arg; for (param = DECL_ARGUMENTS (func), idx = 0; param && idx < gimple_call_num_args (call); @@ -474,15 +452,15 @@ find_tail_calls (basic_block bb, struct tailcall **ret) } if (idx == gimple_call_num_args (call) && !param) tail_recursion = true; + } - /* Make sure the tail invocation of this function does not refer - to local variables. */ - FOR_EACH_REFERENCED_VAR (var, rvi) - { - if (!is_global_var (var) - && ref_maybe_used_by_stmt_p (call, var)) - return; - } + /* Make sure the tail invocation of this function does not refer + to local variables. */ + FOR_EACH_REFERENCED_VAR (var, rvi) + { + if (!is_global_var (var) + && ref_maybe_used_by_stmt_p (call, var)) + return; } /* Now check the statements after the call. None of them has virtual |