This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] Fix PR32586, restore combining of conversions in SCCVN


This fixes PR32586 (as I promised to do) and re-instantiates 
tree-combining of conversions in FRE/SCCVN.  This allows to remove
a bunch of XFAILs Danny added at SCCVN merge time.  This also fixes
the builtins-51.c failure on trunk.

Bootstrapped and tested on x86_64-unknown-linux-gnu.  Danny, are
the SCCVN changes ok?  (Is there a better way than value_expr_p?
What I would need is a predicate that tells whether I can substitute
VN_INFO -> expr for the value number in expressions)

Thanks,
Richard.

2007-09-05  Richard Guenther  <rguenther@suse.de>

	PR tree-optimization/32586
	* tree-ssa-sccvn.c (simplify_binary_expression): Avoid
	folding if nothing changed.
	(value_expr_p): New function.
	(simplify_unary_expression): New function.  Do tree combining
	on conversion like codes.
	(try_to_simplify): Call it.
	* builtins.c (fold_builtin_cexp): Fold the built expressions.
	* fold-const.c (fold_unary): Test result of get_callee_fndecl().

	* g++.dg/tree-ssa/pr27090.C: Remove XFAILs.
	* gcc.dg/tree-ssa/ssa-fre-1.c: Likewise.
	* gcc.dg/tree-ssa/ssa-fre-3.c: Likewise.
	* gcc.dg/tree-ssa/ssa-fre-5.c: Likewise.
	* gcc.dg/tree-ssa/ssa-fre-4.c: Likewise, remove scan for
	now obsolete simplification.

Index: gcc/tree-ssa-sccvn.c
===================================================================
*** gcc/tree-ssa-sccvn.c.orig	2007-09-06 11:10:38.000000000 +0200
--- gcc/tree-ssa-sccvn.c	2007-09-06 11:13:34.000000000 +0200
*************** valueize_expr (tree expr)
*** 1381,1386 ****
--- 1381,1416 ----
    return expr;
  }
  
+ /* Return true, if EXPR is an expression with value number or
+    constant operands only.  */
+ 
+ static bool
+ value_expr_p (tree expr)
+ {
+   if (TREE_CODE (expr) == SSA_NAME
+       || is_gimple_min_invariant (expr))
+     return true;
+ 
+   switch (TREE_CODE_CLASS (TREE_CODE (expr)))
+     {
+     case tcc_binary:
+       if (!is_gimple_min_invariant (TREE_OPERAND (expr, 1))
+ 	  && TREE_CODE (TREE_OPERAND (expr, 1)) != SSA_NAME)
+ 	return false;
+  
+       /* FALLTRHOUGH.  */
+     case tcc_unary:
+       if (!is_gimple_min_invariant (TREE_OPERAND (expr, 0))
+ 	  && TREE_CODE (TREE_OPERAND (expr, 0)) != SSA_NAME)
+ 	return false;
+ 
+       return true;
+ 
+     default:
+       return false;
+     }
+ }
+ 
  /* Simplify the binary expression RHS, and return the result if
     simplified. */
  
*************** simplify_binary_expression (tree rhs)
*** 1411,1416 ****
--- 1441,1451 ----
  	op1 = SSA_VAL (op1);
      }
  
+   /* Avoid folding if nothing changed.  */
+   if (op0 == TREE_OPERAND (rhs, 0)
+       && op1 == TREE_OPERAND (rhs, 1))
+     return NULL_TREE;
+ 
    result = fold_binary (TREE_CODE (rhs), TREE_TYPE (rhs), op0, op1);
  
    /* Make sure result is not a complex expression consisting
*************** simplify_binary_expression (tree rhs)
*** 1423,1428 ****
--- 1458,1504 ----
    return NULL_TREE;
  }
  
+ /* Simplify the unary expression RHS, and return the result if
+    simplified. */
+ 
+ static tree
+ simplify_unary_expression (tree rhs)
+ {
+   tree result = NULL_TREE;
+   tree op0 = TREE_OPERAND (rhs, 0);
+ 
+   if (TREE_CODE (op0) != SSA_NAME)
+     return NULL_TREE;
+ 
+   if (VN_INFO (op0)->has_constants)
+     op0 = valueize_expr (VN_INFO (op0)->expr);
+   else if (TREE_CODE (rhs) == NOP_EXPR
+ 	   || TREE_CODE (rhs) == CONVERT_EXPR
+ 	   || TREE_CODE (rhs) == REALPART_EXPR
+ 	   || TREE_CODE (rhs) == IMAGPART_EXPR)
+     {
+       /* We want to do tree-combining on conversion-like expressions.
+          Make sure we feed only SSA_NAMEs or constants to fold though.  */
+       tree tem = valueize_expr (VN_INFO (op0)->expr);
+       if (value_expr_p (tem))
+ 	op0 = tem;
+     }
+ 
+   /* Avoid folding if nothing changed, but remember the expression.  */
+   if (op0 == TREE_OPERAND (rhs, 0))
+     return rhs;
+ 
+   result = fold_unary (TREE_CODE (rhs), TREE_TYPE (rhs), op0);
+   if (result)
+     {
+       STRIP_USELESS_TYPE_CONVERSION (result);
+       if (valid_gimple_expression_p (result))
+         return result;
+     }
+ 
+   return rhs;
+ }
+ 
  /* Try to simplify RHS using equivalences and constant folding.  */
  
  static tree
