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 be call-used. */
- FOR_EACH_REFERENCED_VAR (var, rvi)
- {
- if (!is_global_var (var)
- && is_call_used (var))
- return false;
- }
-
return true;
}
/* Returns false when the function is not suitable for tail call optimization
tree m, a;
basic_block abb;
size_t idx;
+ tree var;
+ referenced_var_iterator rvi;
if (!single_succ_p (bb))
return;
if (func == current_function_decl)
{
tree arg;
+
for (param = DECL_ARGUMENTS (func), idx = 0;
param && idx < gimple_call_num_args (call);
param = TREE_CHAIN (param), idx ++)
tail_recursion = true;
}
+ /* Make sure the tail invocation of this function does not refer
+ to local variables. */
+ FOR_EACH_REFERENCED_VAR (var, rvi)
+ {
+ if (TREE_CODE (var) != PARM_DECL
+ && auto_var_in_fn_p (var, cfun->decl)
+ && ref_maybe_used_by_stmt_p (call, var))
+ return;
+ }
+
/* Now check the statements after the call. None of them has virtual
operands, so they may only depend on the call through its return
value. The return value should also be dependent on each of them,
{
tree ret_type = TREE_TYPE (DECL_RESULT (current_function_decl));
- tree tmp = create_tmp_var (ret_type, label);
+ tree tmp = create_tmp_reg (ret_type, label);
gimple stmt;
tree result;
- if (TREE_CODE (ret_type) == COMPLEX_TYPE
- || TREE_CODE (ret_type) == VECTOR_TYPE)
- DECL_GIMPLE_REG_P (tmp) = 1;
add_referenced_var (tmp);
if (types_compatible_p (TREE_TYPE (acc), TREE_TYPE (op1)))
create_tailcall_accumulator (const char *label, basic_block bb, tree init)
{
tree ret_type = TREE_TYPE (DECL_RESULT (current_function_decl));
- tree tmp = create_tmp_var (ret_type, label);
+ tree tmp = create_tmp_reg (ret_type, label);
gimple phi;
- if (TREE_CODE (ret_type) == COMPLEX_TYPE
- || TREE_CODE (ret_type) == VECTOR_TYPE)
- DECL_GIMPLE_REG_P (tmp) = 1;
add_referenced_var (tmp);
phi = create_phi_node (tmp, bb);
/* RET_TYPE can be a float when -ffast-maths is enabled. */