[tree-ssa] Partial fix for PR14016
Steven Bosscher
stevenb@suse.de
Thu Feb 5 23:35:00 GMT 2004
Hi,
Bootstrapped and regtested on i686-pc-linux-gnu with three new regressions,
all related to sib/tail calls:
FAIL: gcc.dg/sibcall-6.c execution test
FAIL: gcc.dg/tree-ssa/tailrecursion-1.c scan-tree-dump-times Eliminated tail recursion 1
FAIL: gcc.dg/tree-ssa/tailrecursion-2.c scan-tree-dump-times Eliminated tail recursion 1
But that's not the fault of this patch. It breaks tail call optimizations
because tree-tailcall doesn't recognise a call_expr in the rhs of a
modify-stmt, but this is valid GIMPLE according to the GIMPLE grammar in
tree-simple.c.
This patch doesn't help when tree_could_throw_p returns true, ie. when
exceptions are possible, the user variable still disappears. At least
C code (like GCC itself) is more debugable with this patch :-)
Gr.
Steven
PR optimization/14016
* tree-eh.c (tree_could_throw_p): Generalize so that it handles
not just calls and assignments, but all trees.
* gimplify.c (gimplify_modify_expr): Don't assume all calls can
throw. Use tree_could_throw_p instead of tree_could_trap_p.
Index: gimplify.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/gimplify.c,v
retrieving revision 1.1.2.141
diff -c -3 -p -r1.1.2.141 gimplify.c
*** gimplify.c 30 Jan 2004 13:14:02 -0000 1.1.2.141
--- gimplify.c 5 Feb 2004 08:19:22 -0000
*************** gimplify_modify_expr (tree *expr_p, tree
*** 2389,2396 ****
FIXME this should be handled by the is_gimple_rhs predicate. */
! if (TREE_CODE (*from_p) == CALL_EXPR
! || (flag_non_call_exceptions && tree_could_trap_p (*from_p))
/* If we're dealing with a renamable type, either source or dest
must be a renamed variable. */
|| (is_gimple_reg_type (TREE_TYPE (*from_p))
--- 2389,2395 ----
FIXME this should be handled by the is_gimple_rhs predicate. */
! if (tree_could_throw_p (*from_p)
/* If we're dealing with a renamable type, either source or dest
must be a renamed variable. */
|| (is_gimple_reg_type (TREE_TYPE (*from_p))
Index: tree-eh.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/Attic/tree-eh.c,v
retrieving revision 1.1.2.23
diff -c -3 -p -r1.1.2.23 tree-eh.c
*** tree-eh.c 15 Jan 2004 06:43:19 -0000 1.1.2.23
--- tree-eh.c 5 Feb 2004 08:19:25 -0000
*************** tree_could_throw_p (tree t)
*** 1703,1729 ****
{
if (!flag_exceptions)
return false;
if (TREE_CODE (t) == MODIFY_EXPR)
{
! tree sub = TREE_OPERAND (t, 1);
! if (TREE_CODE (sub) == CALL_EXPR)
! t = sub;
! else
! {
! if (flag_non_call_exceptions)
! {
! if (tree_could_trap_p (sub))
! return true;
! return tree_could_trap_p (TREE_OPERAND (t, 0));
! }
! return false;
! }
}
if (TREE_CODE (t) == CALL_EXPR)
return (call_expr_flags (t) & ECF_NOTHROW) == 0;
! return false;
}
bool
--- 1703,1728 ----
{
if (!flag_exceptions)
return false;
+
+ /* If T is a MODIFY_EXPR and non-call exceptions are possible, we have
+ to look at both the rhs and lhs of the assignment to see if it could
+ throw. */
if (TREE_CODE (t) == MODIFY_EXPR)
{
! tree lhs = TREE_OPERAND (t, 0);
! tree rhs = TREE_OPERAND (t, 1);
! if (flag_non_call_exceptions
! && (tree_could_trap_p (rhs) || tree_could_trap_p (lhs)))
! return true;
! if (TREE_CODE (rhs) == CALL_EXPR)
! t = rhs;
}
+ /* For a call, only nothrow functions can never throw. */
if (TREE_CODE (t) == CALL_EXPR)
return (call_expr_flags (t) & ECF_NOTHROW) == 0;
! return (flag_non_call_exceptions && tree_could_trap_p (t));
}
bool
More information about the Gcc-patches
mailing list