Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/dart_entry.h" | 9 #include "vm/dart_entry.h" |
| 10 #include "vm/flow_graph_allocator.h" | 10 #include "vm/flow_graph_allocator.h" |
| (...skipping 2600 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2611 return false; | 2611 return false; |
| 2612 } | 2612 } |
| 2613 | 2613 |
| 2614 | 2614 |
| 2615 static bool IsArrayLength(Definition* defn) { | 2615 static bool IsArrayLength(Definition* defn) { |
| 2616 LoadFieldInstr* load = defn->AsLoadField(); | 2616 LoadFieldInstr* load = defn->AsLoadField(); |
| 2617 return (load != NULL) && load->IsImmutableLengthLoad(); | 2617 return (load != NULL) && load->IsImmutableLengthLoad(); |
| 2618 } | 2618 } |
| 2619 | 2619 |
| 2620 | 2620 |
| 2621 static int64_t ConstantAbsMax(const Range* range) { | |
| 2622 if (range == NULL) return Smi::kMaxValue; | |
| 2623 const int64_t a = Utils::Abs(Range::ConstantMin(range).value()); | |
|
Florian Schneider
2014/01/06 19:11:43
Maybe rename a/b to abs_min/abs_max.
srdjan
2014/01/06 20:39:09
Done.
| |
| 2624 const int64_t b = Utils::Abs(Range::ConstantMax(range).value()); | |
| 2625 return a > b ? a : b; | |
| 2626 } | |
| 2627 | |
| 2628 | |
| 2629 static bool OnlyPositiveOrZero(const Range* a, const Range* b) { | |
| 2630 if ((a == NULL) || (b == NULL)) return false; | |
| 2631 if (Range::ConstantMin(a).value() < 0) return false; | |
| 2632 if (Range::ConstantMin(b).value() < 0) return false; | |
| 2633 return true; | |
| 2634 } | |
| 2635 | |
| 2636 | |
| 2637 static bool OnlyNegativeOrZero(const Range* a, const Range* b) { | |
| 2638 if ((a == NULL) || (b == NULL)) return false; | |
| 2639 if (Range::ConstantMax(a).value() > 0) return false; | |
| 2640 if (Range::ConstantMax(b).value() > 0) return false; | |
| 2641 return true; | |
| 2642 } | |
| 2643 | |
| 2644 | |
| 2621 void BinarySmiOpInstr::InferRange() { | 2645 void BinarySmiOpInstr::InferRange() { |
| 2622 // TODO(vegorov): canonicalize BinarySmiOp to always have constant on the | 2646 // TODO(vegorov): canonicalize BinarySmiOp to always have constant on the |
| 2623 // right and a non-constant on the left. | 2647 // right and a non-constant on the left. |
| 2624 Definition* left_defn = left()->definition(); | 2648 Definition* left_defn = left()->definition(); |
| 2625 | 2649 |
| 2626 Range* left_range = left_defn->range(); | 2650 Range* left_range = left_defn->range(); |
| 2627 Range* right_range = right()->definition()->range(); | 2651 Range* right_range = right()->definition()->range(); |
| 2628 | 2652 |
| 2629 if ((left_range == NULL) || (right_range == NULL)) { | 2653 if ((left_range == NULL) || (right_range == NULL)) { |
| 2630 range_ = new Range(RangeBoundary::MinSmi(), RangeBoundary::MaxSmi()); | 2654 range_ = new Range(RangeBoundary::MinSmi(), RangeBoundary::MaxSmi()); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2667 } | 2691 } |
| 2668 | 2692 |
| 2669 if (!SymbolicSub(left_max, right_range->min(), &max)) { | 2693 if (!SymbolicSub(left_max, right_range->min(), &max)) { |
| 2670 max = | 2694 max = |
| 2671 RangeBoundary::Sub(Range::ConstantMax(left_range), | 2695 RangeBoundary::Sub(Range::ConstantMax(left_range), |
| 2672 Range::ConstantMin(right_range), | 2696 Range::ConstantMin(right_range), |
| 2673 RangeBoundary::OverflowedMaxSmi()); | 2697 RangeBoundary::OverflowedMaxSmi()); |
| 2674 } | 2698 } |
| 2675 break; | 2699 break; |
| 2676 | 2700 |
| 2701 case Token::kMUL: { | |
| 2702 const int64_t left_max = ConstantAbsMax(left_range); | |
| 2703 const int64_t right_max = ConstantAbsMax(right_range); | |
| 2704 if ((left_max < 0x7FFFFFFF) && (right_max < 0x7FFFFFFF)) { | |
| 2705 // Product of left and right max values stays in 64 bit range. | |
| 2706 const int64_t result_max = left_max * right_max; | |
| 2707 if (Smi::IsValid64(result_max) && Smi::IsValid64(-result_max)) { | |
| 2708 const intptr_t r_min = | |
| 2709 OnlyPositiveOrZero(left_range, right_range) ? 0 : -result_max; | |
| 2710 min = RangeBoundary::FromConstant(r_min); | |
| 2711 const intptr_t r_max = | |
| 2712 OnlyNegativeOrZero(left_range, right_range) ? 0 : result_max; | |
| 2713 max = RangeBoundary::FromConstant(r_max); | |
| 2714 break; | |
| 2715 } | |
| 2716 } | |
| 2717 if (range_ == NULL) { | |
| 2718 range_ = Range::Unknown(); | |
| 2719 } | |
| 2720 return; | |
| 2721 } | |
| 2677 case Token::kBIT_AND: | 2722 case Token::kBIT_AND: |
| 2678 if (Range::ConstantMin(right_range).value() >= 0) { | 2723 if (Range::ConstantMin(right_range).value() >= 0) { |
| 2679 min = RangeBoundary::FromConstant(0); | 2724 min = RangeBoundary::FromConstant(0); |
| 2680 max = Range::ConstantMax(right_range); | 2725 max = Range::ConstantMax(right_range); |
| 2681 break; | 2726 break; |
| 2682 } | 2727 } |
| 2683 if (Range::ConstantMin(left_range).value() >= 0) { | 2728 if (Range::ConstantMin(left_range).value() >= 0) { |
| 2684 min = RangeBoundary::FromConstant(0); | 2729 min = RangeBoundary::FromConstant(0); |
| 2685 max = Range::ConstantMax(left_range); | 2730 max = Range::ConstantMax(left_range); |
| 2686 break; | 2731 break; |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3028 case Token::kTRUNCDIV: return 0; | 3073 case Token::kTRUNCDIV: return 0; |
| 3029 case Token::kMOD: return 1; | 3074 case Token::kMOD: return 1; |
| 3030 default: UNIMPLEMENTED(); return -1; | 3075 default: UNIMPLEMENTED(); return -1; |
| 3031 } | 3076 } |
| 3032 } | 3077 } |
| 3033 | 3078 |
| 3034 | 3079 |
| 3035 #undef __ | 3080 #undef __ |
| 3036 | 3081 |
| 3037 } // namespace dart | 3082 } // namespace dart |
| OLD | NEW |