From 4debfcfc2011ada93fe865e36272fd8b0fb83ba5 Mon Sep 17 00:00:00 2001 From: rguenth Date: Fri, 16 Apr 2010 13:21:38 +0000 Subject: [PATCH] 2010-04-16 Richard Guenther 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 --- gcc/ChangeLog | 15 ++++++++++ gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.dg/tree-ssa/tailcall-5.c | 12 ++++++++ gcc/tree-dfa.c | 3 -- gcc/tree-flow-inline.h | 9 ------ gcc/tree-flow.h | 1 - gcc/tree-nrv.c | 20 ++++++-------- gcc/tree-ssa-alias.c | 5 +++- gcc/tree-ssa-alias.h | 1 + gcc/tree-tailcall.c | 44 ++++++++---------------------- 10 files changed, 57 insertions(+), 58 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/tailcall-5.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f06b1baa0fc..bd2dc3c56bf 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2010-04-16 Richard Guenther + + 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. + 2010-04-16 Diego Novillo * doc/invoke.texi: Explain how are unrecognized -Wno- warnings diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 589e80f89c0..b58bb508e88 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2010-04-16 Richard Guenther + + PR tree-optimization/43572 + * gcc.dg/tree-ssa/tailcall-5.c: New testcase. + 2010-04-16 Olivier Hainque * gnat.dg/specs/discr_private.ads: New test. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/tailcall-5.c b/gcc/testsuite/gcc.dg/tree-ssa/tailcall-5.c new file mode 100644 index 00000000000..7aa433ecf7a --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/tailcall-5.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-tailc" } */ + +void +set_integer (void *dest, int value, int length) +{ + int tmp = value; + __builtin_memcpy (dest, (void *) &tmp, length); +} + +/* { dg-final { scan-tree-dump-not "tail call" "tailc" } } */ +/* { dg-final { cleanup-tree-dump "tailc" } } */ diff --git a/gcc/tree-dfa.c b/gcc/tree-dfa.c index a8415b5a825..5475d79254b 100644 --- a/gcc/tree-dfa.c +++ b/gcc/tree-dfa.c @@ -284,9 +284,6 @@ dump_variable (FILE *file, tree var) if (TREE_THIS_VOLATILE (var)) fprintf (file, ", is volatile"); - if (is_call_clobbered (var)) - fprintf (file, ", call clobbered"); - if (ann && ann->noalias_state == NO_ALIAS) fprintf (file, ", NO_ALIAS (does not alias other NO_ALIAS symbols)"); else if (ann && ann->noalias_state == NO_ALIAS_GLOBAL) diff --git a/gcc/tree-flow-inline.h b/gcc/tree-flow-inline.h index 2430f0355f7..f7609ea7911 100644 --- a/gcc/tree-flow-inline.h +++ b/gcc/tree-flow-inline.h @@ -624,15 +624,6 @@ loop_containing_stmt (gimple stmt) } -/* Return true if VAR is clobbered by function calls. */ -static inline bool -is_call_clobbered (const_tree var) -{ - return (is_global_var (var) - || (may_be_aliased (var) - && pt_solution_includes (&cfun->gimple_df->escaped, var))); -} - /* ----------------------------------------------------------------------- */ /* The following set of routines are used to iterator over various type of diff --git a/gcc/tree-flow.h b/gcc/tree-flow.h index fda7a86f2d0..8f9ab5de0f1 100644 --- a/gcc/tree-flow.h +++ b/gcc/tree-flow.h @@ -774,7 +774,6 @@ extern enum move_pos movement_possibility (gimple); char *get_lsm_tmp_name (tree, unsigned); /* In tree-flow-inline.h */ -static inline bool is_call_clobbered (const_tree); static inline void set_is_used (tree); static inline bool unmodifiable_var_p (const_tree); static inline bool ref_contains_array_ref (const_tree); diff --git a/gcc/tree-nrv.c b/gcc/tree-nrv.c index b85c5a76c67..c2e49d32c17 100644 --- a/gcc/tree-nrv.c +++ b/gcc/tree-nrv.c @@ -291,23 +291,21 @@ struct gimple_opt_pass pass_nrv = optimization, where DEST is expected to be the LHS of a modify expression where the RHS is a function returning an aggregate. - We search for a base VAR_DECL and look to see if it is call clobbered. - Note that we could do better, for example, by - attempting to doing points-to analysis on INDIRECT_REFs. */ + DEST is available if it is not clobbered by the call. */ static bool -dest_safe_for_nrv_p (tree dest) +dest_safe_for_nrv_p (gimple call) { - while (handled_component_p (dest)) - dest = TREE_OPERAND (dest, 0); + tree dest = gimple_call_lhs (call); - if (! SSA_VAR_P (dest)) + dest = get_base_address (dest); + if (! dest) return false; if (TREE_CODE (dest) == SSA_NAME) - dest = SSA_NAME_VAR (dest); + return true; - if (is_call_clobbered (dest)) + if (call_may_clobber_ref_p (call, dest)) return false; return true; @@ -346,8 +344,8 @@ execute_return_slot_opt (void) ) { /* Check if the location being assigned to is - call-clobbered. */ - slot_opt_p = dest_safe_for_nrv_p (gimple_call_lhs (stmt)); + clobbered by the call. */ + slot_opt_p = dest_safe_for_nrv_p (stmt); gimple_call_set_return_slot_opt (stmt, slot_opt_p); } } diff --git a/gcc/tree-ssa-alias.c b/gcc/tree-ssa-alias.c index 8b1fdc37556..67c669e8b4b 100644 --- a/gcc/tree-ssa-alias.c +++ b/gcc/tree-ssa-alias.c @@ -1339,7 +1339,10 @@ call_may_clobber_ref_p_1 (gimple call, ao_ref *ref) return true; } -static bool ATTRIBUTE_UNUSED +/* If the call in statement CALL may clobber the memory reference REF + return true, otherwise return false. */ + +bool call_may_clobber_ref_p (gimple call, tree ref) { bool res; diff --git a/gcc/tree-ssa-alias.h b/gcc/tree-ssa-alias.h index 147f3688434..a2b532747c6 100644 --- a/gcc/tree-ssa-alias.h +++ b/gcc/tree-ssa-alias.h @@ -104,6 +104,7 @@ extern bool refs_output_dependent_p (tree, tree); extern bool ref_maybe_used_by_stmt_p (gimple, tree); extern bool stmt_may_clobber_ref_p (gimple, tree); extern bool stmt_may_clobber_ref_p_1 (gimple, ao_ref *); +extern bool call_may_clobber_ref_p (gimple, tree); extern tree get_continuation_for_phi (gimple, ao_ref *, bitmap *); extern void *walk_non_aliased_vuses (ao_ref *, tree, void *(*)(ao_ref *, tree, void *), 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 -- 2.11.0