aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/tree-vrp.c56
2 files changed, 49 insertions, 13 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 615f13d..b963ad6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2006-12-06 Jan Hubicka <jh@suse.cz>
+
+ * tree-vrp.c (operand_less_p): New.
+ (compare_values, value_inside_range): Rewrite in terms of
+ operand_less_p.
+
2006-12-06 Uros Bizjak <ubizjak@gmail.com>
* config/i386/i386.md (DIRFLAG_REG): Remove constant.
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index bbbaa5b..908f22b 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -442,6 +442,29 @@ valid_value_p (tree expr)
return is_gimple_min_invariant (expr);
}
+/* Return
+ 1 if VAL < VAL2
+ 0 if !(VAL < VAL2)
+ -2 if those are incomparable. */
+static inline int
+operand_less_p (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 -2;
+ return !integer_zerop (tcmp);
+}
+
/* Compare two values VAL1 and VAL2. Return
-2 if VAL1 and VAL2 cannot be compared at compile-time,
@@ -590,13 +613,11 @@ compare_values (tree val1, tree val2)
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)
+ if (operand_less_p (val1, val2) == 1)
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)
+ if (operand_less_p (val2, val1) == 1)
return 1;
/* If VAL1 is different than VAL2, return +2. */
@@ -627,27 +648,36 @@ compare_values (tree val1, tree val2)
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. */
+ 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)
+value_inside_range (tree val, value_range_t * vr)
{
- tree cmp1, cmp2;
+ int cmp1, cmp2;
- cmp1 = fold_binary_to_constant (GE_EXPR, boolean_type_node, val, vr->min);
- if (!cmp1)
+ cmp1 = operand_less_p (val, vr->min);
+ if (cmp1 == -2)
return -2;
+ if (cmp1 == 1)
+ return 0;
- cmp2 = fold_binary_to_constant (LE_EXPR, boolean_type_node, val, vr->max);
- if (!cmp2)
+ cmp2 = operand_less_p (vr->max, val);
+ if (cmp2 == -2)
return -2;
- return cmp1 == boolean_true_node && cmp2 == boolean_true_node;
+ return !cmp2;
}
/* Return true if value ranges VR0 and VR1 have a non-empty
- intersection. */
+ 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)