OLD | NEW |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2014, 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/flow_graph_range_analysis.h" | 5 #include "vm/flow_graph_range_analysis.h" |
6 | 6 |
7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
8 #include "vm/il_printer.h" | 8 #include "vm/il_printer.h" |
9 | 9 |
10 namespace dart { | 10 namespace dart { |
(...skipping 2409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2420 if (Range::ConstantMin(left_range).ConstantValue() >= 0) { | 2420 if (Range::ConstantMin(left_range).ConstantValue() >= 0) { |
2421 *result_min = RangeBoundary::FromConstant(0); | 2421 *result_min = RangeBoundary::FromConstant(0); |
2422 *result_max = Range::ConstantMax(left_range); | 2422 *result_max = Range::ConstantMax(left_range); |
2423 return true; | 2423 return true; |
2424 } | 2424 } |
2425 | 2425 |
2426 return false; | 2426 return false; |
2427 } | 2427 } |
2428 | 2428 |
2429 | 2429 |
| 2430 static int BitSize(const Range* range) { |
| 2431 const int64_t min = Range::ConstantMin(range).ConstantValue(); |
| 2432 const int64_t max = Range::ConstantMax(range).ConstantValue(); |
| 2433 return Utils::Maximum(Utils::BitLength(min), Utils::BitLength(max)); |
| 2434 } |
| 2435 |
| 2436 |
| 2437 void Range::Xor(const Range* left_range, |
| 2438 const Range* right_range, |
| 2439 RangeBoundary* result_min, |
| 2440 RangeBoundary* result_max) { |
| 2441 const int bitsize = |
| 2442 Utils::Maximum(BitSize(left_range), BitSize(right_range)); |
| 2443 |
| 2444 if (left_range->IsPositive() && right_range->IsPositive()) { |
| 2445 *result_min = RangeBoundary::FromConstant(0); |
| 2446 } else { |
| 2447 *result_min = RangeBoundary::FromConstant( |
| 2448 static_cast<int64_t>(-1) << bitsize); |
| 2449 } |
| 2450 |
| 2451 *result_max = RangeBoundary::FromConstant( |
| 2452 (static_cast<uint64_t>(1) << bitsize) - 1); |
| 2453 } |
| 2454 |
| 2455 |
2430 static bool IsArrayLength(Definition* defn) { | 2456 static bool IsArrayLength(Definition* defn) { |
2431 if (defn == NULL) { | 2457 if (defn == NULL) { |
2432 return false; | 2458 return false; |
2433 } | 2459 } |
2434 LoadFieldInstr* load = UnwrapConstraint(defn)->AsLoadField(); | 2460 LoadFieldInstr* load = UnwrapConstraint(defn)->AsLoadField(); |
2435 return (load != NULL) && load->IsImmutableLengthLoad(); | 2461 return (load != NULL) && load->IsImmutableLengthLoad(); |
2436 } | 2462 } |
2437 | 2463 |
2438 | 2464 |
2439 void Range::Add(const Range* left_range, | 2465 void Range::Add(const Range* left_range, |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2588 break; | 2614 break; |
2589 } | 2615 } |
2590 case Token::kSHL: { | 2616 case Token::kSHL: { |
2591 Range::Shl(left_range, right_range, &min, &max); | 2617 Range::Shl(left_range, right_range, &min, &max); |
2592 break; | 2618 break; |
2593 } | 2619 } |
2594 case Token::kSHR: { | 2620 case Token::kSHR: { |
2595 Range::Shr(left_range, right_range, &min, &max); | 2621 Range::Shr(left_range, right_range, &min, &max); |
2596 break; | 2622 break; |
2597 } | 2623 } |
| 2624 |
2598 case Token::kBIT_AND: | 2625 case Token::kBIT_AND: |
2599 if (!Range::And(left_range, right_range, &min, &max)) { | 2626 if (!Range::And(left_range, right_range, &min, &max)) { |
2600 *result = Range::Full(RangeBoundary::kRangeBoundaryInt64); | 2627 *result = Range::Full(RangeBoundary::kRangeBoundaryInt64); |
2601 return; | 2628 return; |
2602 } | 2629 } |
2603 break; | 2630 break; |
| 2631 |
| 2632 case Token::kBIT_XOR: |
| 2633 Range::Xor(left_range, right_range, &min, &max); |
| 2634 break; |
| 2635 |
2604 default: | 2636 default: |
2605 *result = Range::Full(RangeBoundary::kRangeBoundaryInt64); | 2637 *result = Range::Full(RangeBoundary::kRangeBoundaryInt64); |
2606 return; | 2638 return; |
2607 } | 2639 } |
2608 | 2640 |
2609 ASSERT(!min.IsUnknown() && !max.IsUnknown()); | 2641 ASSERT(!min.IsUnknown() && !max.IsUnknown()); |
2610 | 2642 |
2611 *result = Range(min, max); | 2643 *result = Range(min, max); |
2612 } | 2644 } |
2613 | 2645 |
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3094 } | 3126 } |
3095 } while (CanonicalizeMaxBoundary(&max) || | 3127 } while (CanonicalizeMaxBoundary(&max) || |
3096 CanonicalizeMinBoundary(&canonical_length)); | 3128 CanonicalizeMinBoundary(&canonical_length)); |
3097 | 3129 |
3098 // Failed to prove that maximum is bounded with array length. | 3130 // Failed to prove that maximum is bounded with array length. |
3099 return false; | 3131 return false; |
3100 } | 3132 } |
3101 | 3133 |
3102 | 3134 |
3103 } // namespace dart | 3135 } // namespace dart |
OLD | NEW |