Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(48)

Side by Side Diff: runtime/vm/intermediate_language.h

Issue 328503003: Extend Range analysis to 64-bit range and mint operations (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 #ifndef VM_INTERMEDIATE_LANGUAGE_H_ 5 #ifndef VM_INTERMEDIATE_LANGUAGE_H_
6 #define VM_INTERMEDIATE_LANGUAGE_H_ 6 #define VM_INTERMEDIATE_LANGUAGE_H_
7 7
8 #include "vm/allocation.h" 8 #include "vm/allocation.h"
9 #include "vm/ast.h" 9 #include "vm/ast.h"
10 #include "vm/growable_array.h" 10 #include "vm/growable_array.h"
(...skipping 1787 matching lines...) Expand 10 before | Expand all | Expand 10 after
1798 if (type_ == NULL) { 1798 if (type_ == NULL) {
1799 type_ = ComputeInitialType(); 1799 type_ = ComputeInitialType();
1800 } 1800 }
1801 return type_; 1801 return type_;
1802 } 1802 }
1803 1803
1804 virtual CompileType* ComputeInitialType() const { 1804 virtual CompileType* ComputeInitialType() const {
1805 return ZoneCompileType::Wrap(ComputeType()); 1805 return ZoneCompileType::Wrap(ComputeType());
1806 } 1806 }
1807 1807
1808 // Does this define a mint?
1809 bool IsMintDefinition() {
1810 return (Type()->ToCid() == kMintCid) ||
1811 IsBinaryMintOp() ||
1812 IsUnaryMintOp() ||
1813 IsShiftMintOp() ||
1814 IsUnboxInteger();
1815 }
1816
1808 // Compute compile type for this definition. It is safe to use this 1817 // Compute compile type for this definition. It is safe to use this
1809 // approximation even before type propagator was run (e.g. during graph 1818 // approximation even before type propagator was run (e.g. during graph
1810 // building). 1819 // building).
1811 virtual CompileType ComputeType() const { 1820 virtual CompileType ComputeType() const {
1812 return CompileType::Dynamic(); 1821 return CompileType::Dynamic();
1813 } 1822 }
1814 1823
1815 // Update CompileType of the definition. Returns true if the type has changed. 1824 // Update CompileType of the definition. Returns true if the type has changed.
1816 virtual bool RecomputeType() { 1825 virtual bool RecomputeType() {
1817 return false; 1826 return false;
(...skipping 13 matching lines...) Expand all
1831 return false; 1840 return false;
1832 } 1841 }
1833 1842
1834 bool HasUses() const { 1843 bool HasUses() const {
1835 return (input_use_list_ != NULL) || (env_use_list_ != NULL); 1844 return (input_use_list_ != NULL) || (env_use_list_ != NULL);
1836 } 1845 }
1837 bool HasOnlyUse(Value* use) const; 1846 bool HasOnlyUse(Value* use) const;
1838 1847
1839 Value* input_use_list() const { return input_use_list_; } 1848 Value* input_use_list() const { return input_use_list_; }
1840 void set_input_use_list(Value* head) { input_use_list_ = head; } 1849 void set_input_use_list(Value* head) { input_use_list_ = head; }
1850 intptr_t InputUseListLength() const {
1851 intptr_t length = 0;
1852 Value* use = input_use_list_;
1853 while (use != NULL) {
1854 length++;
1855 use = use->next_use();
1856 }
1857 return length;
1858 }
1841 1859
1842 Value* env_use_list() const { return env_use_list_; } 1860 Value* env_use_list() const { return env_use_list_; }
1843 void set_env_use_list(Value* head) { env_use_list_ = head; } 1861 void set_env_use_list(Value* head) { env_use_list_ = head; }
1844 1862
1845 void AddInputUse(Value* value) { Value::AddToList(value, &input_use_list_); } 1863 void AddInputUse(Value* value) { Value::AddToList(value, &input_use_list_); }
1846 void AddEnvUse(Value* value) { Value::AddToList(value, &env_use_list_); } 1864 void AddEnvUse(Value* value) { Value::AddToList(value, &env_use_list_); }
1847 1865
1848 // Replace uses of this definition with uses of other definition or value. 1866 // Replace uses of this definition with uses of other definition or value.
1849 // Precondition: use lists must be properly calculated. 1867 // Precondition: use lists must be properly calculated.
1850 // Postcondition: use lists and use values are still valid. 1868 // Postcondition: use lists and use values are still valid.
(...skipping 639 matching lines...) Expand 10 before | Expand all | Expand 10 after
2490 class RangeBoundary : public ValueObject { 2508 class RangeBoundary : public ValueObject {
2491 public: 2509 public:
2492 enum Kind { 2510 enum Kind {
2493 kUnknown, 2511 kUnknown,
2494 kNegativeInfinity, 2512 kNegativeInfinity,
2495 kPositiveInfinity, 2513 kPositiveInfinity,
2496 kSymbol, 2514 kSymbol,
2497 kConstant, 2515 kConstant,
2498 }; 2516 };
2499 2517
2518 enum RangeSize {
2519 kRangeBoundarySmi,
2520 kRangeBoundaryInt64,
2521 };
2522
2500 RangeBoundary() : kind_(kUnknown), value_(0), offset_(0) { } 2523 RangeBoundary() : kind_(kUnknown), value_(0), offset_(0) { }
2501 2524
2502 RangeBoundary(const RangeBoundary& other) 2525 RangeBoundary(const RangeBoundary& other)
2503 : ValueObject(), 2526 : ValueObject(),
2504 kind_(other.kind_), 2527 kind_(other.kind_),
2505 value_(other.value_), 2528 value_(other.value_),
2506 offset_(other.offset_) { } 2529 offset_(other.offset_) { }
2507 2530
2508 explicit RangeBoundary(intptr_t val) 2531 explicit RangeBoundary(int64_t val)
2509 : kind_(kConstant), value_(val), offset_(0) { } 2532 : kind_(kConstant), value_(val), offset_(0) { }
2510 2533
2511 RangeBoundary& operator=(const RangeBoundary& other) { 2534 RangeBoundary& operator=(const RangeBoundary& other) {
2512 kind_ = other.kind_; 2535 kind_ = other.kind_;
2513 value_ = other.value_; 2536 value_ = other.value_;
2514 offset_ = other.offset_; 2537 offset_ = other.offset_;
2515 return *this; 2538 return *this;
2516 } 2539 }
2517 2540
2518 static RangeBoundary FromConstant(intptr_t val) { 2541 static const int64_t kMin = kMinInt64;
2542 static const int64_t kMax = kMaxInt64;
2543
2544 // Construct a RangeBoundary for a constant value.
2545 static RangeBoundary FromConstant(int64_t val) {
2519 return RangeBoundary(val); 2546 return RangeBoundary(val);
2520 } 2547 }
2521 2548
2549 // Construct a RangeBoundary for -inf.
2522 static RangeBoundary NegativeInfinity() { 2550 static RangeBoundary NegativeInfinity() {
2523 return RangeBoundary(kNegativeInfinity, 0, 0); 2551 return RangeBoundary(kNegativeInfinity, 0, 0);
2524 } 2552 }
2525 2553
2554 // Construct a RangeBoundary for +inf.
2526 static RangeBoundary PositiveInfinity() { 2555 static RangeBoundary PositiveInfinity() {
2527 return RangeBoundary(kPositiveInfinity, 0, 0); 2556 return RangeBoundary(kPositiveInfinity, 0, 0);
2528 } 2557 }
2529 2558
2530 static RangeBoundary FromDefinition(Definition* defn, intptr_t offs = 0); 2559 // Construct a RangeBoundary from a definition and offset.
2560 static RangeBoundary FromDefinition(Definition* defn, int64_t offs = 0);
2531 2561
2562 // Construct a RangeBoundary for the constant MinSmi value.
2532 static RangeBoundary MinSmi() { 2563 static RangeBoundary MinSmi() {
2533 return FromConstant(Smi::kMinValue); 2564 return FromConstant(Smi::kMinValue);
2534 } 2565 }
2535 2566
2567 // Construct a RangeBoundary for the constant MaxSmi value.
2536 static RangeBoundary MaxSmi() { 2568 static RangeBoundary MaxSmi() {
2537 return FromConstant(Smi::kMaxValue); 2569 return FromConstant(Smi::kMaxValue);
2538 } 2570 }
2539 2571
2540 static RangeBoundary Min(RangeBoundary a, RangeBoundary b); 2572 // Construct a RangeBoundary for the constant kMin value.
2541 2573 static RangeBoundary MinConstant() {
2542 static RangeBoundary Max(RangeBoundary a, RangeBoundary b); 2574 return FromConstant(kMin);
2543
2544 bool Overflowed() const {
2545 // If the value is a constant outside of Smi range or infinity.
2546 return (IsConstant() && !Smi::IsValid(value())) || IsInfinity();
2547 } 2575 }
2548 2576
2549 RangeBoundary Clamp() const { 2577 // Construct a RangeBoundary for the constant kMax value.
2578 static RangeBoundary MaxConstant() {
2579 return FromConstant(kMax);
2580 }
2581
2582 // Calculate the minimum of a and b within smi range.
2583 static RangeBoundary Min(RangeBoundary a, RangeBoundary b, RangeSize size);
2584 static RangeBoundary Max(RangeBoundary a, RangeBoundary b, RangeSize size);
2585
2586 // Returns true when this is a constant that is outside of Smi range.
2587 bool OverflowedSmi() const {
2588 return (IsConstant() && !Smi::IsValid(ConstantValue())) || IsInfinity();
2589 }
2590
2591 // Returns true if this outside mint range.
2592 bool OverflowedMint() const {
2593 return IsInfinity();
2594 }
2595
2596 // -/+ infinity are clamped to MinConstant/MaxConstant.
2597 RangeBoundary Clamp(RangeSize size) const {
2550 if (IsNegativeInfinity()) { 2598 if (IsNegativeInfinity()) {
2551 return MinSmi(); 2599 return (size == kRangeBoundaryInt64) ? MinConstant() : MinSmi();
2552 } else if (IsPositiveInfinity()) { 2600 }
2553 return MaxSmi(); 2601 if (IsPositiveInfinity()) {
2554 } else if (IsConstant()) { 2602 return (size == kRangeBoundaryInt64) ? MaxConstant() : MaxSmi();
2555 if (value() < Smi::kMinValue) return MinSmi(); 2603 }
2556 if (value() > Smi::kMaxValue) return MaxSmi(); 2604 if ((size == kRangeBoundarySmi) && IsConstant()) {
2605 if (ConstantValue() <= Smi::kMinValue) {
2606 return MinSmi();
2607 }
2608 if (ConstantValue() >= Smi::kMaxValue) {
2609 return MaxSmi();
2610 }
2557 } 2611 }
2558 return *this; 2612 return *this;
2559 } 2613 }
2560 2614
2561 bool Equals(const RangeBoundary& other) { 2615
2562 return kind_ == other.kind_ 2616 bool IsSmiMinimumOrBelow() const {
2563 && value_ == other.value_ 2617 return IsNegativeInfinity() ||
2564 && offset_ == other.offset_; 2618 (IsConstant() && (ConstantValue() <= Smi::kMinValue));
2565 } 2619 }
2566 2620
2621 bool IsSmiMaximumOrAbove() const {
2622 return IsPositiveInfinity() ||
2623 (IsConstant() && (ConstantValue() >= Smi::kMaxValue));
2624 }
2625
2626 bool IsMinimumOrBelow() const {
2627 return IsNegativeInfinity() || (IsConstant() && (ConstantValue() == kMin));
2628 }
2629
2630 bool IsMaximumOrAbove() const {
2631 return IsPositiveInfinity() || (IsConstant() && (ConstantValue() == kMax));
2632 }
2633
2634 intptr_t kind() const {
2635 return kind_;
2636 }
2637
2638 // Kind tests.
2567 bool IsUnknown() const { return kind_ == kUnknown; } 2639 bool IsUnknown() const { return kind_ == kUnknown; }
2568 bool IsConstant() const { return kind_ == kConstant; } 2640 bool IsConstant() const { return kind_ == kConstant; }
2569 bool IsSymbol() const { return kind_ == kSymbol; } 2641 bool IsSymbol() const { return kind_ == kSymbol; }
2570 bool IsNegativeInfinity() const { return kind_ == kNegativeInfinity; } 2642 bool IsNegativeInfinity() const { return kind_ == kNegativeInfinity; }
2571 bool IsPositiveInfinity() const { return kind_ == kPositiveInfinity; } 2643 bool IsPositiveInfinity() const { return kind_ == kPositiveInfinity; }
2572 bool IsInfinity() const { 2644 bool IsInfinity() const {
2573 return IsNegativeInfinity() || IsPositiveInfinity(); 2645 return IsNegativeInfinity() || IsPositiveInfinity();
2574 } 2646 }
2575 2647 bool IsConstantOrInfinity() const {
2576 intptr_t value() const { 2648 return IsConstant() || IsInfinity();
2577 ASSERT(IsConstant());
2578 return value_;
2579 } 2649 }
2580 2650
2651 // Returns the value of a kConstant RangeBoundary.
2652 int64_t ConstantValue() const;
2653
2654 // Returns the Definition associated with a kSymbol RangeBoundary.
2581 Definition* symbol() const { 2655 Definition* symbol() const {
2582 ASSERT(IsSymbol()); 2656 ASSERT(IsSymbol());
2583 return reinterpret_cast<Definition*>(value_); 2657 return reinterpret_cast<Definition*>(value_);
2584 } 2658 }
2585 2659
2586 intptr_t offset() const { 2660 // Offset from symbol.
2661 int64_t offset() const {
2587 return offset_; 2662 return offset_;
2588 } 2663 }
2589 2664
2665 // Computes the LowerBound of this. Three cases:
2666 // IsInfinity() -> NegativeInfinity().
2667 // IsConstant() -> value().
2668 // IsSymbol() -> lower bound computed from definition + offset.
2590 RangeBoundary LowerBound() const; 2669 RangeBoundary LowerBound() const;
2670
2671 // Computes the UpperBound of this. Three cases:
2672 // IsInfinity() -> PositiveInfinity().
2673 // IsConstant() -> value().
2674 // IsSymbol() -> upper bound computed from definition + offset.
2591 RangeBoundary UpperBound() const; 2675 RangeBoundary UpperBound() const;
2592 2676
2593 void PrintTo(BufferFormatter* f) const; 2677 void PrintTo(BufferFormatter* f) const;
2594 const char* ToCString() const; 2678 const char* ToCString() const;
2595 2679
2596 static RangeBoundary Add(const RangeBoundary& a, 2680 static RangeBoundary Add(const RangeBoundary& a,
2597 const RangeBoundary& b, 2681 const RangeBoundary& b,
2598 const RangeBoundary& overflow) { 2682 const RangeBoundary& overflow);
2599 ASSERT(a.IsConstant() && b.IsConstant());
2600
2601 intptr_t result = a.value() + b.value();
2602 if (!Smi::IsValid(result)) {
2603 return overflow;
2604 }
2605 return RangeBoundary::FromConstant(result);
2606 }
2607 2683
2608 static RangeBoundary Sub(const RangeBoundary& a, 2684 static RangeBoundary Sub(const RangeBoundary& a,
2609 const RangeBoundary& b, 2685 const RangeBoundary& b,
2610 const RangeBoundary& overflow) { 2686 const RangeBoundary& overflow);
2611 ASSERT(a.IsConstant() && b.IsConstant());
2612
2613 intptr_t result = a.value() - b.value();
2614 if (!Smi::IsValid(result)) {
2615 return overflow;
2616 }
2617 return RangeBoundary::FromConstant(result);
2618 }
2619 2687
2620 static RangeBoundary Shl(const RangeBoundary& value_boundary, 2688 static RangeBoundary Shl(const RangeBoundary& value_boundary,
2621 intptr_t shift_count, 2689 int64_t shift_count,
2622 const RangeBoundary& overflow) { 2690 const RangeBoundary& overflow);
2623 ASSERT(value_boundary.IsConstant()); 2691
2624 ASSERT(shift_count >= 0); 2692 // Attempts to calculate a + b when:
2625 intptr_t limit = 64 - shift_count; 2693 // a is a symbol and b is a constant OR
2626 int64_t value = static_cast<int64_t>(value_boundary.value()); 2694 // a is a constant and b is a symbol
2627 if ((value == 0) || 2695 // returns true if it succeeds, output is in result.
2628 (shift_count == 0) || 2696 static bool SymbolicAdd(const RangeBoundary& a,
2629 ((limit > 0) && (Utils::IsInt(limit, value)))) { 2697 const RangeBoundary& b,
2630 // Result stays in 64 bit range. 2698 RangeBoundary* result);
2631 int64_t result = value << shift_count; 2699
2632 return Smi::IsValid64(result) ? RangeBoundary(result) : overflow; 2700 // Attempts to calculate a - b when:
2633 } 2701 // a is a symbol and b is a constant
2634 return overflow; 2702 // returns true if it succeeds, output is in result.
2635 } 2703 static bool SymbolicSub(const RangeBoundary& a,
2704 const RangeBoundary& b,
2705 RangeBoundary* result);
2706
2707 bool Equals(const RangeBoundary& other) const;
2636 2708
2637 private: 2709 private:
2638 RangeBoundary(Kind kind, intptr_t value, intptr_t offset) 2710 RangeBoundary(Kind kind, int64_t value, int64_t offset)
2639 : kind_(kind), value_(value), offset_(offset) { } 2711 : kind_(kind), value_(value), offset_(offset) { }
2640 2712
2641 Kind kind_; 2713 Kind kind_;
2642 intptr_t value_; 2714 int64_t value_;
2643 intptr_t offset_; 2715 int64_t offset_;
2644 }; 2716 };
2645 2717
2646 2718
2647 class Range : public ZoneAllocated { 2719 class Range : public ZoneAllocated {
2648 public: 2720 public:
2649 Range(RangeBoundary min, RangeBoundary max) : min_(min), max_(max) { } 2721 Range(RangeBoundary min, RangeBoundary max) : min_(min), max_(max) { }
2650 2722
2651 static Range* Unknown() { 2723 static Range* Unknown() {
2652 return new Range(RangeBoundary::MinSmi(), RangeBoundary::MaxSmi()); 2724 return new Range(RangeBoundary::MinConstant(),
2725 RangeBoundary::MaxConstant());
2726 }
2727
2728 static Range* UnknownSmi() {
2729 return new Range(RangeBoundary::MinSmi(),
2730 RangeBoundary::MaxSmi());
2653 } 2731 }
2654 2732
2655 void PrintTo(BufferFormatter* f) const; 2733 void PrintTo(BufferFormatter* f) const;
2656 static const char* ToCString(Range* range); 2734 static const char* ToCString(const Range* range);
2657 2735
2658 const RangeBoundary& min() const { return min_; } 2736 const RangeBoundary& min() const { return min_; }
2659 const RangeBoundary& max() const { return max_; } 2737 const RangeBoundary& max() const { return max_; }
2660 2738
2661 static RangeBoundary ConstantMin(const Range* range) { 2739 static RangeBoundary ConstantMinSmi(const Range* range) {
2662 if (range == NULL) { 2740 if (range == NULL) {
2663 return RangeBoundary::MinSmi(); 2741 return RangeBoundary::MinSmi();
2664 } 2742 }
2665 return range->min().LowerBound().Clamp(); 2743 return range->min().LowerBound().Clamp(RangeBoundary::kRangeBoundarySmi);
2744 }
2745
2746 static RangeBoundary ConstantMaxSmi(const Range* range) {
2747 if (range == NULL) {
2748 return RangeBoundary::MaxSmi();
2749 }
2750 return range->max().UpperBound().Clamp(RangeBoundary::kRangeBoundarySmi);
2751 }
2752
2753 static RangeBoundary ConstantMin(const Range* range) {
2754 if (range == NULL) {
2755 return RangeBoundary::MinConstant();
2756 }
2757 return range->min().LowerBound().Clamp(RangeBoundary::kRangeBoundaryInt64);
2666 } 2758 }
2667 2759
2668 static RangeBoundary ConstantMax(const Range* range) { 2760 static RangeBoundary ConstantMax(const Range* range) {
2669 if (range == NULL) { 2761 if (range == NULL) {
2670 return RangeBoundary::MaxSmi(); 2762 return RangeBoundary::MaxConstant();
2671 } 2763 }
2672 return range->max().UpperBound().Clamp(); 2764 return range->max().UpperBound().Clamp(RangeBoundary::kRangeBoundaryInt64);
2673 } 2765 }
2674 2766
2675 // [0, +inf] 2767 // [0, +inf]
2676 bool IsPositive() const; 2768 bool IsPositive() const;
2677 2769
2678 // [-inf, 0) 2770 // [-inf, val].
2679 bool IsNegative() const; 2771 bool OnlyLessThanOrEqualTo(int64_t val) const;
2680 2772
2681 // [-inf, val]. 2773 // [val, +inf].
2682 bool OnlyLessThanOrEqualTo(intptr_t val) const; 2774 bool OnlyGreaterThanOrEqualTo(int64_t val) const;
2683 2775
2684 // Inclusive. 2776 // Inclusive.
2685 bool IsWithin(intptr_t min_int, intptr_t max_int) const; 2777 bool IsWithin(int64_t min_int, int64_t max_int) const;
2686 2778
2687 // Inclusive. 2779 // Inclusive.
2688 bool Overlaps(intptr_t min_int, intptr_t max_int) const; 2780 bool Overlaps(int64_t min_int, int64_t max_int) const;
2689 2781
2690 bool IsUnsatisfiable() const; 2782 bool IsUnsatisfiable() const;
2691 2783
2692 static void Shl(Range* left_range, 2784 bool IsFinite() const {
2693 Range* right_range, 2785 return !min_.IsInfinity() && !max_.IsInfinity();
2786 }
2787
2788 // Clamp this to be within size.
2789 void Clamp(RangeBoundary::RangeSize size);
2790
2791 static void Add(const Range* left_range,
2792 const Range* right_range,
2793 RangeBoundary* min,
2794 RangeBoundary* max,
2795 Definition* left_defn);
2796
2797 static void Sub(const Range* left_range,
2798 const Range* right_range,
2799 RangeBoundary* min,
2800 RangeBoundary* max,
2801 Definition* left_defn);
2802
2803 static bool Mul(const Range* left_range,
2804 const Range* right_range,
2694 RangeBoundary* min, 2805 RangeBoundary* min,
2695 RangeBoundary* max); 2806 RangeBoundary* max);
2696 2807
2808 static void Shl(const Range* left_range,
2809 const Range* right_range,
2810 RangeBoundary* min,
2811 RangeBoundary* max);
2812
2813 static bool And(const Range* left_range,
2814 const Range* right_range,
2815 RangeBoundary* min,
2816 RangeBoundary* max);
2817
2818
2819 // Both the a and b ranges are >= 0.
2820 static bool OnlyPositiveOrZero(const Range& a, const Range& b);
2821
2822 // Both the a and b ranges are <= 0.
2823 static bool OnlyNegativeOrZero(const Range& a, const Range& b);
2824
2825 // Return the maximum absolute value included in range.
2826 static int64_t ConstantAbsMax(const Range* range);
2827
2828 static Range* BinaryOp(const Token::Kind op,
2829 const Range* left_range,
2830 const Range* right_range,
2831 Definition* left_defn);
2832
2697 private: 2833 private:
2698 RangeBoundary min_; 2834 RangeBoundary min_;
2699 RangeBoundary max_; 2835 RangeBoundary max_;
2700 }; 2836 };
2701 2837
2702 2838
2703 class ConstraintInstr : public TemplateDefinition<2> { 2839 class ConstraintInstr : public TemplateDefinition<2> {
2704 public: 2840 public:
2705 ConstraintInstr(Value* value, Range* constraint) 2841 ConstraintInstr(Value* value, Range* constraint)
2706 : constraint_(constraint), 2842 : constraint_(constraint),
(...skipping 2419 matching lines...) Expand 10 before | Expand all | Expand 10 after
5126 virtual bool CanDeoptimize() const { 5262 virtual bool CanDeoptimize() const {
5127 return (value()->Type()->ToCid() != kSmiCid) 5263 return (value()->Type()->ToCid() != kSmiCid)
5128 && (value()->Type()->ToCid() != kMintCid); 5264 && (value()->Type()->ToCid() != kMintCid);
5129 } 5265 }
5130 5266
5131 virtual Representation representation() const { 5267 virtual Representation representation() const {
5132 return kUnboxedMint; 5268 return kUnboxedMint;
5133 } 5269 }
5134 5270
5135 5271
5272 virtual void InferRange();
5273
5136 DECLARE_INSTRUCTION(UnboxInteger) 5274 DECLARE_INSTRUCTION(UnboxInteger)
5137 virtual CompileType ComputeType() const; 5275 virtual CompileType ComputeType() const;
5138 5276
5139 virtual bool AllowsCSE() const { return true; } 5277 virtual bool AllowsCSE() const { return true; }
5140 virtual EffectSet Effects() const { return EffectSet::None(); } 5278 virtual EffectSet Effects() const { return EffectSet::None(); }
5141 virtual EffectSet Dependencies() const { return EffectSet::None(); } 5279 virtual EffectSet Dependencies() const { return EffectSet::None(); }
5142 virtual bool AttributesEqual(Instruction* other) const { return true; } 5280 virtual bool AttributesEqual(Instruction* other) const { return true; }
5143 5281
5144 virtual bool MayThrow() const { return false; } 5282 virtual bool MayThrow() const { return false; }
5145 5283
(...skipping 1769 matching lines...) Expand 10 before | Expand all | Expand 10 after
6915 ASSERT((idx == 0) || (idx == 1)); 7053 ASSERT((idx == 0) || (idx == 1));
6916 return kUnboxedMint; 7054 return kUnboxedMint;
6917 } 7055 }
6918 7056
6919 virtual intptr_t DeoptimizationTarget() const { 7057 virtual intptr_t DeoptimizationTarget() const {
6920 // Direct access since this instruction cannot deoptimize, and the deopt-id 7058 // Direct access since this instruction cannot deoptimize, and the deopt-id
6921 // was inherited from another instruction that could deoptimize. 7059 // was inherited from another instruction that could deoptimize.
6922 return deopt_id_; 7060 return deopt_id_;
6923 } 7061 }
6924 7062
7063 virtual void InferRange();
7064
6925 virtual Definition* Canonicalize(FlowGraph* flow_graph); 7065 virtual Definition* Canonicalize(FlowGraph* flow_graph);
6926 7066
6927 DECLARE_INSTRUCTION(BinaryMintOp) 7067 DECLARE_INSTRUCTION(BinaryMintOp)
6928 virtual CompileType ComputeType() const; 7068 virtual CompileType ComputeType() const;
6929 7069
6930 virtual bool AllowsCSE() const { return true; } 7070 virtual bool AllowsCSE() const { return true; }
6931 virtual EffectSet Effects() const { return EffectSet::None(); } 7071 virtual EffectSet Effects() const { return EffectSet::None(); }
6932 virtual EffectSet Dependencies() const { return EffectSet::None(); } 7072 virtual EffectSet Dependencies() const { return EffectSet::None(); }
6933 virtual bool AttributesEqual(Instruction* other) const { 7073 virtual bool AttributesEqual(Instruction* other) const {
6934 ASSERT(other->IsBinaryMintOp()); 7074 ASSERT(other->IsBinaryMintOp());
(...skipping 1103 matching lines...) Expand 10 before | Expand all | Expand 10 after
8038 ForwardInstructionIterator* current_iterator_; 8178 ForwardInstructionIterator* current_iterator_;
8039 8179
8040 private: 8180 private:
8041 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); 8181 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor);
8042 }; 8182 };
8043 8183
8044 8184
8045 } // namespace dart 8185 } // namespace dart
8046 8186
8047 #endif // VM_INTERMEDIATE_LANGUAGE_H_ 8187 #endif // VM_INTERMEDIATE_LANGUAGE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698