00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "config.h"
00023 #include "system.h"
00024 #include "coretypes.h"
00025 #include "tm.h"
00026 #include "ggc.h"
00027 #include "flags.h"
00028 #include "tree.h"
00029 #include "basic-block.h"
00030 #include "tree-flow.h"
00031 #include "tree-pass.h"
00032 #include "tree-dump.h"
00033 #include "timevar.h"
00034 #include "diagnostic.h"
00035 #include "toplev.h"
00036 #include "intl.h"
00037 #include "cfgloop.h"
00038 #include "tree-scalar-evolution.h"
00039 #include "tree-ssa-propagate.h"
00040 #include "tree-chrec.h"
00041
00042
00043
00044 static sbitmap found_in_subgraph;
00045
00046
00047 static int compare_values (tree val1, tree val2);
00048 static int compare_values_warnv (tree val1, tree val2, bool *);
00049 static tree vrp_evaluate_conditional_warnv (tree, bool, bool *);
00050
00051
00052
00053
00054
00055
00056 struct assert_locus_d
00057 {
00058
00059 basic_block bb;
00060
00061
00062
00063 edge e;
00064
00065
00066 block_stmt_iterator si;
00067
00068
00069 enum tree_code comp_code;
00070
00071
00072 tree val;
00073
00074
00075 struct assert_locus_d *next;
00076 };
00077
00078 typedef struct assert_locus_d *assert_locus_t;
00079
00080
00081
00082 static bitmap need_assert_for;
00083
00084
00085
00086
00087 static assert_locus_t *asserts_for;
00088
00089
00090
00091 static sbitmap blocks_visited;
00092
00093
00094
00095 static value_range_t **vr_value;
00096
00097
00098
00099
00100
00101
00102
00103
00104 static inline bool
00105 needs_overflow_infinity (tree type)
00106 {
00107 return INTEGRAL_TYPE_P (type) && !TYPE_OVERFLOW_WRAPS (type);
00108 }
00109
00110
00111
00112
00113
00114
00115
00116 static inline bool
00117 supports_overflow_infinity (tree type)
00118 {
00119 #ifdef ENABLE_CHECKING
00120 gcc_assert (needs_overflow_infinity (type));
00121 #endif
00122 return (TYPE_MIN_VALUE (type) != NULL_TREE
00123 && CONSTANT_CLASS_P (TYPE_MIN_VALUE (type))
00124 && TYPE_MAX_VALUE (type) != NULL_TREE
00125 && CONSTANT_CLASS_P (TYPE_MAX_VALUE (type)));
00126 }
00127
00128
00129
00130
00131 static inline tree
00132 make_overflow_infinity (tree val)
00133 {
00134 #ifdef ENABLE_CHECKING
00135 gcc_assert (val != NULL_TREE && CONSTANT_CLASS_P (val));
00136 #endif
00137 val = copy_node (val);
00138 TREE_OVERFLOW (val) = 1;
00139 return val;
00140 }
00141
00142
00143
00144 static inline tree
00145 negative_overflow_infinity (tree type)
00146 {
00147 #ifdef ENABLE_CHECKING
00148 gcc_assert (supports_overflow_infinity (type));
00149 #endif
00150 return make_overflow_infinity (TYPE_MIN_VALUE (type));
00151 }
00152
00153
00154
00155 static inline tree
00156 positive_overflow_infinity (tree type)
00157 {
00158 #ifdef ENABLE_CHECKING
00159 gcc_assert (supports_overflow_infinity (type));
00160 #endif
00161 return make_overflow_infinity (TYPE_MAX_VALUE (type));
00162 }
00163
00164
00165
00166 static inline bool
00167 is_negative_overflow_infinity (tree val)
00168 {
00169 return (needs_overflow_infinity (TREE_TYPE (val))
00170 && CONSTANT_CLASS_P (val)
00171 && TREE_OVERFLOW (val)
00172 && operand_equal_p (val, TYPE_MIN_VALUE (TREE_TYPE (val)), 0));
00173 }
00174
00175
00176
00177 static inline bool
00178 is_positive_overflow_infinity (tree val)
00179 {
00180 return (needs_overflow_infinity (TREE_TYPE (val))
00181 && CONSTANT_CLASS_P (val)
00182 && TREE_OVERFLOW (val)
00183 && operand_equal_p (val, TYPE_MAX_VALUE (TREE_TYPE (val)), 0));
00184 }
00185
00186
00187
00188 static inline bool
00189 is_overflow_infinity (tree val)
00190 {
00191 return (needs_overflow_infinity (TREE_TYPE (val))
00192 && CONSTANT_CLASS_P (val)
00193 && TREE_OVERFLOW (val)
00194 && (operand_equal_p (val, TYPE_MAX_VALUE (TREE_TYPE (val)), 0)
00195 || operand_equal_p (val, TYPE_MIN_VALUE (TREE_TYPE (val)), 0)));
00196 }
00197
00198
00199
00200
00201
00202
00203
00204
00205 static inline bool
00206 vrp_val_is_max (tree val)
00207 {
00208 tree type_max = TYPE_MAX_VALUE (TREE_TYPE (val));
00209
00210 return (val == type_max
00211 || (type_max != NULL_TREE
00212 && operand_equal_p (val, type_max, 0)));
00213 }
00214
00215
00216
00217
00218 static inline bool
00219 vrp_val_is_min (tree val)
00220 {
00221 tree type_min = TYPE_MIN_VALUE (TREE_TYPE (val));
00222
00223 return (val == type_min
00224 || (type_min != NULL_TREE
00225 && operand_equal_p (val, type_min, 0)));
00226 }
00227
00228
00229
00230
00231
00232 static bool
00233 nonnull_arg_p (tree arg)
00234 {
00235 tree t, attrs, fntype;
00236 unsigned HOST_WIDE_INT arg_num;
00237
00238 gcc_assert (TREE_CODE (arg) == PARM_DECL && POINTER_TYPE_P (TREE_TYPE (arg)));
00239
00240
00241 if (arg == cfun->static_chain_decl)
00242 return true;
00243
00244 fntype = TREE_TYPE (current_function_decl);
00245 attrs = lookup_attribute ("nonnull", TYPE_ATTRIBUTES (fntype));
00246
00247
00248 if (attrs == NULL_TREE)
00249 return false;
00250
00251
00252 if (TREE_VALUE (attrs) == NULL_TREE)
00253 return true;
00254
00255
00256 for (arg_num = 1, t = DECL_ARGUMENTS (current_function_decl);
00257 t;
00258 t = TREE_CHAIN (t), arg_num++)
00259 {
00260 if (t == arg)
00261 break;
00262 }
00263
00264 gcc_assert (t == arg);
00265
00266
00267 for (t = TREE_VALUE (attrs); t; t = TREE_CHAIN (t))
00268 {
00269 if (compare_tree_int (TREE_VALUE (t), arg_num) == 0)
00270 return true;
00271 }
00272
00273 return false;
00274 }
00275
00276
00277
00278
00279 static void
00280 set_value_range (value_range_t *vr, enum value_range_type t, tree min,
00281 tree max, bitmap equiv)
00282 {
00283 #if defined ENABLE_CHECKING
00284
00285 if (t == VR_RANGE || t == VR_ANTI_RANGE)
00286 {
00287 int cmp;
00288
00289 gcc_assert (min && max);
00290
00291 if (INTEGRAL_TYPE_P (TREE_TYPE (min)) && t == VR_ANTI_RANGE)
00292 gcc_assert (!vrp_val_is_min (min) || !vrp_val_is_max (max));
00293
00294 cmp = compare_values (min, max);
00295 gcc_assert (cmp == 0 || cmp == -1 || cmp == -2);
00296
00297 if (needs_overflow_infinity (TREE_TYPE (min)))
00298 gcc_assert (!is_overflow_infinity (min)
00299 || !is_overflow_infinity (max));
00300 }
00301
00302 if (t == VR_UNDEFINED || t == VR_VARYING)
00303 gcc_assert (min == NULL_TREE && max == NULL_TREE);
00304
00305 if (t == VR_UNDEFINED || t == VR_VARYING)
00306 gcc_assert (equiv == NULL || bitmap_empty_p (equiv));
00307 #endif
00308
00309 vr->type = t;
00310 vr->min = min;
00311 vr->max = max;
00312
00313
00314
00315 if (vr->equiv == NULL)
00316 vr->equiv = BITMAP_ALLOC (NULL);
00317
00318 if (equiv != vr->equiv)
00319 {
00320 if (equiv && !bitmap_empty_p (equiv))
00321 bitmap_copy (vr->equiv, equiv);
00322 else
00323 bitmap_clear (vr->equiv);
00324 }
00325 }
00326
00327
00328
00329
00330 static inline void
00331 copy_value_range (value_range_t *to, value_range_t *from)
00332 {
00333 set_value_range (to, from->type, from->min, from->max, from->equiv);
00334 }
00335
00336
00337
00338
00339 static inline void
00340 set_value_range_to_varying (value_range_t *vr)
00341 {
00342 vr->type = VR_VARYING;
00343 vr->min = vr->max = NULL_TREE;
00344 if (vr->equiv)
00345 bitmap_clear (vr->equiv);
00346 }
00347
00348
00349
00350
00351
00352
00353 static inline void
00354 set_value_range_to_value (value_range_t *vr, tree val)
00355 {
00356 gcc_assert (is_gimple_min_invariant (val));
00357 if (is_overflow_infinity (val))
00358 {
00359 if (operand_equal_p (val, TYPE_MAX_VALUE (TREE_TYPE (val)), 0))
00360 val = TYPE_MAX_VALUE (TREE_TYPE (val));
00361 else
00362 {
00363 #ifdef ENABLE_CHECKING
00364 gcc_assert (operand_equal_p (val,
00365 TYPE_MIN_VALUE (TREE_TYPE (val)), 0));
00366 #endif
00367 val = TYPE_MIN_VALUE (TREE_TYPE (val));
00368 }
00369 }
00370 set_value_range (vr, VR_RANGE, val, val, NULL);
00371 }
00372
00373
00374
00375
00376
00377
00378
00379 static inline void
00380 set_value_range_to_nonnegative (value_range_t *vr, tree type,
00381 bool overflow_infinity)
00382 {
00383 tree zero;
00384
00385 if (overflow_infinity && !supports_overflow_infinity (type))
00386 {
00387 set_value_range_to_varying (vr);
00388 return;
00389 }
00390
00391 zero = build_int_cst (type, 0);
00392 set_value_range (vr, VR_RANGE, zero,
00393 (overflow_infinity
00394 ? positive_overflow_infinity (type)
00395 : TYPE_MAX_VALUE (type)),
00396 vr->equiv);
00397 }
00398
00399
00400
00401 static inline void
00402 set_value_range_to_nonnull (value_range_t *vr, tree type)
00403 {
00404 tree zero = build_int_cst (type, 0);
00405 set_value_range (vr, VR_ANTI_RANGE, zero, zero, vr->equiv);
00406 }
00407
00408
00409
00410
00411 static inline void
00412 set_value_range_to_null (value_range_t *vr, tree type)
00413 {
00414 tree zero = build_int_cst (type, 0);
00415 set_value_range (vr, VR_RANGE, zero, zero, vr->equiv);
00416 }
00417
00418
00419
00420
00421 static inline void
00422 set_value_range_to_undefined (value_range_t *vr)
00423 {
00424 vr->type = VR_UNDEFINED;
00425 vr->min = vr->max = NULL_TREE;
00426 if (vr->equiv)
00427 bitmap_clear (vr->equiv);
00428 }
00429
00430
00431
00432
00433
00434
00435
00436 static value_range_t *
00437 get_value_range (tree var)
00438 {
00439 value_range_t *vr;
00440 tree sym;
00441 unsigned ver = SSA_NAME_VERSION (var);
00442
00443
00444 if (! vr_value)
00445 return NULL;
00446
00447 vr = vr_value[ver];
00448 if (vr)
00449 return vr;
00450
00451
00452 vr_value[ver] = vr = XNEW (value_range_t);
00453 memset (vr, 0, sizeof (*vr));
00454
00455
00456 vr->equiv = BITMAP_ALLOC (NULL);
00457
00458
00459
00460 sym = SSA_NAME_VAR (var);
00461 if (var == default_def (sym))
00462 {
00463
00464
00465
00466 if (TREE_CODE (sym) == PARM_DECL
00467 && POINTER_TYPE_P (TREE_TYPE (sym))
00468 && nonnull_arg_p (sym))
00469 set_value_range_to_nonnull (vr, TREE_TYPE (sym));
00470 else
00471 set_value_range_to_varying (vr);
00472 }
00473
00474 return vr;
00475 }
00476
00477
00478
00479 static inline bool
00480 vrp_operand_equal_p (tree val1, tree val2)
00481 {
00482 if (val1 == val2)
00483 return true;
00484 if (!val1 || !val2 || !operand_equal_p (val1, val2, 0))
00485 return false;
00486 if (is_overflow_infinity (val1))
00487 return is_overflow_infinity (val2);
00488 return true;
00489 }
00490
00491
00492
00493 static inline bool
00494 vrp_bitmap_equal_p (bitmap b1, bitmap b2)
00495 {
00496 return (b1 == b2
00497 || (b1 && b2
00498 && bitmap_equal_p (b1, b2)));
00499 }
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509
00510
00511 static inline bool
00512 update_value_range (tree var, value_range_t *new_vr)
00513 {
00514 value_range_t *old_vr;
00515 bool is_new;
00516
00517
00518 old_vr = get_value_range (var);
00519 is_new = old_vr->type != new_vr->type
00520 || !vrp_operand_equal_p (old_vr->min, new_vr->min)
00521 || !vrp_operand_equal_p (old_vr->max, new_vr->max)
00522 || !vrp_bitmap_equal_p (old_vr->equiv, new_vr->equiv);
00523
00524 if (is_new)
00525 set_value_range (old_vr, new_vr->type, new_vr->min, new_vr->max,
00526 new_vr->equiv);
00527
00528 BITMAP_FREE (new_vr->equiv);
00529 new_vr->equiv = NULL;
00530
00531 return is_new;
00532 }
00533
00534
00535
00536
00537 static void
00538 add_equivalence (bitmap equiv, tree var)
00539 {
00540 unsigned ver = SSA_NAME_VERSION (var);
00541 value_range_t *vr = vr_value[ver];
00542
00543 bitmap_set_bit (equiv, ver);
00544 if (vr && vr->equiv)
00545 bitmap_ior_into (equiv, vr->equiv);
00546 }
00547
00548
00549
00550
00551 static inline bool
00552 range_is_nonnull (value_range_t *vr)
00553 {
00554 return vr->type == VR_ANTI_RANGE
00555 && integer_zerop (vr->min)
00556 && integer_zerop (vr->max);
00557 }
00558
00559
00560
00561
00562 static inline bool
00563 range_is_null (value_range_t *vr)
00564 {
00565 return vr->type == VR_RANGE
00566 && integer_zerop (vr->min)
00567 && integer_zerop (vr->max);
00568 }
00569
00570
00571
00572
00573 static inline bool
00574 symbolic_range_p (value_range_t *vr)
00575 {
00576 return (!is_gimple_min_invariant (vr->min)
00577 || !is_gimple_min_invariant (vr->max));
00578 }
00579
00580
00581
00582 static inline bool
00583 overflow_infinity_range_p (value_range_t *vr)
00584 {
00585 return (vr->type == VR_RANGE
00586 && (is_overflow_infinity (vr->min)
00587 || is_overflow_infinity (vr->max)));
00588 }
00589
00590
00591
00592
00593
00594
00595
00596 static bool
00597 usable_range_p (value_range_t *vr, bool *strict_overflow_p)
00598 {
00599 gcc_assert (vr->type == VR_RANGE);
00600 if (is_overflow_infinity (vr->min))
00601 {
00602 *strict_overflow_p = true;
00603 if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (vr->min)))
00604 return false;
00605 }
00606 if (is_overflow_infinity (vr->max))
00607 {
00608 *strict_overflow_p = true;
00609 if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (vr->max)))
00610 return false;
00611 }
00612 return true;
00613 }
00614
00615
00616
00617
00618
00619 static bool
00620 vrp_expr_computes_nonnegative (tree expr, bool *strict_overflow_p)
00621 {
00622 return tree_expr_nonnegative_warnv_p (expr, strict_overflow_p);
00623 }
00624
00625
00626
00627
00628 static bool
00629 vrp_expr_computes_nonzero (tree expr, bool *strict_overflow_p)
00630 {
00631 if (tree_expr_nonzero_warnv_p (expr, strict_overflow_p))
00632 return true;
00633
00634
00635
00636 if (TREE_CODE (expr) == ADDR_EXPR)
00637 {
00638 tree base = get_base_address (TREE_OPERAND (expr, 0));
00639
00640 if (base != NULL_TREE
00641 && TREE_CODE (base) == INDIRECT_REF
00642 && TREE_CODE (TREE_OPERAND (base, 0)) == SSA_NAME)
00643 {
00644 value_range_t *vr = get_value_range (TREE_OPERAND (base, 0));
00645 if (range_is_nonnull (vr))
00646 return true;
00647 }
00648 }
00649
00650 return false;
00651 }
00652
00653
00654
00655
00656 static bool
00657 valid_value_p (tree expr)
00658 {
00659 if (TREE_CODE (expr) == SSA_NAME)
00660 return true;
00661
00662 if (TREE_CODE (expr) == PLUS_EXPR
00663 || TREE_CODE (expr) == MINUS_EXPR)
00664 return (TREE_CODE (TREE_OPERAND (expr, 0)) == SSA_NAME
00665 && TREE_CODE (TREE_OPERAND (expr, 1)) == INTEGER_CST);
00666
00667 return is_gimple_min_invariant (expr);
00668 }
00669
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681
00682
00683
00684
00685 static int
00686 compare_values_warnv (tree val1, tree val2, bool *strict_overflow_p)
00687 {
00688 if (val1 == val2)
00689 return 0;
00690
00691
00692
00693 gcc_assert (POINTER_TYPE_P (TREE_TYPE (val1))
00694 == POINTER_TYPE_P (TREE_TYPE (val2)));
00695
00696 if ((TREE_CODE (val1) == SSA_NAME
00697 || TREE_CODE (val1) == PLUS_EXPR
00698 || TREE_CODE (val1) == MINUS_EXPR)
00699 && (TREE_CODE (val2) == SSA_NAME
00700 || TREE_CODE (val2) == PLUS_EXPR
00701 || TREE_CODE (val2) == MINUS_EXPR))
00702 {
00703 tree n1, c1, n2, c2;
00704 enum tree_code code1, code2;
00705
00706
00707
00708
00709 if (TREE_CODE (val1) == SSA_NAME)
00710 {
00711 code1 = SSA_NAME;
00712 n1 = val1;
00713 c1 = NULL_TREE;
00714 }
00715 else
00716 {
00717 code1 = TREE_CODE (val1);
00718 n1 = TREE_OPERAND (val1, 0);
00719 c1 = TREE_OPERAND (val1, 1);
00720 if (tree_int_cst_sgn (c1) == -1)
00721 {
00722 if (is_negative_overflow_infinity (c1))
00723 return -2;
00724 c1 = fold_unary_to_constant (NEGATE_EXPR, TREE_TYPE (c1), c1);
00725 if (!c1)
00726 return -2;
00727 code1 = code1 == MINUS_EXPR ? PLUS_EXPR : MINUS_EXPR;
00728 }
00729 }
00730
00731 if (TREE_CODE (val2) == SSA_NAME)
00732 {
00733 code2 = SSA_NAME;
00734 n2 = val2;
00735 c2 = NULL_TREE;
00736 }
00737 else
00738 {
00739 code2 = TREE_CODE (val2);
00740 n2 = TREE_OPERAND (val2, 0);
00741 c2 = TREE_OPERAND (val2, 1);
00742 if (tree_int_cst_sgn (c2) == -1)
00743 {
00744 if (is_negative_overflow_infinity (c2))
00745 return -2;
00746 c2 = fold_unary_to_constant (NEGATE_EXPR, TREE_TYPE (c2), c2);
00747 if (!c2)
00748 return -2;
00749 code2 = code2 == MINUS_EXPR ? PLUS_EXPR : MINUS_EXPR;
00750 }
00751 }
00752
00753
00754 if (n1 != n2)
00755 return -2;
00756
00757 if (code1 == SSA_NAME
00758 && code2 == SSA_NAME)
00759
00760 return 0;
00761
00762
00763 if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (val1)))
00764 return -2;
00765
00766 if (strict_overflow_p != NULL)
00767 *strict_overflow_p = true;
00768
00769 if (code1 == SSA_NAME)
00770 {
00771 if (code2 == PLUS_EXPR)
00772
00773 return -1;
00774 else if (code2 == MINUS_EXPR)
00775
00776 return 1;
00777 }
00778 else if (code1 == PLUS_EXPR)
00779 {
00780 if (code2 == SSA_NAME)
00781
00782 return 1;
00783 else if (code2 == PLUS_EXPR)
00784
00785 return compare_values_warnv (c1, c2, strict_overflow_p);
00786 else if (code2 == MINUS_EXPR)
00787
00788 return 1;
00789 }
00790 else if (code1 == MINUS_EXPR)
00791 {
00792 if (code2 == SSA_NAME)
00793
00794 return -1;
00795 else if (code2 == PLUS_EXPR)
00796
00797 return -1;
00798 else if (code2 == MINUS_EXPR)
00799
00800
00801 return compare_values_warnv (c2, c1, strict_overflow_p);
00802 }
00803
00804 gcc_unreachable ();
00805 }
00806
00807
00808 if (!is_gimple_min_invariant (val1) || !is_gimple_min_invariant (val2))
00809 return -2;
00810
00811 if (!POINTER_TYPE_P (TREE_TYPE (val1)))
00812 {
00813
00814
00815 if (TREE_OVERFLOW (val1) || TREE_OVERFLOW (val2))
00816 {
00817 if (strict_overflow_p != NULL)
00818 *strict_overflow_p = true;
00819 if (is_negative_overflow_infinity (val1))
00820 return is_negative_overflow_infinity (val2) ? 0 : -1;
00821 else if (is_negative_overflow_infinity (val2))
00822 return 1;
00823 else if (is_positive_overflow_infinity (val1))
00824 return is_positive_overflow_infinity (val2) ? 0 : 1;
00825 else if (is_positive_overflow_infinity (val2))
00826 return -1;
00827 return -2;
00828 }
00829
00830 return tree_int_cst_compare (val1, val2);
00831 }
00832 else
00833 {
00834 tree t;
00835
00836
00837 if (val1 == val2 || operand_equal_p (val1, val2, 0))
00838 return 0;
00839
00840
00841 t = fold_binary (LT_EXPR, boolean_type_node, val1, val2);
00842 if (t == boolean_true_node)
00843 return -1;
00844
00845
00846 t = fold_binary (GT_EXPR, boolean_type_node, val1, val2);
00847 if (t == boolean_true_node)
00848 return 1;
00849
00850
00851 t = fold_binary (NE_EXPR, boolean_type_node, val1, val2);
00852 if (t == boolean_true_node)
00853 return 2;
00854
00855 return -2;
00856 }
00857 }
00858
00859
00860
00861
00862 static int
00863 compare_values (tree val1, tree val2)
00864 {
00865 bool sop;
00866 int ret;
00867
00868 sop = false;
00869 ret = compare_values_warnv (val1, val2, &sop);
00870 if (sop
00871 && (!is_gimple_min_invariant (val1) || !is_gimple_min_invariant (val2)))
00872 ret = -2;
00873 return ret;
00874 }
00875
00876
00877
00878
00879
00880
00881
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894
00895
00896
00897 static inline int
00898 value_inside_range (tree val, value_range_t *vr)
00899 {
00900 tree cmp1, cmp2;
00901
00902 fold_defer_overflow_warnings ();
00903
00904 cmp1 = fold_binary_to_constant (GE_EXPR, boolean_type_node, val, vr->min);
00905 if (!cmp1)
00906 {
00907 fold_undefer_and_ignore_overflow_warnings ();
00908 return -2;
00909 }
00910
00911 cmp2 = fold_binary_to_constant (LE_EXPR, boolean_type_node, val, vr->max);
00912
00913 fold_undefer_and_ignore_overflow_warnings ();
00914
00915 if (!cmp2)
00916 return -2;
00917
00918 return cmp1 == boolean_true_node && cmp2 == boolean_true_node;
00919 }
00920
00921
00922
00923
00924
00925 static inline bool
00926 value_ranges_intersect_p (value_range_t *vr0, value_range_t *vr1)
00927 {
00928 return (value_inside_range (vr1->min, vr0) == 1
00929 || value_inside_range (vr1->max, vr0) == 1
00930 || value_inside_range (vr0->min, vr1) == 1
00931 || value_inside_range (vr0->max, vr1) == 1);
00932 }
00933
00934
00935
00936
00937
00938
00939
00940
00941 static inline bool
00942 range_includes_zero_p (value_range_t *vr)
00943 {
00944 tree zero;
00945
00946 gcc_assert (vr->type != VR_UNDEFINED
00947 && vr->type != VR_VARYING
00948 && !symbolic_range_p (vr));
00949
00950 zero = build_int_cst (TREE_TYPE (vr->min), 0);
00951 return (value_inside_range (zero, vr) == 1);
00952 }
00953
00954
00955
00956
00957 bool
00958 ssa_name_nonnegative_p (tree t)
00959 {
00960 value_range_t *vr = get_value_range (t);
00961
00962 if (!vr)
00963 return false;
00964
00965
00966
00967 if (vr->type == VR_RANGE)
00968 {
00969 int result = compare_values (vr->min, integer_zero_node);
00970
00971 return (result == 0 || result == 1);
00972 }
00973 return false;
00974 }
00975
00976
00977
00978
00979 bool
00980 ssa_name_nonzero_p (tree t)
00981 {
00982 value_range_t *vr = get_value_range (t);
00983
00984 if (!vr)
00985 return false;
00986
00987
00988 if (vr->type == VR_RANGE && !symbolic_range_p (vr))
00989 return ! range_includes_zero_p (vr);
00990
00991
00992 if (vr->type == VR_ANTI_RANGE && !symbolic_range_p (vr))
00993 return range_includes_zero_p (vr);
00994
00995 return false;
00996 }
00997
00998
00999
01000
01001
01002 static void
01003 extract_range_from_assert (value_range_t *vr_p, tree expr)
01004 {
01005 tree var, cond, limit, min, max, type;
01006 value_range_t *var_vr, *limit_vr;
01007 enum tree_code cond_code;
01008
01009 var = ASSERT_EXPR_VAR (expr);
01010 cond = ASSERT_EXPR_COND (expr);
01011
01012 gcc_assert (COMPARISON_CLASS_P (cond));
01013
01014
01015 if (var == TREE_OPERAND (cond, 0))
01016 {
01017
01018
01019 limit = TREE_OPERAND (cond, 1);
01020 cond_code = TREE_CODE (cond);
01021 }
01022 else
01023 {
01024
01025
01026
01027 limit = TREE_OPERAND (cond, 0);
01028 cond_code = swap_tree_comparison (TREE_CODE (cond));
01029 }
01030
01031 type = TREE_TYPE (limit);
01032 gcc_assert (limit != var);
01033
01034
01035
01036 if (POINTER_TYPE_P (type) && cond_code != NE_EXPR && cond_code != EQ_EXPR)
01037 {
01038 set_value_range_to_varying (vr_p);
01039 return;
01040 }
01041
01042
01043
01044
01045 limit_vr = (TREE_CODE (limit) == SSA_NAME) ? get_value_range (limit) : NULL;
01046
01047
01048 if (limit_vr
01049 && (limit_vr->type == VR_UNDEFINED
01050 || limit_vr->type == VR_VARYING
01051 || symbolic_range_p (limit_vr)))
01052 limit_vr = NULL;
01053
01054
01055
01056
01057
01058
01059 gcc_assert (vr_p->equiv == NULL);
01060 vr_p->equiv = BITMAP_ALLOC (NULL);
01061 add_equivalence (vr_p->equiv, var);
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072 if (cond_code == EQ_EXPR)
01073 {
01074 enum value_range_type range_type;
01075
01076 if (limit_vr)
01077 {
01078 range_type = limit_vr->type;
01079 min = limit_vr->min;
01080 max = limit_vr->max;
01081 }
01082 else
01083 {
01084 range_type = VR_RANGE;
01085 min = limit;
01086 max = limit;
01087 }
01088
01089 set_value_range (vr_p, range_type, min, max, vr_p->equiv);
01090
01091
01092
01093
01094 if (TREE_CODE (limit) == SSA_NAME)
01095 add_equivalence (vr_p->equiv, limit);
01096 }
01097 else if (cond_code == NE_EXPR)
01098 {
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119 if (limit_vr
01120 && limit_vr->type == VR_RANGE
01121 && compare_values (limit_vr->min, limit_vr->max) == 0)
01122 {
01123 min = limit_vr->min;
01124 max = limit_vr->max;
01125 }
01126 else
01127 {
01128
01129
01130 min = max = limit;
01131 }
01132
01133
01134
01135 if (INTEGRAL_TYPE_P (type)
01136 && vrp_val_is_min (min)
01137 && vrp_val_is_max (max))
01138 min = max = limit;
01139
01140 set_value_range (vr_p, VR_ANTI_RANGE, min, max, vr_p->equiv);
01141 }
01142 else if (cond_code == LE_EXPR || cond_code == LT_EXPR)
01143 {
01144 min = TYPE_MIN_VALUE (type);
01145
01146 if (limit_vr == NULL || limit_vr->type == VR_ANTI_RANGE)
01147 max = limit;
01148 else
01149 {
01150
01151
01152
01153 max = limit_vr->max;
01154 }
01155
01156
01157
01158
01159 if ((cond_code == LT_EXPR
01160 && compare_values (max, min) == 0)
01161 || is_overflow_infinity (max))
01162 set_value_range_to_varying (vr_p);
01163 else
01164 {
01165
01166 if (cond_code == LT_EXPR)
01167 {
01168 tree one = build_int_cst (type, 1);
01169 max = fold_build2 (MINUS_EXPR, type, max, one);
01170 }
01171
01172 set_value_range (vr_p, VR_RANGE, min, max, vr_p->equiv);
01173 }
01174 }
01175 else if (cond_code == GE_EXPR || cond_code == GT_EXPR)
01176 {
01177 max = TYPE_MAX_VALUE (type);
01178
01179 if (limit_vr == NULL || limit_vr->type == VR_ANTI_RANGE)
01180 min = limit;
01181 else
01182 {
01183
01184
01185
01186 min = limit_vr->min;
01187 }
01188
01189
01190
01191
01192 if ((cond_code == GT_EXPR
01193 && compare_values (min, max) == 0)
01194 || is_overflow_infinity (min))
01195 set_value_range_to_varying (vr_p);
01196 else
01197 {
01198
01199 if (cond_code == GT_EXPR)
01200 {
01201 tree one = build_int_cst (type, 1);
01202 min = fold_build2 (PLUS_EXPR, type, min, one);
01203 }
01204
01205 set_value_range (vr_p, VR_RANGE, min, max, vr_p->equiv);
01206 }
01207 }
01208 else
01209 gcc_unreachable ();
01210
01211
01212
01213
01214
01215
01216
01217
01218
01219
01220
01221
01222
01223
01224
01225
01226
01227
01228
01229
01230
01231
01232
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245 var_vr = get_value_range (var);
01246
01247
01248
01249 if (vr_p->type == VR_VARYING
01250 || vr_p->type == VR_UNDEFINED
01251 || var_vr->type == VR_VARYING
01252 || var_vr->type == VR_UNDEFINED
01253 || symbolic_range_p (vr_p)
01254 || symbolic_range_p (var_vr))
01255 return;
01256
01257 if (var_vr->type == VR_RANGE && vr_p->type == VR_RANGE)
01258 {
01259
01260
01261
01262
01263
01264 if (value_ranges_intersect_p (var_vr, vr_p))
01265 {
01266
01267 if (compare_values (vr_p->min, var_vr->min) == -1)
01268 min = var_vr->min;
01269 else
01270 min = vr_p->min;
01271
01272
01273 if (compare_values (vr_p->max, var_vr->max) == 1)
01274 max = var_vr->max;
01275 else
01276 max = vr_p->max;
01277
01278 set_value_range (vr_p, vr_p->type, min, max, vr_p->equiv);
01279 }
01280 else
01281 {
01282
01283
01284
01285 set_value_range_to_varying (vr_p);
01286 }
01287 }
01288 else if ((var_vr->type == VR_RANGE && vr_p->type == VR_ANTI_RANGE)
01289 || (var_vr->type == VR_ANTI_RANGE && vr_p->type == VR_RANGE))
01290 {
01291
01292
01293
01294
01295 if (compare_values (var_vr->min, vr_p->min) == 0
01296 && compare_values (var_vr->max, vr_p->max) == 0)
01297 set_value_range_to_varying (vr_p);
01298 else
01299 {
01300 tree min, max, anti_min, anti_max, real_min, real_max;
01301
01302
01303
01304
01305
01306
01307
01308
01309
01310
01311
01312
01313
01314
01315
01316
01317
01318
01319
01320
01321
01322
01323
01324
01325
01326
01327
01328
01329
01330 if (vr_p->type == VR_ANTI_RANGE)
01331 {
01332 anti_min = vr_p->min;
01333 anti_max = vr_p->max;
01334 real_min = var_vr->min;
01335 real_max = var_vr->max;
01336 }
01337 else
01338 {
01339 anti_min = var_vr->min;
01340 anti_max = var_vr->max;
01341 real_min = vr_p->min;
01342 real_max = vr_p->max;
01343 }
01344
01345
01346
01347
01348 if (compare_values (anti_max, real_max) == -1
01349 && compare_values (anti_min, real_min) == 1)
01350 {
01351 set_value_range (vr_p, VR_RANGE, real_min,
01352 real_max, vr_p->equiv);
01353 }
01354
01355
01356 else if (compare_values (anti_min, real_max) == 1
01357 || compare_values (anti_max, real_min) == -1)
01358 {
01359 set_value_range (vr_p, VR_RANGE, real_min,
01360 real_max, vr_p->equiv);
01361 }
01362
01363
01364
01365 else if ((compare_values (anti_max, real_min) == 1
01366 || compare_values (anti_max, real_min) == 0)
01367 && compare_values (anti_max, real_max) == -1)
01368 {
01369 gcc_assert (!is_positive_overflow_infinity (anti_max));
01370 if (needs_overflow_infinity (TREE_TYPE (anti_max))
01371 && vrp_val_is_max (anti_max))
01372 {
01373 if (!supports_overflow_infinity (TREE_TYPE (var_vr->min)))
01374 {
01375 set_value_range_to_varying (vr_p);
01376 return;
01377 }
01378 min = positive_overflow_infinity (TREE_TYPE (var_vr->min));
01379 }
01380 else
01381 min = fold_build2 (PLUS_EXPR, TREE_TYPE (var_vr->min),
01382 anti_max,
01383 build_int_cst (TREE_TYPE (var_vr->min), 1));
01384 max = real_max;
01385 set_value_range (vr_p, VR_RANGE, min, max, vr_p->equiv);
01386 }
01387
01388
01389
01390 else if (compare_values (anti_min, real_min) == 1
01391 && (compare_values (anti_min, real_max) == -1
01392 || compare_values (anti_min, real_max) == 0))
01393 {
01394 gcc_assert (!is_negative_overflow_infinity (anti_min));
01395 if (needs_overflow_infinity (TREE_TYPE (anti_min))
01396 && vrp_val_is_min (anti_min))
01397 {
01398 if (!supports_overflow_infinity (TREE_TYPE (var_vr->min)))
01399 {
01400 set_value_range_to_varying (vr_p);
01401 return;
01402 }
01403 max = negative_overflow_infinity (TREE_TYPE (var_vr->min));
01404 }
01405 else
01406 max = fold_build2 (MINUS_EXPR, TREE_TYPE (var_vr->min),
01407 anti_min,
01408 build_int_cst (TREE_TYPE (var_vr->min), 1));
01409 min = real_min;
01410 set_value_range (vr_p, VR_RANGE, min, max, vr_p->equiv);
01411 }
01412 }
01413 }
01414 }
01415
01416
01417
01418
01419
01420
01421
01422
01423
01424
01425
01426
01427
01428
01429
01430 static void
01431 extract_range_from_ssa_name (value_range_t *vr, tree var)
01432 {
01433 value_range_t *var_vr = get_value_range (var);
01434
01435 if (var_vr->type != VR_UNDEFINED && var_vr->type != VR_VARYING)
01436 copy_value_range (vr, var_vr);
01437 else
01438 set_value_range (vr, VR_RANGE, var, var, NULL);
01439
01440 add_equivalence (vr->equiv, var);
01441 }
01442
01443
01444
01445
01446
01447
01448
01449
01450 static tree
01451 vrp_int_const_binop (enum tree_code code, tree val1, tree val2)
01452 {
01453 tree res;
01454
01455 res = int_const_binop (code, val1, val2, 0);
01456
01457
01458
01459 if (TYPE_OVERFLOW_WRAPS (TREE_TYPE (val1)))
01460 {
01461 int checkz = compare_values (res, val1);
01462 bool overflow = false;
01463
01464
01465
01466 if ((code == PLUS_EXPR
01467 && !(checkz == 1 || checkz == 0))
01468 || (code == MINUS_EXPR
01469 && !(checkz == 0 || checkz == -1)))
01470 {
01471 overflow = true;
01472 }
01473
01474
01475
01476
01477
01478 else if (code == MULT_EXPR && !integer_zerop (val1))
01479 {
01480 tree tmp = int_const_binop (TRUNC_DIV_EXPR,
01481 res,
01482 val1, 0);
01483 int check = compare_values (tmp, val2);
01484
01485 if (check != 0)
01486 overflow = true;
01487 }
01488
01489 if (overflow)
01490 {
01491 res = copy_node (res);
01492 TREE_OVERFLOW (res) = 1;
01493 }
01494
01495 }
01496 else if ((TREE_OVERFLOW (res)
01497 && !TREE_OVERFLOW (val1)
01498 && !TREE_OVERFLOW (val2))
01499 || is_overflow_infinity (val1)
01500 || is_overflow_infinity (val2))
01501 {
01502
01503
01504
01505 int sgn1 = tree_int_cst_sgn (val1);
01506 int sgn2 = tree_int_cst_sgn (val2);
01507
01508 if (needs_overflow_infinity (TREE_TYPE (res))
01509 && !supports_overflow_infinity (TREE_TYPE (res)))
01510 return NULL_TREE;
01511
01512
01513
01514
01515 if (((code == PLUS_EXPR && sgn1 != sgn2)
01516 || (code == MINUS_EXPR && sgn1 == sgn2))
01517 && is_overflow_infinity (val1)
01518 && is_overflow_infinity (val2))
01519 return NULL_TREE;
01520
01521
01522 if ((code == TRUNC_DIV_EXPR
01523 || code == FLOOR_DIV_EXPR
01524 || code == CEIL_DIV_EXPR
01525 || code == EXACT_DIV_EXPR
01526 || code == ROUND_DIV_EXPR
01527 || code == RSHIFT_EXPR)
01528 && (is_overflow_infinity (val1)
01529 || is_overflow_infinity (val2)))
01530 return NULL_TREE;
01531
01532
01533
01534
01535
01536
01537
01538
01539
01540
01541
01542 if ((code == MULT_EXPR && sgn1 == sgn2)
01543
01544
01545
01546
01547 || (code == PLUS_EXPR
01548 && (sgn1 >= 0
01549 ? !is_negative_overflow_infinity (val2)
01550 : is_positive_overflow_infinity (val2)))
01551
01552
01553
01554
01555
01556
01557
01558 || (code == MINUS_EXPR
01559 && (sgn1 >= 0
01560 ? !is_positive_overflow_infinity (val2)
01561 : is_negative_overflow_infinity (val2)))
01562
01563 || code == TRUNC_DIV_EXPR
01564 || code == FLOOR_DIV_EXPR
01565 || code == CEIL_DIV_EXPR
01566 || code == EXACT_DIV_EXPR
01567 || code == ROUND_DIV_EXPR)
01568 return (needs_overflow_infinity (TREE_TYPE (res))
01569 ? positive_overflow_infinity (TREE_TYPE (res))
01570 : TYPE_MAX_VALUE (TREE_TYPE (res)));
01571 else
01572 return (needs_overflow_infinity (TREE_TYPE (res))
01573 ? negative_overflow_infinity (TREE_TYPE (res))
01574 : TYPE_MIN_VALUE (TREE_TYPE (res)));
01575 }
01576
01577 return res;
01578 }
01579
01580
01581
01582
01583
01584 static void
01585 extract_range_from_binary_expr (value_range_t *vr, tree expr)
01586 {
01587 enum tree_code code = TREE_CODE (expr);
01588 enum value_range_type type;
01589 tree op0, op1, min, max;
01590 int cmp;
01591 value_range_t vr0 = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
01592 value_range_t vr1 = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
01593
01594
01595
01596 if (code != PLUS_EXPR
01597 && code != MINUS_EXPR
01598 && code != MULT_EXPR
01599 && code != TRUNC_DIV_EXPR
01600 && code != FLOOR_DIV_EXPR
01601 && code != CEIL_DIV_EXPR
01602 && code != EXACT_DIV_EXPR
01603 && code != ROUND_DIV_EXPR
01604 && code != MIN_EXPR
01605 && code != MAX_EXPR
01606 && code != BIT_AND_EXPR
01607 && code != TRUTH_ANDIF_EXPR
01608 && code != TRUTH_ORIF_EXPR
01609 && code != TRUTH_AND_EXPR
01610 && code != TRUTH_OR_EXPR)
01611 {
01612 set_value_range_to_varying (vr);
01613 return;
01614 }
01615
01616
01617
01618 op0 = TREE_OPERAND (expr, 0);
01619 if (TREE_CODE (op0) == SSA_NAME)
01620 vr0 = *(get_value_range (op0));
01621 else if (is_gimple_min_invariant (op0))
01622 set_value_range_to_value (&vr0, op0);
01623 else
01624 set_value_range_to_varying (&vr0);
01625
01626 op1 = TREE_OPERAND (expr, 1);
01627 if (TREE_CODE (op1) == SSA_NAME)
01628 vr1 = *(get_value_range (op1));
01629 else if (is_gimple_min_invariant (op1))
01630 set_value_range_to_value (&vr1, op1);
01631 else
01632 set_value_range_to_varying (&vr1);
01633
01634
01635 if (vr0.type == VR_UNDEFINED || vr1.type == VR_UNDEFINED)
01636 {
01637 set_value_range_to_undefined (vr);
01638 return;
01639 }
01640
01641
01642 type = vr0.type;
01643
01644
01645
01646
01647
01648
01649 if (code != BIT_AND_EXPR
01650 && code != TRUTH_AND_EXPR
01651 && code != TRUTH_OR_EXPR
01652 && (vr0.type == VR_VARYING
01653 || vr1.type == VR_VARYING
01654 || vr0.type != vr1.type
01655 || symbolic_range_p (&vr0)
01656 || symbolic_range_p (&vr1)))
01657 {
01658 set_value_range_to_varying (vr);
01659 return;
01660 }
01661
01662
01663 if (POINTER_TYPE_P (TREE_TYPE (expr))
01664 || POINTER_TYPE_P (TREE_TYPE (op0))
01665 || POINTER_TYPE_P (TREE_TYPE (op1)))
01666 {
01667
01668
01669
01670
01671
01672 if (code == PLUS_EXPR)
01673 {
01674 if (range_is_nonnull (&vr0) || range_is_nonnull (&vr1))
01675 set_value_range_to_nonnull (vr, TREE_TYPE (expr));
01676 else if (range_is_null (&vr0) && range_is_null (&vr1))
01677 set_value_range_to_null (vr, TREE_TYPE (expr));
01678 else
01679 set_value_range_to_varying (vr);
01680 }
01681 else
01682 {
01683
01684
01685 set_value_range_to_varying (vr);
01686 }
01687
01688 return;
01689 }
01690
01691
01692
01693 if (code == TRUTH_ANDIF_EXPR
01694 || code == TRUTH_ORIF_EXPR
01695 || code == TRUTH_AND_EXPR
01696 || code == TRUTH_OR_EXPR)
01697 {
01698
01699
01700 if (code == TRUTH_AND_EXPR
01701 && ((vr0.type == VR_RANGE
01702 && integer_zerop (vr0.min)
01703 && integer_zerop (vr0.max))
01704 || (vr1.type == VR_RANGE
01705 && integer_zerop (vr1.min)
01706 && integer_zerop (vr1.max))))
01707 {
01708 type = VR_RANGE;
01709 min = max = build_int_cst (TREE_TYPE (expr), 0);
01710 }
01711
01712
01713 else if (code == TRUTH_OR_EXPR
01714 && ((vr0.type == VR_RANGE
01715 && integer_onep (vr0.min)
01716 && integer_onep (vr0.max))
01717 || (vr1.type == VR_RANGE
01718 && integer_onep (vr1.min)
01719 && integer_onep (vr1.max))))
01720 {
01721 type = VR_RANGE;
01722 min = max = build_int_cst (TREE_TYPE (expr), 1);
01723 }
01724 else if (vr0.type != VR_VARYING
01725 && vr1.type != VR_VARYING
01726 && vr0.type == vr1.type
01727 && !symbolic_range_p (&vr0)
01728 && !overflow_infinity_range_p (&vr0)
01729 && !symbolic_range_p (&vr1)
01730 && !overflow_infinity_range_p (&vr1))
01731 {
01732
01733 min = fold_binary (code, TREE_TYPE (expr), vr0.min, vr1.min);
01734 max = fold_binary (code, TREE_TYPE (expr), vr0.max, vr1.max);
01735 }
01736 else
01737 {
01738 set_value_range_to_varying (vr);
01739 return;
01740 }
01741 }
01742 else if (code == PLUS_EXPR
01743 || code == MIN_EXPR
01744 || code == MAX_EXPR)
01745 {
01746
01747
01748
01749
01750
01751
01752
01753 if (code == PLUS_EXPR && vr0.type == VR_ANTI_RANGE)
01754 {
01755 set_value_range_to_varying (vr);
01756 return;
01757 }
01758
01759
01760
01761
01762 min = vrp_int_const_binop (code, vr0.min, vr1.min);
01763 max = vrp_int_const_binop (code, vr0.max, vr1.max);
01764 }
01765 else if (code == MULT_EXPR
01766 || code == TRUNC_DIV_EXPR
01767 || code == FLOOR_DIV_EXPR
01768 || code == CEIL_DIV_EXPR
01769 || code == EXACT_DIV_EXPR
01770 || code == ROUND_DIV_EXPR)
01771 {
01772 tree val[4];
01773 size_t i;
01774 bool sop;
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784 if (code == MULT_EXPR
01785 && vr0.type == VR_ANTI_RANGE
01786 && !TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (op0)))
01787 {
01788 set_value_range_to_varying (vr);
01789 return;
01790 }
01791
01792
01793
01794
01795
01796
01797
01798
01799
01800
01801
01802
01803
01804
01805
01806 if (code != MULT_EXPR
01807 && (vr0.type == VR_ANTI_RANGE || range_includes_zero_p (&vr1)))
01808 {
01809 set_value_range_to_varying (vr);
01810 return;
01811 }
01812
01813
01814 sop = false;
01815 val[0] = vrp_int_const_binop (code, vr0.min, vr1.min);
01816 if (val[0] == NULL_TREE)
01817 sop = true;
01818
01819 if (vr1.max == vr1.min)
01820 val[1] = NULL_TREE;
01821 else
01822 {
01823 val[1] = vrp_int_const_binop (code, vr0.min, vr1.max);
01824 if (val[1] == NULL_TREE)
01825 sop = true;
01826 }
01827
01828 if (vr0.max == vr0.min)
01829 val[2] = NULL_TREE;
01830 else
01831 {
01832 val[2] = vrp_int_const_binop (code, vr0.max, vr1.min);
01833 if (val[2] == NULL_TREE)
01834 sop = true;
01835 }
01836
01837 if (vr0.min == vr0.max || vr1.min == vr1.max)
01838 val[3] = NULL_TREE;
01839 else
01840 {
01841 val[3] = vrp_int_const_binop (code, vr0.max, vr1.max);
01842 if (val[3] == NULL_TREE)
01843 sop = true;
01844 }
01845
01846 if (sop)
01847 {
01848 set_value_range_to_varying (vr);
01849 return;
01850 }
01851
01852
01853
01854 min = val[0];
01855 max = val[0];
01856 for (i = 1; i < 4; i++)
01857 {
01858 if (!is_gimple_min_invariant (min)
01859 || (TREE_OVERFLOW (min) && !is_overflow_infinity (min))
01860 || !is_gimple_min_invariant (max)
01861 || (TREE_OVERFLOW (max) && !is_overflow_infinity (max)))
01862 break;
01863
01864 if (val[i])
01865 {
01866 if (!is_gimple_min_invariant (val[i])
01867 || (TREE_OVERFLOW (val[i])
01868 && !is_overflow_infinity (val[i])))
01869 {
01870
01871
01872
01873 min = max = val[i];
01874 break;
01875 }
01876
01877 if (compare_values (val[i], min) == -1)
01878 min = val[i];
01879
01880 if (compare_values (val[i], max) == 1)
01881 max = val[i];
01882 }
01883 }
01884 }
01885 else if (code == MINUS_EXPR)
01886 {
01887
01888
01889
01890
01891
01892
01893
01894 if (vr0.type == VR_ANTI_RANGE)
01895 {
01896 set_value_range_to_varying (vr);
01897 return;
01898 }
01899
01900
01901
01902 min = vrp_int_const_binop (code, vr0.min, vr1.max);
01903 max = vrp_int_const_binop (code, vr0.max, vr1.min);
01904 }
01905 else if (code == BIT_AND_EXPR)
01906 {
01907 if (vr0.type == VR_RANGE
01908 && vr0.min == vr0.max
01909 && TREE_CODE (vr0.max) == INTEGER_CST
01910 && !TREE_OVERFLOW (vr0.max)
01911 && tree_int_cst_sgn (vr0.max) >= 0)
01912 {
01913 min = build_int_cst (TREE_TYPE (expr), 0);
01914 max = vr0.max;
01915 }
01916 else if (vr1.type == VR_RANGE
01917 && vr1.min == vr1.max
01918 && TREE_CODE (vr1.max) == INTEGER_CST
01919 && !TREE_OVERFLOW (vr1.max)
01920 && tree_int_cst_sgn (vr1.max) >= 0)
01921 {
01922 type = VR_RANGE;
01923 min = build_int_cst (TREE_TYPE (expr), 0);
01924 max = vr1.max;
01925 }
01926 else
01927 {
01928 set_value_range_to_varying (vr);
01929 return;
01930 }
01931 }
01932 else
01933 gcc_unreachable ();
01934
01935
01936
01937
01938 if (min == NULL_TREE
01939 || !is_gimple_min_invariant (min)
01940 || (TREE_OVERFLOW (min) && !is_overflow_infinity (min))
01941 || max == NULL_TREE
01942 || !is_gimple_min_invariant (max)
01943 || (TREE_OVERFLOW (max) && !is_overflow_infinity (max)))
01944 {
01945 set_value_range_to_varying (vr);
01946 return;
01947 }
01948
01949
01950
01951
01952
01953
01954
01955
01956
01957 if ((vrp_val_is_min (min) || is_overflow_infinity (min))
01958 && (vrp_val_is_max (max) || is_overflow_infinity (max)))
01959 {
01960 set_value_range_to_varying (vr);
01961 return;
01962 }
01963
01964 cmp = compare_values (min, max);
01965 if (cmp == -2 || cmp == 1)
01966 {
01967
01968
01969
01970 set_value_range_to_varying (vr);
01971 }
01972 else
01973 set_value_range (vr, type, min, max, NULL);
01974 }
01975
01976
01977
01978
01979
01980 static void
01981 extract_range_from_unary_expr (value_range_t *vr, tree expr)
01982 {
01983 enum tree_code code = TREE_CODE (expr);
01984 tree min, max, op0;
01985 int cmp;
01986 value_range_t vr0 = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
01987
01988
01989
01990 if (code == FIX_TRUNC_EXPR
01991 || code == FIX_CEIL_EXPR
01992 || code == FIX_FLOOR_EXPR
01993 || code == FIX_ROUND_EXPR
01994 || code == FLOAT_EXPR
01995 || code == BIT_NOT_EXPR
01996 || code == NON_LVALUE_EXPR
01997 || code == CONJ_EXPR)
01998 {
01999 set_value_range_to_varying (vr);
02000 return;
02001 }
02002
02003
02004
02005 op0 = TREE_OPERAND (expr, 0);
02006 if (TREE_CODE (op0) == SSA_NAME)
02007 vr0 = *(get_value_range (op0));
02008 else if (is_gimple_min_invariant (op0))
02009 set_value_range_to_value (&vr0, op0);
02010 else
02011 set_value_range_to_varying (&vr0);
02012
02013
02014 if (vr0.type == VR_UNDEFINED)
02015 {
02016 set_value_range_to_undefined (vr);
02017 return;
02018 }
02019
02020
02021
02022 if ((!INTEGRAL_TYPE_P (TREE_TYPE (op0))
02023 && !POINTER_TYPE_P (TREE_TYPE (op0)))
02024 || (vr0.type != VR_VARYING
02025 && symbolic_range_p (&vr0)))
02026 {
02027 set_value_range_to_varying (vr);
02028 return;
02029 }
02030
02031
02032
02033 if (POINTER_TYPE_P (TREE_TYPE (expr)) || POINTER_TYPE_P (TREE_TYPE (op0)))
02034 {
02035 bool sop;
02036
02037 sop = false;
02038 if (range_is_nonnull (&vr0)
02039 || (tree_expr_nonzero_warnv_p (expr, &sop)
02040 && !sop))
02041 set_value_range_to_nonnull (vr, TREE_TYPE (expr));
02042 else if (range_is_null (&vr0))
02043 set_value_range_to_null (vr, TREE_TYPE (expr));
02044 else
02045 set_value_range_to_varying (vr);
02046
02047 return;
02048 }
02049
02050
02051 if (code == NOP_EXPR || code == CONVERT_EXPR)
02052 {
02053 tree inner_type = TREE_TYPE (op0);
02054 tree outer_type = TREE_TYPE (expr);
02055
02056
02057
02058
02059
02060
02061
02062
02063 if ((vr0.type == VR_RANGE
02064 && !overflow_infinity_range_p (&vr0))
02065 || (vr0.type == VR_VARYING
02066 && TYPE_PRECISION (outer_type) > TYPE_PRECISION (inner_type)))
02067 {
02068 tree new_min, new_max, orig_min, orig_max;
02069
02070
02071
02072
02073 if (vr0.type == VR_RANGE)
02074 {
02075 orig_min = vr0.min;
02076 orig_max = vr0.max;
02077 }
02078 else
02079 {
02080 orig_min = TYPE_MIN_VALUE (inner_type);
02081 orig_max = TYPE_MAX_VALUE (inner_type);
02082 }
02083
02084 new_min = fold_convert (outer_type, orig_min);
02085 new_max = fold_convert (outer_type, orig_max);
02086
02087
02088
02089
02090 if (is_gimple_val (new_min)
02091 && is_gimple_val (new_max)
02092 && tree_int_cst_equal (new_min, orig_min)
02093 && tree_int_cst_equal (new_max, orig_max)
02094 && compare_values (new_min, new_max) <= 0
02095 && compare_values (new_min, new_max) >= -1)
02096 {
02097 set_value_range (vr, VR_RANGE, new_min, new_max, vr->equiv);
02098 return;
02099 }
02100 }
02101
02102
02103
02104
02105
02106
02107
02108 if (TYPE_SIZE (inner_type) != TYPE_SIZE (outer_type)
02109 || TYPE_PRECISION (inner_type) != TYPE_PRECISION (outer_type))
02110 {
02111 set_value_range_to_varying (vr);
02112 return;
02113 }
02114 }
02115
02116
02117
02118
02119
02120 if (vr0.type == VR_VARYING)
02121 {
02122 set_value_range_to_varying (vr);
02123 return;
02124 }
02125
02126
02127
02128 if (code == NEGATE_EXPR
02129 && !TYPE_UNSIGNED (TREE_TYPE (expr)))
02130 {
02131
02132
02133 if (is_positive_overflow_infinity (vr0.max))
02134 min = negative_overflow_infinity (TREE_TYPE (expr));
02135 else if (is_negative_overflow_infinity (vr0.max))
02136 min = positive_overflow_infinity (TREE_TYPE (expr));
02137 else if (!vrp_val_is_min (vr0.max))
02138 min = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.max);
02139 else if (needs_overflow_infinity (TREE_TYPE (expr)))
02140 {
02141 if (supports_overflow_infinity (TREE_TYPE (expr))
02142 && !is_overflow_infinity (vr0.min)
02143 && !vrp_val_is_min (vr0.min))
02144 min = positive_overflow_infinity (TREE_TYPE (expr));
02145 else
02146 {
02147 set_value_range_to_varying (vr);
02148 return;
02149 }
02150 }
02151 else
02152 min = TYPE_MIN_VALUE (TREE_TYPE (expr));
02153
02154 if (is_positive_overflow_infinity (vr0.min))
02155 max = negative_overflow_infinity (TREE_TYPE (expr));
02156 else if (is_negative_overflow_infinity (vr0.min))
02157 max = positive_overflow_infinity (TREE_TYPE (expr));
02158 else if (!vrp_val_is_min (vr0.min))
02159 max = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.min);
02160 else if (needs_overflow_infinity (TREE_TYPE (expr)))
02161 {
02162 if (supports_overflow_infinity (TREE_TYPE (expr)))
02163 max = positive_overflow_infinity (TREE_TYPE (expr));
02164 else
02165 {
02166 set_value_range_to_varying (vr);
02167 return;
02168 }
02169 }
02170 else
02171 max = TYPE_MIN_VALUE (TREE_TYPE (expr));
02172 }
02173 else if (code == NEGATE_EXPR
02174 && TYPE_UNSIGNED (TREE_TYPE (expr)))
02175 {
02176 if (!range_includes_zero_p (&vr0))
02177 {
02178 max = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.min);
02179 min = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.max);
02180 }
02181 else
02182 {
02183 if (range_is_null (&vr0))
02184 set_value_range_to_null (vr, TREE_TYPE (expr));
02185 else
02186 set_value_range_to_varying (vr);
02187 return;
02188 }
02189 }
02190 else if (code == ABS_EXPR
02191 && !TYPE_UNSIGNED (TREE_TYPE (expr)))
02192 {
02193
02194
02195 if (!TYPE_OVERFLOW_UNDEFINED (TREE_TYPE (expr))
02196 && ((vr0.type == VR_RANGE
02197 && vrp_val_is_min (vr0.min))
02198 || (vr0.type == VR_ANTI_RANGE
02199 && !vrp_val_is_min (vr0.min)
02200 && !range_includes_zero_p (&vr0))))
02201 {
02202 set_value_range_to_varying (vr);
02203 return;
02204 }
02205
02206
02207
02208 if (is_overflow_infinity (vr0.min))
02209 min = positive_overflow_infinity (TREE_TYPE (expr));
02210 else if (!vrp_val_is_min (vr0.min))
02211 min = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.min);
02212 else if (!needs_overflow_infinity (TREE_TYPE (expr)))
02213 min = TYPE_MAX_VALUE (TREE_TYPE (expr));
02214 else if (supports_overflow_infinity (TREE_TYPE (expr)))
02215 min = positive_overflow_infinity (TREE_TYPE (expr));
02216 else
02217 {
02218 set_value_range_to_varying (vr);
02219 return;
02220 }
02221
02222 if (is_overflow_infinity (vr0.max))
02223 max = positive_overflow_infinity (TREE_TYPE (expr));
02224 else if (!vrp_val_is_min (vr0.max))
02225 max = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.max);
02226 else if (!needs_overflow_infinity (TREE_TYPE (expr)))
02227 max = TYPE_MAX_VALUE (TREE_TYPE (expr));
02228 else if (supports_overflow_infinity (TREE_TYPE (expr)))
02229 max = positive_overflow_infinity (TREE_TYPE (expr));
02230 else
02231 {
02232 set_value_range_to_varying (vr);
02233 return;
02234 }
02235
02236 cmp = compare_values (min, max);
02237
02238
02239
02240 if (vr0.type == VR_ANTI_RANGE)
02241 {
02242 if (range_includes_zero_p (&vr0))
02243 {
02244
02245 if (cmp != 1)
02246 max = min;
02247
02248
02249
02250
02251
02252 if (TYPE_OVERFLOW_WRAPS (TREE_TYPE (expr)))
02253 {
02254 tree type_min_value = TYPE_MIN_VALUE (TREE_TYPE (expr));
02255
02256 min = (vr0.min != type_min_value
02257 ? int_const_binop (PLUS_EXPR, type_min_value,
02258 integer_one_node, 0)
02259 : type_min_value);
02260 }
02261 else
02262 {
02263 if (overflow_infinity_range_p (&vr0))
02264 min = negative_overflow_infinity (TREE_TYPE (expr));
02265 else
02266 min = TYPE_MIN_VALUE (TREE_TYPE (expr));
02267 }
02268 }
02269 else
02270 {
02271
02272
02273
02274 vr0.type = VR_RANGE;
02275 min = build_int_cst (TREE_TYPE (expr), 0);
02276 if (needs_overflow_infinity (TREE_TYPE (expr)))
02277 {
02278 if (supports_overflow_infinity (TREE_TYPE (expr)))
02279 max = positive_overflow_infinity (TREE_TYPE (expr));
02280 else
02281 {
02282 set_value_range_to_varying (vr);
02283 return;
02284 }
02285 }
02286 else
02287 max = TYPE_MAX_VALUE (TREE_TYPE (expr));
02288 }
02289 }
02290
02291
02292
02293 else if (range_includes_zero_p (&vr0))
02294 {
02295 if (cmp == 1)
02296 max = min;
02297 min = build_int_cst (TREE_TYPE (expr), 0);
02298 }
02299 else
02300 {
02301
02302 if (cmp == 1)
02303 {
02304 tree t = min;
02305 min = max;
02306 max = t;
02307 }
02308 }
02309 }
02310 else
02311 {
02312
02313 min = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.min);
02314 max = fold_unary_to_constant (code, TREE_TYPE (expr), vr0.max);
02315
02316 if (needs_overflow_infinity (TREE_TYPE (expr)))
02317 {
02318 gcc_assert (code != NEGATE_EXPR && code != ABS_EXPR);
02319
02320
02321
02322 if ((is_overflow_infinity (vr0.min)
02323 || TREE_OVERFLOW (min))
02324 && (is_overflow_infinity (vr0.max)
02325 || TREE_OVERFLOW (max)))
02326 {
02327 set_value_range_to_varying (vr);
02328 return;
02329 }
02330
02331 if (is_overflow_infinity (vr0.min))
02332 min = vr0.min;
02333 else if (TREE_OVERFLOW (min))
02334 {
02335 if (supports_overflow_infinity (TREE_TYPE (expr)))
02336 min = (tree_int_cst_sgn (min) >= 0
02337 ? positive_overflow_infinity (TREE_TYPE (min))
02338 : negative_overflow_infinity (TREE_TYPE (min)));
02339 else
02340 {
02341 set_value_range_to_varying (vr);
02342 return;
02343 }
02344 }
02345
02346 if (is_overflow_infinity (vr0.max))
02347 max = vr0.max;
02348 else if (TREE_OVERFLOW (max))
02349 {
02350 if (supports_overflow_infinity (TREE_TYPE (expr)))
02351 max = (tree_int_cst_sgn (max) >= 0
02352 ? positive_overflow_infinity (TREE_TYPE (max))
02353 : negative_overflow_infinity (TREE_TYPE (max)));
02354 else
02355 {
02356 set_value_range_to_varying (vr);
02357 return;
02358 }
02359 }
02360 }
02361 }
02362
02363 cmp = compare_values (min, max);
02364 if (cmp == -2 || cmp == 1)
02365 {
02366
02367
02368
02369 set_value_range_to_varying (vr);
02370 }
02371 else
02372 set_value_range (vr, vr0.type, min, max, NULL);
02373 }
02374
02375
02376
02377
02378
02379 static void
02380 extract_range_from_comparison (value_range_t *vr, tree expr)
02381 {
02382 bool sop = false;
02383 tree val = vrp_evaluate_conditional_warnv (expr, false, &sop);
02384
02385
02386
02387
02388
02389
02390 if (val && !is_overflow_infinity (val) && !sop)
02391 {
02392
02393
02394
02395 val = fold_convert (TREE_TYPE (expr), val);
02396 set_value_range (vr, VR_RANGE, val, val, vr->equiv);
02397 }
02398 else
02399 set_value_range_to_varying (vr);
02400 }
02401
02402
02403
02404
02405
02406 static void
02407 extract_range_from_expr (value_range_t *vr, tree expr)
02408 {
02409 enum tree_code code = TREE_CODE (expr);
02410
02411 if (code == ASSERT_EXPR)
02412 extract_range_from_assert (vr, expr);
02413 else if (code == SSA_NAME)
02414 extract_range_from_ssa_name (vr, expr);
02415 else if (TREE_CODE_CLASS (code) == tcc_binary
02416 || code == TRUTH_ANDIF_EXPR
02417 || code == TRUTH_ORIF_EXPR
02418 || code == TRUTH_AND_EXPR
02419 || code == TRUTH_OR_EXPR
02420 || code == TRUTH_XOR_EXPR)
02421 extract_range_from_binary_expr (vr, expr);
02422 else if (TREE_CODE_CLASS (code) == tcc_unary)
02423 extract_range_from_unary_expr (vr, expr);
02424 else if (TREE_CODE_CLASS (code) == tcc_comparison)
02425 extract_range_from_comparison (vr, expr);
02426 else if (is_gimple_min_invariant (expr))
02427 set_value_range_to_value (vr, expr);
02428 else
02429 set_value_range_to_varying (vr);
02430
02431
02432
02433
02434
02435 if (vr->type == VR_VARYING)
02436 {
02437 bool sop = false;
02438
02439 if (INTEGRAL_TYPE_P (TREE_TYPE (expr))
02440 && vrp_expr_computes_nonnegative (expr, &sop))
02441 set_value_range_to_nonnegative (vr, TREE_TYPE (expr),
02442 sop || is_overflow_infinity (expr));
02443 else if (vrp_expr_computes_nonzero (expr, &sop)
02444 && !sop)
02445 set_value_range_to_nonnull (vr, TREE_TYPE (expr));
02446 }
02447 }
02448
02449
02450
02451
02452
02453 static void
02454 adjust_range_with_scev (value_range_t *vr, struct loop *loop, tree stmt,
02455 tree var)
02456 {
02457 tree init, step, chrec, tmin, tmax, min, max, type;
02458 enum ev_direction dir;
02459
02460
02461
02462 if (vr->type == VR_ANTI_RANGE)
02463 return;
02464
02465 chrec = instantiate_parameters (loop, analyze_scalar_evolution (loop, var));
02466 if (TREE_CODE (chrec) != POLYNOMIAL_CHREC)
02467 return;
02468
02469 init = initial_condition_in_loop_num (chrec, loop->num);
02470 step = evolution_part_in_loop_num (chrec, loop->num);
02471
02472
02473
02474
02475
02476 if (step == NULL_TREE
02477 || !is_gimple_min_invariant (step)
02478 || !valid_value_p (init))
02479 return;
02480
02481 dir = scev_direction (chrec);
02482 if (
02483
02484 dir == EV_DIR_UNKNOWN
02485
02486 || scev_probably_wraps_p (init, step, stmt,
02487 current_loops->parray[CHREC_VARIABLE (chrec)],
02488 true))
02489 return;
02490
02491
02492
02493
02494
02495
02496 type = TREE_TYPE (var);
02497 if (POINTER_TYPE_P (type) || !TYPE_MIN_VALUE (type))
02498 tmin = lower_bound_in_type (type, type);
02499 else
02500 tmin = TYPE_MIN_VALUE (type);
02501 if (POINTER_TYPE_P (type) || !TYPE_MAX_VALUE (type))
02502 tmax = upper_bound_in_type (type, type);
02503 else
02504 tmax = TYPE_MAX_VALUE (type);
02505
02506 if (vr->type == VR_VARYING || vr->type == VR_UNDEFINED)
02507 {
02508 min = tmin;
02509 max = tmax;
02510
02511
02512
02513
02514 if (dir == EV_DIR_DECREASES)
02515 max = init;
02516 else
02517 min = init;
02518
02519
02520
02521
02522
02523 if (compare_values (min, max) == 1)
02524 return;
02525
02526 set_value_range (vr, VR_RANGE, min, max, vr->equiv);
02527 }
02528 else if (vr->type == VR_RANGE)
02529 {
02530 min = vr->min;
02531 max = vr->max;
02532
02533 if (dir == EV_DIR_DECREASES)
02534 {
02535
02536
02537 if (compare_values (init, max) == -1)
02538 {
02539 max = init;
02540
02541
02542
02543
02544
02545 if (compare_values (min, max) == 1)
02546 return;
02547 }
02548 }
02549 else
02550 {
02551
02552 if (compare_values (init, min) == 1)
02553 {
02554 min = init;
02555
02556
02557 if (compare_values (min, max) == 1)
02558 return;
02559 }
02560 }
02561
02562 set_value_range (vr, VR_RANGE, min, max, vr->equiv);
02563 }
02564 }
02565
02566
02567
02568
02569
02570
02571
02572
02573
02574
02575
02576
02577
02578
02579
02580
02581 static tree
02582 compare_ranges (enum tree_code comp, value_range_t *vr0, value_range_t *vr1,
02583 bool *strict_overflow_p)
02584 {
02585
02586 if (vr0->type == VR_VARYING
02587 || vr0->type == VR_UNDEFINED
02588 || vr1->type == VR_VARYING
02589 || vr1->type == VR_UNDEFINED)
02590 return NULL_TREE;
02591
02592
02593 if (vr0->type == VR_ANTI_RANGE || vr1->type == VR_ANTI_RANGE)
02594 {
02595
02596
02597 if (vr0->type == VR_ANTI_RANGE && vr1->type == VR_ANTI_RANGE)
02598 return NULL_TREE;
02599
02600
02601 if (comp == GT_EXPR
02602 || comp == GE_EXPR
02603 || comp == LT_EXPR
02604 || comp == LE_EXPR)
02605 return NULL_TREE;
02606
02607
02608
02609 if (vr0->type == VR_RANGE)
02610 {
02611
02612 value_range_t *tmp = vr0;
02613 vr0 = vr1;
02614 vr1 = tmp;
02615 }
02616
02617 gcc_assert (comp == NE_EXPR || comp == EQ_EXPR);
02618
02619 if (compare_values_warnv (vr0->min, vr1->min, strict_overflow_p) == 0
02620 && compare_values_warnv (vr0->max, vr1->max, strict_overflow_p) == 0)
02621 return (comp == NE_EXPR) ? boolean_true_node : boolean_false_node;
02622
02623 return NULL_TREE;
02624 }
02625
02626 if (!usable_range_p (vr0, strict_overflow_p)
02627 || !usable_range_p (vr1, strict_overflow_p))
02628 return NULL_TREE;
02629
02630
02631
02632 if (comp == GT_EXPR || comp == GE_EXPR)
02633 {
02634 value_range_t *tmp;
02635 comp = (comp == GT_EXPR) ? LT_EXPR : LE_EXPR;
02636 tmp = vr0;
02637 vr0 = vr1;
02638 vr1 = tmp;
02639 }
02640
02641 if (comp == EQ_EXPR)
02642 {
02643
02644
02645 if (compare_values_warnv (vr0->min, vr0->max, strict_overflow_p) == 0
02646 && compare_values_warnv (vr1->min, vr1->max, strict_overflow_p) == 0)
02647 {
02648 int cmp_min = compare_values_warnv (vr0->min, vr1->min,
02649 strict_overflow_p);
02650 int cmp_max = compare_values_warnv (vr0->max, vr1->max,
02651 strict_overflow_p);
02652 if (cmp_min == 0 && cmp_max == 0)
02653 return boolean_true_node;
02654 else if (cmp_min != -2 && cmp_max != -2)
02655 return boolean_false_node;
02656 }
02657
02658 else if (compare_values_warnv (vr0->min, vr1->max,
02659 strict_overflow_p) == 1
02660 || compare_values_warnv (vr1->min, vr0->max,
02661 strict_overflow_p) == 1)
02662 return boolean_false_node;
02663
02664 return NULL_TREE;
02665 }
02666 else if (comp == NE_EXPR)
02667 {
02668 int cmp1, cmp2;
02669
02670
02671
02672
02673
02674
02675 cmp1 = compare_values_warnv (vr0->max, vr1->min, strict_overflow_p);
02676 cmp2 = compare_values_warnv (vr0->min, vr1->max, strict_overflow_p);
02677 if ((cmp1 == -1 && cmp2 == -1) || (cmp1 == 1 && cmp2 == 1))
02678 return boolean_true_node;
02679
02680
02681
02682 else if (compare_values_warnv (vr0->min, vr0->max,
02683 strict_overflow_p) == 0
02684 && compare_values_warnv (vr1->min, vr1->max,
02685 strict_overflow_p) == 0
02686 && compare_values_warnv (vr0->min, vr1->min,
02687 strict_overflow_p) == 0
02688 && compare_values_warnv (vr0->max, vr1->max,
02689 strict_overflow_p) == 0)
02690 return boolean_false_node;
02691
02692
02693 else
02694 return NULL_TREE;
02695 }
02696 else if (comp == LT_EXPR || comp == LE_EXPR)
02697 {
02698 int tst;
02699
02700
02701 tst = compare_values_warnv (vr0->max, vr1->min, strict_overflow_p);
02702 if ((comp == LT_EXPR && tst == -1)
02703 || (comp == LE_EXPR && (tst == -1 || tst == 0)))
02704 {
02705 if (overflow_infinity_range_p (vr0)
02706 || overflow_infinity_range_p (vr1))
02707 *strict_overflow_p = true;
02708 return boolean_true_node;
02709 }
02710
02711
02712 tst = compare_values_warnv (vr0->min, vr1->max, strict_overflow_p);
02713 if ((comp == LT_EXPR && (tst == 0 || tst == 1))
02714 || (comp == LE_EXPR && tst == 1))
02715 {
02716 if (overflow_infinity_range_p (vr0)
02717 || overflow_infinity_range_p (vr1))
02718 *strict_overflow_p = true;
02719 return boolean_false_node;
02720 }
02721
02722
02723 return NULL_TREE;
02724 }
02725
02726 gcc_unreachable ();
02727 }
02728
02729
02730
02731
02732
02733
02734
02735
02736
02737
02738 static tree
02739 compare_range_with_value (enum tree_code comp, value_range_t *vr, tree val,
02740 bool *strict_overflow_p)
02741 {
02742 if (vr->type == VR_VARYING || vr->type == VR_UNDEFINED)
02743 return NULL_TREE;
02744
02745
02746 if (vr->type == VR_ANTI_RANGE)
02747 {
02748
02749
02750 if (comp == GT_EXPR
02751 || comp == GE_EXPR
02752 || comp == LT_EXPR
02753 || comp == LE_EXPR)
02754 return NULL_TREE;
02755
02756
02757 if (value_inside_range (val, vr) == 1)
02758 return (comp == NE_EXPR) ? boolean_true_node : boolean_false_node;
02759
02760 return NULL_TREE;
02761 }
02762
02763 if (!usable_range_p (vr, strict_overflow_p))
02764 return NULL_TREE;
02765
02766 if (comp == EQ_EXPR)
02767 {
02768
02769
02770 if (compare_values_warnv (vr->min, vr->max, strict_overflow_p) == 0)
02771 {
02772 int cmp = compare_values_warnv (vr->min, val, strict_overflow_p);
02773 if (cmp == 0)
02774 return boolean_true_node;
02775 else if (cmp == -1 || cmp == 1 || cmp == 2)
02776 return boolean_false_node;
02777 }
02778 else if (compare_values_warnv (val, vr->min, strict_overflow_p) == -1
02779 || compare_values_warnv (vr->max, val, strict_overflow_p) == -1)
02780 return boolean_false_node;
02781
02782 return NULL_TREE;
02783 }
02784 else if (comp == NE_EXPR)
02785 {
02786
02787 if (compare_values_warnv (vr->max, val, strict_overflow_p) == -1
02788 || compare_values_warnv (vr->min, val, strict_overflow_p) == 1)
02789 return boolean_true_node;
02790
02791
02792
02793 if (compare_values_warnv (vr->min, vr->max, strict_overflow_p) == 0
02794 && compare_values_warnv (vr->min, val, strict_overflow_p) == 0)
02795 return boolean_false_node;
02796
02797
02798 return NULL_TREE;
02799 }
02800 else if (comp == LT_EXPR || comp == LE_EXPR)
02801 {
02802 int tst;
02803
02804
02805 tst = compare_values_warnv (vr->max, val, strict_overflow_p);
02806 if ((comp == LT_EXPR && tst == -1)
02807 || (comp == LE_EXPR && (tst == -1 || tst == 0)))
02808 {
02809 if (overflow_infinity_range_p (vr))
02810 *strict_overflow_p = true;
02811 return boolean_true_node;
02812 }
02813
02814
02815 tst = compare_values_warnv (vr->min, val, strict_overflow_p);
02816 if ((comp == LT_EXPR && (tst == 0 || tst == 1))
02817 || (comp == LE_EXPR && tst == 1))
02818 {
02819 if (overflow_infinity_range_p (vr))
02820 *strict_overflow_p = true;
02821 return boolean_false_node;
02822 }
02823
02824
02825 return NULL_TREE;
02826 }
02827 else if (comp == GT_EXPR || comp == GE_EXPR)
02828 {
02829 int tst;
02830
02831
02832 tst = compare_values_warnv (vr->min, val, strict_overflow_p);
02833 if ((comp == GT_EXPR && tst == 1)
02834 || (comp == GE_EXPR && (tst == 0 || tst == 1)))
02835 {
02836 if (overflow_infinity_range_p (vr))
02837 *strict_overflow_p = true;
02838 return boolean_true_node;
02839 }
02840
02841
02842 tst = compare_values_warnv (vr->max, val, strict_overflow_p);
02843 if ((comp == GT_EXPR && (tst == -1 || tst == 0))
02844 || (comp == GE_EXPR && tst == -1))
02845 {
02846 if (overflow_infinity_range_p (vr))
02847 *strict_overflow_p = true;
02848 return boolean_false_node;
02849 }
02850
02851
02852 return NULL_TREE;
02853 }
02854
02855 gcc_unreachable ();
02856 }
02857
02858
02859
02860
02861 void dump_value_range (FILE *, value_range_t *);
02862 void debug_value_range (value_range_t *);
02863 void dump_all_value_ranges (FILE *);
02864 void debug_all_value_ranges (void);
02865 void dump_vr_equiv (FILE *, bitmap);
02866 void debug_vr_equiv (bitmap);
02867
02868
02869
02870
02871 void
02872 dump_value_range (FILE *file, value_range_t *vr)
02873 {
02874 if (vr == NULL)
02875 fprintf (file, "[]");
02876 else if (vr->type == VR_UNDEFINED)
02877 fprintf (file, "UNDEFINED");
02878 else if (vr->type == VR_RANGE || vr->type == VR_ANTI_RANGE)
02879 {
02880 tree type = TREE_TYPE (vr->min);
02881
02882 fprintf (file, "%s[", (vr->type == VR_ANTI_RANGE) ? "~" : "");
02883
02884 if (is_negative_overflow_infinity (vr->min))
02885 fprintf (file, "-INF(OVF)");
02886 else if (INTEGRAL_TYPE_P (type)
02887 && !TYPE_UNSIGNED (type)
02888 && vrp_val_is_min (vr->min))
02889 fprintf (file, "-INF");
02890 else
02891 print_generic_expr (file, vr->min, 0);
02892
02893 fprintf (file, ", ");
02894
02895 if (is_positive_overflow_infinity (vr->max))
02896 fprintf (file, "+INF(OVF)");
02897 else if (INTEGRAL_TYPE_P (type)
02898 && vrp_val_is_max (vr->max))
02899 fprintf (file, "+INF");
02900 else
02901 print_generic_expr (file, vr->max, 0);
02902
02903 fprintf (file, "]");
02904
02905 if (vr->equiv)
02906 {
02907 bitmap_iterator bi;
02908 unsigned i, c = 0;
02909
02910 fprintf (file, " EQUIVALENCES: { ");
02911
02912 EXECUTE_IF_SET_IN_BITMAP (vr->equiv, 0, i, bi)
02913 {
02914 print_generic_expr (file, ssa_name (i), 0);
02915 fprintf (file, " ");
02916 c++;
02917 }
02918
02919 fprintf (file, "} (%u elements)", c);
02920 }
02921 }
02922 else if (vr->type == VR_VARYING)
02923 fprintf (file, "VARYING");
02924 else
02925 fprintf (file, "INVALID RANGE");
02926 }
02927
02928
02929
02930
02931 void
02932 debug_value_range (value_range_t *vr)
02933 {
02934 dump_value_range (stderr, vr);
02935 fprintf (stderr, "\n");
02936 }
02937
02938
02939
02940
02941 void
02942 dump_all_value_ranges (FILE *file)
02943 {
02944 size_t i;
02945
02946 for (i = 0; i < num_ssa_names; i++)
02947 {
02948 if (vr_value[i])
02949 {
02950 print_generic_expr (file, ssa_name (i), 0);
02951 fprintf (file, ": ");
02952 dump_value_range (file, vr_value[i]);
02953 fprintf (file, "\n");
02954 }
02955 }
02956
02957 fprintf (file, "\n");
02958 }
02959
02960
02961
02962
02963 void
02964 debug_all_value_ranges (void)
02965 {
02966 dump_all_value_ranges (stderr);
02967 }
02968
02969
02970
02971
02972
02973
02974 static tree
02975 build_assert_expr_for (tree cond, tree v)
02976 {
02977 tree n, assertion;
02978
02979 gcc_assert (TREE_CODE (v) == SSA_NAME);
02980 n = duplicate_ssa_name (v, NULL_TREE);
02981
02982 if (COMPARISON_CLASS_P (cond))
02983 {
02984 tree a = build2 (ASSERT_EXPR, TREE_TYPE (v), v, cond);
02985 assertion = build2 (MODIFY_EXPR, TREE_TYPE (v), n, a);
02986 }
02987 else if (TREE_CODE (cond) == TRUTH_NOT_EXPR)
02988 {
02989
02990 tree op0 = TREE_OPERAND (cond, 0);
02991 gcc_assert (op0 == v);
02992 assertion = build2 (MODIFY_EXPR, TREE_TYPE (v), n, boolean_false_node);
02993 }
02994 else if (TREE_CODE (cond) == SSA_NAME)
02995 {
02996
02997 gcc_assert (v == cond);
02998 assertion = build2 (MODIFY_EXPR, TREE_TYPE (v), n, boolean_true_node);
02999 }
03000 else
03001 gcc_unreachable ();
03002
03003 SSA_NAME_DEF_STMT (n) = assertion;
03004
03005
03006
03007
03008
03009 register_new_name_mapping (n, v);
03010
03011 return assertion;
03012 }
03013
03014
03015
03016
03017
03018 static inline bool
03019 fp_predicate (tree expr)
03020 {
03021 return (COMPARISON_CLASS_P (expr)
03022 && FLOAT_TYPE_P (TREE_TYPE (TREE_OPERAND (expr, 0))));
03023 }
03024
03025
03026
03027
03028
03029
03030
03031 static bool
03032 infer_value_range (tree stmt, tree op, enum tree_code *comp_code_p, tree *val_p)
03033 {
03034 *val_p = NULL_TREE;
03035 *comp_code_p = ERROR_MARK;
03036
03037
03038
03039 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (op))
03040 return false;
03041
03042
03043
03044 if (tree_could_throw_p (stmt))
03045 return false;
03046
03047
03048
03049
03050
03051 if (stmt_ends_bb_p (stmt) && EDGE_COUNT (bb_for_stmt (stmt)->succs) == 0)
03052 return false;
03053
03054
03055
03056 if (flag_delete_null_pointer_checks && POINTER_TYPE_P (TREE_TYPE (op)))
03057 {
03058 bool is_store;
03059 unsigned num_uses, num_derefs;
03060
03061 count_uses_and_derefs (op, stmt, &num_uses, &num_derefs, &is_store);
03062 if (num_derefs > 0)
03063 {
03064 *val_p = build_int_cst (TREE_TYPE (op), 0);
03065 *comp_code_p = NE_EXPR;
03066 return true;
03067 }
03068 }
03069
03070 return false;
03071 }
03072
03073
03074 void dump_asserts_for (FILE *, tree);
03075 void debug_asserts_for (tree);
03076 void dump_all_asserts (FILE *);
03077 void debug_all_asserts (void);
03078
03079
03080
03081 void
03082 dump_asserts_for (FILE *file, tree name)
03083 {
03084 assert_locus_t loc;
03085
03086 fprintf (file, "Assertions to be inserted for ");
03087 print_generic_expr (file, name, 0);
03088 fprintf (file, "\n");
03089
03090 loc = asserts_for[SSA_NAME_VERSION (name)];
03091 while (loc)
03092 {
03093 fprintf (file, "\t");
03094 print_generic_expr (file, bsi_stmt (loc->si), 0);
03095 fprintf (file, "\n\tBB #%d", loc->bb->index);
03096 if (loc->e)
03097 {
03098 fprintf (file, "\n\tEDGE %d->%d", loc->e->src->index,
03099 loc->e->dest->index);
03100 dump_edge_info (file, loc->e, 0);
03101 }
03102 fprintf (file, "\n\tPREDICATE: ");
03103 print_generic_expr (file, name, 0);
03104 fprintf (file, " %s ", tree_code_name[(int)loc->comp_code]);
03105 print_generic_expr (file, loc->val, 0);
03106 fprintf (file, "\n\n");
03107 loc = loc->next;
03108 }
03109
03110 fprintf (file, "\n");
03111 }
03112
03113
03114
03115
03116 void
03117 debug_asserts_for (tree name)
03118 {
03119 dump_asserts_for (stderr, name);
03120 }
03121
03122
03123
03124
03125 void
03126 dump_all_asserts (FILE *file)
03127 {
03128 unsigned i;
03129 bitmap_iterator bi;
03130
03131 fprintf (file, "\nASSERT_EXPRs to be inserted\n\n");
03132 EXECUTE_IF_SET_IN_BITMAP (need_assert_for, 0, i, bi)
03133 dump_asserts_for (file, ssa_name (i));
03134 fprintf (file, "\n");
03135 }
03136
03137
03138
03139
03140 void
03141 debug_all_asserts (void)
03142 {
03143 dump_all_asserts (stderr);
03144 }
03145
03146
03147
03148
03149
03150
03151
03152
03153
03154
03155
03156
03157
03158 static void
03159 register_new_assert_for (tree name,
03160 enum tree_code comp_code,
03161 tree val,
03162 basic_block bb,
03163 edge e,
03164 block_stmt_iterator si)
03165 {
03166 assert_locus_t n, loc, last_loc;
03167 bool found;
03168 basic_block dest_bb;
03169
03170 #if defined ENABLE_CHECKING
03171 gcc_assert (bb == NULL || e == NULL);
03172
03173 if (e == NULL)
03174 gcc_assert (TREE_CODE (bsi_stmt (si)) != COND_EXPR
03175 && TREE_CODE (bsi_stmt (si)) != SWITCH_EXPR);
03176 #endif
03177
03178
03179
03180
03181
03182
03183
03184
03185
03186
03187
03188
03189
03190
03191
03192
03193 dest_bb = (bb) ? bb : e->dest;
03194
03195
03196
03197
03198
03199
03200
03201
03202
03203
03204
03205
03206 loc = asserts_for[SSA_NAME_VERSION (name)];
03207 last_loc = loc;
03208 found = false;
03209 while (loc)
03210 {
03211 if (loc->comp_code == comp_code
03212 && (loc->val == val
03213 || operand_equal_p (loc->val, val, 0)))
03214 {
03215
03216
03217
03218
03219
03220
03221
03222
03223
03224
03225
03226
03227
03228 if (e == NULL
03229 && dominated_by_p (CDI_DOMINATORS, dest_bb, loc->bb))
03230 return;
03231
03232
03233
03234
03235
03236 if ((e == NULL || !EDGE_CRITICAL_P (e))
03237 && dominated_by_p (CDI_DOMINATORS, loc->bb, dest_bb))
03238 {
03239 loc->bb = dest_bb;
03240 loc->e = e;
03241 loc->si = si;
03242 return;
03243 }
03244 }
03245
03246
03247 last_loc = loc;
03248 loc = loc->next;
03249 }
03250
03251
03252
03253
03254 n = XNEW (struct assert_locus_d);
03255 n->bb = dest_bb;
03256 n->e = e;
03257 n->si = si;
03258 n->comp_code = comp_code;
03259 n->val = val;
03260 n->next = NULL;
03261
03262 if (last_loc)
03263 last_loc->next = n;
03264 else
03265 asserts_for[SSA_NAME_VERSION (name)] = n;
03266
03267 bitmap_set_bit (need_assert_for, SSA_NAME_VERSION (name));
03268 }
03269
03270
03271
03272
03273
03274
03275 static bool
03276 register_edge_assert_for (tree name, edge e, block_stmt_iterator si)
03277 {
03278 tree val, stmt;
03279 enum tree_code comp_code;
03280
03281 stmt = bsi_stmt (si);
03282
03283
03284
03285 if (SSA_NAME_OCCURS_IN_ABNORMAL_PHI (name))
03286 return false;
03287
03288
03289
03290 if (!TEST_BIT (found_in_subgraph, SSA_NAME_VERSION (name)))
03291 return false;
03292
03293
03294
03295
03296 if (TREE_CODE (stmt) == COND_EXPR)
03297 {
03298
03299
03300
03301 tree cond = COND_EXPR_COND (stmt);
03302 bool is_else_edge = (e->flags & EDGE_FALSE_VALUE) != 0;
03303
03304
03305 if (cond == name)
03306 {
03307
03308
03309
03310 comp_code = EQ_EXPR;
03311 val = (is_else_edge) ? boolean_false_node : boolean_true_node;
03312 }
03313 else
03314 {
03315
03316
03317 if (name == TREE_OPERAND (cond, 1))
03318 {
03319
03320
03321
03322 comp_code = swap_tree_comparison (TREE_CODE (cond));
03323 val = TREE_OPERAND (cond, 0);
03324 }
03325 else
03326 {
03327
03328
03329 comp_code = TREE_CODE (cond);
03330 val = TREE_OPERAND (cond, 1);
03331 }
03332
03333
03334
03335 if (is_else_edge)
03336 comp_code = invert_tree_comparison (comp_code, 0);
03337
03338
03339
03340
03341
03342 if ((comp_code == GT_EXPR || comp_code == LT_EXPR)
03343 && (INTEGRAL_TYPE_P (TREE_TYPE (val))
03344 || SCALAR_FLOAT_TYPE_P (TREE_TYPE (val))))
03345 {
03346 tree min = TYPE_MIN_VALUE (TREE_TYPE (val));
03347 tree max = TYPE_MAX_VALUE (TREE_TYPE (val));
03348
03349 if (comp_code == GT_EXPR && compare_values (val, max) == 0)
03350 return false;
03351
03352 if (comp_code == LT_EXPR && compare_values (val, min) == 0)
03353 return false;
03354 }
03355 }
03356 }
03357 else
03358 {
03359
03360 gcc_unreachable ();
03361 }
03362
03363 register_new_assert_for (name, comp_code, val, NULL, e, si);
03364 return true;
03365 }
03366
03367
03368 static bool find_assert_locations (basic_block bb);
03369
03370
03371
03372
03373
03374
03375
03376
03377
03378 static bool
03379 find_conditional_asserts (basic_block bb)
03380 {
03381 bool need_assert;
03382 block_stmt_iterator last_si;
03383 tree op, last;
03384 edge_iterator ei;
03385 edge e;
03386 ssa_op_iter iter;
03387
03388 need_assert = false;
03389 last_si = bsi_last (bb);
03390 last = bsi_stmt (last_si);
03391
03392
03393
03394
03395
03396 FOR_EACH_EDGE (e, ei, bb->succs)
03397 {
03398 if (e->dest == bb)
03399 continue;
03400
03401
03402
03403
03404
03405
03406
03407
03408
03409
03410
03411
03412
03413
03414
03415
03416
03417
03418
03419
03420
03421
03422 FOR_EACH_SSA_TREE_OPERAND (op, last, iter, SSA_OP_USE)
03423 RESET_BIT (found_in_subgraph, SSA_NAME_VERSION (op));
03424
03425
03426
03427
03428 if (e->dest != bb)
03429 need_assert |= find_assert_locations (e->dest);
03430
03431
03432
03433 FOR_EACH_SSA_TREE_OPERAND (op, last, iter, SSA_OP_USE)
03434 need_assert |= register_edge_assert_for (op, e, last_si);
03435 }
03436
03437
03438
03439 FOR_EACH_SSA_TREE_OPERAND (op, last, iter, SSA_OP_USE)
03440 SET_BIT (found_in_subgraph, SSA_NAME_VERSION (op));
03441
03442 return need_assert;
03443 }
03444
03445
03446
03447
03448
03449
03450
03451
03452
03453
03454
03455
03456
03457
03458
03459
03460
03461
03462
03463
03464
03465
03466
03467
03468
03469
03470
03471
03472
03473
03474
03475
03476
03477
03478
03479
03480
03481
03482
03483
03484
03485
03486
03487
03488
03489
03490
03491
03492
03493
03494
03495
03496
03497
03498
03499
03500
03501
03502
03503
03504
03505
03506
03507
03508
03509
03510
03511 static bool
03512 find_assert_locations (basic_block bb)
03513 {
03514 block_stmt_iterator si;
03515 tree last, phi;
03516 bool need_assert;
03517 basic_block son;
03518
03519 if (TEST_BIT (blocks_visited, bb->index))
03520 return false;
03521
03522 SET_BIT (blocks_visited, bb->index);
03523
03524 need_assert = false;
03525
03526
03527 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
03528 {
03529 use_operand_p arg_p;
03530 ssa_op_iter i;
03531
03532 FOR_EACH_PHI_ARG (arg_p, phi, i, SSA_OP_USE)
03533 {
03534 tree arg = USE_FROM_PTR (arg_p);
03535 if (TREE_CODE (arg) == SSA_NAME)
03536 {
03537 gcc_assert (is_gimple_reg (PHI_RESULT (phi)));
03538 SET_BIT (found_in_subgraph, SSA_NAME_VERSION (arg));
03539 }
03540 }
03541 }
03542
03543
03544
03545 last = NULL_TREE;
03546 for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
03547 {
03548 tree stmt, op;
03549 ssa_op_iter i;
03550
03551 stmt = bsi_stmt (si);
03552
03553
03554 FOR_EACH_SSA_TREE_OPERAND (op, stmt, i, SSA_OP_USE)
03555 {
03556 tree value;
03557 enum tree_code comp_code;
03558
03559
03560
03561
03562
03563
03564 SET_BIT (found_in_subgraph, SSA_NAME_VERSION (op));
03565
03566
03567
03568
03569 if (infer_value_range (stmt, op, &comp_code, &value))
03570 {
03571
03572
03573
03574
03575
03576
03577 if (comp_code == NE_EXPR && integer_zerop (value))
03578 {
03579 tree t = op;
03580 tree def_stmt = SSA_NAME_DEF_STMT (t);
03581
03582 while (TREE_CODE (def_stmt) == MODIFY_EXPR
03583 && TREE_CODE (TREE_OPERAND (def_stmt, 1)) == NOP_EXPR
03584 && TREE_CODE (TREE_OPERAND (TREE_OPERAND (def_stmt, 1), 0)) == SSA_NAME
03585 && POINTER_TYPE_P (TREE_TYPE (TREE_OPERAND (TREE_OPERAND (def_stmt, 1), 0))))
03586 {
03587 t = TREE_OPERAND (TREE_OPERAND (def_stmt, 1), 0);
03588 def_stmt = SSA_NAME_DEF_STMT (t);
03589
03590
03591
03592
03593 if (! has_single_use (t))
03594 {
03595 register_new_assert_for (t, comp_code, value,
03596 bb, NULL, si);
03597 need_assert = true;
03598 }
03599 }
03600 }
03601
03602
03603
03604
03605 if (!has_single_use (op))
03606 {
03607 register_new_assert_for (op, comp_code, value, bb, NULL, si);
03608 need_assert = true;
03609 }
03610 }
03611 }
03612
03613
03614 last = stmt;
03615 }
03616
03617
03618
03619
03620 if (last
03621 && TREE_CODE (last) == COND_EXPR
03622 && !fp_predicate (COND_EXPR_COND (last))
03623 && !ZERO_SSA_OPERANDS (last, SSA_OP_USE))
03624 need_assert |= find_conditional_asserts (bb);
03625
03626
03627 for (son = first_dom_son (CDI_DOMINATORS, bb);
03628 son;
03629 son = next_dom_son (CDI_DOMINATORS, son))
03630 need_assert |= find_assert_locations (son);
03631
03632 return need_assert;
03633 }
03634
03635
03636
03637
03638
03639 static bool
03640 process_assert_insertions_for (tree name, assert_locus_t loc)
03641 {
03642
03643 tree stmt, cond, assert_expr;
03644 edge_iterator ei;
03645 edge e;
03646
03647 cond = build2 (loc->comp_code, boolean_type_node, name, loc->val);
03648 assert_expr = build_assert_expr_for (cond, name);
03649
03650 if (loc->e)
03651 {
03652
03653
03654 #if defined ENABLE_CHECKING
03655 gcc_assert (TREE_CODE (bsi_stmt (loc->si)) == COND_EXPR
03656 || TREE_CODE (bsi_stmt (loc->si)) == SWITCH_EXPR);
03657 #endif
03658
03659 bsi_insert_on_edge (loc->e, assert_expr);
03660 return true;
03661 }
03662
03663
03664
03665 stmt = bsi_stmt (loc->si);
03666 if (!stmt_ends_bb_p (stmt))
03667 {
03668 bsi_insert_after (&loc->si, assert_expr, BSI_SAME_STMT);
03669 return false;
03670 }
03671
03672
03673
03674
03675
03676 FOR_EACH_EDGE (e, ei, loc->bb->succs)
03677 if (!(e->flags & EDGE_ABNORMAL))
03678 {
03679 bsi_insert_on_edge (e, assert_expr);
03680 return true;
03681 }
03682
03683 gcc_unreachable ();
03684 }
03685
03686
03687
03688
03689
03690
03691 static void
03692 process_assert_insertions (void)
03693 {
03694 unsigned i;
03695 bitmap_iterator bi;
03696 bool update_edges_p = false;
03697 int num_asserts = 0;
03698
03699 if (dump_file && (dump_flags & TDF_DETAILS))
03700 dump_all_asserts (dump_file);
03701
03702 EXECUTE_IF_SET_IN_BITMAP (need_assert_for, 0, i, bi)
03703 {
03704 assert_locus_t loc = asserts_for[i];
03705 gcc_assert (loc);
03706
03707 while (loc)
03708 {
03709 assert_locus_t next = loc->next;
03710 update_edges_p |= process_assert_insertions_for (ssa_name (i), loc);
03711 free (loc);
03712 loc = next;
03713 num_asserts++;
03714 }
03715 }
03716
03717 if (update_edges_p)
03718 bsi_commit_edge_inserts ();
03719
03720 if (dump_file && (dump_flags & TDF_STATS))
03721 fprintf (dump_file, "\nNumber of ASSERT_EXPR expressions inserted: %d\n\n",
03722 num_asserts);
03723 }
03724
03725
03726
03727
03728
03729
03730
03731
03732
03733
03734
03735
03736
03737
03738
03739
03740
03741
03742
03743
03744
03745
03746
03747
03748
03749
03750
03751
03752
03753
03754
03755
03756
03757
03758 static void
03759 insert_range_assertions (void)
03760 {
03761 edge e;
03762 edge_iterator ei;
03763 bool update_ssa_p;
03764
03765 found_in_subgraph = sbitmap_alloc (num_ssa_names);
03766 sbitmap_zero (found_in_subgraph);
03767
03768 blocks_visited = sbitmap_alloc (last_basic_block);
03769 sbitmap_zero (blocks_visited);
03770
03771 need_assert_for = BITMAP_ALLOC (NULL);
03772 asserts_for = XNEWVEC (assert_locus_t, num_ssa_names);
03773 memset (asserts_for, 0, num_ssa_names * sizeof (assert_locus_t));
03774
03775 calculate_dominance_info (CDI_DOMINATORS);
03776
03777 update_ssa_p = false;
03778 FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
03779 if (find_assert_locations (e->dest))
03780 update_ssa_p = true;
03781
03782 if (update_ssa_p)
03783 {
03784 process_assert_insertions ();
03785 update_ssa (TODO_update_ssa_no_phi);
03786 }
03787
03788 if (dump_file && (dump_flags & TDF_DETAILS))
03789 {
03790 fprintf (dump_file, "\nSSA form after inserting ASSERT_EXPRs\n");
03791 dump_function_to_file (current_function_decl, dump_file, dump_flags);
03792 }
03793
03794 sbitmap_free (found_in_subgraph);
03795 free (asserts_for);
03796 BITMAP_FREE (need_assert_for);
03797 }
03798
03799
03800
03801
03802
03803
03804
03805
03806
03807
03808
03809
03810
03811
03812
03813
03814
03815
03816
03817
03818
03819
03820
03821
03822
03823
03824 static void
03825 remove_range_assertions (void)
03826 {
03827 basic_block bb;
03828 block_stmt_iterator si;
03829
03830
03831
03832
03833 FOR_EACH_BB (bb)
03834 for (si = bsi_start (bb); !bsi_end_p (si);)
03835 {
03836 tree stmt = bsi_stmt (si);
03837 tree use_stmt;
03838
03839 if (TREE_CODE (stmt) == MODIFY_EXPR
03840 && TREE_CODE (TREE_OPERAND (stmt, 1)) == ASSERT_EXPR)
03841 {
03842 tree rhs = TREE_OPERAND (stmt, 1), var;
03843 tree cond = fold (ASSERT_EXPR_COND (rhs));
03844 use_operand_p use_p;
03845 imm_use_iterator iter;
03846
03847 gcc_assert (cond != boolean_false_node);
03848
03849
03850 var = ASSERT_EXPR_VAR (rhs);
03851 FOR_EACH_IMM_USE_STMT (use_stmt, iter, TREE_OPERAND (stmt, 0))
03852 FOR_EACH_IMM_USE_ON_STMT (use_p, iter)
03853 {
03854 SET_USE (use_p, var);
03855 gcc_assert (TREE_CODE (var) == SSA_NAME);
03856 }
03857
03858
03859 bsi_remove (&si, true);
03860 }
03861 else
03862 bsi_next (&si);
03863 }
03864
03865 sbitmap_free (blocks_visited);
03866 }
03867
03868
03869
03870
03871 static bool
03872 stmt_interesting_for_vrp (tree stmt)
03873 {
03874 if (TREE_CODE (stmt) == PHI_NODE
03875 && is_gimple_reg (PHI_RESULT (stmt))
03876 && (INTEGRAL_TYPE_P (TREE_TYPE (PHI_RESULT (stmt)))
03877 || POINTER_TYPE_P (TREE_TYPE (PHI_RESULT (stmt)))))
03878 return true;
03879 else if (TREE_CODE (stmt) == MODIFY_EXPR)
03880 {
03881 tree lhs = TREE_OPERAND (stmt, 0);
03882 tree rhs = TREE_OPERAND (stmt, 1);
03883
03884
03885
03886
03887 if (TREE_CODE (lhs) == SSA_NAME
03888 && (INTEGRAL_TYPE_P (TREE_TYPE (lhs))
03889 || POINTER_TYPE_P (TREE_TYPE (lhs)))
03890 && ((TREE_CODE (rhs) == CALL_EXPR
03891 && TREE_CODE (TREE_OPERAND (rhs, 0)) == ADDR_EXPR
03892 && DECL_P (TREE_OPERAND (TREE_OPERAND (rhs, 0), 0))
03893 && DECL_IS_BUILTIN (TREE_OPERAND (TREE_OPERAND (rhs, 0), 0)))
03894 || ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS)))
03895 return true;
03896 }
03897 else if (TREE_CODE (stmt) == COND_EXPR || TREE_CODE (stmt) == SWITCH_EXPR)
03898 return true;
03899
03900 return false;
03901 }
03902
03903
03904
03905
03906 static void
03907 vrp_initialize (void)
03908 {
03909 basic_block bb;
03910
03911 vr_value = XNEWVEC (value_range_t *, num_ssa_names);
03912 memset (vr_value, 0, num_ssa_names * sizeof (value_range_t *));
03913
03914 FOR_EACH_BB (bb)
03915 {
03916 block_stmt_iterator si;
03917 tree phi;
03918
03919 for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
03920 {
03921 if (!stmt_interesting_for_vrp (phi))
03922 {
03923 tree lhs = PHI_RESULT (phi);
03924 set_value_range_to_varying (get_value_range (lhs));
03925 DONT_SIMULATE_AGAIN (phi) = true;
03926 }
03927 else
03928 DONT_SIMULATE_AGAIN (phi) = false;
03929 }
03930
03931 for (si = bsi_start (bb); !bsi_end_p (si); bsi_next (&si))
03932 {
03933 tree stmt = bsi_stmt (si);
03934
03935 if (!stmt_interesting_for_vrp (stmt))
03936 {
03937 ssa_op_iter i;
03938 tree def;
03939 FOR_EACH_SSA_TREE_OPERAND (def, stmt, i, SSA_OP_DEF)
03940 set_value_range_to_varying (get_value_range (def));
03941 DONT_SIMULATE_AGAIN (stmt) = true;
03942 }
03943 else
03944 {
03945 DONT_SIMULATE_AGAIN (stmt) = false;
03946 }
03947 }
03948 }
03949 }
03950
03951
03952
03953
03954
03955 static enum ssa_prop_result
03956 vrp_visit_assignment (tree stmt, tree *output_p)
03957 {
03958 tree lhs, rhs, def;
03959 ssa_op_iter iter;
03960
03961 lhs = TREE_OPERAND (stmt, 0);
03962 rhs = TREE_OPERAND (stmt, 1);
03963
03964
03965 if (TREE_CODE (lhs) == SSA_NAME
03966 && ((INTEGRAL_TYPE_P (TREE_TYPE (lhs))
03967
03968
03969 && TYPE_MIN_VALUE (TREE_TYPE (lhs))
03970 && TYPE_MAX_VALUE (TREE_TYPE (lhs)))
03971 || POINTER_TYPE_P (TREE_TYPE (lhs))))
03972 {
03973 struct loop *l;
03974 value_range_t new_vr = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
03975
03976 extract_range_from_expr (&new_vr, rhs);
03977
03978
03979
03980
03981 if (current_loops && (l = loop_containing_stmt (stmt)))
03982 adjust_range_with_scev (&new_vr, l, stmt, lhs);
03983
03984 if (update_value_range (lhs, &new_vr))
03985 {
03986 *output_p = lhs;
03987
03988 if (dump_file && (dump_flags & TDF_DETAILS))
03989 {
03990 fprintf (dump_file, "Found new range for ");
03991 print_generic_expr (dump_file, lhs, 0);
03992 fprintf (dump_file, ": ");
03993 dump_value_range (dump_file, &new_vr);
03994 fprintf (dump_file, "\n\n");
03995 }
03996
03997 if (new_vr.type == VR_VARYING)
03998 return SSA_PROP_VARYING;
03999
04000 return SSA_PROP_INTERESTING;
04001 }
04002
04003 return SSA_PROP_NOT_INTERESTING;
04004 }
04005
04006
04007 FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF)
04008 set_value_range_to_varying (get_value_range (def));
04009
04010 return SSA_PROP_VARYING;
04011 }
04012
04013
04014
04015
04016
04017
04018
04019 static tree
04020 compare_name_with_value (enum tree_code comp, tree var, tree val,
04021 bool *strict_overflow_p)
04022 {
04023 bitmap_iterator bi;
04024 unsigned i;
04025 bitmap e;
04026 tree retval, t;
04027 int used_strict_overflow;
04028
04029 t = retval = NULL_TREE;
04030
04031
04032 e = get_value_range (var)->equiv;
04033
04034
04035
04036
04037 bitmap_set_bit (e, SSA_NAME_VERSION (var));
04038
04039
04040
04041 used_strict_overflow = -1;
04042
04043 EXECUTE_IF_SET_IN_BITMAP (e, 0, i, bi)
04044 {
04045 bool sop;
04046
04047 value_range_t equiv_vr = *(vr_value[i]);
04048
04049
04050
04051
04052 if (equiv_vr.type == VR_VARYING || equiv_vr.type == VR_UNDEFINED)
04053 {
04054 equiv_vr.type = VR_RANGE;
04055 equiv_vr.min = ssa_name (i);
04056 equiv_vr.max = ssa_name (i);
04057 }
04058
04059 sop = false;
04060 t = compare_range_with_value (comp, &equiv_vr, val, &sop);
04061 if (t)
04062 {
04063
04064
04065
04066
04067 if (retval != NULL
04068 && t != retval)
04069 {
04070 retval = NULL_TREE;
04071 break;
04072 }
04073 retval = t;
04074
04075 if (!sop)
04076 used_strict_overflow = 0;
04077 else if (used_strict_overflow < 0)
04078 used_strict_overflow = 1;
04079 }
04080 }
04081
04082
04083 bitmap_clear_bit (e, SSA_NAME_VERSION (var));
04084
04085 if (retval)
04086 {
04087 if (used_strict_overflow > 0)
04088 *strict_overflow_p = true;
04089 return retval;
04090 }
04091
04092
04093 return NULL_TREE;
04094 }
04095
04096
04097
04098
04099
04100
04101
04102
04103
04104 static tree
04105 compare_names (enum tree_code comp, tree n1, tree n2,
04106 bool *strict_overflow_p)
04107 {
04108 tree t, retval;
04109 bitmap e1, e2;
04110 bitmap_iterator bi1, bi2;
04111 unsigned i1, i2;
04112 int used_strict_overflow;
04113
04114
04115
04116 e1 = get_value_range (n1)->equiv;
04117 e2 = get_value_range (n2)->equiv;
04118
04119
04120
04121
04122 bitmap_set_bit (e1, SSA_NAME_VERSION (n1));
04123 bitmap_set_bit (e2, SSA_NAME_VERSION (n2));
04124
04125
04126
04127 if (bitmap_intersect_p (e1, e2))
04128 {
04129 bitmap_clear_bit (e1, SSA_NAME_VERSION (n1));
04130 bitmap_clear_bit (e2, SSA_NAME_VERSION (n2));
04131
04132 return (comp == EQ_EXPR || comp == GE_EXPR || comp == LE_EXPR)
04133 ? boolean_true_node
04134 : boolean_false_node;
04135 }
04136
04137
04138
04139 used_strict_overflow = -1;
04140
04141
04142
04143
04144 EXECUTE_IF_SET_IN_BITMAP (e1, 0, i1, bi1)
04145 {
04146 value_range_t vr1 = *(vr_value[i1]);
04147
04148
04149 if (vr1.type == VR_VARYING || vr1.type == VR_UNDEFINED)
04150 {
04151 vr1.type = VR_RANGE;
04152 vr1.min = ssa_name (i1);
04153 vr1.max = ssa_name (i1);
04154 }
04155
04156 t = retval = NULL_TREE;
04157 EXECUTE_IF_SET_IN_BITMAP (e2, 0, i2, bi2)
04158 {
04159 bool sop;
04160
04161 value_range_t vr2 = *(vr_value[i2]);
04162
04163 if (vr2.type == VR_VARYING || vr2.type == VR_UNDEFINED)
04164 {
04165 vr2.type = VR_RANGE;
04166 vr2.min = ssa_name (i2);
04167 vr2.max = ssa_name (i2);
04168 }
04169
04170 t = compare_ranges (comp, &vr1, &vr2, &sop);
04171 if (t)
04172 {
04173
04174
04175
04176
04177 if (retval != NULL
04178 && t != retval)
04179 {
04180 bitmap_clear_bit (e1, SSA_NAME_VERSION (n1));
04181 bitmap_clear_bit (e2, SSA_NAME_VERSION (n2));
04182 return NULL_TREE;
04183 }
04184 retval = t;
04185
04186 if (!sop)
04187 used_strict_overflow = 0;
04188 else if (used_strict_overflow < 0)
04189 used_strict_overflow = 1;
04190 }
04191 }
04192
04193 if (retval)
04194 {
04195 bitmap_clear_bit (e1, SSA_NAME_VERSION (n1));
04196 bitmap_clear_bit (e2, SSA_NAME_VERSION (n2));
04197 if (used_strict_overflow > 0)
04198 *strict_overflow_p = true;
04199 return retval;
04200 }
04201 }
04202
04203
04204
04205 bitmap_clear_bit (e1, SSA_NAME_VERSION (n1));
04206 bitmap_clear_bit (e2, SSA_NAME_VERSION (n2));
04207 return NULL_TREE;
04208 }
04209
04210
04211
04212
04213
04214
04215
04216
04217
04218
04219
04220
04221
04222
04223
04224
04225 static tree
04226 vrp_evaluate_conditional_warnv (tree cond, bool use_equiv_p,
04227 bool *strict_overflow_p)
04228 {
04229 gcc_assert (TREE_CODE (cond) == SSA_NAME
04230 || TREE_CODE_CLASS (TREE_CODE (cond)) == tcc_comparison);
04231
04232 if (TREE_CODE (cond) == SSA_NAME)
04233 {
04234 value_range_t *vr;
04235 tree retval;
04236
04237 if (use_equiv_p)
04238 retval = compare_name_with_value (NE_EXPR, cond, boolean_false_node,
04239 strict_overflow_p);
04240 else
04241 {
04242 value_range_t *vr = get_value_range (cond);
04243 retval = compare_range_with_value (NE_EXPR, vr, boolean_false_node,
04244 strict_overflow_p);
04245 }
04246
04247
04248 if (retval)
04249 return retval;
04250
04251
04252
04253 vr = get_value_range (cond);
04254 if (vr->type == VR_RANGE && vr->min == vr->max)
04255 return vr->min;
04256 }
04257 else
04258 {
04259 tree op0 = TREE_OPERAND (cond, 0);
04260 tree op1 = TREE_OPERAND (cond, 1);
04261
04262
04263 if (!INTEGRAL_TYPE_P (TREE_TYPE (op0))
04264 && !POINTER_TYPE_P (TREE_TYPE (op0)))
04265 return NULL_TREE;
04266
04267 if (use_equiv_p)
04268 {
04269 if (TREE_CODE (op0) == SSA_NAME && TREE_CODE (op1) == SSA_NAME)
04270 return compare_names (TREE_CODE (cond), op0, op1,
04271 strict_overflow_p);
04272 else if (TREE_CODE (op0) == SSA_NAME)
04273 return compare_name_with_value (TREE_CODE (cond), op0, op1,
04274 strict_overflow_p);
04275 else if (TREE_CODE (op1) == SSA_NAME)
04276 return (compare_name_with_value
04277 (swap_tree_comparison (TREE_CODE (cond)), op1, op0,
04278 strict_overflow_p));
04279 }
04280 else
04281 {
04282 value_range_t *vr0, *vr1;
04283
04284 vr0 = (TREE_CODE (op0) == SSA_NAME) ? get_value_range (op0) : NULL;
04285 vr1 = (TREE_CODE (op1) == SSA_NAME) ? get_value_range (op1) : NULL;
04286
04287 if (vr0 && vr1)
04288 return compare_ranges (TREE_CODE (cond), vr0, vr1,
04289 strict_overflow_p);
04290 else if (vr0 && vr1 == NULL)
04291 return compare_range_with_value (TREE_CODE (cond), vr0, op1,
04292 strict_overflow_p);
04293 else if (vr0 == NULL && vr1)
04294 return (compare_range_with_value
04295 (swap_tree_comparison (TREE_CODE (cond)), vr1, op0,
04296 strict_overflow_p));
04297 }
04298 }
04299
04300
04301 return NULL_TREE;
04302 }
04303
04304
04305
04306
04307
04308
04309
04310
04311 tree
04312 vrp_evaluate_conditional (tree cond, tree stmt)
04313 {
04314 bool sop;
04315 tree ret;
04316
04317 sop = false;
04318 ret = vrp_evaluate_conditional_warnv (cond, true, &sop);
04319
04320 if (ret && sop)
04321 {
04322 enum warn_strict_overflow_code wc;
04323 const char* warnmsg;
04324
04325 if (is_gimple_min_invariant (ret))
04326 {
04327 wc = WARN_STRICT_OVERFLOW_CONDITIONAL;
04328 warnmsg = G_("assuming signed overflow does not occur when "
04329 "simplifying conditional to constant");
04330 }
04331 else
04332 {
04333 wc = WARN_STRICT_OVERFLOW_COMPARISON;
04334 warnmsg = G_("assuming signed overflow does not occur when "
04335 "simplifying conditional");
04336 }
04337
04338 if (issue_strict_overflow_warning (wc))
04339 {
04340 location_t locus;
04341
04342 if (!EXPR_HAS_LOCATION (stmt))
04343 locus = input_location;
04344 else
04345 locus = EXPR_LOCATION (stmt);
04346 warning (OPT_Wstrict_overflow, "%H%s", &locus, warnmsg);
04347 }
04348 }
04349
04350 return ret;
04351 }
04352
04353
04354
04355
04356
04357
04358
04359 static enum ssa_prop_result
04360 vrp_visit_cond_stmt (tree stmt, edge *taken_edge_p)
04361 {
04362 tree cond, val;
04363 bool sop;
04364
04365 *taken_edge_p = NULL;
04366
04367
04368
04369 if (TREE_CODE (stmt) == SWITCH_EXPR)
04370 return SSA_PROP_VARYING;
04371
04372 cond = COND_EXPR_COND (stmt);
04373
04374 if (dump_file && (dump_flags & TDF_DETAILS))
04375 {
04376 tree use;
04377 ssa_op_iter i;
04378
04379 fprintf (dump_file, "\nVisiting conditional with predicate: ");
04380 print_generic_expr (dump_file, cond, 0);
04381 fprintf (dump_file, "\nWith known ranges\n");
04382
04383 FOR_EACH_SSA_TREE_OPERAND (use, stmt, i, SSA_OP_USE)
04384 {
04385 fprintf (dump_file, "\t");
04386 print_generic_expr (dump_file, use, 0);
04387 fprintf (dump_file, ": ");
04388 dump_value_range (dump_file, vr_value[SSA_NAME_VERSION (use)]);
04389 }
04390
04391 fprintf (dump_file, "\n");
04392 }
04393
04394
04395
04396
04397
04398
04399
04400
04401
04402
04403
04404
04405
04406
04407
04408
04409
04410
04411
04412
04413
04414
04415
04416
04417
04418
04419
04420
04421
04422
04423
04424
04425
04426
04427
04428
04429
04430
04431
04432
04433
04434
04435
04436 sop = false;
04437 val = vrp_evaluate_conditional_warnv (cond, false, &sop);
04438 if (val)
04439 {
04440 if (!sop)
04441 *taken_edge_p = find_taken_edge (bb_for_stmt (stmt), val);
04442 else
04443 {
04444 if (dump_file && (dump_flags & TDF_DETAILS))
04445 fprintf (dump_file,
04446 "\nIgnoring predicate evaluation because "
04447 "it assumes that signed overflow is undefined");
04448 val = NULL_TREE;
04449 }
04450 }
04451
04452 if (dump_file && (dump_flags & TDF_DETAILS))
04453 {
04454 fprintf (dump_file, "\nPredicate evaluates to: ");
04455 if (val == NULL_TREE)
04456 fprintf (dump_file, "DON'T KNOW\n");
04457 else
04458 print_generic_stmt (dump_file, val, 0);
04459 }
04460
04461 return (*taken_edge_p) ? SSA_PROP_INTERESTING : SSA_PROP_VARYING;
04462 }
04463
04464
04465
04466
04467
04468
04469
04470
04471
04472
04473
04474 static enum ssa_prop_result
04475 vrp_visit_stmt (tree stmt, edge *taken_edge_p, tree *output_p)
04476 {
04477 tree def;
04478 ssa_op_iter iter;
04479 stmt_ann_t ann;
04480
04481 if (dump_file && (dump_flags & TDF_DETAILS))
04482 {
04483 fprintf (dump_file, "\nVisiting statement:\n");
04484 print_generic_stmt (dump_file, stmt, dump_flags);
04485 fprintf (dump_file, "\n");
04486 }
04487
04488 ann = stmt_ann (stmt);
04489 if (TREE_CODE (stmt) == MODIFY_EXPR)
04490 {
04491 tree rhs = TREE_OPERAND (stmt, 1);
04492
04493
04494
04495
04496 if ((TREE_CODE (rhs) == CALL_EXPR
04497 && TREE_CODE (TREE_OPERAND (rhs, 0)) == ADDR_EXPR
04498 && DECL_P (TREE_OPERAND (TREE_OPERAND (rhs, 0), 0))
04499 && DECL_IS_BUILTIN (TREE_OPERAND (TREE_OPERAND (rhs, 0), 0)))
04500 || ZERO_SSA_OPERANDS (stmt, SSA_OP_ALL_VIRTUALS))
04501 return vrp_visit_assignment (stmt, output_p);
04502 }
04503 else if (TREE_CODE (stmt) == COND_EXPR || TREE_CODE (stmt) == SWITCH_EXPR)
04504 return vrp_visit_cond_stmt (stmt, taken_edge_p);
04505
04506
04507
04508 FOR_EACH_SSA_TREE_OPERAND (def, stmt, iter, SSA_OP_DEF)
04509 set_value_range_to_varying (get_value_range (def));
04510
04511 return SSA_PROP_VARYING;
04512 }
04513
04514
04515
04516
04517
04518
04519
04520
04521
04522
04523
04524
04525 static void
04526 vrp_meet (value_range_t *vr0, value_range_t *vr1)
04527 {
04528 if (vr0->type == VR_UNDEFINED)
04529 {
04530 copy_value_range (vr0, vr1);
04531 return;
04532 }
04533
04534 if (vr1->type == VR_UNDEFINED)
04535 {
04536
04537 return;
04538 }
04539
04540 if (vr0->type == VR_VARYING)
04541 {
04542
04543 return;
04544 }
04545
04546 if (vr1->type == VR_VARYING)
04547 {
04548 set_value_range_to_varying (vr0);
04549 return;
04550 }
04551
04552 if (vr0->type == VR_RANGE && vr1->type == VR_RANGE)
04553 {
04554
04555
04556 if (value_ranges_intersect_p (vr0, vr1))
04557 {
04558 int cmp;
04559 tree min, max;
04560
04561
04562
04563
04564 cmp = compare_values (vr0->min, vr1->min);
04565 if (cmp == 0 || cmp == 1)
04566 min = vr1->min;
04567 else if (cmp == -1)
04568 min = vr0->min;
04569 else
04570 {
04571 set_value_range_to_varying (vr0);
04572 return;
04573 }
04574
04575
04576
04577
04578 cmp = compare_values (vr0->max, vr1->max);
04579 if (cmp == 0 || cmp == -1)
04580 max = vr1->max;
04581 else if (cmp == 1)
04582 max = vr0->max;
04583 else
04584 {
04585 set_value_range_to_varying (vr0);
04586 return;
04587 }
04588
04589
04590 if (INTEGRAL_TYPE_P (TREE_TYPE (min))
04591 && ((vrp_val_is_min (min) || is_overflow_infinity (min))
04592 && (vrp_val_is_max (max) || is_overflow_infinity (max))))
04593 {
04594 set_value_range_to_varying (vr0);
04595 return;
04596 }
04597
04598
04599
04600 if (vr0->equiv && vr1->equiv && vr0->equiv != vr1->equiv)
04601 bitmap_and_into (vr0->equiv, vr1->equiv);
04602 else if (vr0->equiv && !vr1->equiv)
04603 bitmap_clear (vr0->equiv);
04604
04605 set_value_range (vr0, vr0->type, min, max, vr0->equiv);
04606 }
04607 else
04608 goto no_meet;
04609 }
04610 else if (vr0->type == VR_ANTI_RANGE && vr1->type == VR_ANTI_RANGE)
04611 {
04612
04613 if (compare_values (vr0->min, vr1->min) == 0
04614 && compare_values (vr0->max, vr1->max) == 0
04615 && compare_values (vr0->min, vr0->max) == 0)
04616 {
04617
04618
04619 if (vr0->equiv && vr1->equiv && vr0->equiv != vr1->equiv)
04620 bitmap_and_into (vr0->equiv, vr1->equiv);
04621 else if (vr0->equiv && !vr1->equiv)
04622 bitmap_clear (vr0->equiv);
04623 }
04624 else
04625 goto no_meet;
04626 }
04627 else if (vr0->type == VR_ANTI_RANGE || vr1->type == VR_ANTI_RANGE)
04628 {
04629
04630
04631
04632 if (!symbolic_range_p (vr0)
04633 && !symbolic_range_p (vr1)
04634 && !value_ranges_intersect_p (vr0, vr1))
04635 {
04636
04637
04638
04639 if (vr1->type == VR_ANTI_RANGE)
04640 set_value_range (vr0, vr1->type, vr1->min, vr1->max, vr0->equiv);
04641
04642
04643
04644 if (vr0->equiv && vr1->equiv && vr0->equiv != vr1->equiv)
04645 bitmap_and_into (vr0->equiv, vr1->equiv);
04646 else if (vr0->equiv && !vr1->equiv)
04647 bitmap_clear (vr0->equiv);
04648 }
04649 else
04650 goto no_meet;
04651 }
04652 else
04653 gcc_unreachable ();
04654
04655 return;
04656
04657 no_meet:
04658
04659
04660
04661
04662
04663 if (!symbolic_range_p (vr0)
04664 && ((vr0->type == VR_RANGE && !range_includes_zero_p (vr0))
04665 || (vr0->type == VR_ANTI_RANGE && range_includes_zero_p (vr0)))
04666 && !symbolic_range_p (vr1)
04667 && ((vr1->type == VR_RANGE && !range_includes_zero_p (vr1))
04668 || (vr1->type == VR_ANTI_RANGE && range_includes_zero_p (vr1))))
04669 {
04670 set_value_range_to_nonnull (vr0, TREE_TYPE (vr0->min));
04671
04672
04673
04674 if (vr0->equiv)
04675 bitmap_clear (vr0->equiv);
04676 }
04677 else
04678 set_value_range_to_varying (vr0);
04679 }
04680
04681
04682
04683
04684
04685
04686 static enum ssa_prop_result
04687 vrp_visit_phi_node (tree phi)
04688 {
04689 int i;
04690 tree lhs = PHI_RESULT (phi);
04691 value_range_t *lhs_vr = get_value_range (lhs);
04692 value_range_t vr_result = { VR_UNDEFINED, NULL_TREE, NULL_TREE, NULL };
04693
04694 copy_value_range (&vr_result, lhs_vr);
04695
04696 if (dump_file && (dump_flags & TDF_DETAILS))
04697 {
04698 fprintf (dump_file, "\nVisiting PHI node: ");
04699 print_generic_expr (dump_file, phi, dump_flags);
04700 }
04701
04702 for (i = 0; i < PHI_NUM_ARGS (phi); i++)
04703 {
04704 edge e = PHI_ARG_EDGE (phi, i);
04705
04706 if (dump_file && (dump_flags & TDF_DETAILS))
04707 {
04708 fprintf (dump_file,
04709 "\n Argument #%d (%d -> %d %sexecutable)\n",
04710 i, e->src->index, e->dest->index,
04711 (e->flags & EDGE_EXECUTABLE) ? "" : "not ");
04712 }
04713
04714 if (e->flags & EDGE_EXECUTABLE)
04715 {
04716 tree arg = PHI_ARG_DEF (phi, i);
04717 value_range_t vr_arg;
04718
04719 if (TREE_CODE (arg) == SSA_NAME)
04720 vr_arg = *(get_value_range (arg));
04721 else
04722 {
04723 if (is_overflow_infinity (arg))
04724 {
04725 arg = copy_node (arg);
04726 TREE_OVERFLOW (arg) = 0;
04727 }
04728
04729 vr_arg.type = VR_RANGE;
04730 vr_arg.min = arg;
04731 vr_arg.max = arg;
04732 vr_arg.equiv = NULL;
04733 }
04734
04735 if (dump_file && (dump_flags & TDF_DETAILS))
04736 {
04737 fprintf (dump_file, "\t");
04738 print_generic_expr (dump_file, arg, dump_flags);
04739 fprintf (dump_file, "\n\tValue: ");
04740 dump_value_range (dump_file, &vr_arg);
04741 fprintf (dump_file, "\n");
04742 }
04743
04744 vrp_meet (&vr_result, &vr_arg);
04745
04746 if (vr_result.type == VR_VARYING)
04747 break;
04748 }
04749 }
04750
04751 if (vr_result.type == VR_VARYING)
04752 goto varying;
04753
04754
04755
04756
04757 if (lhs_vr->type == VR_RANGE && vr_result.type == VR_RANGE)
04758 {
04759 if (!POINTER_TYPE_P (TREE_TYPE (lhs)))
04760 {
04761 int cmp_min = compare_values (lhs_vr->min, vr_result.min);
04762 int cmp_max = compare_values (lhs_vr->max, vr_result.max);
04763
04764
04765
04766
04767
04768
04769 if (cmp_min > 0 || cmp_min < 0)
04770 {
04771
04772
04773 if (vrp_val_is_max (vr_result.max))
04774 goto varying;
04775
04776 if (!needs_overflow_infinity (TREE_TYPE (vr_result.min)))
04777 vr_result.min = TYPE_MIN_VALUE (TREE_TYPE (vr_result.min));
04778 else if (supports_overflow_infinity (TREE_TYPE (vr_result.min)))
04779 vr_result.min =
04780 negative_overflow_infinity (TREE_TYPE (vr_result.min));
04781 else
04782 goto varying;
04783 }
04784
04785
04786
04787 if (cmp_max < 0 || cmp_max > 0)
04788 {
04789
04790
04791 if (vrp_val_is_min (vr_result.min))
04792 goto varying;
04793
04794 if (!needs_overflow_infinity (TREE_TYPE (vr_result.max)))
04795 vr_result.max = TYPE_MAX_VALUE (TREE_TYPE (vr_result.max));
04796 else if (supports_overflow_infinity (TREE_TYPE (vr_result.max)))
04797 vr_result.max =
04798 positive_overflow_infinity (TREE_TYPE (vr_result.max));
04799 else
04800 goto varying;
04801 }
04802 }
04803 }
04804
04805
04806
04807 if (update_value_range (lhs, &vr_result))
04808 return SSA_PROP_INTERESTING;
04809
04810
04811 return SSA_PROP_NOT_INTERESTING;
04812
04813
04814 varying:
04815 set_value_range_to_varying (lhs_vr);
04816 return SSA_PROP_VARYING;
04817 }
04818
04819
04820
04821
04822
04823 static void
04824 simplify_div_or_mod_using_ranges (tree stmt, tree rhs, enum tree_code rhs_code)
04825 {
04826 tree val = NULL;
04827 tree op = TREE_OPERAND (rhs, 0);
04828 value_range_t *vr = get_value_range (TREE_OPERAND (rhs, 0));
04829
04830 if (TYPE_UNSIGNED (TREE_TYPE (op)))
04831 {
04832 val = integer_one_node;
04833 }
04834 else
04835 {
04836 bool sop = false;
04837
04838 val = compare_range_with_value (GT_EXPR, vr, integer_zero_node, &sop);
04839
04840 if (val
04841 && sop
04842 && integer_onep (val)
04843 && issue_strict_overflow_warning (WARN_STRICT_OVERFLOW_MISC))
04844 {
04845 location_t locus;
04846
04847 if (!EXPR_HAS_LOCATION (stmt))
04848 locus = input_location;
04849 else
04850 locus = EXPR_LOCATION (stmt);
04851 warning (OPT_Wstrict_overflow,
04852 ("%Hassuming signed overflow does not occur when "
04853 "simplifying / or %% to >> or &"),
04854 &locus);
04855 }
04856 }
04857
04858 if (val && integer_onep (val))
04859 {
04860 tree t;
04861 tree op0 = TREE_OPERAND (rhs, 0);
04862 tree op1 = TREE_OPERAND (rhs, 1);
04863
04864 if (rhs_code == TRUNC_DIV_EXPR)
04865 {
04866 t = build_int_cst (NULL_TREE, tree_log2 (op1));
04867 t = build2 (RSHIFT_EXPR, TREE_TYPE (op0), op0, t);
04868 }
04869 else
04870 {
04871 t = build_int_cst (TREE_TYPE (op1), 1);
04872 t = int_const_binop (MINUS_EXPR, op1, t, 0);
04873 t = fold_convert (TREE_TYPE (op0), t);
04874 t = build2 (BIT_AND_EXPR, TREE_TYPE (op0), op0, t);
04875 }
04876
04877 TREE_OPERAND (stmt, 1) = t;
04878 update_stmt (stmt);
04879 }
04880 }
04881
04882
04883
04884
04885
04886 static void
04887 simplify_abs_using_ranges (tree stmt, tree rhs)
04888 {
04889 tree val = NULL;
04890 tree op = TREE_OPERAND (rhs, 0);
04891 tree type = TREE_TYPE (op);
04892 value_range_t *vr = get_value_range (TREE_OPERAND (rhs, 0));
04893
04894 if (TYPE_UNSIGNED (type))
04895 {
04896 val = integer_zero_node;
04897 }
04898 else if (vr)
04899 {
04900 bool sop = false;
04901
04902 val = compare_range_with_value (LE_EXPR, vr, integer_zero_node, &sop);
04903 if (!val)
04904 {
04905 sop = false;
04906 val = compare_range_with_value (GE_EXPR, vr, integer_zero_node,
04907 &sop);
04908
04909 if (val)
04910 {
04911 if (integer_zerop (val))
04912 val = integer_one_node;
04913 else if (integer_onep (val))
04914 val = integer_zero_node;
04915 }
04916 }
04917
04918 if (val
04919 && (integer_onep (val) || integer_zerop (val)))
04920 {
04921 tree t;
04922
04923 if (sop && issue_strict_overflow_warning (WARN_STRICT_OVERFLOW_MISC))
04924 {
04925 location_t locus;
04926
04927 if (!EXPR_HAS_LOCATION (stmt))
04928 locus = input_location;
04929 else
04930 locus = EXPR_LOCATION (stmt);
04931 warning (OPT_Wstrict_overflow,
04932 ("%Hassuming signed overflow does not occur when "
04933 "simplifying abs (X) to X or -X"),
04934 &locus);
04935 }
04936
04937 if (integer_onep (val))
04938 t = build1 (NEGATE_EXPR, TREE_TYPE (op), op);
04939 else
04940 t = op;
04941
04942 TREE_OPERAND (stmt, 1) = t;
04943 update_stmt (stmt);
04944 }
04945 }
04946 }
04947
04948
04949
04950
04951
04952
04953
04954 static tree
04955 test_for_singularity (enum tree_code cond_code, tree op0,
04956 tree op1, value_range_t *vr)
04957 {
04958 tree min = NULL;
04959 tree max = NULL;
04960
04961
04962
04963 if (cond_code == LE_EXPR || cond_code == LT_EXPR)
04964 {
04965
04966
04967 min = TYPE_MIN_VALUE (TREE_TYPE (op0));
04968
04969 max = op1;
04970 if (cond_code == LT_EXPR && !is_overflow_infinity (max))
04971 {
04972 tree one = build_int_cst (TREE_TYPE (op0), 1);
04973 max = fold_build2 (MINUS_EXPR, TREE_TYPE (op0), max, one);
04974 }
04975 }
04976 else if (cond_code == GE_EXPR || cond_code == GT_EXPR)
04977 {
04978
04979
04980 max = TYPE_MAX_VALUE (TREE_TYPE (op0));
04981
04982 min = op1;
04983 if (cond_code == GT_EXPR && !is_overflow_infinity (min))
04984 {
04985 tree one = build_int_cst (TREE_TYPE (op0), 1);
04986 min = fold_build2 (PLUS_EXPR, TREE_TYPE (op0), min, one);
04987 }
04988 }
04989
04990
04991
04992 if (min && max)
04993 {
04994 if (compare_values (vr->min, min) == -1)
04995 min = min;
04996 else
04997 min = vr->min;
04998 if (compare_values (vr->max, max) == 1)
04999 max = max;
05000 else
05001 max = vr->max;
05002
05003
05004
05005
05006 if (operand_equal_p (min, max, 0) && is_gimple_min_invariant (min))
05007 return min;
05008 }
05009 return NULL;
05010 }
05011
05012
05013
05014
05015
05016 static void
05017 simplify_cond_using_ranges (tree stmt)
05018 {
05019 tree cond = COND_EXPR_COND (stmt);
05020 tree op0 = TREE_OPERAND (cond, 0);
05021 tree op1 = TREE_OPERAND (cond, 1);
05022 enum tree_code cond_code = TREE_CODE (cond);
05023
05024 if (cond_code != NE_EXPR
05025 && cond_code != EQ_EXPR
05026 && TREE_CODE (op0) == SSA_NAME
05027 && INTEGRAL_TYPE_P (TREE_TYPE (op0))
05028 && is_gimple_min_invariant (op1))
05029 {
05030 value_range_t *vr = get_value_range (op0);
05031
05032
05033
05034 if (vr->type == VR_RANGE)
05035 {
05036 tree new = test_for_singularity (cond_code, op0, op1, vr);
05037
05038 if (new)
05039 {
05040 if (dump_file)
05041 {
05042 fprintf (dump_file, "Simplified relational ");
05043 print_generic_expr (dump_file, cond, 0);
05044 fprintf (dump_file, " into ");
05045 }
05046
05047 COND_EXPR_COND (stmt)
05048 = build2 (EQ_EXPR, boolean_type_node, op0, new);
05049 update_stmt (stmt);
05050
05051 if (dump_file)
05052 {
05053 print_generic_expr (dump_file, COND_EXPR_COND (stmt), 0);
05054 fprintf (dump_file, "\n");
05055 }
05056 return;
05057
05058 }
05059
05060
05061
05062
05063 cond_code = invert_tree_comparison (cond_code, false);
05064 new = test_for_singularity (cond_code, op0, op1, vr);
05065
05066 if (new)
05067 {
05068 if (dump_file)
05069 {
05070 fprintf (dump_file, "Simplified relational ");
05071 print_generic_expr (dump_file, cond, 0);
05072 fprintf (dump_file, " into ");
05073 }
05074
05075 COND_EXPR_COND (stmt)
05076 = build2 (NE_EXPR, boolean_type_node, op0, new);
05077 update_stmt (stmt);
05078
05079 if (dump_file)
05080 {
05081 print_generic_expr (dump_file, COND_EXPR_COND (stmt), 0);
05082 fprintf (dump_file, "\n");
05083 }
05084 return;
05085
05086 }
05087 }
05088 }
05089 }
05090
05091
05092
05093 void
05094 simplify_stmt_using_ranges (tree stmt)
05095 {
05096 if (TREE_CODE (stmt) == MODIFY_EXPR)
05097 {
05098 tree rhs = TREE_OPERAND (stmt, 1);
05099 enum tree_code rhs_code = TREE_CODE (rhs);
05100
05101
05102
05103
05104 if ((rhs_code == TRUNC_DIV_EXPR || rhs_code == TRUNC_MOD_EXPR)
05105 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (rhs, 0)))
05106 && integer_pow2p (TREE_OPERAND (rhs, 1)))
05107 simplify_div_or_mod_using_ranges (stmt, rhs, rhs_code);
05108
05109
05110 if (rhs_code == ABS_EXPR
05111 && TREE_CODE (TREE_OPERAND (rhs, 0)) == SSA_NAME
05112 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (rhs, 0))))
05113 simplify_abs_using_ranges (stmt, rhs);
05114 }
05115 else if (TREE_CODE (stmt) == COND_EXPR
05116 && COMPARISON_CLASS_P (COND_EXPR_COND (stmt)))
05117 {
05118 simplify_cond_using_ranges (stmt);
05119 }
05120 }
05121
05122
05123
05124
05125
05126
05127 static VEC(tree,heap) *stack;
05128
05129
05130
05131
05132
05133
05134 static tree
05135 simplify_stmt_for_jump_threading (tree stmt, tree within_stmt)
05136 {
05137
05138
05139
05140 if (TREE_CODE (stmt) != COND_EXPR)
05141 return NULL;
05142
05143 return vrp_evaluate_conditional (COND_EXPR_COND (stmt), within_stmt);
05144 }
05145
05146
05147
05148
05149
05150
05151
05152
05153
05154
05155
05156
05157
05158
05159
05160
05161
05162
05163
05164
05165
05166 static void
05167 identify_jump_threads (void)
05168 {
05169 basic_block bb;
05170 tree dummy;
05171
05172
05173
05174
05175 calculate_dominance_info (CDI_DOMINATORS);
05176
05177
05178
05179
05180
05181
05182 mark_dfs_back_edges ();
05183
05184
05185
05186 stack = VEC_alloc (tree, heap, 20);
05187
05188
05189
05190
05191 dummy = build2 (EQ_EXPR, boolean_type_node, NULL, NULL);
05192 dummy = build3 (COND_EXPR, void_type_node, dummy, NULL, NULL);
05193
05194
05195
05196
05197
05198
05199
05200 FOR_EACH_BB (bb)
05201 {
05202 tree last, cond;
05203
05204
05205
05206 if (! potentially_threadable_block (bb))
05207 continue;
05208
05209
05210
05211
05212 last = bsi_stmt (bsi_last (bb));
05213 if (TREE_CODE (last) != COND_EXPR)
05214 continue;
05215
05216
05217
05218 cond = COND_EXPR_COND (last);
05219 if ((TREE_CODE (cond) == SSA_NAME
05220 && INTEGRAL_TYPE_P (TREE_TYPE (cond)))
05221 || (COMPARISON_CLASS_P (cond)
05222 && TREE_CODE (TREE_OPERAND (cond, 0)) == SSA_NAME
05223 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (cond, 0)))
05224 && (TREE_CODE (TREE_OPERAND (cond, 1)) == SSA_NAME
05225 || is_gimple_min_invariant (TREE_OPERAND (cond, 1)))
05226 && INTEGRAL_TYPE_P (TREE_TYPE (TREE_OPERAND (cond, 1)))))
05227 {
05228 edge_iterator ei;
05229 edge e;
05230
05231
05232
05233
05234
05235 FOR_EACH_EDGE (e, ei, bb->preds)
05236 {
05237
05238
05239 if (e->flags & (EDGE_DFS_BACK | EDGE_COMPLEX))
05240 continue;
05241
05242 thread_across_edge (dummy, e, true,
05243 &stack,
05244 simplify_stmt_for_jump_threading);
05245 }
05246 }
05247 }
05248
05249
05250
05251
05252 }
05253
05254
05255
05256
05257
05258
05259
05260 static void
05261 finalize_jump_threads (void)
05262 {
05263 bool cfg_altered = false;
05264 cfg_altered = thread_through_all_blocks ();
05265
05266
05267
05268 if (cfg_altered)
05269 {
05270 free_dominance_info (CDI_DOMINATORS);
05271 cleanup_tree_cfg ();
05272 calculate_dominance_info (CDI_DOMINATORS);
05273 }
05274 VEC_free (tree, heap, stack);
05275 }
05276
05277
05278
05279
05280 static void
05281 vrp_finalize (void)
05282 {
05283 size_t i;
05284 prop_value_t *single_val_range;
05285 bool do_value_subst_p;
05286
05287 if (dump_file)
05288 {
05289 fprintf (dump_file, "\nValue ranges after VRP:\n\n");
05290 dump_all_value_ranges (dump_file);
05291 fprintf (dump_file, "\n");
05292 }
05293
05294
05295
05296
05297 single_val_range = XNEWVEC (prop_value_t, num_ssa_names);
05298 memset (single_val_range, 0, num_ssa_names * sizeof (*single_val_range));
05299
05300 do_value_subst_p = false;
05301 for (i = 0; i < num_ssa_names; i++)
05302 if (vr_value[i]
05303 && vr_value[i]->type == VR_RANGE
05304 && vr_value[i]->min == vr_value[i]->max)
05305 {
05306 single_val_range[i].value = vr_value[i]->min;
05307 do_value_subst_p = true;
05308 }
05309
05310 if (!do_value_subst_p)
05311 {
05312
05313
05314 free (single_val_range);
05315 single_val_range = NULL;
05316 }
05317
05318 substitute_and_fold (single_val_range, true);
05319
05320
05321
05322 identify_jump_threads ();
05323
05324
05325 for (i = 0; i < num_ssa_names; i++)
05326 if (vr_value[i])
05327 {
05328 BITMAP_FREE (vr_value[i]->equiv);
05329 free (vr_value[i]);
05330 }
05331
05332 free (single_val_range);
05333 free (vr_value);
05334
05335
05336
05337 vr_value = NULL;
05338 }
05339
05340
05341
05342
05343
05344
05345
05346
05347
05348
05349
05350
05351
05352
05353
05354
05355
05356
05357
05358
05359
05360
05361
05362
05363
05364
05365
05366
05367
05368
05369
05370
05371
05372
05373
05374
05375
05376
05377
05378
05379
05380
05381
05382
05383
05384
05385 static unsigned int
05386 execute_vrp (void)
05387 {
05388 insert_range_assertions ();
05389
05390 current_loops = loop_optimizer_init (LOOPS_NORMAL);
05391 if (current_loops)
05392 scev_initialize (current_loops);
05393
05394 vrp_initialize ();
05395 ssa_propagate (vrp_visit_stmt, vrp_visit_phi_node);
05396 vrp_finalize ();
05397
05398 if (current_loops)
05399 {
05400 scev_finalize ();
05401 loop_optimizer_finalize (current_loops);
05402 current_loops = NULL;
05403 }
05404
05405
05406
05407
05408 remove_range_assertions ();
05409
05410
05411
05412
05413
05414
05415 update_ssa (TODO_update_ssa);
05416
05417 finalize_jump_threads ();
05418 return 0;
05419 }
05420
05421 static bool
05422 gate_vrp (void)
05423 {
05424 return flag_tree_vrp != 0;
05425 }
05426
05427 struct tree_opt_pass pass_vrp =
05428 {
05429 "vrp",
05430 gate_vrp,
05431 execute_vrp,
05432 NULL,
05433 NULL,
05434 0,
05435 TV_TREE_VRP,
05436 PROP_ssa | PROP_alias,
05437 0,
05438 PROP_smt_usage,
05439 0,
05440 TODO_cleanup_cfg
05441 | TODO_ggc_collect
05442 | TODO_verify_ssa
05443 | TODO_dump_func
05444 | TODO_update_ssa
05445 | TODO_update_smt_usage,
05446 0
05447 };