This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH][5/n] VRP and anti-ranges
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Tue, 19 Jun 2012 14:54:53 +0200 (CEST)
- Subject: [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. */