diff options
author | Richard Guenther <rguenther@suse.de> | 2012-06-19 13:06:35 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2012-06-19 13:06:35 +0000 |
commit | 105b7208d1f4630a29c09c31b5273b1c602a04c1 (patch) | |
tree | f2c02a77b95275c93238479fe3e13a1e15cb5f83 /gcc | |
parent | af4d0d913bb41215875b7e9e668009ba98d973e6 (diff) | |
download | gcc-105b7208d1f4630a29c09c31b5273b1c602a04c1.zip gcc-105b7208d1f4630a29c09c31b5273b1c602a04c1.tar.gz gcc-105b7208d1f4630a29c09c31b5273b1c602a04c1.tar.bz2 |
tree-vrp.c (intersect_ranges): Handle more cases.
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.
From-SVN: r188776
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/tree-vrp.c | 151 |
2 files changed, 134 insertions, 23 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index df128a4..9b96131 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 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. + +2012-06-19 Richard Guenther <rguenther@suse.de> + PR tree-optimization/53708 * tree-vect-data-refs.c (vect_can_force_dr_alignment_p): Preserve user-supplied alignment and alignment of decls with the used diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index 1147552..53d6ac3 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -6781,9 +6781,31 @@ intersect_ranges (enum value_range_type *vr0type, 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 (operand_less_p (*vr0max, vr1min) == 1 - || operand_less_p (vr1max, *vr0min) == 1) + 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 @@ -6813,19 +6835,48 @@ intersect_ranges (enum value_range_type *vr0type, /* Take VR0. */ } } - else if (operand_less_p (vr1max, *vr0max) == 1 - && operand_less_p (*vr0min, vr1min) == 1) + else if ((maxeq || operand_less_p (vr1max, *vr0max) == 1) + && (mineq || operand_less_p (*vr0min, vr1min) == 1)) { - /* [ ( ) ] */ - if (*vr0type == VR_RANGE) + /* [ ( ) ] or [( ) ] or [ ( )] */ + if (*vr0type == VR_RANGE + && 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. */ + /* 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. */ @@ -6841,16 +6892,52 @@ intersect_ranges (enum value_range_type *vr0type, else gcc_unreachable (); } - else if (operand_less_p (*vr0max, vr1max) == 1 - && operand_less_p (vr1min, *vr0min) == 1) + else if ((maxeq || operand_less_p (*vr0max, vr1max) == 1) + && (mineq || 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. */ + /* ( [ ] ) 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. */ @@ -6871,10 +6958,9 @@ intersect_ranges (enum value_range_type *vr0type, } 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))) + && operand_less_p (*vr0min, vr1min) == 1) { - /* [ ( ] ) */ + /* [ ( ] ) or [ ]( ) */ if (*vr0type == VR_ANTI_RANGE && vr1type == VR_ANTI_RANGE) *vr0max = vr1max; @@ -6906,10 +6992,9 @@ intersect_ranges (enum value_range_type *vr0type, } 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))) + && operand_less_p (vr1min, *vr0min) == 1) { - /* ( [ ) ] */ + /* ( [ ) ] or ( )[ ] */ if (*vr0type == VR_ANTI_RANGE && vr1type == VR_ANTI_RANGE) *vr0min = vr1min; @@ -6952,7 +7037,7 @@ intersect_ranges (enum value_range_type *vr0type, in *VR0. This may not be the smallest possible such range. */ static void -vrp_intersect_ranges (value_range_t *vr0, value_range_t *vr1) +vrp_intersect_ranges_1 (value_range_t *vr0, value_range_t *vr1) { value_range_t saved; @@ -7003,6 +7088,26 @@ vrp_intersect_ranges (value_range_t *vr0, value_range_t *vr1) 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. */ |