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]

[tuples] [patch] refactoring of tree_expr_nonzero_warnv_p


2008-03-04  Rafael Espindola  <espindola@google.com>
  * tree-outof-ssa.c (tree_unary_expr_nonzero_warnv_p): New.
  (tree_binary_expr_nonzero_warnv_p): New.
  (tree_single_expr_nonzero_warnv_p): New.
  (tree_expr_nonzero_warnv_p): Redefine using the new functions.

Cheers,
-- 
Rafael Avila de Espindola

Google Ireland Ltd.
Gordon House
Barrow Street
Dublin 4
Ireland

Registered in Dublin, Ireland
Registration Number: 368047
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 3a8fd08..2c26327 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -65,6 +65,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "langhooks.h"
 #include "md5.h"
 #include "gimple.h"
+#include "tree-gimple.h"
 
 /* Nonzero if we are folding constants inside an initializer; zero
    otherwise.  */
@@ -14371,38 +14372,62 @@ tree_expr_nonnegative_p (tree t)
   return ret;
 }
 
-/* Return true when T is an address and is known to be nonzero.
+
+/* Return true when (CODE OP0) is an address and is known to be nonzero.
    For floating point we further ensure that T is not denormal.
    Similar logic is present in nonzero_address in rtlanal.h.
 
    If the return value is based on the assumption that signed overflow
    is undefined, set *STRICT_OVERFLOW_P to true; otherwise, don't
    change *STRICT_OVERFLOW_P.  */
-
-bool
-tree_expr_nonzero_warnv_p (tree t, bool *strict_overflow_p)
+static bool
+tree_unary_expr_nonzero_warnv_p (enum tree_code code, tree type, tree op0,
+				 bool *strict_overflow_p)
 {
-  tree type = TREE_TYPE (t);
-  bool sub_strict_overflow_p;
+  switch (code)
+    {
+    case ABS_EXPR:
+      return tree_expr_nonzero_warnv_p (op0,
+					strict_overflow_p);
 
-  /* Doing something useful for floating point would need more work.  */
-  if (!INTEGRAL_TYPE_P (type) && !POINTER_TYPE_P (type))
-    return false;
+    case NOP_EXPR:
+      {
+	tree inner_type = TREE_TYPE (op0);
+	tree outer_type = type;
 
-  switch (TREE_CODE (t))
-    {
-    case SSA_NAME:
-      /* Query VRP to see if it has recorded any information about
-	 the range of this object.  */
-      return ssa_name_nonzero_p (t);
+	return (TYPE_PRECISION (outer_type) >= TYPE_PRECISION (inner_type)
+		&& tree_expr_nonzero_warnv_p (op0,
+					      strict_overflow_p));
+      }
+      break;
 
-    case ABS_EXPR:
-      return tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 0),
+    case NON_LVALUE_EXPR:
+      return tree_expr_nonzero_warnv_p (op0,
 					strict_overflow_p);
 
-    case INTEGER_CST:
-      return !integer_zerop (t);
+    default:
+      break;
+  }
+
+  return false;
+}
 
+/* Return true when (CODE OP0 OP1) is an address and is known to be nonzero.
+   For floating point we further ensure that T is not denormal.
+   Similar logic is present in nonzero_address in rtlanal.h.
+
+   If the return value is based on the assumption that signed overflow
+   is undefined, set *STRICT_OVERFLOW_P to true; otherwise, don't
+   change *STRICT_OVERFLOW_P.  */
+static bool
+tree_binary_expr_nonzero_warnv_p (enum tree_code code,
+				  tree type __attribute__((unused)),
+				  tree op0,
+				  tree op1, bool *strict_overflow_p)
+{
+  bool sub_strict_overflow_p;
+  switch (code)
+    {
     case POINTER_PLUS_EXPR:
     case PLUS_EXPR:
       if (TYPE_OVERFLOW_UNDEFINED (type))
@@ -14410,18 +14435,18 @@ tree_expr_nonzero_warnv_p (tree t, bool *strict_overflow_p)
 	  /* With the presence of negative values it is hard
 	     to say something.  */
 	  sub_strict_overflow_p = false;
-	  if (!tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 0),
+	  if (!tree_expr_nonnegative_warnv_p (op0,
 					      &sub_strict_overflow_p)
-	      || !tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 1),
+	      || !tree_expr_nonnegative_warnv_p (op1,
 						 &sub_strict_overflow_p))
 	    return false;
 	  /* One of operands must be positive and the other non-negative.  */
 	  /* We don't set *STRICT_OVERFLOW_P here: even if this value
 	     overflows, on a twos-complement machine the sum of two
 	     nonnegative numbers can never be zero.  */
-	  return (tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 0),
+	  return (tree_expr_nonzero_warnv_p (op0,
 					     strict_overflow_p)
-	          || tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 1),
+		  || tree_expr_nonzero_warnv_p (op1,
 						strict_overflow_p));
 	}
       break;
