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: VRP speedup


> On Sun, 2006-12-03 at 18:58 +0100, Jan Hubicka wrote:
> > > On Sun, 2006-12-03 at 15:21 +0100, Jan Hubicka wrote:
> > > > 
> > > > +   return tcmp == boolean_true_node; 
> > > 
> > > I would not do that, I would just do integer_onep (tcmp).
> > > As I don't trust fold_binary_to_constant returning always
> > > boolean_true_node.
> > 
> > It is what old code did and I must say I can't figure out way how the
> > fold_binary_to_constant can correctly behave otherwise.  Perhaps instead
> > of extra function call on the quite hot code, we can add gcc_assert that
> > integer_one_p is equivalent to this test?
> 
> I think there is at least one case where integer_onep would return true
> and the direct comparision to boolean_true_node would be false:
> >From fold-const.c:8351 (fold_comparison):
>                   /* Always true.  */
>                   return omit_one_operand (type, integer_one_node,
> arg0);

Hmm, OK.  I am retesting with this patch testing !integer_zerop (...)

	* tree-vrp.c (fast_lt_compare): New.
	(compare_values, value_inside_range): Rewrite in terms of
	fast_lt_compare.

Index: tree-vrp.c
===================================================================
*** tree-vrp.c	(revision 119454)
--- tree-vrp.c	(working copy)
*************** valid_value_p (tree expr)
*** 442,447 ****
--- 442,470 ----
    return is_gimple_min_invariant (expr);
  }
  
+ /* Return 
+    1 if VAL < VAL2
+    0 if !(VAL < VAL2)
+    -2 if those are incomparable.  */
+ static inline int
+ fast_lt_compare (tree val, tree val2)
+ {
+   tree tcmp;
+   /* LT is folded faster than GE and others.  Inline the common case.  */
+   if (TREE_CODE (val) == INTEGER_CST && TREE_CODE (val2) == INTEGER_CST)
+     {
+       if (TYPE_UNSIGNED (TREE_TYPE (val)))
+ 	return INT_CST_LT_UNSIGNED (val, val2);
+       else
+ 	return INT_CST_LT (val, val2);
+     }
+   else
+     tcmp = fold_binary_to_constant (LT_EXPR, boolean_type_node, val, val2);
+   if (!tcmp)
+     return -1;
+   return !integer_zerop (tcmp);
+ }
+ 
  /* Compare two values VAL1 and VAL2.  Return
     
     	-2 if VAL1 and VAL2 cannot be compared at compile-time,
*************** compare_values (tree val1, tree val2)
*** 590,602 ****
  	return 0;
        
        /* If VAL1 is a lower address than VAL2, return -1.  */
!       t = fold_binary (LT_EXPR, boolean_type_node, val1, val2);
!       if (t == boolean_true_node)
  	return -1;
  
        /* If VAL1 is a higher address than VAL2, return +1.  */
!       t = fold_binary (GT_EXPR, boolean_type_node, val1, val2);
!       if (t == boolean_true_node)
  	return 1;
  
        /* If VAL1 is different than VAL2, return +2.  */
--- 613,623 ----
  	return 0;
        
        /* If VAL1 is a lower address than VAL2, return -1.  */
!       if (fast_lt_compare (val1, val2) == 1)
  	return -1;
  
        /* If VAL1 is a higher address than VAL2, return +1.  */
!       if (fast_lt_compare (val2, val1) == 1)
  	return 1;
  
        /* If VAL1 is different than VAL2, return +2.  */
*************** compare_values (tree val1, tree val2)
*** 608,614 ****
      }
  }
  
- 
  /* Return 1 if VAL is inside value range VR (VR->MIN <= VAL <= VR->MAX),
            0 if VAL is not inside VR,
  	 -2 if we cannot tell either way.
--- 629,634 ----
*************** compare_values (tree val1, tree val2)
*** 627,653 ****
  	  This also applies to value_ranges_intersect_p and
  	  range_includes_zero_p.  The semantics of VR_RANGE and
  	  VR_ANTI_RANGE should be encoded here, but that also means
! 	  adapting the users of these functions to the new semantics.  */
  
  static inline int
! value_inside_range (tree val, value_range_t *vr)
  {
!   tree cmp1, cmp2;
  
!   cmp1 = fold_binary_to_constant (GE_EXPR, boolean_type_node, val, vr->min);
!   if (!cmp1)
      return -2;
  
!   cmp2 = fold_binary_to_constant (LE_EXPR, boolean_type_node, val, vr->max);
!   if (!cmp2)
      return -2;
  
!   return cmp1 == boolean_true_node && cmp2 == boolean_true_node;
  }
  
  
  /* Return true if value ranges VR0 and VR1 have a non-empty
!    intersection.  */
  
  static inline bool
  value_ranges_intersect_p (value_range_t *vr0, value_range_t *vr1)
--- 647,682 ----
  	  This also applies to value_ranges_intersect_p and
  	  range_includes_zero_p.  The semantics of VR_RANGE and
  	  VR_ANTI_RANGE should be encoded here, but that also means
! 	  adapting the users of these functions to the new semantics.  
! 
!    Benchmark compile/20001226-1.c compilation time after changing this
!    function.  */
  
  static inline int
! value_inside_range (tree val, value_range_t * vr)
  {
!   int cmp1, cmp2;
  
!   cmp1 = fast_lt_compare (val, vr->min);
!   if (cmp1 == -2)
      return -2;
+   if (cmp1)
+     return 0;
  
!   cmp2 = fast_lt_compare (vr->max, val);
!   if (cmp2 == -2)
      return -2;
  
!   return !cmp2;
  }
  
  
  /* Return true if value ranges VR0 and VR1 have a non-empty
!    intersection.  
!    
!    Benchmark compile/20001226-1.c compilation time after changing this
!    function.
!    */
  
  static inline bool
  value_ranges_intersect_p (value_range_t *vr0, value_range_t *vr1)


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