Chromium Code Reviews| 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::HighestBit(max >= 0 ? max : 0), | |
|
Florian Schneider
2014/11/11 11:48:35
HighestBit already takes the sign into account, so
Vyacheslav Egorov (Google)
2014/11/11 14:29:40
Done.
| |
| 2434 Utils::HighestBit(min < -1 ? ~min : 0)) + 1; | |
| 2435 } | |
| 2436 | |
| 2437 | |
| 2438 void Range::Xor(const Range* left_range, | |
|
Florian Schneider
2014/11/11 11:48:34
Please add test coverage for Xor to flow_graph_ran
Vyacheslav Egorov (Google)
2014/11/11 14:29:40
Done.
| |
| 2439 const Range* right_range, | |
| 2440 RangeBoundary* result_min, | |
| 2441 RangeBoundary* result_max) { | |
| 2442 const int bitsize = | |
| 2443 Utils::Maximum(BitSize(left_range), BitSize(right_range)); | |
| 2444 | |
| 2445 if (left_range->IsPositive() && right_range->IsPositive()) { | |
| 2446 *result_min = RangeBoundary::FromConstant(0); | |
| 2447 } else { | |
| 2448 *result_min = RangeBoundary::FromConstant( | |
| 2449 static_cast<int64_t>(-1) << bitsize); | |
| 2450 } | |
| 2451 | |
| 2452 *result_max = RangeBoundary::FromConstant( | |
| 2453 (static_cast<uint64_t>(1) << bitsize) - 1); | |
| 2454 } | |
| 2455 | |
| 2456 | |
| 2430 static bool IsArrayLength(Definition* defn) { | 2457 static bool IsArrayLength(Definition* defn) { |
| 2431 if (defn == NULL) { | 2458 if (defn == NULL) { |
| 2432 return false; | 2459 return false; |
| 2433 } | 2460 } |
| 2434 LoadFieldInstr* load = UnwrapConstraint(defn)->AsLoadField(); | 2461 LoadFieldInstr* load = UnwrapConstraint(defn)->AsLoadField(); |
| 2435 return (load != NULL) && load->IsImmutableLengthLoad(); | 2462 return (load != NULL) && load->IsImmutableLengthLoad(); |
| 2436 } | 2463 } |
| 2437 | 2464 |
| 2438 | 2465 |
| 2439 void Range::Add(const Range* left_range, | 2466 void Range::Add(const Range* left_range, |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2588 break; | 2615 break; |
| 2589 } | 2616 } |
| 2590 case Token::kSHL: { | 2617 case Token::kSHL: { |
| 2591 Range::Shl(left_range, right_range, &min, &max); | 2618 Range::Shl(left_range, right_range, &min, &max); |
| 2592 break; | 2619 break; |
| 2593 } | 2620 } |
| 2594 case Token::kSHR: { | 2621 case Token::kSHR: { |
| 2595 Range::Shr(left_range, right_range, &min, &max); | 2622 Range::Shr(left_range, right_range, &min, &max); |
| 2596 break; | 2623 break; |
| 2597 } | 2624 } |
| 2625 | |
| 2598 case Token::kBIT_AND: | 2626 case Token::kBIT_AND: |
| 2599 if (!Range::And(left_range, right_range, &min, &max)) { | 2627 if (!Range::And(left_range, right_range, &min, &max)) { |
| 2600 *result = Range::Full(RangeBoundary::kRangeBoundaryInt64); | 2628 *result = Range::Full(RangeBoundary::kRangeBoundaryInt64); |
| 2601 return; | 2629 return; |
| 2602 } | 2630 } |
| 2603 break; | 2631 break; |
| 2632 | |
| 2633 case Token::kBIT_XOR: | |
| 2634 Range::Xor(left_range, right_range, &min, &max); | |
| 2635 break; | |
| 2636 | |
| 2604 default: | 2637 default: |
| 2605 *result = Range::Full(RangeBoundary::kRangeBoundaryInt64); | 2638 *result = Range::Full(RangeBoundary::kRangeBoundaryInt64); |
| 2606 return; | 2639 return; |
| 2607 } | 2640 } |
| 2608 | 2641 |
| 2609 ASSERT(!min.IsUnknown() && !max.IsUnknown()); | 2642 ASSERT(!min.IsUnknown() && !max.IsUnknown()); |
| 2610 | 2643 |
| 2611 *result = Range(min, max); | 2644 *result = Range(min, max); |
| 2612 } | 2645 } |
| 2613 | 2646 |
| (...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3094 } | 3127 } |
| 3095 } while (CanonicalizeMaxBoundary(&max) || | 3128 } while (CanonicalizeMaxBoundary(&max) || |
| 3096 CanonicalizeMinBoundary(&canonical_length)); | 3129 CanonicalizeMinBoundary(&canonical_length)); |
| 3097 | 3130 |
| 3098 // Failed to prove that maximum is bounded with array length. | 3131 // Failed to prove that maximum is bounded with array length. |
| 3099 return false; | 3132 return false; |
| 3100 } | 3133 } |
| 3101 | 3134 |
| 3102 | 3135 |
| 3103 } // namespace dart | 3136 } // namespace dart |
| OLD | NEW |