[PATCH] Fix PR26198, a missed-optimization with combining into COND_EXPRs

Richard Guenther rguenther@suse.de
Fri Oct 12 08:38:00 GMT 2007


This is low-hanging fruit to get this PR finally fixed and optimize the
loop-header copy comparisons properly.  We already do all the work to
tree-combine both operands of COND_EXPRs, so it's easy to also try
forwarding both.  Of course we need to be careful what to propagate
here, no side-effects or memory operations are allowed (it didn't bite
us before, but with combining both operands it would - hence the new
testcase).

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to mainline.

Richard.

2007-10-11  Richard Guenther  <rguenther@suse.de>

	PR middle-end/26198
	* tree-ssa-forwprop.c (can_propagate_from): Do not propagate from
	a rhs with side-effects or which is a load.
	(forward_propagate_into_cond): Also try combining both operands.

	* gcc.dg/tree-ssa/forwprop-3.c: New testcase.
	* gcc.c-torture/execute/20071011-1.c: Likewise.
	* gcc.dg/tree-ssa/ssa-pre-9.c: Adjust.

Index: testsuite/gcc.c-torture/execute/20071011-1.c
===================================================================
*** testsuite/gcc.c-torture/execute/20071011-1.c	(revision 0)
--- testsuite/gcc.c-torture/execute/20071011-1.c	(revision 0)
***************
*** 0 ****
--- 1,19 ----
+ extern void abort(void);
+ void foo(int *p)
+ {
+   int x;
+   int y;
+   x = *p;
+   *p = 0;
+   y = *p;
+   if (x != y)
+     return;
+   abort ();
+ }
+ 
+ int main()
+ {
+   int a = 1;
+   foo(&a);
+   return 0;
+ }
Index: testsuite/gcc.dg/tree-ssa/forwprop-3.c
===================================================================
*** testsuite/gcc.dg/tree-ssa/forwprop-3.c	(revision 0)
--- testsuite/gcc.dg/tree-ssa/forwprop-3.c	(revision 0)
***************
*** 0 ****
--- 1,18 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O -fdump-tree-forwprop1" } */
+ 
+ struct bar {
+   int a[2];
+ };
+ 
+ int foo(struct bar *x)
+ {
+   int *p = &x->a[0];
+   int *q = &x->a[1];
+   if (p < q)
+     return 1;
+   return 0;
+ }
+ 
+ /* { dg-final { scan-tree-dump "Replaced .p_. < q_.. with .1." "forwprop1" } } */
+ /* { dg-final { cleanup-tree-dump "forwprop1" } } */
Index: tree-ssa-forwprop.c
===================================================================
*** tree-ssa-forwprop.c	(revision 129227)
--- tree-ssa-forwprop.c	(working copy)
*************** can_propagate_from (tree def_stmt)
*** 237,242 ****
--- 237,250 ----
  {
    tree rhs = GIMPLE_STMT_OPERAND (def_stmt, 1);
  
+   /* If the rhs has side-effects we cannot propagate from it.  */
+   if (TREE_SIDE_EFFECTS (rhs))
+     return false;
+ 
+   /* If the rhs is a load we cannot propagate from it.  */
+   if (REFERENCE_CLASS_P (rhs))
+     return false;
+ 
    /* We cannot propagate ssa names that occur in abnormal phi nodes.  */
    switch (TREE_CODE_LENGTH (TREE_CODE (rhs)))
      {
*************** forward_propagate_into_cond (tree cond_e
*** 351,357 ****
    do {
      tree tmp = NULL_TREE;
      tree cond = COND_EXPR_COND (cond_expr);
!     tree name, def_stmt, rhs;
      bool single_use_p;
  
      /* We can do tree combining on SSA_NAME and comparison expressions.  */
--- 359,365 ----
    do {
      tree tmp = NULL_TREE;
      tree cond = COND_EXPR_COND (cond_expr);
!     tree name, def_stmt, rhs0 = NULL_TREE, rhs1 = NULL_TREE;
      bool single_use_p;
  
      /* We can do tree combining on SSA_NAME and comparison expressions.  */
*************** forward_propagate_into_cond (tree cond_e
*** 366,374 ****
  	    && can_propagate_from (def_stmt))
  	  {
  	    tree op1 = TREE_OPERAND (cond, 1);
! 	    rhs = GIMPLE_STMT_OPERAND (def_stmt, 1);
  	    tmp = combine_cond_expr_cond (TREE_CODE (cond), boolean_type_node,
! 				          fold_convert (TREE_TYPE (op1), rhs),
  				          op1, !single_use_p);
  	  }
  	/* If that wasn't successful, try the second operand.  */
--- 374,382 ----
  	    && can_propagate_from (def_stmt))
  	  {
  	    tree op1 = TREE_OPERAND (cond, 1);
! 	    rhs0 = GIMPLE_STMT_OPERAND (def_stmt, 1);
  	    tmp = combine_cond_expr_cond (TREE_CODE (cond), boolean_type_node,
! 				          fold_convert (TREE_TYPE (op1), rhs0),
  				          op1, !single_use_p);
  	  }
  	/* If that wasn't successful, try the second operand.  */
*************** forward_propagate_into_cond (tree cond_e
*** 382,393 ****
  	        || !can_propagate_from (def_stmt))
  	      return did_something;
  
! 	    rhs = GIMPLE_STMT_OPERAND (def_stmt, 1);
  	    tmp = combine_cond_expr_cond (TREE_CODE (cond), boolean_type_node,
  					  op0,
! 				          fold_convert (TREE_TYPE (op0), rhs),
  					  !single_use_p);
  	  }
        }
      else if (TREE_CODE (cond) == SSA_NAME)
        {
--- 390,409 ----
  	        || !can_propagate_from (def_stmt))
  	      return did_something;
  
! 	    rhs1 = GIMPLE_STMT_OPERAND (def_stmt, 1);
  	    tmp = combine_cond_expr_cond (TREE_CODE (cond), boolean_type_node,
  					  op0,
! 				          fold_convert (TREE_TYPE (op0), rhs1),
  					  !single_use_p);
  	  }
+ 	/* If that wasn't successful either, try both operands.  */
+ 	if (tmp == NULL_TREE
+ 	    && rhs0 != NULL_TREE
+ 	    && rhs1 != NULL_TREE)
+ 	  tmp = combine_cond_expr_cond (TREE_CODE (cond), boolean_type_node,
+ 					rhs0,
+ 				        fold_convert (TREE_TYPE (rhs0), rhs1),
+ 					!single_use_p);
        }
      else if (TREE_CODE (cond) == SSA_NAME)
        {
*************** forward_propagate_into_cond (tree cond_e
*** 397,405 ****
  	    || !can_propagate_from (def_stmt))
  	  return did_something;
  
! 	rhs = GIMPLE_STMT_OPERAND (def_stmt, 1);
! 	tmp = combine_cond_expr_cond (NE_EXPR, boolean_type_node, rhs,
! 				      build_int_cst (TREE_TYPE (rhs), 0),
  				      false);
        }
  
--- 413,421 ----
  	    || !can_propagate_from (def_stmt))
  	  return did_something;
  
! 	rhs0 = GIMPLE_STMT_OPERAND (def_stmt, 1);
! 	tmp = combine_cond_expr_cond (NE_EXPR, boolean_type_node, rhs0,
! 				      build_int_cst (TREE_TYPE (rhs0), 0),
  				      false);
        }
  
Index: testsuite/gcc.dg/tree-ssa/ssa-pre-9.c
===================================================================
*** testsuite/gcc.dg/tree-ssa/ssa-pre-9.c	(revision 129227)
--- testsuite/gcc.dg/tree-ssa/ssa-pre-9.c	(working copy)
*************** foo (unsigned long a)
*** 9,13 ****
      return 1;
    return 0;
  }
! /* { dg-final { scan-tree-dump-times "Eliminated: 1" 1 "fre"} } */
  /* { dg-final { cleanup-tree-dump "fre" } } */
--- 9,13 ----
      return 1;
    return 0;
  }
! /* { dg-final { scan-tree-dump-times "return 0;" 0 "fre"} } */
  /* { dg-final { cleanup-tree-dump "fre" } } */



More information about the Gcc-patches mailing list