Avoid tree-tailcall upsetting tree-inline
Jan Hubicka
jh@suse.cz
Sat Jan 20 10:46:00 GMT 2007
Hi,
the tailrecursion-5.c optimization fails with Razya's IP constant propagation
patch and also with -O3. The problem is caused by tail recursion seeing:
return (result_decl = var);
and to increase result_decl by accumulator, it does somewhat zelaous conversion:
result_decl = var;
acc = result_decl + other_acc;
return acc
so now result_decl is used as temporary but actually not used for returning.
This upsets inliner that does expect result_decl to either not exist or be used
for returning. The attached patch makes tree-tailcall to rewrite it as:
acc = var + other_acc
return (result_decl = acc);
Bootstrapped/regtested i686-linux (without fortran as fortran is broken currently)
OK? (might do c/fortran run before comitting).
Honza
* tree-tailcall.c (adjust_return_value): Do not use RESULT_DECL
as temporary.
Index: tree-tailcall.c
===================================================================
--- tree-tailcall.c (revision 120974)
+++ tree-tailcall.c (working copy)
@@ -617,6 +617,7 @@ adjust_return_value (basic_block bb, tre
{
tree ret_stmt = last_stmt (bb), ret_var, var, stmt, tmp;
tree ret_type = TREE_TYPE (DECL_RESULT (current_function_decl));
+ tree *ret_op;
block_stmt_iterator bsi = bsi_last (bb);
gcc_assert (TREE_CODE (ret_stmt) == RETURN_EXPR);
@@ -627,13 +628,11 @@ adjust_return_value (basic_block bb, tre
if (TREE_CODE (ret_var) == GIMPLE_MODIFY_STMT)
{
- ret_var->base.ann = (tree_ann_t) stmt_ann (ret_stmt);
- bsi_replace (&bsi, ret_var, true);
- SSA_NAME_DEF_STMT (GIMPLE_STMT_OPERAND (ret_var, 0)) = ret_var;
- ret_var = GIMPLE_STMT_OPERAND (ret_var, 0);
- ret_stmt = build1 (RETURN_EXPR, TREE_TYPE (ret_stmt), ret_var);
- bsi_insert_after (&bsi, ret_stmt, BSI_NEW_STMT);
+ ret_op = &GIMPLE_STMT_OPERAND (ret_var, 1);
+ ret_var = *ret_op;
}
+ else
+ ret_op = &TREE_OPERAND (ret_stmt, 0);
if (m)
{
@@ -663,7 +662,7 @@ adjust_return_value (basic_block bb, tre
bsi_insert_before (&bsi, stmt, BSI_SAME_STMT);
}
- TREE_OPERAND (ret_stmt, 0) = var;
+ *ret_op = var;
update_stmt (ret_stmt);
}
More information about the Gcc-patches
mailing list