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][19/n] Merge from match-and-simplify, conditional patterns


This merges simplifications of conditionals from tree-ssa-forwprop.c.

Slight complication arises from having to also implement
0 ? A : B because otherwise X ? A : A may trigger which
may trigger an overflow warning during bootstrap if A and A
are not equal but 0 and 0(OVF) but we selected the "wrong"
result.  As automatic side-effects handling in genmatch
gives up for conditional execution it cannot simplify
0 ? x = callA() : x = callB() which in turn causes
(bogus) evaluation order warnings during bootstrap.
Thus I had to preserve the fold-const.c variant.

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

Richard.

2014-11-13  Richard Biener  <rguenther@suse.de>

	* match.pd: Implement conditional expression patterns.
	* tree-ssa-forwprop.c (forward_propagate_into_cond): Remove
	them here.
	(combine_cond_exprs): Remove.
	(pass_forwprop::execute): Do not call combine_cond_exprs.
	* fold-const.c (fold_ternary_loc): Remove patterns here.
	(pedantic_omit_one_operand_loc): Remove.

Index: trunk/gcc/match.pd
===================================================================
*** trunk.orig/gcc/match.pd	2014-11-13 09:42:36.866294878 +0100
--- trunk/gcc/match.pd	2014-11-13 09:42:54.314294115 +0100
*************** along with GCC; see the file COPYING3.
*** 590,592 ****
--- 590,640 ----
    (simplify
     (bswap (bitop:c (bswap @0) @1))
     (bitop @0 (bswap @1)))))