*************** try_to_simplify (tree stmt, tree rhs)
*** 1457,1477 ****
  	    if (result)
  	      return result;
  	  }
! 	  break;
  	  /* We could do a little more with unary ops, if they expand
  	     into binary ops, but it's debatable whether it is worth it. */
  	case tcc_unary:
! 	  {
! 	    tree result = NULL_TREE;
! 	    tree op0 = TREE_OPERAND (rhs, 0);
! 	    if (TREE_CODE (op0) == SSA_NAME && VN_INFO (op0)->has_constants)
! 	      op0 = VN_INFO (op0)->expr;
! 	    else if (TREE_CODE (op0) == SSA_NAME && SSA_VAL (op0) != op0)
! 	      op0 = SSA_VAL (op0);
! 	    result = fold_unary (TREE_CODE (rhs), TREE_TYPE (rhs), op0);
! 	    if (result)
! 	      return result;
! 	  }
  	  break;
  	case tcc_comparison:
  	case tcc_binary:
--- 1533,1546 ----
  	    if (result)
  	      return result;
  	  }
! 	  /* Fallthrough for some codes.  */
! 	  if (!(TREE_CODE (rhs) == REALPART_EXPR
! 	        || TREE_CODE (rhs) == IMAGPART_EXPR))
! 	    break;
  	  /* We could do a little more with unary ops, if they expand
  	     into binary ops, but it's debatable whether it is worth it. */
  	case tcc_unary:
! 	  return simplify_unary_expression (rhs);
  	  break;
  	case tcc_comparison:
  	case tcc_binary:
Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-1.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-1.c.orig	2007-09-06 11:10:38.000000000 +0200
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-1.c	2007-09-06 11:13:34.000000000 +0200
*************** int f(int *a)
*** 11,16 ****
    return *c + t;
  }
  
! /* { dg-final { scan-tree-dump "Replaced \\\(int \\\*\\\) b_.*with a_" "fre" { xfail *-*-* } } } */
! /* { dg-final { scan-tree-dump "Replaced \\\*c_.*with t_" "fre" { xfail *-*-* } } } */
  /* { dg-final { cleanup-tree-dump "fre" } } */
--- 11,16 ----
    return *c + t;
  }
  
! /* { dg-final { scan-tree-dump "Replaced \\\(int \\\*\\\) b_.*with a_" "fre" } } */
! /* { dg-final { scan-tree-dump "Replaced \\\*c_.*with t_" "fre" } } */
  /* { dg-final { cleanup-tree-dump "fre" } } */
Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-3.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-3.c.orig	2007-09-06 11:10:38.000000000 +0200
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-3.c	2007-09-06 11:13:34.000000000 +0200
*************** foo (int a, int b)
*** 11,15 ****
    return aa + bb;
  }
  
! /* { dg-final { scan-tree-dump "Replaced \\\(int\\\) aa_.*with a_" "fre" { xfail *-*-* } } } */
  /* { dg-final { cleanup-tree-dump "fre" } } */
--- 11,15 ----
    return aa + bb;
  }
  
! /* { dg-final { scan-tree-dump "Replaced \\\(int\\\) aa_.*with a_" "fre" } } */
  /* { dg-final { cleanup-tree-dump "fre" } } */
Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-4.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-4.c.orig	2007-09-06 11:10:38.000000000 +0200
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-4.c	2007-09-06 11:13:34.000000000 +0200
*************** char bar(char f)
*** 9,14 ****
          return wrap(f);
  }
  
! /* { dg-final { scan-tree-dump "Replaced \\\(char\\\) .*with " "fre" { xfail *-*-* } } } */
! /* { dg-final { scan-tree-dump "Replaced \\\(int\\\) .*with " "fre" { xfail *-*-* } } } */
  /* { dg-final { cleanup-tree-dump "fre" } } */
--- 9,13 ----
          return wrap(f);
  }
  
! /* { dg-final { scan-tree-dump "Replaced \\\(char\\\) .*with " "fre" } } */
  /* { dg-final { cleanup-tree-dump "fre" } } */
Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-5.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-5.c.orig	2007-09-06 11:10:38.000000000 +0200
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-fre-5.c	2007-09-06 11:13:34.000000000 +0200
*************** bar (unsigned int t)
*** 10,14 ****
    return a == t;
  }
  
