| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 1096 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1107 virtual void PrintTo(BufferFormatter* f) const; | 1107 virtual void PrintTo(BufferFormatter* f) const; |
| 1108 virtual void PrintOperandsTo(BufferFormatter* f) const; | 1108 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 1109 virtual void PrintToVisualizer(BufferFormatter* f) const; | 1109 virtual void PrintToVisualizer(BufferFormatter* f) const; |
| 1110 | 1110 |
| 1111 // A value in the constant propagation lattice. | 1111 // A value in the constant propagation lattice. |
| 1112 // - non-constant sentinel | 1112 // - non-constant sentinel |
| 1113 // - a constant (any non-sentinel value) | 1113 // - a constant (any non-sentinel value) |
| 1114 // - unknown sentinel | 1114 // - unknown sentinel |
| 1115 Object& constant_value() const { return constant_value_; } | 1115 Object& constant_value() const { return constant_value_; } |
| 1116 | 1116 |
| 1117 virtual bool InferRange(); | 1117 enum RangeOperator { kRangeInit, kRangeWiden, kRangeNarrow }; |
| 1118 |
| 1119 virtual bool InferRange(RangeOperator op); |
| 1118 | 1120 |
| 1119 Range* range() const { return range_; } | 1121 Range* range() const { return range_; } |
| 1120 | 1122 |
| 1121 // Definitions can be canonicalized only into definitions to ensure | 1123 // Definitions can be canonicalized only into definitions to ensure |
| 1122 // this check statically we override base Canonicalize with a Canonicalize | 1124 // this check statically we override base Canonicalize with a Canonicalize |
| 1123 // returning Definition (return type is covariant). | 1125 // returning Definition (return type is covariant). |
| 1124 virtual Definition* Canonicalize(); | 1126 virtual Definition* Canonicalize(); |
| 1125 | 1127 |
| 1126 protected: | 1128 protected: |
| 1127 Range* range_; | 1129 Range* range_; |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1202 virtual intptr_t ResultCid() const { | 1204 virtual intptr_t ResultCid() const { |
| 1203 UNREACHABLE(); | 1205 UNREACHABLE(); |
| 1204 return kIllegalCid; | 1206 return kIllegalCid; |
| 1205 } | 1207 } |
| 1206 | 1208 |
| 1207 DECLARE_INSTRUCTION(Phi) | 1209 DECLARE_INSTRUCTION(Phi) |
| 1208 | 1210 |
| 1209 virtual void PrintTo(BufferFormatter* f) const; | 1211 virtual void PrintTo(BufferFormatter* f) const; |
| 1210 virtual void PrintToVisualizer(BufferFormatter* f) const; | 1212 virtual void PrintToVisualizer(BufferFormatter* f) const; |
| 1211 | 1213 |
| 1212 virtual bool InferRange(); | 1214 virtual bool InferRange(RangeOperator op); |
| 1213 | 1215 |
| 1214 private: | 1216 private: |
| 1215 friend class JoinEntryInstr; // Direct access to inputs_ array. | 1217 friend class JoinEntryInstr; // Direct access to inputs_ array. |
| 1216 | 1218 |
| 1217 JoinEntryInstr* block_; | 1219 JoinEntryInstr* block_; |
| 1218 GrowableArray<Value*> inputs_; | 1220 GrowableArray<Value*> inputs_; |
| 1219 bool is_alive_; | 1221 bool is_alive_; |
| 1220 Representation representation_; | 1222 Representation representation_; |
| 1221 | 1223 |
| 1222 // Used to determine an interation of a range analysis after all phi inputs | 1224 // Used to determine an interation of a range analysis after all phi inputs |
| (...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1595 } | 1597 } |
| 1596 | 1598 |
| 1597 static RangeBoundary MinSmi() { | 1599 static RangeBoundary MinSmi() { |
| 1598 return FromConstant(Smi::kMinValue); | 1600 return FromConstant(Smi::kMinValue); |
| 1599 } | 1601 } |
| 1600 | 1602 |
| 1601 static RangeBoundary MaxSmi() { | 1603 static RangeBoundary MaxSmi() { |
| 1602 return FromConstant(Smi::kMaxValue); | 1604 return FromConstant(Smi::kMaxValue); |
| 1603 } | 1605 } |
| 1604 | 1606 |
| 1607 static const intptr_t kMinusInfinity = Smi::kMinValue - 1; |
| 1608 static const intptr_t kPlusInfinity = Smi::kMaxValue + 1; |
| 1609 |
| 1605 static RangeBoundary OverflowedMinSmi() { | 1610 static RangeBoundary OverflowedMinSmi() { |
| 1606 return FromConstant(Smi::kMinValue - 1); | 1611 return FromConstant(Smi::kMinValue - 1); |
| 1607 } | 1612 } |
| 1608 | 1613 |
| 1609 static RangeBoundary OverflowedMaxSmi() { | 1614 static RangeBoundary OverflowedMaxSmi() { |
| 1610 return FromConstant(Smi::kMaxValue + 1); | 1615 return FromConstant(Smi::kMaxValue + 1); |
| 1611 } | 1616 } |
| 1612 | 1617 |
| 1613 static RangeBoundary Min(RangeBoundary a, RangeBoundary b) { | 1618 static RangeBoundary Min(RangeBoundary a, RangeBoundary b) { |
| 1614 const intptr_t min_a = a.LowerBound().value(); | 1619 const intptr_t min_a = a.LowerBound().value(); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1653 ASSERT(IsSymbol()); | 1658 ASSERT(IsSymbol()); |
| 1654 return reinterpret_cast<Definition*>(value_); | 1659 return reinterpret_cast<Definition*>(value_); |
| 1655 } | 1660 } |
| 1656 | 1661 |
| 1657 RangeBoundary LowerBound() const; | 1662 RangeBoundary LowerBound() const; |
| 1658 RangeBoundary UpperBound() const; | 1663 RangeBoundary UpperBound() const; |
| 1659 | 1664 |
| 1660 static RangeBoundary WidenMin(const RangeBoundary& old_min, | 1665 static RangeBoundary WidenMin(const RangeBoundary& old_min, |
| 1661 const RangeBoundary& new_min) { | 1666 const RangeBoundary& new_min) { |
| 1662 if (new_min.LowerBound().value() < old_min.LowerBound().value()) { | 1667 if (new_min.LowerBound().value() < old_min.LowerBound().value()) { |
| 1663 return MinSmi(); | 1668 return OverflowedMinSmi(); |
| 1664 } | 1669 } |
| 1665 return new_min; | 1670 return old_min; |
| 1666 } | 1671 } |
| 1667 | 1672 |
| 1668 static RangeBoundary WidenMax(const RangeBoundary& old_max, | 1673 static RangeBoundary WidenMax(const RangeBoundary& old_max, |
| 1669 const RangeBoundary& new_max) { | 1674 const RangeBoundary& new_max) { |
| 1670 if (new_max.UpperBound().value() > old_max.UpperBound().value()) { | 1675 if (new_max.UpperBound().value() > old_max.UpperBound().value()) { |
| 1671 return MaxSmi(); | 1676 return OverflowedMaxSmi(); |
| 1672 } | 1677 } |
| 1673 return new_max; | 1678 return old_max; |
| 1679 } |
| 1680 |
| 1681 static RangeBoundary NarrowMin(const RangeBoundary& old_min, |
| 1682 const RangeBoundary& new_min) { |
| 1683 ASSERT(old_min.IsConstant()); |
| 1684 ASSERT(new_min.IsConstant()); |
| 1685 return (old_min.value() == kMinusInfinity) ? new_min |
| 1686 : Min(old_min, new_min); |
| 1687 } |
| 1688 |
| 1689 static RangeBoundary NarrowMax(const RangeBoundary& old_max, |
| 1690 const RangeBoundary& new_max) { |
| 1691 return (old_max.value() == kPlusInfinity) ? new_max |
| 1692 : Max(old_max, new_max); |
| 1674 } | 1693 } |
| 1675 | 1694 |
| 1676 void PrintTo(BufferFormatter* f) const; | 1695 void PrintTo(BufferFormatter* f) const; |
| 1677 | 1696 |
| 1678 static RangeBoundary Add(const RangeBoundary& a, | 1697 static RangeBoundary Add(const RangeBoundary& a, |
| 1679 const RangeBoundary& b, | 1698 const RangeBoundary& b, |
| 1680 const RangeBoundary& overflow) { | 1699 const RangeBoundary& overflow) { |
| 1681 ASSERT(a.IsConstant() && b.IsConstant()); | 1700 ASSERT(a.IsConstant() && b.IsConstant()); |
| 1682 | 1701 |
| 1683 intptr_t result = a.value() + b.value(); | 1702 intptr_t result = a.value() + b.value(); |
| (...skipping 27 matching lines...) Expand all Loading... |
| 1711 | 1730 |
| 1712 class Range : public ZoneAllocated { | 1731 class Range : public ZoneAllocated { |
| 1713 public: | 1732 public: |
| 1714 Range(RangeBoundary min, RangeBoundary max) : min_(min), max_(max) { } | 1733 Range(RangeBoundary min, RangeBoundary max) : min_(min), max_(max) { } |
| 1715 | 1734 |
| 1716 static Range* Unknown() { | 1735 static Range* Unknown() { |
| 1717 return new Range(RangeBoundary::MinSmi(), RangeBoundary::MaxSmi()); | 1736 return new Range(RangeBoundary::MinSmi(), RangeBoundary::MaxSmi()); |
| 1718 } | 1737 } |
| 1719 | 1738 |
| 1720 void PrintTo(BufferFormatter* f) const; | 1739 void PrintTo(BufferFormatter* f) const; |
| 1740 static const char* ToCString(Range* range); |
| 1721 | 1741 |
| 1722 const RangeBoundary& min() { return min_; } | 1742 const RangeBoundary& min() { return min_; } |
| 1723 const RangeBoundary& max() { return max_; } | 1743 const RangeBoundary& max() { return max_; } |
| 1724 | 1744 |
| 1725 bool Equals(Range* other) { | 1745 bool Equals(Range* other) { |
| 1726 return min_.Equals(other->min_) && max_.Equals(other->max_); | 1746 return min_.Equals(other->min_) && max_.Equals(other->max_); |
| 1727 } | 1747 } |
| 1728 | 1748 |
| 1729 static bool Update(Range** range_slot, | 1749 static bool Update(Range** range_slot, |
| 1730 const RangeBoundary& min, | 1750 const RangeBoundary& min, |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1784 virtual bool AttributesEqual(Instruction* other) const { | 1804 virtual bool AttributesEqual(Instruction* other) const { |
| 1785 UNREACHABLE(); | 1805 UNREACHABLE(); |
| 1786 return false; | 1806 return false; |
| 1787 } | 1807 } |
| 1788 | 1808 |
| 1789 virtual void PrintOperandsTo(BufferFormatter* f) const; | 1809 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 1790 | 1810 |
| 1791 Value* value() const { return inputs_[0]; } | 1811 Value* value() const { return inputs_[0]; } |
| 1792 Range* constraint() const { return constraint_; } | 1812 Range* constraint() const { return constraint_; } |
| 1793 | 1813 |
| 1794 virtual bool InferRange(); | 1814 virtual bool InferRange(RangeOperator op); |
| 1795 | 1815 |
| 1796 void AddDependency(Definition* defn) { | 1816 void AddDependency(Definition* defn) { |
| 1797 Value* val = new Value(defn); | 1817 Value* val = new Value(defn); |
| 1798 val->set_use_index(1); | 1818 val->set_use_index(1); |
| 1799 val->set_instruction(this); | 1819 val->set_instruction(this); |
| 1800 val->AddToInputUseList(); | 1820 val->AddToInputUseList(); |
| 1801 set_dependency(val); | 1821 set_dependency(val); |
| 1802 } | 1822 } |
| 1803 | 1823 |
| 1804 void RemoveDependency() { | 1824 void RemoveDependency() { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1837 | 1857 |
| 1838 virtual bool CanDeoptimize() const { return false; } | 1858 virtual bool CanDeoptimize() const { return false; } |
| 1839 | 1859 |
| 1840 virtual bool HasSideEffect() const { return false; } | 1860 virtual bool HasSideEffect() const { return false; } |
| 1841 | 1861 |
| 1842 virtual intptr_t ResultCid() const; | 1862 virtual intptr_t ResultCid() const; |
| 1843 | 1863 |
| 1844 virtual bool AttributesEqual(Instruction* other) const; | 1864 virtual bool AttributesEqual(Instruction* other) const; |
| 1845 virtual bool AffectedBySideEffect() const { return false; } | 1865 virtual bool AffectedBySideEffect() const { return false; } |
| 1846 | 1866 |
| 1847 virtual bool InferRange(); | 1867 virtual bool InferRange(RangeOperator op); |
| 1848 | 1868 |
| 1849 private: | 1869 private: |
| 1850 const Object& value_; | 1870 const Object& value_; |
| 1851 | 1871 |
| 1852 DISALLOW_COPY_AND_ASSIGN(ConstantInstr); | 1872 DISALLOW_COPY_AND_ASSIGN(ConstantInstr); |
| 1853 }; | 1873 }; |
| 1854 | 1874 |
| 1855 | 1875 |
| 1856 class AssertAssignableInstr : public TemplateDefinition<3> { | 1876 class AssertAssignableInstr : public TemplateDefinition<3> { |
| 1857 public: | 1877 public: |
| (...skipping 1620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3478 virtual bool AttributesEqual(Instruction* other) const; | 3498 virtual bool AttributesEqual(Instruction* other) const; |
| 3479 | 3499 |
| 3480 virtual intptr_t ResultCid() const; | 3500 virtual intptr_t ResultCid() const; |
| 3481 | 3501 |
| 3482 void set_overflow(bool overflow) { | 3502 void set_overflow(bool overflow) { |
| 3483 overflow_ = overflow; | 3503 overflow_ = overflow; |
| 3484 } | 3504 } |
| 3485 | 3505 |
| 3486 void PrintTo(BufferFormatter* f) const; | 3506 void PrintTo(BufferFormatter* f) const; |
| 3487 | 3507 |
| 3488 virtual bool InferRange(); | 3508 virtual bool InferRange(RangeOperator op); |
| 3489 | 3509 |
| 3490 private: | 3510 private: |
| 3491 const Token::Kind op_kind_; | 3511 const Token::Kind op_kind_; |
| 3492 InstanceCallInstr* instance_call_; | 3512 InstanceCallInstr* instance_call_; |
| 3493 bool overflow_; | 3513 bool overflow_; |
| 3494 | 3514 |
| 3495 DISALLOW_COPY_AND_ASSIGN(BinarySmiOpInstr); | 3515 DISALLOW_COPY_AND_ASSIGN(BinarySmiOpInstr); |
| 3496 }; | 3516 }; |
| 3497 | 3517 |
| 3498 | 3518 |
| (...skipping 467 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3966 ForwardInstructionIterator* current_iterator_; | 3986 ForwardInstructionIterator* current_iterator_; |
| 3967 | 3987 |
| 3968 private: | 3988 private: |
| 3969 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 3989 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
| 3970 }; | 3990 }; |
| 3971 | 3991 |
| 3972 | 3992 |
| 3973 } // namespace dart | 3993 } // namespace dart |
| 3974 | 3994 |
| 3975 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 3995 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
| OLD | NEW |