+ 
+ 
+ /* Combine COND_EXPRs and VEC_COND_EXPRs.  */
+ 
+ /* Simplify constant conditions.
+    Only optimize constant conditions when the selected branch
+    has the same type as the COND_EXPR.  This avoids optimizing
+    away "c ? x : throw", where the throw has a void type.
+    Note that we cannot throw away the fold-const.c variant nor
+    this one as we depend on doing this transform before possibly
+    A ? B : B -> B triggers and the fold-const.c one can optimize
+    0 ? A : B to B even if A has side-effects.  Something
+    genmatch cannot handle.  */
+ (simplify
+  (cond INTEGER_CST@0 @1 @2)
+  (if (integer_zerop (@0)
+       && (!VOID_TYPE_P (TREE_TYPE (@2))
+ 	  || VOID_TYPE_P (type)))
+   @2)
+  (if (!integer_zerop (@0)
+       && (!VOID_TYPE_P (TREE_TYPE (@1))
+ 	  || VOID_TYPE_P (type)))
+   @1))
+ (simplify
+  (vec_cond VECTOR_CST@0 @1 @2)
+  (if (integer_all_onesp (@0))
+   @1)
+  (if (integer_zerop (@0))
+   @2))
+ 
+ (for cnd (cond vec_cond)
+  /* A ? B : (A ? X : C) -> A ? B : C.  */
+  (simplify
+   (cnd @0 (cnd @0 @1 @2) @3)
+   (cnd @0 @1 @3))
+  (simplify
+   (cnd @0 @1 (cnd @0 @2 @3))
+   (cnd @0 @1 @3))
+ 
+  /* A ? B : B -> B.  */
+  (simplify
+   (cnd @0 @1 @1)
+   @1))
+ 
+ /* !A ? B : C -> A ? C : B.  */
+ (simplify
+  (cond (logical_inverted_value truth_valued_p@0) @1 @2)
+  (cond @0 @2 @1))
Index: trunk/gcc/tree-ssa-forwprop.c
===================================================================
*** trunk.orig/gcc/tree-ssa-forwprop.c	2014-11-13 09:41:21.566298173 +0100
--- trunk/gcc/tree-ssa-forwprop.c	2014-11-13 09:42:39.776294751 +0100
*************** forward_propagate_into_cond (gimple_stmt
*** 617,623 ****
    tree tmp = NULL_TREE;
    tree cond = gimple_assign_rhs1 (stmt);
    enum tree_code code = gimple_assign_rhs_code (stmt);
-   bool swap = false;
  
    /* We can do tree combining on SSA_NAME and comparison expressions.  */
    if (COMPARISON_CLASS_P (cond))
--- 617,622 ----
*************** forward_propagate_into_cond (gimple_stmt
*** 640,654 ****
  			       TREE_TYPE (cond),
  			       gimple_assign_rhs1 (def_stmt),
  			       gimple_assign_rhs2 (def_stmt));
-       else if (code == COND_EXPR
- 	       && ((def_code == BIT_NOT_EXPR
- 		    && TYPE_PRECISION (TREE_TYPE (cond)) == 1)
- 		   || (def_code == BIT_XOR_EXPR
- 		       && integer_onep (gimple_assign_rhs2 (def_stmt)))))
- 	{
- 	  tmp = gimple_assign_rhs1 (def_stmt);
- 	  swap = true;
- 	}
      }
  
    if (tmp
--- 639,644 ----
*************** forward_propagate_into_cond (gimple_stmt
*** 669,683 ****
        else if (integer_zerop (tmp))
  	gimple_assign_set_rhs_from_tree (gsi_p, gimple_assign_rhs3 (stmt));
        else
! 	{
! 	  gimple_assign_set_rhs1 (stmt, unshare_expr (tmp));
! 	  if (swap)
! 	    {
! 	      tree t = gimple_assign_rhs2 (stmt);
! 	      gimple_assign_set_rhs2 (stmt, gimple_assign_rhs3 (stmt));
! 	      gimple_assign_set_rhs3 (stmt, t);
! 	    }
! 	}
        stmt = gsi_stmt (*gsi_p);
        update_stmt (stmt);
  
--- 659,665 ----
        else if (integer_zerop (tmp))
  	gimple_assign_set_rhs_from_tree (gsi_p, gimple_assign_rhs3 (stmt));
        else
! 	gimple_assign_set_rhs1 (stmt, unshare_expr (tmp));
        stmt = gsi_stmt (*gsi_p);
        update_stmt (stmt);
  
*************** forward_propagate_into_cond (gimple_stmt
*** 687,744 ****
    return 0;
  }
  
- /* Propagate from the ssa name definition statements of COND_EXPR
-    values in the rhs of statement STMT into the conditional arms
-    if that simplifies it.
-    Returns true if the stmt was changed.  */
- 
- static bool
- combine_cond_exprs (gimple_stmt_iterator *gsi_p)
- {
-   gimple stmt = gsi_stmt (*gsi_p);
-   tree cond, val1, val2;
-   bool changed = false;
- 
-   cond = gimple_assign_rhs1 (stmt);
-   val1 = gimple_assign_rhs2 (stmt);
-   if (TREE_CODE (val1) == SSA_NAME)
-     {
-       gimple def_stmt = SSA_NAME_DEF_STMT (val1);
-       if (is_gimple_assign (def_stmt)
- 	  && gimple_assign_rhs_code (def_stmt) == gimple_assign_rhs_code (stmt)
- 	  && operand_equal_p (gimple_assign_rhs1 (def_stmt), cond, 0))
- 	{
- 	  val1 = unshare_expr (gimple_assign_rhs2 (def_stmt));
- 	  gimple_assign_set_rhs2 (stmt, val1);
- 	  changed = true;
- 	}
-     }
-   val2 = gimple_assign_rhs3 (stmt);
-   if (TREE_CODE (val2) == SSA_NAME)
-     {
-       gimple def_stmt = SSA_NAME_DEF_STMT (val2);
-       if (is_gimple_assign (def_stmt)
- 	  && gimple_assign_rhs_code (def_stmt) == gimple_assign_rhs_code (stmt)
- 	  && operand_equal_p (gimple_assign_rhs1 (def_stmt), cond, 0))
- 	{
- 	  val2 = unshare_expr (gimple_assign_rhs3 (def_stmt));
- 	  gimple_assign_set_rhs3 (stmt, val2);
- 	  changed = true;
- 	}
-     }
-   if (operand_equal_p (val1, val2, 0))
-     {
-       gimple_assign_set_rhs_from_tree (gsi_p, val1);
-       stmt = gsi_stmt (*gsi_p);
-       changed = true;
-     }
- 
-   if (changed)
-     update_stmt (stmt);
- 
-   return changed;
- }
- 
  /* We've just substituted an ADDR_EXPR into stmt.  Update all the
     relevant data structures to match.  */
  
--- 669,674 ----
*************** pass_forwprop::execute (function *fun)
*** 2432,2439 ****
  		    || code == VEC_COND_EXPR)
  		  {
  		    /* In this case the entire COND_EXPR is in rhs1. */
! 		    if (forward_propagate_into_cond (&gsi)
! 			|| combine_cond_exprs (&gsi))
  		      {
  			changed = true;
  			stmt = gsi_stmt (gsi);
--- 2362,2368 ----
  		    || code == VEC_COND_EXPR)
  		  {
  		    /* In this case the entire COND_EXPR is in rhs1. */
! 		    if (forward_propagate_into_cond (&gsi))
  		      {
  			changed = true;
  			stmt = gsi_stmt (gsi);
Index: trunk/gcc/fold-const.c
===================================================================
*** trunk.orig/gcc/fold-const.c	2014-11-13 09:42:03.921296320 +0100
--- trunk/gcc/fold-const.c	2014-11-13 09:42:39.781294751 +0100
*************** static enum tree_code compcode_to_compar
*** 121,127 ****
  static int operand_equal_for_comparison_p (tree, tree, tree);
  static int twoval_comparison_p (tree, tree *, tree *, int *);
  static tree eval_subst (location_t, tree, tree, tree, tree, tree);
- static tree pedantic_omit_one_operand_loc (location_t, tree, tree, tree);
  static tree distribute_bit_expr (location_t, enum tree_code, tree, tree, tree);
  static tree make_bit_field_ref (location_t, tree, tree,
  				HOST_WIDE_INT, HOST_WIDE_INT, int);
--- 121,126 ----
*************** omit_one_operand_loc (location_t loc, tr
*** 3074,3100 ****
    return non_lvalue_loc (loc, t);
  }
  
- /* Similar, but call pedantic_non_lvalue instead of non_lvalue.  */
- 
- static tree
- pedantic_omit_one_operand_loc (location_t loc, tree type, tree result,
- 			       tree omitted)
- {
-   tree t = fold_convert_loc (loc, type, result);
- 
-   /* If the resulting operand is an empty statement, just return the omitted
-      statement casted to void. */
-   if (IS_EMPTY_STMT (t) && TREE_SIDE_EFFECTS (omitted))
-     return build1_loc (loc, NOP_EXPR, void_type_node,
- 		       fold_ignored_result (omitted));
- 
-   if (TREE_SIDE_EFFECTS (omitted))
-     return build2_loc (loc, COMPOUND_EXPR, type,
- 		       fold_ignored_result (omitted), t);
- 
-   return pedantic_non_lvalue_loc (loc, t);
- }
- 
  /* Return a tree for the case when the result of an expression is RESULT
     converted to TYPE and OMITTED1 and OMITTED2 were previously operands
     of the expression but are now not needed.
--- 3073,3078 ----
*************** fold_ternary_loc (location_t loc, enum t
*** 13553,13563 ****
  	}
        else if (TREE_CODE (arg0) == VECTOR_CST)
  	{
- 	  if (integer_all_onesp (arg0))
- 	    return pedantic_omit_one_operand_loc (loc, type, arg1, arg2);
- 	  if (integer_zerop (arg0))
- 	    return pedantic_omit_one_operand_loc (loc, type, arg2, arg1);
- 
  	  if ((TREE_CODE (arg1) == VECTOR_CST
  	       || TREE_CODE (arg1) == CONSTRUCTOR)
  	      && (TREE_CODE (arg2) == VECTOR_CST
--- 13531,13536 ----
*************** fold_ternary_loc (location_t loc, enum t
*** 13582,13590 ****
  	    }
  	}
  
-       if (operand_equal_p (arg1, op2, 0))
- 	return pedantic_omit_one_operand_loc (loc, type, arg1, arg0);
- 
        /* If we have A op B ? A : C, we may be able to convert this to a
  	 simpler expression, depending on the operation and the values
  	 of B and C.  Signed zeros prevent all of these transformations,
--- 13555,13560 ----


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