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]

Re: [tree-ssa/mainline PATCH] fold "test"==0 into constant


Hi,
here is updated patch.  It has passed testing on i386 tree-ssa and
really hope I got it right this time.
As mentioned earlier, I can modify it to use positive_p predicate if it
seems usefull at some runtime cost.

Honza

2003-11-06  Jan Hubicka  <jh@suse.cz>
	* fold-const.c (tree_expr_nonzero_p): New function.
	(fold_relational_const): Use it.
Index: fold-const.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/fold-const.c,v
retrieving revision 1.213.2.55
diff -c -3 -p -r1.213.2.55 fold-const.c
*** fold-const.c	30 Oct 2003 02:27:40 -0000	1.213.2.55
--- fold-const.c	6 Nov 2003 18:08:14 -0000
*************** tree_expr_nonnegative_p (tree t)
*** 8605,8610 ****
--- 8605,8710 ----
    return 0;
  }
  
+ /* 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  */
+ 
+ static bool
+ tree_expr_nonzero_p (tree t)
+ {
+   tree type = TREE_TYPE (t);
+ 
+   /* Doing something usefull for floating point would need more work.  */
+   if (!INTEGRAL_TYPE_P (t))
+     return false;
+ 
+   switch (TREE_CODE (t))
+     {
+     case ABS_EXPR:
+       if (!TREE_UNSIGNED (type) && !flag_wrapv)
+ 	return tree_expr_nonzero_p (TREE_OPERAND (t, 0));
+ 
+     case INTEGER_CST:
+       return !integer_zerop (t);
+ 
+     case PLUS_EXPR:
+       if (!TREE_UNSIGNED (type) && !flag_wrapv)
+ 	{
+ 	  /* With the presence of negative values it is hard
+ 	     to say something.  */
+ 	  if (!tree_expr_nonnegative_p (TREE_OPERAND (t, 0))
+ 	      || !tree_expr_nonnegative_p (TREE_OPERAND (t, 1)))
+ 	    return false;
+ 	  /* One of operands must be positive and the other non-negative.  */
+ 	  return (tree_expr_nonzero_p (TREE_OPERAND (t, 0))
+ 	          || tree_expr_nonzero_p (TREE_OPERAND (t, 1)));
+ 	}
+       break;
+ 
+     case MULT_EXPR:
+       if (!TREE_UNSIGNED (type) && !flag_wrapv)
+ 	{
+ 	  return (tree_expr_nonzero_p (TREE_OPERAND (t, 0))
+ 	          && tree_expr_nonzero_p (TREE_OPERAND (t, 1)));
+ 	}
+       break;
+ 
+     case NOP_EXPR:
+       {
+ 	tree inner_type = TREE_TYPE (TREE_OPERAND (t, 0));
+ 	tree outer_type = TREE_TYPE (t);
+ 
+ 	return (TYPE_PRECISION (inner_type) >= TYPE_PRECISION (outer_type)
+ 		&& tree_expr_nonzero_p (TREE_OPERAND (t, 0)));
+       }
+       break;
+ 
+    case ADDR_EXPR:
+       /* Weak declarations may link to NULL.  */
+       if (DECL_P (TREE_OPERAND (t, 0)))
+ 	return !DECL_WEAK (TREE_OPERAND (t, 0));
+       /* Constants and all other cases are never weak.  */
+       return true;
+ 
+     case COND_EXPR:
+       return (tree_expr_nonzero_p (TREE_OPERAND (t, 1))
+ 	      && tree_expr_nonzero_p (TREE_OPERAND (t, 2)));
+ 
+     case MIN_EXPR:
+       return (tree_expr_nonzero_p (TREE_OPERAND (t, 0))
+ 	      && tree_expr_nonzero_p (TREE_OPERAND (t, 1)));
+ 
+     case MAX_EXPR:
+       if (tree_expr_nonzero_p (TREE_OPERAND (t, 0)))
+ 	{
+ 	  /* When both operands are nonzero, then MAX must be too.  */
+ 	  if (tree_expr_nonzero_p (TREE_OPERAND (t, 1)))
+ 	    return true;
+ 
+ 	  /* MAX where operand 0 is positive is positive.  */
+ 	  return tree_expr_nonnegative_p (TREE_OPERAND (t, 0));
+ 	}
+       /* MAX where operand 1 is positive is positive.  */
+       else if (tree_expr_nonzero_p (TREE_OPERAND (t, 1))
+ 	       && tree_expr_nonnegative_p (TREE_OPERAND (t, 1)))
+ 	return true;
+       break;
+ 
+     case COMPOUND_EXPR:
+     case MODIFY_EXPR:
+     case BIND_EXPR:
+       return tree_expr_nonzero_p (TREE_OPERAND (t, 1));
+ 
+     case SAVE_EXPR:
+     case NON_LVALUE_EXPR:
+       return tree_expr_nonzero_p (TREE_OPERAND (t, 0));
+ 
+     default:
+       break;
+     }
+   return false;
+ }
+ 
  /* Return true if `r' is known to be non-negative.
     Only handles constants at the moment.  */
  
*************** fold_relational_const (enum tree_code co
*** 8787,8792 ****
--- 8887,8899 ----
  			   0);
      }
  
+   else if (code == EQ_EXPR
+            && integer_zerop (op1) && tree_expr_nonzero_p (op0))
+     tem = build_int_2 (0, 0);
+   else if (code == NE_EXPR
+            && integer_zerop (op1) && tree_expr_nonzero_p (op0))
+     tem = build_int_2 (1, 0);
+ 
    /* Two real constants can be compared explicitly.  */
    else if (TREE_CODE (op0) == REAL_CST && TREE_CODE (op1) == REAL_CST)
      {


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