! /* { dg-final { scan-tree-dump "Replaced \\\(unsigned int\\\) a_.*with t_" "fre" { xfail *-*-* } } } */
  /* { dg-final { cleanup-tree-dump "fre" } } */
--- 10,14 ----
    return a == t;
  }
  
! /* { dg-final { scan-tree-dump "Replaced \\\(unsigned int\\\) a_.*with t_" "fre" } } */
  /* { dg-final { cleanup-tree-dump "fre" } } */
Index: gcc/builtins.c
===================================================================
*** gcc/builtins.c.orig	2007-09-06 11:11:21.000000000 +0200
--- gcc/builtins.c	2007-09-06 11:13:34.000000000 +0200
*************** fold_builtin_cexp (tree arg0, tree type)
*** 7799,7811 ****
        icall = builtin_save_expr (icall);
        rcall = build_call_expr (rfn, 1, realp);
        rcall = builtin_save_expr (rcall);
!       return build2 (COMPLEX_EXPR, type,
! 		     build2 (MULT_EXPR, rtype,
! 			     rcall,
! 			     build1 (REALPART_EXPR, rtype, icall)),
! 		     build2 (MULT_EXPR, rtype,
! 			     rcall,
! 			     build1 (IMAGPART_EXPR, rtype, icall)));
      }
  
    return NULL_TREE;
--- 7799,7811 ----
        icall = builtin_save_expr (icall);
        rcall = build_call_expr (rfn, 1, realp);
        rcall = builtin_save_expr (rcall);
!       return fold_build2 (COMPLEX_EXPR, type,
! 			  fold_build2 (MULT_EXPR, rtype,
! 				       rcall,
! 			 	       fold_build1 (REALPART_EXPR, rtype, icall)),
! 			  fold_build2 (MULT_EXPR, rtype,
! 				       rcall,
! 				       fold_build1 (IMAGPART_EXPR, rtype, icall)));
      }
  
    return NULL_TREE;
Index: gcc/testsuite/g++.dg/tree-ssa/pr27090.C
===================================================================
*** gcc/testsuite/g++.dg/tree-ssa/pr27090.C.orig	2007-09-06 11:10:38.000000000 +0200
--- gcc/testsuite/g++.dg/tree-ssa/pr27090.C	2007-09-06 11:13:34.000000000 +0200
*************** int foo(Foo& f)
*** 17,21 ****
          return f.get();
  }
  
! /* { dg-final { scan-tree-dump "return f->x;" "optimized" { xfail *-*-* } } } */
  /* { dg-final { cleanup-tree-dump "optimized" } } */
--- 17,21 ----
          return f.get();
  }
  
! /* { dg-final { scan-tree-dump "return f->x;" "optimized" } } */
  /* { dg-final { cleanup-tree-dump "optimized" } } */
Index: gcc/fold-const.c
===================================================================
*** gcc/fold-const.c.orig	2007-09-06 11:10:38.000000000 +0200
--- gcc/fold-const.c	2007-09-06 11:13:34.000000000 +0200
*************** fold_unary (enum tree_code code, tree ty
*** 8464,8470 ****
        if (TREE_CODE (arg0) == CALL_EXPR)
  	{
  	  tree fn = get_callee_fndecl (arg0);
! 	  if (DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL)
  	    switch (DECL_FUNCTION_CODE (fn))
  	      {
  	      CASE_FLT_FN (BUILT_IN_CEXPI):
--- 8464,8470 ----
        if (TREE_CODE (arg0) == CALL_EXPR)
  	{
  	  tree fn = get_callee_fndecl (arg0);
! 	  if (fn && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL)
  	    switch (DECL_FUNCTION_CODE (fn))
  	      {
  	      CASE_FLT_FN (BUILT_IN_CEXPI):
*************** fold_unary (enum tree_code code, tree ty
*** 8506,8512 ****
        if (TREE_CODE (arg0) == CALL_EXPR)
  	{
  	  tree fn = get_callee_fndecl (arg0);
! 	  if (DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL)
  	    switch (DECL_FUNCTION_CODE (fn))
  	      {
  	      CASE_FLT_FN (BUILT_IN_CEXPI):
--- 8506,8512 ----
        if (TREE_CODE (arg0) == CALL_EXPR)
  	{
  	  tree fn = get_callee_fndecl (arg0);
! 	  if (fn && DECL_BUILT_IN_CLASS (fn) == BUILT_IN_NORMAL)
  	    switch (DECL_FUNCTION_CODE (fn))
  	      {
  	      CASE_FLT_FN (BUILT_IN_CEXPI):


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]