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][5/n] VRP and anti-ranges


This adjusts intersect_ranges to match what will become union_ranges
(but in a separate patch).

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

Richard.

2012-06-19  Richard Guenther  <rguenther@suse.de>

	* tree-vrp.c (intersect_ranges): Handle more cases.
	(vrp_intersect_ranges): Dump what we intersect and call ...
	(vrp_intersect_ranges_1): ... this.

Index: gcc/tree-vrp.c
===================================================================
*** gcc/tree-vrp.c	(revision 188771)
--- gcc/tree-vrp.c	(working copy)
*************** intersect_ranges (enum value_range_type
*** 6781,6789 ****
  		  enum value_range_type vr1type,
  		  tree vr1min, tree vr1max)
  {
    /* [] is vr0, () is vr1 in the following classification comments.  */
!   if (operand_less_p (*vr0max, vr1min) == 1
!       || operand_less_p (vr1max, *vr0min) == 1)
      {
        /* [ ] ( ) or ( ) [ ]
  	 If the ranges have an empty intersection, the result of the
--- 6781,6811 ----
  		  enum value_range_type vr1type,
  		  tree vr1min, tree vr1max)
  {
+   bool mineq = operand_equal_p (*vr0min, vr1min, 0);
+   bool maxeq = operand_equal_p (*vr0max, vr1max, 0);
+ 
    /* [] is vr0, () is vr1 in the following classification comments.  */
!   if (mineq && maxeq)
!     {
!       /* [(  )] */
!       if (*vr0type == vr1type)
! 	/* Nothing to do for equal ranges.  */
! 	;
!       else if ((*vr0type == VR_RANGE
! 		&& vr1type == VR_ANTI_RANGE)
! 	       || (*vr0type == VR_ANTI_RANGE
! 		   && vr1type == VR_RANGE))
! 	{
! 	  /* For anti-range with range intersection the result is empty.  */
! 	  *vr0type = VR_UNDEFINED;
! 	  *vr0min = NULL_TREE;
! 	  *vr0max = NULL_TREE;
! 	}
!       else
! 	gcc_unreachable ();
!     }
!   else if (operand_less_p (*vr0max, vr1min) == 1
! 	   || operand_less_p (vr1max, *vr0min) == 1)
      {
        /* [ ] ( ) or ( ) [ ]
  	 If the ranges have an empty intersection, the result of the
*************** intersect_ranges (enum value_range_type
*** 6813,6831 ****
  	  /* Take VR0.  */
  	}
      }
!   else if (operand_less_p (vr1max, *vr0max) == 1
! 	   && operand_less_p (*vr0min, vr1min) == 1)
      {
!       /* [ (  ) ]  */
!       if (*vr0type == VR_RANGE)
  	{
! 	  /* If the outer is a range choose the inner one.
! 	     ???  If the inner is an anti-range this arbitrarily chooses
! 	     the anti-range.  */
  	  *vr0type = vr1type;
  	  *vr0min = vr1min;
  	  *vr0max = vr1max;
  	}
        else if (*vr0type == VR_ANTI_RANGE
  	       && vr1type == VR_ANTI_RANGE)
  	/* If both are anti-ranges the result is the outer one.  */
--- 6835,6882 ----
  	  /* Take VR0.  */
  	}
      }