@@ -14429,9 +14454,9 @@ tree_expr_nonzero_warnv_p (tree t, bool *strict_overflow_p)
     case MULT_EXPR:
       if (TYPE_OVERFLOW_UNDEFINED (type))
 	{
-	  if (tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 0),
+	  if (tree_expr_nonzero_warnv_p (op0,
 					 strict_overflow_p)
-	      && tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 1),
+	      && tree_expr_nonzero_warnv_p (op1,
 					    strict_overflow_p))
 	    {
 	      *strict_overflow_p = true;
@@ -14440,18 +14465,83 @@ tree_expr_nonzero_warnv_p (tree t, bool *strict_overflow_p)
 	}
       break;
 
-    case NOP_EXPR:
-      {
-	tree inner_type = TREE_TYPE (TREE_OPERAND (t, 0));
-	tree outer_type = TREE_TYPE (t);
+    case MIN_EXPR:
+      sub_strict_overflow_p = false;
+      if (tree_expr_nonzero_warnv_p (op0,
+				     &sub_strict_overflow_p)
+	  && tree_expr_nonzero_warnv_p (op1,
+					&sub_strict_overflow_p))
+	{
+	  if (sub_strict_overflow_p)
+	    *strict_overflow_p = true;
+	}
+      break;
 
-	return (TYPE_PRECISION (outer_type) >= TYPE_PRECISION (inner_type)
-		&& tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 0),
-					      strict_overflow_p));
-      }
+    case MAX_EXPR:
+      sub_strict_overflow_p = false;
+      if (tree_expr_nonzero_warnv_p (op0,
+				     &sub_strict_overflow_p))
+	{
+	  if (sub_strict_overflow_p)
+	    *strict_overflow_p = true;
+
+	  /* When both operands are nonzero, then MAX must be too.  */
+	  if (tree_expr_nonzero_warnv_p (op1,
+					 strict_overflow_p))
+	    return true;
+
+	  /* MAX where operand 0 is positive is positive.  */
+	  return tree_expr_nonnegative_warnv_p (op0,
+					       strict_overflow_p);
+	}
+      /* MAX where operand 1 is positive is positive.  */
+      else if (tree_expr_nonzero_warnv_p (op1,
+					  &sub_strict_overflow_p)
+	       && tree_expr_nonnegative_warnv_p (op1,
+						 &sub_strict_overflow_p))
+	{
+	  if (sub_strict_overflow_p)
+	    *strict_overflow_p = true;
+	  return true;
+	}
+      break;
+
+    case BIT_IOR_EXPR:
+      return (tree_expr_nonzero_warnv_p (op1,
+					 strict_overflow_p)
+	      || tree_expr_nonzero_warnv_p (op0,
+					    strict_overflow_p));
+
+    default:
       break;
+  }
+
+  return false;
+}
 
