| 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 2625 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2636 return false; | 2636 return false; |
| 2637 } | 2637 } |
| 2638 | 2638 |
| 2639 | 2639 |
| 2640 static bool IsArrayLength(Definition* defn) { | 2640 static bool IsArrayLength(Definition* defn) { |
| 2641 LoadFieldInstr* load = defn->AsLoadField(); | 2641 LoadFieldInstr* load = defn->AsLoadField(); |
| 2642 return (load != NULL) && load->IsImmutableLengthLoad(); | 2642 return (load != NULL) && load->IsImmutableLengthLoad(); |
| 2643 } | 2643 } |
| 2644 | 2644 |
| 2645 | 2645 |
| 2646 static int64_t ConstantAbsMax(const Range* range) { |
| 2647 if (range == NULL) return Smi::kMaxValue; |
| 2648 const int64_t abs_min = Utils::Abs(Range::ConstantMin(range).value()); |
| 2649 const int64_t abs_max = Utils::Abs(Range::ConstantMax(range).value()); |
| 2650 return abs_min > abs_max ? abs_min : abs_max; |
| 2651 } |
| 2652 |
| 2653 |
| 2654 static bool OnlyPositiveOrZero(const Range* a, const Range* b) { |
| 2655 if ((a == NULL) || (b == NULL)) return false; |
| 2656 if (Range::ConstantMin(a).value() < 0) return false; |
| 2657 if (Range::ConstantMin(b).value() < 0) return false; |
| 2658 return true; |
| 2659 } |
| 2660 |
| 2661 |
| 2662 static bool OnlyNegativeOrZero(const Range* a, const Range* b) { |
| 2663 if ((a == NULL) || (b == NULL)) return false; |
| 2664 if (Range::ConstantMax(a).value() > 0) return false; |
| 2665 if (Range::ConstantMax(b).value() > 0) return false; |
| 2666 return true; |
| 2667 } |
| 2668 |
| 2669 |
| 2646 void BinarySmiOpInstr::InferRange() { | 2670 void BinarySmiOpInstr::InferRange() { |
| 2647 // TODO(vegorov): canonicalize BinarySmiOp to always have constant on the | 2671 // TODO(vegorov): canonicalize BinarySmiOp to always have constant on the |
| 2648 // right and a non-constant on the left. | 2672 // right and a non-constant on the left. |
| 2649 Definition* left_defn = left()->definition(); | 2673 Definition* left_defn = left()->definition(); |
| 2650 | 2674 |
| 2651 Range* left_range = left_defn->range(); | 2675 Range* left_range = left_defn->range(); |
| 2652 Range* right_range = right()->definition()->range(); | 2676 Range* right_range = right()->definition()->range(); |
| 2653 | 2677 |
| 2654 if ((left_range == NULL) || (right_range == NULL)) { | 2678 if ((left_range == NULL) || (right_range == NULL)) { |
| 2655 range_ = new Range(RangeBoundary::MinSmi(), RangeBoundary::MaxSmi()); | 2679 range_ = new Range(RangeBoundary::MinSmi(), RangeBoundary::MaxSmi()); |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2692 } | 2716 } |
| 2693 | 2717 |
| 2694 if (!SymbolicSub(left_max, right_range->min(), &max)) { | 2718 if (!SymbolicSub(left_max, right_range->min(), &max)) { |
| 2695 max = | 2719 max = |
| 2696 RangeBoundary::Sub(Range::ConstantMax(left_range), | 2720 RangeBoundary::Sub(Range::ConstantMax(left_range), |
| 2697 Range::ConstantMin(right_range), | 2721 Range::ConstantMin(right_range), |
| 2698 RangeBoundary::OverflowedMaxSmi()); | 2722 RangeBoundary::OverflowedMaxSmi()); |
| 2699 } | 2723 } |
| 2700 break; | 2724 break; |
| 2701 | 2725 |
| 2726 case Token::kMUL: { |
| 2727 const int64_t left_max = ConstantAbsMax(left_range); |
| 2728 const int64_t right_max = ConstantAbsMax(right_range); |
| 2729 if ((left_max < 0x7FFFFFFF) && (right_max < 0x7FFFFFFF)) { |
| 2730 // Product of left and right max values stays in 64 bit range. |
| 2731 const int64_t result_max = left_max * right_max; |
| 2732 if (Smi::IsValid64(result_max) && Smi::IsValid64(-result_max)) { |
| 2733 const intptr_t r_min = |
| 2734 OnlyPositiveOrZero(left_range, right_range) ? 0 : -result_max; |
| 2735 min = RangeBoundary::FromConstant(r_min); |
| 2736 const intptr_t r_max = |
| 2737 OnlyNegativeOrZero(left_range, right_range) ? 0 : result_max; |
| 2738 max = RangeBoundary::FromConstant(r_max); |
| 2739 break; |
| 2740 } |
| 2741 } |
| 2742 if (range_ == NULL) { |
| 2743 range_ = Range::Unknown(); |
| 2744 } |
| 2745 return; |
| 2746 } |
| 2702 case Token::kBIT_AND: | 2747 case Token::kBIT_AND: |
| 2703 if (Range::ConstantMin(right_range).value() >= 0) { | 2748 if (Range::ConstantMin(right_range).value() >= 0) { |
| 2704 min = RangeBoundary::FromConstant(0); | 2749 min = RangeBoundary::FromConstant(0); |
| 2705 max = Range::ConstantMax(right_range); | 2750 max = Range::ConstantMax(right_range); |
| 2706 break; | 2751 break; |
| 2707 } | 2752 } |
| 2708 if (Range::ConstantMin(left_range).value() >= 0) { | 2753 if (Range::ConstantMin(left_range).value() >= 0) { |
| 2709 min = RangeBoundary::FromConstant(0); | 2754 min = RangeBoundary::FromConstant(0); |
| 2710 max = Range::ConstantMax(left_range); | 2755 max = Range::ConstantMax(left_range); |
| 2711 break; | 2756 break; |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3053 case Token::kTRUNCDIV: return 0; | 3098 case Token::kTRUNCDIV: return 0; |
| 3054 case Token::kMOD: return 1; | 3099 case Token::kMOD: return 1; |
| 3055 default: UNIMPLEMENTED(); return -1; | 3100 default: UNIMPLEMENTED(); return -1; |
| 3056 } | 3101 } |
| 3057 } | 3102 } |
| 3058 | 3103 |
| 3059 | 3104 |
| 3060 #undef __ | 3105 #undef __ |
| 3061 | 3106 |
| 3062 } // namespace dart | 3107 } // namespace dart |
| OLD | NEW |