Commit 12de6355 by Richard Guenther Committed by Richard Biener

re PR tree-optimization/43572 (FAIL: gfortran.dg/PR19872.f execution test;…

re PR tree-optimization/43572 (FAIL: gfortran.dg/PR19872.f execution test; formatted read - wrong numbers)

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.

From-SVN: r158418
parent 6ab643b5
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.
2010-04-16 Diego Novillo <dnovillo@google.com> 2010-04-16 Diego Novillo <dnovillo@google.com>
* doc/invoke.texi: Explain how are unrecognized -Wno- warnings * doc/invoke.texi: Explain how are unrecognized -Wno- warnings
......
2010-04-16 Richard Guenther <rguenther@suse.de>
PR tree-optimization/43572
* gcc.dg/tree-ssa/tailcall-5.c: New testcase.
2010-04-16 Olivier Hainque <hainque@adacore.com> 2010-04-16 Olivier Hainque <hainque@adacore.com>
* gnat.dg/specs/discr_private.ads: New test. * gnat.dg/specs/discr_private.ads: New test.
......
/* { 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" } } */
...@@ -284,9 +284,6 @@ dump_variable (FILE *file, tree var) ...@@ -284,9 +284,6 @@ dump_variable (FILE *file, tree var)
if (TREE_THIS_VOLATILE (var)) if (TREE_THIS_VOLATILE (var))
fprintf (file, ", is volatile"); fprintf (file, ", is volatile");
if (is_call_clobbered (var))
fprintf (file, ", call clobbered");
if (ann && ann->noalias_state == NO_ALIAS) if (ann && ann->noalias_state == NO_ALIAS)
fprintf (file, ", NO_ALIAS (does not alias other NO_ALIAS symbols)"); fprintf (file, ", NO_ALIAS (does not alias other NO_ALIAS symbols)");
else if (ann && ann->noalias_state == NO_ALIAS_GLOBAL) else if (ann && ann->noalias_state == NO_ALIAS_GLOBAL)
......
...@@ -624,15 +624,6 @@ loop_containing_stmt (gimple stmt) ...@@ -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 /* The following set of routines are used to iterator over various type of
......
...@@ -774,7 +774,6 @@ extern enum move_pos movement_possibility (gimple); ...@@ -774,7 +774,6 @@ extern enum move_pos movement_possibility (gimple);
char *get_lsm_tmp_name (tree, unsigned); char *get_lsm_tmp_name (tree, unsigned);
/* In tree-flow-inline.h */ /* In tree-flow-inline.h */
static inline bool is_call_clobbered (const_tree);
static inline void set_is_used (tree); static inline void set_is_used (tree);
static inline bool unmodifiable_var_p (const_tree); static inline bool unmodifiable_var_p (const_tree);
static inline bool ref_contains_array_ref (const_tree); static inline bool ref_contains_array_ref (const_tree);
......
...@@ -291,23 +291,21 @@ struct gimple_opt_pass pass_nrv = ...@@ -291,23 +291,21 @@ struct gimple_opt_pass pass_nrv =
optimization, where DEST is expected to be the LHS of a modify optimization, where DEST is expected to be the LHS of a modify
expression where the RHS is a function returning an aggregate. 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. DEST is available if it is not clobbered by the call. */
Note that we could do better, for example, by
attempting to doing points-to analysis on INDIRECT_REFs. */
static bool static bool
dest_safe_for_nrv_p (tree dest) dest_safe_for_nrv_p (gimple call)
{ {
while (handled_component_p (dest)) tree dest = gimple_call_lhs (call);
dest = TREE_OPERAND (dest, 0);
if (! SSA_VAR_P (dest)) dest = get_base_address (dest);
if (! dest)
return false; return false;
if (TREE_CODE (dest) == SSA_NAME) 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 false;
return true; return true;
...@@ -346,8 +344,8 @@ execute_return_slot_opt (void) ...@@ -346,8 +344,8 @@ execute_return_slot_opt (void)
) )
{ {
/* Check if the location being assigned to is /* Check if the location being assigned to is
call-clobbered. */ clobbered by the call. */
slot_opt_p = dest_safe_for_nrv_p (gimple_call_lhs (stmt)); slot_opt_p = dest_safe_for_nrv_p (stmt);
gimple_call_set_return_slot_opt (stmt, slot_opt_p); gimple_call_set_return_slot_opt (stmt, slot_opt_p);
} }
} }
......
...@@ -1339,7 +1339,10 @@ call_may_clobber_ref_p_1 (gimple call, ao_ref *ref) ...@@ -1339,7 +1339,10 @@ call_may_clobber_ref_p_1 (gimple call, ao_ref *ref)
return true; 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) call_may_clobber_ref_p (gimple call, tree ref)
{ {
bool res; bool res;
......
...@@ -104,6 +104,7 @@ extern bool refs_output_dependent_p (tree, tree); ...@@ -104,6 +104,7 @@ extern bool refs_output_dependent_p (tree, tree);
extern bool ref_maybe_used_by_stmt_p (gimple, 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 (gimple, tree);
extern bool stmt_may_clobber_ref_p_1 (gimple, ao_ref *); 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 tree get_continuation_for_phi (gimple, ao_ref *, bitmap *);
extern void *walk_non_aliased_vuses (ao_ref *, tree, extern void *walk_non_aliased_vuses (ao_ref *, tree,
void *(*)(ao_ref *, tree, void *), void *(*)(ao_ref *, tree, void *),
......
...@@ -130,32 +130,9 @@ static void find_tail_calls (basic_block, struct tailcall **); ...@@ -130,32 +130,9 @@ static void find_tail_calls (basic_block, struct tailcall **);
static bool static bool
suitable_for_tail_opt_p (void) suitable_for_tail_opt_p (void)
{ {
referenced_var_iterator rvi;
tree var;
if (cfun->stdarg) if (cfun->stdarg)
return false; 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; return true;
} }
/* Returns false when the function is not suitable for tail call optimization /* 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) ...@@ -387,6 +364,8 @@ find_tail_calls (basic_block bb, struct tailcall **ret)
tree m, a; tree m, a;
basic_block abb; basic_block abb;
size_t idx; size_t idx;
tree var;
referenced_var_iterator rvi;
if (!single_succ_p (bb)) if (!single_succ_p (bb))
return; return;
...@@ -442,8 +421,7 @@ find_tail_calls (basic_block bb, struct tailcall **ret) ...@@ -442,8 +421,7 @@ find_tail_calls (basic_block bb, struct tailcall **ret)
func = gimple_call_fndecl (call); func = gimple_call_fndecl (call);
if (func == current_function_decl) if (func == current_function_decl)
{ {
tree arg, var; tree arg;
referenced_var_iterator rvi;
for (param = DECL_ARGUMENTS (func), idx = 0; for (param = DECL_ARGUMENTS (func), idx = 0;
param && idx < gimple_call_num_args (call); param && idx < gimple_call_num_args (call);
...@@ -474,6 +452,7 @@ find_tail_calls (basic_block bb, struct tailcall **ret) ...@@ -474,6 +452,7 @@ find_tail_calls (basic_block bb, struct tailcall **ret)
} }
if (idx == gimple_call_num_args (call) && !param) if (idx == gimple_call_num_args (call) && !param)
tail_recursion = true; tail_recursion = true;
}
/* Make sure the tail invocation of this function does not refer /* Make sure the tail invocation of this function does not refer
to local variables. */ to local variables. */
...@@ -483,7 +462,6 @@ find_tail_calls (basic_block bb, struct tailcall **ret) ...@@ -483,7 +462,6 @@ find_tail_calls (basic_block bb, struct tailcall **ret)
&& ref_maybe_used_by_stmt_p (call, var)) && ref_maybe_used_by_stmt_p (call, var))
return; return;
} }
}
/* Now check the statements after the call. None of them has virtual /* Now check the statements after the call. None of them has virtual
operands, so they may only depend on the call through its return operands, so they may only depend on the call through its return
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment