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 |