diff options
author | Richard Biener <rguenther@suse.de> | 2019-07-29 11:38:46 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2019-07-29 11:38:46 +0000 |
commit | a55d6091230ae8d0d6f6c20dcc55158f6705090e (patch) | |
tree | cec10398d4ae477966d760d992c57c79ff102569 /gcc/tree-vrp.c | |
parent | fc5e7d2ac42fbc9169458095f4fff257e4a80d03 (diff) | |
download | gcc-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.c | 68 |
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; } } |