Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(124)

Side by Side Diff: runtime/vm/intermediate_language.cc

Issue 321593004: Refactor RangeBoundary +/- infinity to be distinct RangeBoundary kinds. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/intermediate_language.h" 5 #include "vm/intermediate_language.h"
6 6
7 #include "vm/bigint_operations.h" 7 #include "vm/bigint_operations.h"
8 #include "vm/bit_vector.h" 8 #include "vm/bit_vector.h"
9 #include "vm/cpu.h" 9 #include "vm/cpu.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 1215 matching lines...) Expand 10 before | Expand all | Expand 10 after
1226 return true; 1226 return true;
1227 } 1227 }
1228 switch (op_kind()) { 1228 switch (op_kind()) {
1229 case Token::kBIT_AND: 1229 case Token::kBIT_AND:
1230 case Token::kBIT_OR: 1230 case Token::kBIT_OR:
1231 case Token::kBIT_XOR: 1231 case Token::kBIT_XOR:
1232 return false; 1232 return false;
1233 case Token::kSHR: { 1233 case Token::kSHR: {
1234 // Can't deopt if shift-count is known positive. 1234 // Can't deopt if shift-count is known positive.
1235 Range* right_range = this->right()->definition()->range(); 1235 Range* right_range = this->right()->definition()->range();
1236 return (right_range == NULL) 1236 return (right_range == NULL) || right_range->IsNegative();
1237 || !right_range->IsWithin(0, RangeBoundary::kPlusInfinity);
1238 } 1237 }
1239 case Token::kSHL: { 1238 case Token::kSHL: {
1240 Range* right_range = this->right()->definition()->range(); 1239 Range* right_range = this->right()->definition()->range();
1241 if ((right_range != NULL) && is_truncating()) { 1240 if ((right_range != NULL) && is_truncating()) {
1242 // Can deoptimize if right can be negative. 1241 // Can deoptimize if right can be negative.
1243 return !right_range->IsWithin(0, RangeBoundary::kPlusInfinity); 1242 return right_range->IsNegative();
1244 } 1243 }
1245 return true; 1244 return true;
1246 } 1245 }
1247 case Token::kMOD: { 1246 case Token::kMOD: {
1248 Range* right_range = this->right()->definition()->range(); 1247 Range* right_range = this->right()->definition()->range();
1249 return (right_range == NULL) || right_range->Overlaps(0, 0); 1248 return (right_range == NULL) || right_range->Overlaps(0, 0);
1250 } 1249 }
1251 default: 1250 default:
1252 return overflow_; 1251 return overflow_;
1253 } 1252 }
(...skipping 1204 matching lines...) Expand 10 before | Expand all | Expand 10 after
2458 2457
2459 RangeBoundary RangeBoundary::FromDefinition(Definition* defn, intptr_t offs) { 2458 RangeBoundary RangeBoundary::FromDefinition(Definition* defn, intptr_t offs) {
2460 if (defn->IsConstant() && defn->AsConstant()->value().IsSmi()) { 2459 if (defn->IsConstant() && defn->AsConstant()->value().IsSmi()) {
2461 return FromConstant(Smi::Cast(defn->AsConstant()->value()).Value() + offs); 2460 return FromConstant(Smi::Cast(defn->AsConstant()->value()).Value() + offs);
2462 } 2461 }
2463 return RangeBoundary(kSymbol, reinterpret_cast<intptr_t>(defn), offs); 2462 return RangeBoundary(kSymbol, reinterpret_cast<intptr_t>(defn), offs);
2464 } 2463 }
2465 2464
2466 2465
2467 RangeBoundary RangeBoundary::LowerBound() const { 2466 RangeBoundary RangeBoundary::LowerBound() const {
2467 if (IsNegativeInfinity()) return *this;
2468 if (IsConstant()) return *this; 2468 if (IsConstant()) return *this;
2469 return Add(Range::ConstantMin(symbol()->range()), 2469 return Add(Range::ConstantMin(symbol()->range()),
2470 RangeBoundary::FromConstant(offset_), 2470 RangeBoundary::FromConstant(offset_),
2471 OverflowedMinSmi()); 2471 NegativeInfinity());
2472 } 2472 }
2473 2473
2474 2474
2475 RangeBoundary RangeBoundary::UpperBound() const { 2475 RangeBoundary RangeBoundary::UpperBound() const {
2476 if (IsPositiveInfinity()) return *this;
2476 if (IsConstant()) return *this; 2477 if (IsConstant()) return *this;
2477 return Add(Range::ConstantMax(symbol()->range()), 2478 return Add(Range::ConstantMax(symbol()->range()),
2478 RangeBoundary::FromConstant(offset_), 2479 RangeBoundary::FromConstant(offset_),
2479 OverflowedMaxSmi()); 2480 PositiveInfinity());
2480 } 2481 }
2481 2482
2482 2483
2483 static Definition* UnwrapConstraint(Definition* defn) { 2484 static Definition* UnwrapConstraint(Definition* defn) {
2484 while (defn->IsConstraint()) { 2485 while (defn->IsConstraint()) {
2485 defn = defn->AsConstraint()->value()->definition(); 2486 defn = defn->AsConstraint()->value()->definition();
2486 } 2487 }
2487 return defn; 2488 return defn;
2488 } 2489 }
2489 2490
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
2530 } else if (a.IsSymbol() && b.IsSymbol()) { 2531 } else if (a.IsSymbol() && b.IsSymbol()) {
2531 return (a.offset() == b.offset()) && DependOnSameSymbol(a, b); 2532 return (a.offset() == b.offset()) && DependOnSameSymbol(a, b);
2532 } else { 2533 } else {
2533 return false; 2534 return false;
2534 } 2535 }
2535 } 2536 }
2536 2537
2537 2538
2538 static RangeBoundary CanonicalizeBoundary(const RangeBoundary& a, 2539 static RangeBoundary CanonicalizeBoundary(const RangeBoundary& a,
2539 const RangeBoundary& overflow) { 2540 const RangeBoundary& overflow) {
2540 if (a.IsConstant()) return a; 2541 if (a.IsConstant() || a.IsNegativeInfinity() || a.IsPositiveInfinity()) {
2542 return a;
2543 }
2541 2544
2542 intptr_t offset = a.offset(); 2545 intptr_t offset = a.offset();
2543 Definition* symbol = a.symbol(); 2546 Definition* symbol = a.symbol();
2544 2547
2545 bool changed; 2548 bool changed;
2546 do { 2549 do {
2547 changed = false; 2550 changed = false;
2548 if (symbol->IsConstraint()) { 2551 if (symbol->IsConstraint()) {
2549 symbol = symbol->AsConstraint()->value()->definition(); 2552 symbol = symbol->AsConstraint()->value()->definition();
2550 changed = true; 2553 changed = true;
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2587 2590
2588 static bool CanonicalizeMaxBoundary(RangeBoundary* a) { 2591 static bool CanonicalizeMaxBoundary(RangeBoundary* a) {
2589 if (!a->IsSymbol()) return false; 2592 if (!a->IsSymbol()) return false;
2590 2593
2591 Range* range = a->symbol()->range(); 2594 Range* range = a->symbol()->range();
2592 if ((range == NULL) || !range->max().IsSymbol()) return false; 2595 if ((range == NULL) || !range->max().IsSymbol()) return false;
2593 2596
2594 const intptr_t offset = range->max().offset() + a->offset(); 2597 const intptr_t offset = range->max().offset() + a->offset();
2595 2598
2596 if (!Smi::IsValid(offset)) { 2599 if (!Smi::IsValid(offset)) {
2597 *a = RangeBoundary::OverflowedMaxSmi(); 2600 *a = RangeBoundary::PositiveInfinity();
2598 return true; 2601 return true;
2599 } 2602 }
2600 2603
2601 *a = CanonicalizeBoundary( 2604 *a = CanonicalizeBoundary(
2602 RangeBoundary::FromDefinition(range->max().symbol(), offset), 2605 RangeBoundary::FromDefinition(range->max().symbol(), offset),
2603 RangeBoundary::OverflowedMaxSmi()); 2606 RangeBoundary::PositiveInfinity());
2604 2607
2605 return true; 2608 return true;
2606 } 2609 }
2607 2610
2608 2611
2609 static bool CanonicalizeMinBoundary(RangeBoundary* a) { 2612 static bool CanonicalizeMinBoundary(RangeBoundary* a) {
2610 if (!a->IsSymbol()) return false; 2613 if (!a->IsSymbol()) return false;
2611 2614
2612 Range* range = a->symbol()->range(); 2615 Range* range = a->symbol()->range();
2613 if ((range == NULL) || !range->min().IsSymbol()) return false; 2616 if ((range == NULL) || !range->min().IsSymbol()) return false;
2614 2617
2615 const intptr_t offset = range->min().offset() + a->offset(); 2618 const intptr_t offset = range->min().offset() + a->offset();
2616 if (!Smi::IsValid(offset)) { 2619 if (!Smi::IsValid(offset)) {
2617 *a = RangeBoundary::OverflowedMinSmi(); 2620 *a = RangeBoundary::NegativeInfinity();
2618 return true; 2621 return true;
2619 } 2622 }
2620 2623
2621 *a = CanonicalizeBoundary( 2624 *a = CanonicalizeBoundary(
2622 RangeBoundary::FromDefinition(range->min().symbol(), offset), 2625 RangeBoundary::FromDefinition(range->min().symbol(), offset),
2623 RangeBoundary::OverflowedMinSmi()); 2626 RangeBoundary::NegativeInfinity());
2624 2627
2625 return true; 2628 return true;
2626 } 2629 }
2627 2630
2628 2631
2629 RangeBoundary RangeBoundary::Min(RangeBoundary a, RangeBoundary b) { 2632 RangeBoundary RangeBoundary::Min(RangeBoundary a, RangeBoundary b) {
2630 if (DependOnSameSymbol(a, b)) { 2633 if (DependOnSameSymbol(a, b)) {
2631 return (a.offset() <= b.offset()) ? a : b; 2634 return (a.offset() <= b.offset()) ? a : b;
2632 } 2635 }
2633 2636
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
2678 min = constraint()->min(); 2681 min = constraint()->min();
2679 } else if (IsMinSmi(constraint()) && !IsMinSmi(value_range)) { 2682 } else if (IsMinSmi(constraint()) && !IsMinSmi(value_range)) {
2680 min = value_range->min(); 2683 min = value_range->min();
2681 } else if ((value_range != NULL) && 2684 } else if ((value_range != NULL) &&
2682 IsEqual(constraint()->min(), value_range->min())) { 2685 IsEqual(constraint()->min(), value_range->min())) {
2683 min = constraint()->min(); 2686 min = constraint()->min();
2684 } else { 2687 } else {
2685 if (value_range != NULL) { 2688 if (value_range != NULL) {
2686 RangeBoundary canonical_a = 2689 RangeBoundary canonical_a =
2687 CanonicalizeBoundary(constraint()->min(), 2690 CanonicalizeBoundary(constraint()->min(),
2688 RangeBoundary::OverflowedMinSmi()); 2691 RangeBoundary::NegativeInfinity());
2689 RangeBoundary canonical_b = 2692 RangeBoundary canonical_b =
2690 CanonicalizeBoundary(value_range->min(), 2693 CanonicalizeBoundary(value_range->min(),
2691 RangeBoundary::OverflowedMinSmi()); 2694 RangeBoundary::NegativeInfinity());
2692 2695
2693 do { 2696 do {
2694 if (DependOnSameSymbol(canonical_a, canonical_b)) { 2697 if (DependOnSameSymbol(canonical_a, canonical_b)) {
2695 min = (canonical_a.offset() <= canonical_b.offset()) ? canonical_b 2698 min = (canonical_a.offset() <= canonical_b.offset()) ? canonical_b
2696 : canonical_a; 2699 : canonical_a;
2697 } 2700 }
2698 } while (CanonicalizeMinBoundary(&canonical_a) || 2701 } while (CanonicalizeMinBoundary(&canonical_a) ||
2699 CanonicalizeMinBoundary(&canonical_b)); 2702 CanonicalizeMinBoundary(&canonical_b));
2700 } 2703 }
2701 2704
2702 if (min.IsUnknown()) { 2705 if (min.IsUnknown()) {
2703 min = RangeBoundary::Max(Range::ConstantMin(value_range), 2706 min = RangeBoundary::Max(Range::ConstantMin(value_range),
2704 Range::ConstantMin(constraint())); 2707 Range::ConstantMin(constraint()));
2705 } 2708 }
2706 } 2709 }
2707 2710
2708 if (IsMaxSmi(value_range) && !IsMaxSmi(constraint())) { 2711 if (IsMaxSmi(value_range) && !IsMaxSmi(constraint())) {
2709 max = constraint()->max(); 2712 max = constraint()->max();
2710 } else if (IsMaxSmi(constraint()) && !IsMaxSmi(value_range)) { 2713 } else if (IsMaxSmi(constraint()) && !IsMaxSmi(value_range)) {
2711 max = value_range->max(); 2714 max = value_range->max();
2712 } else if ((value_range != NULL) && 2715 } else if ((value_range != NULL) &&
2713 IsEqual(constraint()->max(), value_range->max())) { 2716 IsEqual(constraint()->max(), value_range->max())) {
2714 max = constraint()->max(); 2717 max = constraint()->max();
2715 } else { 2718 } else {
2716 if (value_range != NULL) { 2719 if (value_range != NULL) {
2717 RangeBoundary canonical_b = 2720 RangeBoundary canonical_b =
2718 CanonicalizeBoundary(value_range->max(), 2721 CanonicalizeBoundary(value_range->max(),
2719 RangeBoundary::OverflowedMaxSmi()); 2722 RangeBoundary::PositiveInfinity());
2720 RangeBoundary canonical_a = 2723 RangeBoundary canonical_a =
2721 CanonicalizeBoundary(constraint()->max(), 2724 CanonicalizeBoundary(constraint()->max(),
2722 RangeBoundary::OverflowedMaxSmi()); 2725 RangeBoundary::PositiveInfinity());
2723 2726
2724 do { 2727 do {
2725 if (DependOnSameSymbol(canonical_a, canonical_b)) { 2728 if (DependOnSameSymbol(canonical_a, canonical_b)) {
2726 max = (canonical_a.offset() <= canonical_b.offset()) ? canonical_a 2729 max = (canonical_a.offset() <= canonical_b.offset()) ? canonical_a
2727 : canonical_b; 2730 : canonical_b;
2728 break; 2731 break;
2729 } 2732 }
2730 } while (CanonicalizeMaxBoundary(&canonical_a) || 2733 } while (CanonicalizeMaxBoundary(&canonical_a) ||
2731 CanonicalizeMaxBoundary(&canonical_b)); 2734 CanonicalizeMaxBoundary(&canonical_b));
2732 } 2735 }
(...skipping 320 matching lines...) Expand 10 before | Expand all | Expand 10 after
3053 RangeBoundary::FromDefinition(left_defn) : left_range->max(); 3056 RangeBoundary::FromDefinition(left_defn) : left_range->max();
3054 3057
3055 RangeBoundary min; 3058 RangeBoundary min;
3056 RangeBoundary max; 3059 RangeBoundary max;
3057 switch (op_kind()) { 3060 switch (op_kind()) {
3058 case Token::kADD: 3061 case Token::kADD:
3059 if (!SymbolicAdd(left_min, right_range->min(), &min)) { 3062 if (!SymbolicAdd(left_min, right_range->min(), &min)) {
3060 min = 3063 min =
3061 RangeBoundary::Add(Range::ConstantMin(left_range), 3064 RangeBoundary::Add(Range::ConstantMin(left_range),
3062 Range::ConstantMin(right_range), 3065 Range::ConstantMin(right_range),
3063 RangeBoundary::OverflowedMinSmi()); 3066 RangeBoundary::NegativeInfinity());
3064 } 3067 }
3065 3068
3066 if (!SymbolicAdd(left_max, right_range->max(), &max)) { 3069 if (!SymbolicAdd(left_max, right_range->max(), &max)) {
3067 max = 3070 max =
3068 RangeBoundary::Add(Range::ConstantMax(right_range), 3071 RangeBoundary::Add(Range::ConstantMax(right_range),
3069 Range::ConstantMax(left_range), 3072 Range::ConstantMax(left_range),
3070 RangeBoundary::OverflowedMaxSmi()); 3073 RangeBoundary::PositiveInfinity());
3071 } 3074 }
3072 break; 3075 break;
3073 3076
3074 case Token::kSUB: 3077 case Token::kSUB:
3075 if (!SymbolicSub(left_min, right_range->max(), &min)) { 3078 if (!SymbolicSub(left_min, right_range->max(), &min)) {
3076 min = 3079 min =
3077 RangeBoundary::Sub(Range::ConstantMin(left_range), 3080 RangeBoundary::Sub(Range::ConstantMin(left_range),
3078 Range::ConstantMax(right_range), 3081 Range::ConstantMax(right_range),
3079 RangeBoundary::OverflowedMinSmi()); 3082 RangeBoundary::NegativeInfinity());
3080 } 3083 }
3081 3084
3082 if (!SymbolicSub(left_max, right_range->min(), &max)) { 3085 if (!SymbolicSub(left_max, right_range->min(), &max)) {
3083 max = 3086 max =
3084 RangeBoundary::Sub(Range::ConstantMax(left_range), 3087 RangeBoundary::Sub(Range::ConstantMax(left_range),
3085 Range::ConstantMin(right_range), 3088 Range::ConstantMin(right_range),
3086 RangeBoundary::OverflowedMaxSmi()); 3089 RangeBoundary::PositiveInfinity());
3087 } 3090 }
3088 break; 3091 break;
3089 3092
3090 case Token::kMUL: { 3093 case Token::kMUL: {
3091 const int64_t left_max = ConstantAbsMax(left_range); 3094 const int64_t left_max = ConstantAbsMax(left_range);
3092 const int64_t right_max = ConstantAbsMax(right_range); 3095 const int64_t right_max = ConstantAbsMax(right_range);
3093 if ((left_max < 0x7FFFFFFF) && (right_max < 0x7FFFFFFF)) { 3096 if ((left_max < 0x7FFFFFFF) && (right_max < 0x7FFFFFFF)) {
3094 // Product of left and right max values stays in 64 bit range. 3097 // Product of left and right max values stays in 64 bit range.
3095 const int64_t result_max = left_max * right_max; 3098 const int64_t result_max = left_max * right_max;
3096 if (Smi::IsValid64(result_max) && Smi::IsValid64(-result_max)) { 3099 if (Smi::IsValid64(result_max) && Smi::IsValid64(-result_max)) {
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
3135 ASSERT(!min.IsUnknown() && !max.IsUnknown()); 3138 ASSERT(!min.IsUnknown() && !max.IsUnknown());
3136 set_overflow(min.LowerBound().Overflowed() || max.UpperBound().Overflowed()); 3139 set_overflow(min.LowerBound().Overflowed() || max.UpperBound().Overflowed());
3137 3140
3138 if (min.IsConstant()) min.Clamp(); 3141 if (min.IsConstant()) min.Clamp();
3139 if (max.IsConstant()) max.Clamp(); 3142 if (max.IsConstant()) max.Clamp();
3140 3143
3141 range_ = new Range(min, max); 3144 range_ = new Range(min, max);
3142 } 3145 }
3143 3146
3144 3147
3148 bool Range::IsPositive() const {
3149 if (min().IsNegativeInfinity()) {
3150 return false;
3151 }
3152 if (min().LowerBound().value() < 0) {
3153 return false;
3154 }
3155 if (max().IsPositiveInfinity()) {
3156 return true;
3157 }
3158 return max().UpperBound().value() >= 0;
3159 }
3160
3161
3162 bool Range::IsNegative() const {
3163 if (max().IsPositiveInfinity()) {
3164 return false;
3165 }
3166 if (max().UpperBound().value() >= 0) {
3167 return false;
3168 }
3169 if (min().IsNegativeInfinity()) {
3170 return true;
3171 }
3172 return min().LowerBound().value() < 0;
3173 }
3174
3175
3176 bool Range::OnlyLessThanOrEqualTo(intptr_t val) const {
3177 if (max().IsPositiveInfinity()) {
3178 // Cannot be true.
3179 return false;
3180 }
3181 if (max().UpperBound().value() > val) {
3182 // Not true.
3183 return false;
3184 }
3185 if (!min().IsNegativeInfinity()) {
3186 if (min().LowerBound().value() > val) {
3187 // Lower bound is > value.
3188 return false;
3189 }
3190 }
3191 return true;
3192 }
3193
3194
3145 // Inclusive. 3195 // Inclusive.
3146 bool Range::IsWithin(intptr_t min_int, intptr_t max_int) const { 3196 bool Range::IsWithin(intptr_t min_int, intptr_t max_int) const {
3147 if (min().LowerBound().value() < min_int) return false; 3197 RangeBoundary lower_min = min().LowerBound();
3148 if (max().UpperBound().value() > max_int) return false; 3198 if (lower_min.IsNegativeInfinity() || (lower_min.value() < min_int)) {
3199 return false;
3200 }
3201 RangeBoundary upper_max = max().UpperBound();
3202 if (upper_max.IsPositiveInfinity() || (upper_max.value() > max_int)) {
3203 return false;
3204 }
3149 return true; 3205 return true;
3150 } 3206 }
3151 3207
3152 3208
3153 bool Range::Overlaps(intptr_t min_int, intptr_t max_int) const { 3209 bool Range::Overlaps(intptr_t min_int, intptr_t max_int) const {
3154 const intptr_t this_min = min().LowerBound().value(); 3210 const intptr_t this_min = min().IsNegativeInfinity() ?
3155 const intptr_t this_max = max().UpperBound().value(); 3211 kIntptrMin : min().LowerBound().value();
3212 const intptr_t this_max = max().IsPositiveInfinity() ?
3213 kIntptrMax : max().UpperBound().value();
3156 if ((this_min <= min_int) && (min_int <= this_max)) return true; 3214 if ((this_min <= min_int) && (min_int <= this_max)) return true;
3157 if ((this_min <= max_int) && (max_int <= this_max)) return true; 3215 if ((this_min <= max_int) && (max_int <= this_max)) return true;
3158 if ((min_int < this_min) && (max_int > this_max)) return true; 3216 if ((min_int < this_min) && (max_int > this_max)) return true;
3159 return false; 3217 return false;
3160 } 3218 }
3161 3219
3162 3220
3163 bool Range::IsUnsatisfiable() const { 3221 bool Range::IsUnsatisfiable() const {
3222 // Infinity case: [+inf, ...] || [..., -inf]
3223 if (min().IsPositiveInfinity() || max().IsNegativeInfinity()) {
3224 return true;
3225 }
3164 // Constant case: For example [0, -1]. 3226 // Constant case: For example [0, -1].
3165 if (Range::ConstantMin(this).value() > Range::ConstantMax(this).value()) { 3227 if (Range::ConstantMin(this).value() > Range::ConstantMax(this).value()) {
3166 return true; 3228 return true;
3167 } 3229 }
3168 // Symbol case: For example [v+1, v]. 3230 // Symbol case: For example [v+1, v].
3169 if (DependOnSameSymbol(min(), max()) && min().offset() > max().offset()) { 3231 if (DependOnSameSymbol(min(), max()) && min().offset() > max().offset()) {
3170 return true; 3232 return true;
3171 } 3233 }
3172 return false; 3234 return false;
3173 } 3235 }
(...skipping 11 matching lines...) Expand all
3185 if (index_range == NULL) { 3247 if (index_range == NULL) {
3186 return false; 3248 return false;
3187 } 3249 }
3188 3250
3189 // Range of the index is not positive. Check can't be redundant. 3251 // Range of the index is not positive. Check can't be redundant.
3190 if (Range::ConstantMin(index_range).value() < 0) { 3252 if (Range::ConstantMin(index_range).value() < 0) {
3191 return false; 3253 return false;
3192 } 3254 }
3193 3255
3194 RangeBoundary max = CanonicalizeBoundary(index_range->max(), 3256 RangeBoundary max = CanonicalizeBoundary(index_range->max(),
3195 RangeBoundary::OverflowedMaxSmi()); 3257 RangeBoundary::PositiveInfinity());
3196 3258
3197 if (max.Overflowed()) { 3259 if (max.Overflowed()) {
3198 return false; 3260 return false;
3199 } 3261 }
3200 3262
3263
3264 RangeBoundary max_upper = max.UpperBound();
3265 RangeBoundary length_lower = length.LowerBound();
3266
3267 if (max_upper.Overflowed() || length_lower.Overflowed()) {
3268 return false;
3269 }
3270
3201 // Try to compare constant boundaries. 3271 // Try to compare constant boundaries.
3202 if (max.UpperBound().value() < length.LowerBound().value()) { 3272 if (max_upper.value() < length_lower.value()) {
3203 return true; 3273 return true;
3204 } 3274 }
3205 3275
3206 length = CanonicalizeBoundary(length, RangeBoundary::OverflowedMaxSmi()); 3276 length = CanonicalizeBoundary(length, RangeBoundary::PositiveInfinity());
3207 if (length.Overflowed()) { 3277 if (length.Overflowed()) {
3208 return false; 3278 return false;
3209 } 3279 }
3210 3280
3211 // Try symbolic comparison. 3281 // Try symbolic comparison.
3212 do { 3282 do {
3213 if (DependOnSameSymbol(max, length)) return max.offset() < length.offset(); 3283 if (DependOnSameSymbol(max, length)) return max.offset() < length.offset();
3214 } while (CanonicalizeMaxBoundary(&max) || CanonicalizeMinBoundary(&length)); 3284 } while (CanonicalizeMaxBoundary(&max) || CanonicalizeMinBoundary(&length));
3215 3285
3216 // Failed to prove that maximum is bounded with array length. 3286 // Failed to prove that maximum is bounded with array length.
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after
3490 case Token::kTRUNCDIV: return 0; 3560 case Token::kTRUNCDIV: return 0;
3491 case Token::kMOD: return 1; 3561 case Token::kMOD: return 1;
3492 default: UNIMPLEMENTED(); return -1; 3562 default: UNIMPLEMENTED(); return -1;
3493 } 3563 }
3494 } 3564 }
3495 3565
3496 3566
3497 #undef __ 3567 #undef __
3498 3568
3499 } // namespace dart 3569 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698