[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