!   else if ((maxeq || operand_less_p (vr1max, *vr0max) == 1)
! 	   && (mineq || operand_less_p (*vr0min, vr1min) == 1))
      {
!       /* [ (  ) ] or [(  ) ] or [ (  )] */
!       if (*vr0type == VR_RANGE
! 	  && vr1type == VR_RANGE)
  	{
! 	  /* If both are ranges the result is the inner one.  */
  	  *vr0type = vr1type;
  	  *vr0min = vr1min;
  	  *vr0max = vr1max;
  	}
+       else if (*vr0type == VR_RANGE
+ 	       && vr1type == VR_ANTI_RANGE)
+ 	{
+ 	  /* Choose the right gap if the left one is empty.  */
+ 	  if (mineq)
+ 	    {
+ 	      if (TREE_CODE (vr1max) == INTEGER_CST)
+ 		*vr0min = int_const_binop (PLUS_EXPR, vr1max, integer_one_node);
+ 	      else
+ 		*vr0min = vr1max;
+ 	    }
+ 	  /* Choose the left gap if the right one is empty.  */
+ 	  else if (maxeq)
+ 	    {
+ 	      if (TREE_CODE (vr1min) == INTEGER_CST)
+ 		*vr0max = int_const_binop (MINUS_EXPR, vr1min,
+ 					   integer_one_node);
+ 	      else
+ 		*vr0max = vr1min;
+ 	    }
+ 	  /* Choose the anti-range if the range is effectively varying.  */
+ 	  else if (vrp_val_is_min (*vr0min)
+ 		   && vrp_val_is_max (*vr0max))
+ 	    {
+ 	      *vr0type = vr1type;
+ 	      *vr0min = vr1min;
+ 	      *vr0max = vr1max;
+ 	    }
+ 	  /* Else choose the range.  */
+ 	}
        else if (*vr0type == VR_ANTI_RANGE
  	       && vr1type == VR_ANTI_RANGE)
  	/* If both are anti-ranges the result is the outer one.  */
*************** intersect_ranges (enum value_range_type
*** 6841,6856 ****
        else
  	gcc_unreachable ();
      }
!   else if (operand_less_p (*vr0max, vr1max) == 1
! 	   && operand_less_p (vr1min, *vr0min) == 1)
      {
!       /* ( [  ] )  */
!       if (vr1type == VR_RANGE)
! 	/* If the outer is a range, choose the inner one.
! 	   ???  If the inner is an anti-range this arbitrarily chooses
! 	   the anti-range.  */
  	;
        else if (*vr0type == VR_ANTI_RANGE
  	       && vr1type == VR_ANTI_RANGE)
  	{
  	  /* If both are anti-ranges the result is the outer one.  */
--- 6892,6943 ----
        else
  	gcc_unreachable ();
      }
!   else if ((maxeq || operand_less_p (*vr0max, vr1max) == 1)
! 	   && (mineq || operand_less_p (vr1min, *vr0min) == 1))
      {
!       /* ( [  ] ) or ([  ] ) or ( [  ]) */
!       if (*vr0type == VR_RANGE
! 	  && vr1type == VR_RANGE)
! 	/* Choose the inner range.  */
  	;
        else if (*vr0type == VR_ANTI_RANGE
+ 	       && vr1type == VR_RANGE)
+ 	{
+ 	  /* Choose the right gap if the left is empty.  */
+ 	  if (mineq)
+ 	    {
+ 	      *vr0type = VR_RANGE;
+ 	      if (TREE_CODE (*vr0max) == INTEGER_CST)
+ 		*vr0min = int_const_binop (PLUS_EXPR, *vr0max,
+ 					   integer_one_node);
+ 	      else
+ 		*vr0min = *vr0max;
+ 	      *vr0max = vr1max;
+ 	    }
+ 	  /* Choose the left gap if the right is empty.  */
+ 	  else if (maxeq)
+ 	    {
+ 	      *vr0type = VR_RANGE;
+ 	      if (TREE_CODE (*vr0min) == INTEGER_CST)
+ 		*vr0max = int_const_binop (MINUS_EXPR, *vr0min,
+ 					   integer_one_node);
+ 	      else
+ 		*vr0max = *vr0min;
+ 	      *vr0min = vr1min;
+ 	    }
+ 	  /* Choose the anti-range if the range is effectively varying.  */
+ 	  else if (vrp_val_is_min (vr1min)
+ 		   && vrp_val_is_max (vr1max))
+ 	    ;
+ 	  /* Else choose the range.  */
+ 	  else
+ 	    {
+ 	      *vr0type = vr1type;
+ 	      *vr0min = vr1min;
+ 	      *vr0max = vr1max;
+ 	    }
+ 	}
+       else if (*vr0type == VR_ANTI_RANGE
  	       && vr1type == VR_ANTI_RANGE)
  	{
  	  /* If both are anti-ranges the result is the outer one.  */
*************** intersect_ranges (enum value_range_type
*** 6871,6880 ****
      }
    else if ((operand_less_p (vr1min, *vr0max) == 1
  	    || operand_equal_p (vr1min, *vr0max, 0))
! 	   && (operand_less_p (*vr0min, vr1min) == 1
! 	       || operand_equal_p (*vr0min, vr1min, 0)))
      {
!       /* [  (  ]  ) */
        if (*vr0type == VR_ANTI_RANGE
  	  && vr1type == VR_ANTI_RANGE)
  	*vr0max = vr1max;
--- 6958,6966 ----
      }
    else if ((operand_less_p (vr1min, *vr0max) == 1
  	    || operand_equal_p (vr1min, *vr0max, 0))
! 	   && operand_less_p (*vr0min, vr1min) == 1)
      {
!       /* [  (  ]  ) or [  ](  ) */
        if (*vr0type == VR_ANTI_RANGE
  	  && vr1type == VR_ANTI_RANGE)
  	*vr0max = vr1max;
*************** intersect_ranges (enum value_range_type
*** 6906,6915 ****
      }
    else if ((operand_less_p (*vr0min, vr1max) == 1
  	    || operand_equal_p (*vr0min, vr1max, 0))
! 	   && (operand_less_p (vr1min, *vr0min) == 1
! 	       || operand_equal_p (vr1min, *vr0min, 0)))
      {
!       /* (  [  )  ] */
        if (*vr0type == VR_ANTI_RANGE
  	  && vr1type == VR_ANTI_RANGE)
  	*vr0min = vr1min;
--- 6992,7000 ----
      }
    else if ((operand_less_p (*vr0min, vr1max) == 1
  	    || operand_equal_p (*vr0min, vr1max, 0))
! 	   && operand_less_p (vr1min, *vr0min) == 1)
      {
!       /* (  [  )  ] or (  )[  ] */
        if (*vr0type == VR_ANTI_RANGE
  	  && vr1type == VR_ANTI_RANGE)
  	*vr0min = vr1min;
*************** intersect_ranges (enum value_range_type
*** 6952,6958 ****
     in *VR0.  This may not be the smallest possible such range.  */
  
  static void
! vrp_intersect_ranges (value_range_t *vr0, value_range_t *vr1)
  {
    value_range_t saved;
  
--- 7037,7043 ----
     in *VR0.  This may not be the smallest possible such range.  */
  
  static void
! vrp_intersect_ranges_1 (value_range_t *vr0, value_range_t *vr1)
  {
    value_range_t saved;
  
*************** vrp_intersect_ranges (value_range_t *vr0
*** 7003,7008 ****
--- 7088,7113 ----
      bitmap_copy (vr0->equiv, vr1->equiv);
  }
  
+ static void
+ vrp_intersect_ranges (value_range_t *vr0, value_range_t *vr1)
+ {
+   if (dump_file && (dump_flags & TDF_DETAILS))
+     {
+       fprintf (dump_file, "Intersecting\n  ");
+       dump_value_range (dump_file, vr0);
+       fprintf (dump_file, "\nand\n  ");
+       dump_value_range (dump_file, vr1);
+       fprintf (dump_file, "\n");
+     }
+   vrp_intersect_ranges_1 (vr0, vr1);
+   if (dump_file && (dump_flags & TDF_DETAILS))
+     {
+       fprintf (dump_file, "to\n  ");
+       dump_value_range (dump_file, vr0);
+       fprintf (dump_file, "\n");
+     }
+ }
+ 
  /* Meet operation for value ranges.  Given two value ranges VR0 and
     VR1, store in VR0 a range that contains both VR0 and VR1.  This
     may not be the smallest possible such range.  */


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