-   case ADDR_EXPR:
+/* Return true when T is an address and is known to be nonzero.
+   For floating point we further ensure that T is not denormal.
+   Similar logic is present in nonzero_address in rtlanal.h.
+
+   If the return value is based on the assumption that signed overflow
+   is undefined, set *STRICT_OVERFLOW_P to true; otherwise, don't
+   change *STRICT_OVERFLOW_P.  */
+
+static bool
+tree_single_expr_nonzero_warnv_p (tree t, bool *strict_overflow_p)
+{
+  bool sub_strict_overflow_p;
+  switch (TREE_CODE (t))
+    {
+    case SSA_NAME:
+      /* Query VRP to see if it has recorded any information about
+	 the range of this object.  */
+      return ssa_name_nonzero_p (t);
+
+    case INTEGER_CST:
+      return !integer_zerop (t);
+
+    case ADDR_EXPR:
       {
 	tree base = get_base_address (TREE_OPERAND (t, 0));
 
@@ -14482,47 +14572,52 @@ tree_expr_nonzero_warnv_p (tree t, bool *strict_overflow_p)
 	}
       break;
 
-    case MIN_EXPR:
-      sub_strict_overflow_p = false;
-      if (tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 0),
-				     &sub_strict_overflow_p)
-	  && tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 1),
-					&sub_strict_overflow_p))
-	{
-	  if (sub_strict_overflow_p)
-	    *strict_overflow_p = true;
-	}
+    default:
       break;
+    }
+  return false;
+}
 
-    case MAX_EXPR:
-      sub_strict_overflow_p = false;
-      if (tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 0),
-				     &sub_strict_overflow_p))
-	{
-	  if (sub_strict_overflow_p)
-	    *strict_overflow_p = true;
+/* Return true when T is an address and is known to be nonzero.
+   For floating point we further ensure that T is not denormal.
+   Similar logic is present in nonzero_address in rtlanal.h.
 
-	  /* When both operands are nonzero, then MAX must be too.  */
-	  if (tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 1),
-					 strict_overflow_p))
-	    return true;
+   If the return value is based on the assumption that signed overflow
+   is undefined, set *STRICT_OVERFLOW_P to true; otherwise, don't
+   change *STRICT_OVERFLOW_P.  */
 
-	  /* MAX where operand 0 is positive is positive.  */
-	  return tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 0),
+bool
+tree_expr_nonzero_warnv_p (tree t, bool *strict_overflow_p)
+{
+  tree type = TREE_TYPE (t);
+  enum gimple_rhs_class class;
+  enum tree_code code;
+
+  /* Doing something useful for floating point would need more work.  */
+  if (!INTEGRAL_TYPE_P (type) && !POINTER_TYPE_P (type))
+    return false;
+
+  code = TREE_CODE (t);
+  class = get_gimple_rhs_class (code);
+  switch (class)
+    {
+    case GIMPLE_UNARY_RHS:
+      return tree_unary_expr_nonzero_warnv_p (code, type, TREE_OPERAND (t, 0),
+					      strict_overflow_p);
+    case GIMPLE_BINARY_RHS:
+      return tree_binary_expr_nonzero_warnv_p (code, type,
+					       TREE_OPERAND (t, 0),
+					       TREE_OPERAND (t, 1),
 					       strict_overflow_p);
-	}
-      /* MAX where operand 1 is positive is positive.  */
-      else if (tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 1),
-					  &sub_strict_overflow_p)
-	       && tree_expr_nonnegative_warnv_p (TREE_OPERAND (t, 1),
-						 &sub_strict_overflow_p))
-	{
-	  if (sub_strict_overflow_p)
-	    *strict_overflow_p = true;
-	  return true;
-	}
+    case GIMPLE_SINGLE_RHS:
+      return tree_single_expr_nonzero_warnv_p (t, strict_overflow_p);
+
+    default:
       break;
+    }
 
+  switch (code)
+    {
     case COMPOUND_EXPR:
     case MODIFY_EXPR:
     case GIMPLE_MODIFY_STMT:
@@ -14531,16 +14626,9 @@ tree_expr_nonzero_warnv_p (tree t, bool *strict_overflow_p)
 					strict_overflow_p);
 
     case SAVE_EXPR:
-    case NON_LVALUE_EXPR:
       return tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 0),
 					strict_overflow_p);
 
-    case BIT_IOR_EXPR:
-      return (tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 1),
-					strict_overflow_p)
-	      || tree_expr_nonzero_warnv_p (TREE_OPERAND (t, 0),
-					    strict_overflow_p));
-
     case CALL_EXPR:
       return alloca_call_p (t);
 

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