aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-vrp.c
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2019-07-29 11:38:46 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2019-07-29 11:38:46 +0000
commita55d6091230ae8d0d6f6c20dcc55158f6705090e (patch)
treecec10398d4ae477966d760d992c57c79ff102569 /gcc/tree-vrp.c
parentfc5e7d2ac42fbc9169458095f4fff257e4a80d03 (diff)
downloadgcc-a55d6091230ae8d0d6f6c20dcc55158f6705090e.zip
gcc-a55d6091230ae8d0d6f6c20dcc55158f6705090e.tar.gz
gcc-a55d6091230ae8d0d6f6c20dcc55158f6705090e.tar.bz2
re PR tree-optimization/91257 (Compile-time and memory-hog hog)
2019-07-29 Richard Biener <rguenther@suse.de> PR tree-optimization/91257 * tree-vrp.c (operand_less_p): Avoid dispatching to fold for most cases, instead call compare_values which handles the symbolic ranges we handle specially. (compare_values_warnv): Do not call operand_less_p but open-code the effective fold calls. Avoid converting so much. From-SVN: r273876
Diffstat (limited to 'gcc/tree-vrp.c')
-rw-r--r--gcc/tree-vrp.c68
1 files changed, 37 insertions, 31 deletions
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 9ba6f80..1b20489 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -909,22 +909,17 @@ operand_less_p (tree val, tree val2)
/* LT is folded faster than GE and others. Inline the common case. */
if (TREE_CODE (val) == INTEGER_CST && TREE_CODE (val2) == INTEGER_CST)
return tree_int_cst_lt (val, val2);
+ else if (TREE_CODE (val) == SSA_NAME && TREE_CODE (val2) == SSA_NAME)
+ return val == val2 ? 0 : -2;
else
{
- tree tcmp;
-
- fold_defer_overflow_warnings ();
-
- tcmp = fold_binary_to_constant (LT_EXPR, boolean_type_node, val, val2);
-
- fold_undefer_and_ignore_overflow_warnings ();
-
- if (!tcmp
- || TREE_CODE (tcmp) != INTEGER_CST)
- return -2;
-
- if (!integer_zerop (tcmp))
+ int cmp = compare_values (val, val2);
+ if (cmp == -1)
return 1;
+ else if (cmp == 0 || cmp == 1)
+ return 0;
+ else
+ return -2;
}
return 0;
@@ -958,8 +953,8 @@ compare_values_warnv (tree val1, tree val2, bool *strict_overflow_p)
/* Convert the two values into the same type. This is needed because
sizetype causes sign extension even for unsigned types. */
- val2 = fold_convert (TREE_TYPE (val1), val2);
- STRIP_USELESS_TYPE_CONVERSION (val2);
+ if (!useless_type_conversion_p (TREE_TYPE (val1), TREE_TYPE (val2)))
+ val2 = fold_convert (TREE_TYPE (val1), val2);
const bool overflow_undefined
= INTEGRAL_TYPE_P (TREE_TYPE (val1))
@@ -1067,32 +1062,43 @@ compare_values_warnv (tree val1, tree val2, bool *strict_overflow_p)
}
else
{
- tree t;
+ if (TREE_CODE (val1) == INTEGER_CST && TREE_CODE (val2) == INTEGER_CST)
+ {
+ /* We cannot compare overflowed values. */
+ if (TREE_OVERFLOW (val1) || TREE_OVERFLOW (val2))
+ return -2;
+
+ return tree_int_cst_compare (val1, val2);
+ }
/* First see if VAL1 and VAL2 are not the same. */
- if (val1 == val2 || operand_equal_p (val1, val2, 0))
+ if (operand_equal_p (val1, val2, 0))
return 0;
+ fold_defer_overflow_warnings ();
+
/* If VAL1 is a lower address than VAL2, return -1. */
- if (operand_less_p (val1, val2) == 1)
- return -1;
+ tree t = fold_binary_to_constant (LT_EXPR, boolean_type_node, val1, val2);
+ if (t && integer_onep (t))
+ {
+ fold_undefer_and_ignore_overflow_warnings ();
+ return -1;
+ }
/* If VAL1 is a higher address than VAL2, return +1. */
- if (operand_less_p (val2, val1) == 1)
- return 1;
-
- /* If VAL1 is different than VAL2, return +2.
- For integer constants we either have already returned -1 or 1
- or they are equivalent. We still might succeed in proving
- something about non-trivial operands. */
- if (TREE_CODE (val1) != INTEGER_CST
- || TREE_CODE (val2) != INTEGER_CST)
+ t = fold_binary_to_constant (LT_EXPR, boolean_type_node, val2, val1);
+ if (t && integer_onep (t))
{
- t = fold_binary_to_constant (NE_EXPR, boolean_type_node, val1, val2);
- if (t && integer_onep (t))
- return 2;
+ fold_undefer_and_ignore_overflow_warnings ();
+ return 1;
}
+ /* If VAL1 is different than VAL2, return +2. */
+ t = fold_binary_to_constant (NE_EXPR, boolean_type_node, val1, val2);
+ fold_undefer_and_ignore_overflow_warnings ();
+ if (t && integer_onep (t))
+ return 2;
+
return -2;
}
}