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

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
« no previous file with comments | « runtime/vm/il_printer.cc ('k') | runtime/vm/intermediate_language.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 the given 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 of the given type.
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()) {
2553 return MaxSmi();
2554 } else if (IsConstant()) {
2555 if (value() < Smi::kMinValue) return MinSmi();
2556 if (value() > Smi::kMaxValue) return MaxSmi();
2557 } 2600 }
2601 if (IsPositiveInfinity()) {
2602 return (size == kRangeBoundaryInt64) ? MaxConstant() : MaxSmi();
2603 }
2604 if ((size == kRangeBoundarySmi) && IsConstant()) {
2605 if (ConstantValue() <= Smi::kMinValue) {
2606 return MinSmi();
2607 }
2608 if (ConstantValue() >= Smi::kMaxValue) {
2609 return MaxSmi();
2610 }
2611 }
2612 // If this range is a symbolic range, we do not clamp it.
2613 // This could lead to some imprecision later on.
2558 return *this; 2614 return *this;
2559 } 2615 }
2560 2616
2561 bool Equals(const RangeBoundary& other) { 2617
2562 return kind_ == other.kind_ 2618 bool IsSmiMinimumOrBelow() const {
2563 && value_ == other.value_ 2619 return IsNegativeInfinity() ||
2564 && offset_ == other.offset_; 2620 (IsConstant() && (ConstantValue() <= Smi::kMinValue));
2565 } 2621 }
2566 2622
2623 bool IsSmiMaximumOrAbove() const {
2624 return IsPositiveInfinity() ||
2625 (IsConstant() && (ConstantValue() >= Smi::kMaxValue));
2626 }
2627
2628 bool IsMinimumOrBelow() const {
2629 return IsNegativeInfinity() || (IsConstant() && (ConstantValue() == kMin));
2630 }
2631
2632 bool IsMaximumOrAbove() const {
2633 return IsPositiveInfinity() || (IsConstant() && (ConstantValue() == kMax));
2634 }
2635
2636 intptr_t kind() const {
2637 return kind_;
2638 }
2639
2640 // Kind tests.
2567 bool IsUnknown() const { return kind_ == kUnknown; } 2641 bool IsUnknown() const { return kind_ == kUnknown; }
2568 bool IsConstant() const { return kind_ == kConstant; } 2642 bool IsConstant() const { return kind_ == kConstant; }
2569 bool IsSymbol() const { return kind_ == kSymbol; } 2643 bool IsSymbol() const { return kind_ == kSymbol; }
2570 bool IsNegativeInfinity() const { return kind_ == kNegativeInfinity; } 2644 bool IsNegativeInfinity() const { return kind_ == kNegativeInfinity; }
2571 bool IsPositiveInfinity() const { return kind_ == kPositiveInfinity; } 2645 bool IsPositiveInfinity() const { return kind_ == kPositiveInfinity; }
2572 bool IsInfinity() const { 2646 bool IsInfinity() const {
2573 return IsNegativeInfinity() || IsPositiveInfinity(); 2647 return IsNegativeInfinity() || IsPositiveInfinity();
2574 } 2648 }
2575 2649 bool IsConstantOrInfinity() const {
2576 intptr_t value() const { 2650 return IsConstant() || IsInfinity();
2577 ASSERT(IsConstant());
2578 return value_;
2579 } 2651 }
2580 2652
2653 // Returns the value of a kConstant RangeBoundary.
2654 int64_t ConstantValue() const;
2655
2656 // Returns the Definition associated with a kSymbol RangeBoundary.
2581 Definition* symbol() const { 2657 Definition* symbol() const {
2582 ASSERT(IsSymbol()); 2658 ASSERT(IsSymbol());
2583 return reinterpret_cast<Definition*>(value_); 2659 return reinterpret_cast<Definition*>(value_);
2584 } 2660 }
2585 2661
2586 intptr_t offset() const { 2662 // Offset from symbol.
2663 int64_t offset() const {
2587 return offset_; 2664 return offset_;
2588 } 2665 }
2589 2666
2667 // Computes the LowerBound of this. Three cases:
2668 // IsInfinity() -> NegativeInfinity().
2669 // IsConstant() -> value().
2670 // IsSymbol() -> lower bound computed from definition + offset.
2590 RangeBoundary LowerBound() const; 2671 RangeBoundary LowerBound() const;
2672
2673 // Computes the UpperBound of this. Three cases:
2674 // IsInfinity() -> PositiveInfinity().
2675 // IsConstant() -> value().
2676 // IsSymbol() -> upper bound computed from definition + offset.
2591 RangeBoundary UpperBound() const; 2677 RangeBoundary UpperBound() const;
2592 2678
2593 void PrintTo(BufferFormatter* f) const; 2679 void PrintTo(BufferFormatter* f) const;
2594 const char* ToCString() const; 2680 const char* ToCString() const;
2595 2681
2596 static RangeBoundary Add(const RangeBoundary& a, 2682 static RangeBoundary Add(const RangeBoundary& a,
2597 const RangeBoundary& b, 2683 const RangeBoundary& b,
2598 const RangeBoundary& overflow) { 2684 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 2685
2608 static RangeBoundary Sub(const RangeBoundary& a, 2686 static RangeBoundary Sub(const RangeBoundary& a,
2609 const RangeBoundary& b, 2687 const RangeBoundary& b,
2610 const RangeBoundary& overflow) { 2688 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 2689
2620 static RangeBoundary Shl(const RangeBoundary& value_boundary, 2690 static RangeBoundary Shl(const RangeBoundary& value_boundary,
2621 intptr_t shift_count, 2691 int64_t shift_count,
2622 const RangeBoundary& overflow) { 2692 const RangeBoundary& overflow);
2623 ASSERT(value_boundary.IsConstant()); 2693
2624 ASSERT(shift_count >= 0); 2694 // Attempts to calculate a + b when:
2625 intptr_t limit = 64 - shift_count; 2695 // a is a symbol and b is a constant OR
2626 int64_t value = static_cast<int64_t>(value_boundary.value()); 2696 // a is a constant and b is a symbol
2627 if ((value == 0) || 2697 // returns true if it succeeds, output is in result.
2628 (shift_count == 0) || 2698 static bool SymbolicAdd(const RangeBoundary& a,
2629 ((limit > 0) && (Utils::IsInt(limit, value)))) { 2699 const RangeBoundary& b,
2630 // Result stays in 64 bit range. 2700 RangeBoundary* result);
2631 int64_t result = value << shift_count; 2701
2632 return Smi::IsValid64(result) ? RangeBoundary(result) : overflow; 2702 // Attempts to calculate a - b when:
2633 } 2703 // a is a symbol and b is a constant
2634 return overflow; 2704 // returns true if it succeeds, output is in result.
2635 } 2705 static bool SymbolicSub(const RangeBoundary& a,
2706 const RangeBoundary& b,
2707 RangeBoundary* result);
2708
2709 bool Equals(const RangeBoundary& other) const;
2636 2710
2637 private: 2711 private:
2638 RangeBoundary(Kind kind, intptr_t value, intptr_t offset) 2712 RangeBoundary(Kind kind, int64_t value, int64_t offset)
2639 : kind_(kind), value_(value), offset_(offset) { } 2713 : kind_(kind), value_(value), offset_(offset) { }
2640 2714
2641 Kind kind_; 2715 Kind kind_;
2642 intptr_t value_; 2716 int64_t value_;
2643 intptr_t offset_; 2717 int64_t offset_;
2644 }; 2718 };
2645 2719
2646 2720
2647 class Range : public ZoneAllocated { 2721 class Range : public ZoneAllocated {
2648 public: 2722 public:
2649 Range(RangeBoundary min, RangeBoundary max) : min_(min), max_(max) { } 2723 Range(RangeBoundary min, RangeBoundary max) : min_(min), max_(max) { }
2650 2724
2651 static Range* Unknown() { 2725 static Range* Unknown() {
2652 return new Range(RangeBoundary::MinSmi(), RangeBoundary::MaxSmi()); 2726 return new Range(RangeBoundary::MinConstant(),
2727 RangeBoundary::MaxConstant());
2728 }
2729
2730 static Range* UnknownSmi() {
2731 return new Range(RangeBoundary::MinSmi(),
2732 RangeBoundary::MaxSmi());
2653 } 2733 }
2654 2734
2655 void PrintTo(BufferFormatter* f) const; 2735 void PrintTo(BufferFormatter* f) const;
2656 static const char* ToCString(Range* range); 2736 static const char* ToCString(const Range* range);
2657 2737
2658 const RangeBoundary& min() const { return min_; } 2738 const RangeBoundary& min() const { return min_; }
2659 const RangeBoundary& max() const { return max_; } 2739 const RangeBoundary& max() const { return max_; }
2660 2740
2661 static RangeBoundary ConstantMin(const Range* range) { 2741 static RangeBoundary ConstantMinSmi(const Range* range) {
2662 if (range == NULL) { 2742 if (range == NULL) {
2663 return RangeBoundary::MinSmi(); 2743 return RangeBoundary::MinSmi();
2664 } 2744 }
2665 return range->min().LowerBound().Clamp(); 2745 return range->min().LowerBound().Clamp(RangeBoundary::kRangeBoundarySmi);
2746 }
2747
2748 static RangeBoundary ConstantMaxSmi(const Range* range) {
2749 if (range == NULL) {
2750 return RangeBoundary::MaxSmi();
2751 }
2752 return range->max().UpperBound().Clamp(RangeBoundary::kRangeBoundarySmi);
2753 }
2754
2755 static RangeBoundary ConstantMin(const Range* range) {
2756 if (range == NULL) {
2757 return RangeBoundary::MinConstant();
2758 }
2759 return range->min().LowerBound().Clamp(RangeBoundary::kRangeBoundaryInt64);
2666 } 2760 }
2667 2761
2668 static RangeBoundary ConstantMax(const Range* range) { 2762 static RangeBoundary ConstantMax(const Range* range) {
2669 if (range == NULL) { 2763 if (range == NULL) {
2670 return RangeBoundary::MaxSmi(); 2764 return RangeBoundary::MaxConstant();
2671 } 2765 }
2672 return range->max().UpperBound().Clamp(); 2766 return range->max().UpperBound().Clamp(RangeBoundary::kRangeBoundaryInt64);
2673 } 2767 }
2674 2768
2675 // [0, +inf] 2769 // [0, +inf]
2676 bool IsPositive() const; 2770 bool IsPositive() const;
2677 2771
2678 // [-inf, 0) 2772 // [-inf, val].
2679 bool IsNegative() const; 2773 bool OnlyLessThanOrEqualTo(int64_t val) const;
2680 2774
2681 // [-inf, val]. 2775 // [val, +inf].
2682 bool OnlyLessThanOrEqualTo(intptr_t val) const; 2776 bool OnlyGreaterThanOrEqualTo(int64_t val) const;
2683 2777
2684 // Inclusive. 2778 // Inclusive.
2685 bool IsWithin(intptr_t min_int, intptr_t max_int) const; 2779 bool IsWithin(int64_t min_int, int64_t max_int) const;
2686 2780
2687 // Inclusive. 2781 // Inclusive.
2688 bool Overlaps(intptr_t min_int, intptr_t max_int) const; 2782 bool Overlaps(int64_t min_int, int64_t max_int) const;
2689 2783
2690 bool IsUnsatisfiable() const; 2784 bool IsUnsatisfiable() const;
2691 2785
2692 static void Shl(Range* left_range, 2786 bool IsFinite() const {
2693 Range* right_range, 2787 return !min_.IsInfinity() && !max_.IsInfinity();
2788 }
2789
2790 // Clamp this to be within size.
2791 void Clamp(RangeBoundary::RangeSize size);
2792
2793 static void Add(const Range* left_range,
2794 const Range* right_range,
2795 RangeBoundary* min,
2796 RangeBoundary* max,
2797 Definition* left_defn);
2798
2799 static void Sub(const Range* left_range,
2800 const Range* right_range,
2801 RangeBoundary* min,
2802 RangeBoundary* max,
2803 Definition* left_defn);
2804
2805 static bool Mul(const Range* left_range,
2806 const Range* right_range,
2694 RangeBoundary* min, 2807 RangeBoundary* min,
2695 RangeBoundary* max); 2808 RangeBoundary* max);
2696 2809
2810 static void Shl(const Range* left_range,
2811 const Range* right_range,
2812 RangeBoundary* min,
2813 RangeBoundary* max);
2814
2815 static bool And(const Range* left_range,
2816 const Range* right_range,
2817 RangeBoundary* min,
2818 RangeBoundary* max);
2819
2820
2821 // Both the a and b ranges are >= 0.
2822 static bool OnlyPositiveOrZero(const Range& a, const Range& b);
2823
2824 // Both the a and b ranges are <= 0.
2825 static bool OnlyNegativeOrZero(const Range& a, const Range& b);
2826
2827 // Return the maximum absolute value included in range.
2828 static int64_t ConstantAbsMax(const Range* range);
2829
2830 static Range* BinaryOp(const Token::Kind op,
2831 const Range* left_range,
2832 const Range* right_range,
2833 Definition* left_defn);
2834
2697 private: 2835 private:
2698 RangeBoundary min_; 2836 RangeBoundary min_;
2699 RangeBoundary max_; 2837 RangeBoundary max_;
2700 }; 2838 };
2701 2839
2702 2840
2703 class ConstraintInstr : public TemplateDefinition<2> { 2841 class ConstraintInstr : public TemplateDefinition<2> {
2704 public: 2842 public:
2705 ConstraintInstr(Value* value, Range* constraint) 2843 ConstraintInstr(Value* value, Range* constraint)
2706 : constraint_(constraint), 2844 : constraint_(constraint),
(...skipping 2419 matching lines...) Expand 10 before | Expand all | Expand 10 after
5126 virtual bool CanDeoptimize() const { 5264 virtual bool CanDeoptimize() const {
5127 return (value()->Type()->ToCid() != kSmiCid) 5265 return (value()->Type()->ToCid() != kSmiCid)
5128 && (value()->Type()->ToCid() != kMintCid); 5266 && (value()->Type()->ToCid() != kMintCid);
5129 } 5267 }
5130 5268
5131 virtual Representation representation() const { 5269 virtual Representation representation() const {
5132 return kUnboxedMint; 5270 return kUnboxedMint;
5133 } 5271 }
5134 5272
5135 5273
5274 virtual void InferRange();
5275
5136 DECLARE_INSTRUCTION(UnboxInteger) 5276 DECLARE_INSTRUCTION(UnboxInteger)
5137 virtual CompileType ComputeType() const; 5277 virtual CompileType ComputeType() const;
5138 5278
5139 virtual bool AllowsCSE() const { return true; } 5279 virtual bool AllowsCSE() const { return true; }
5140 virtual EffectSet Effects() const { return EffectSet::None(); } 5280 virtual EffectSet Effects() const { return EffectSet::None(); }
5141 virtual EffectSet Dependencies() const { return EffectSet::None(); } 5281 virtual EffectSet Dependencies() const { return EffectSet::None(); }
5142 virtual bool AttributesEqual(Instruction* other) const { return true; } 5282 virtual bool AttributesEqual(Instruction* other) const { return true; }
5143 5283
5144 virtual bool MayThrow() const { return false; } 5284 virtual bool MayThrow() const { return false; }
5145 5285
(...skipping 1769 matching lines...) Expand 10 before | Expand all | Expand 10 after
6915 ASSERT((idx == 0) || (idx == 1)); 7055 ASSERT((idx == 0) || (idx == 1));
6916 return kUnboxedMint; 7056 return kUnboxedMint;
6917 } 7057 }
6918 7058
6919 virtual intptr_t DeoptimizationTarget() const { 7059 virtual intptr_t DeoptimizationTarget() const {
6920 // Direct access since this instruction cannot deoptimize, and the deopt-id 7060 // Direct access since this instruction cannot deoptimize, and the deopt-id
6921 // was inherited from another instruction that could deoptimize. 7061 // was inherited from another instruction that could deoptimize.
6922 return deopt_id_; 7062 return deopt_id_;
6923 } 7063 }
6924 7064
7065 virtual void InferRange();
7066
6925 virtual Definition* Canonicalize(FlowGraph* flow_graph); 7067 virtual Definition* Canonicalize(FlowGraph* flow_graph);
6926 7068
6927 DECLARE_INSTRUCTION(BinaryMintOp) 7069 DECLARE_INSTRUCTION(BinaryMintOp)
6928 virtual CompileType ComputeType() const; 7070 virtual CompileType ComputeType() const;
6929 7071
6930 virtual bool AllowsCSE() const { return true; } 7072 virtual bool AllowsCSE() const { return true; }
6931 virtual EffectSet Effects() const { return EffectSet::None(); } 7073 virtual EffectSet Effects() const { return EffectSet::None(); }
6932 virtual EffectSet Dependencies() const { return EffectSet::None(); } 7074 virtual EffectSet Dependencies() const { return EffectSet::None(); }
6933 virtual bool AttributesEqual(Instruction* other) const { 7075 virtual bool AttributesEqual(Instruction* other) const {
6934 ASSERT(other->IsBinaryMintOp()); 7076 ASSERT(other->IsBinaryMintOp());
(...skipping 1103 matching lines...) Expand 10 before | Expand all | Expand 10 after
8038 ForwardInstructionIterator* current_iterator_; 8180 ForwardInstructionIterator* current_iterator_;
8039 8181
8040 private: 8182 private:
8041 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); 8183 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor);
8042 }; 8184 };
8043 8185
8044 8186
8045 } // namespace dart 8187 } // namespace dart
8046 8188
8047 #endif // VM_INTERMEDIATE_LANGUAGE_H_ 8189 #endif // VM_INTERMEDIATE_LANGUAGE_H_
OLDNEW
« no previous file with comments | « runtime/vm/il_printer.cc ('k') | runtime/vm/intermediate_language.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698