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

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

Issue 10960014: Implement range analysis for smi values. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: addressed majority of comments Created 8 years, 3 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) 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"
11 #include "vm/handles_impl.h" 11 #include "vm/handles_impl.h"
12 #include "vm/locations.h" 12 #include "vm/locations.h"
13 #include "vm/object.h" 13 #include "vm/object.h"
14 14
15 namespace dart { 15 namespace dart {
16 16
17 class BitVector; 17 class BitVector;
18 class BlockEntryInstr; 18 class BlockEntryInstr;
19 class BufferFormatter; 19 class BufferFormatter;
20 class ComparisonInstr; 20 class ComparisonInstr;
21 class ControlInstruction; 21 class ControlInstruction;
22 class Definition; 22 class Definition;
23 class Environment; 23 class Environment;
24 class FlowGraphCompiler; 24 class FlowGraphCompiler;
25 class FlowGraphVisitor; 25 class FlowGraphVisitor;
26 class Instruction; 26 class Instruction;
27 class LocalVariable; 27 class LocalVariable;
28 class Range;
28 29
29 30
30 // TODO(srdjan): Add _ByteArrayBase, get:length. 31 // TODO(srdjan): Add _ByteArrayBase, get:length.
31 32
32 #define RECOGNIZED_LIST(V) \ 33 #define RECOGNIZED_LIST(V) \
33 V(ObjectArray, get:length, ObjectArrayLength) \ 34 V(ObjectArray, get:length, ObjectArrayLength) \
34 V(ImmutableArray, get:length, ImmutableArrayLength) \ 35 V(ImmutableArray, get:length, ImmutableArrayLength) \
35 V(GrowableObjectArray, get:length, GrowableArrayLength) \ 36 V(GrowableObjectArray, get:length, GrowableArrayLength) \
36 V(GrowableObjectArray, get:capacity, GrowableArrayCapacity) \ 37 V(GrowableObjectArray, get:capacity, GrowableArrayCapacity) \
37 V(StringBase, get:length, StringBaseLength) \ 38 V(StringBase, get:length, StringBaseLength) \
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
73 74
74 Instruction* instruction() const { return instruction_; } 75 Instruction* instruction() const { return instruction_; }
75 void set_instruction(Instruction* instruction) { instruction_ = instruction; } 76 void set_instruction(Instruction* instruction) { instruction_ = instruction; }
76 77
77 intptr_t use_index() const { return use_index_; } 78 intptr_t use_index() const { return use_index_; }
78 void set_use_index(intptr_t index) { use_index_ = index; } 79 void set_use_index(intptr_t index) { use_index_ = index; }
79 80
80 void AddToInputUseList(); 81 void AddToInputUseList();
81 void AddToEnvUseList(); 82 void AddToEnvUseList();
82 83
84 void RemoveFromInputUseList();
85
83 Value* Copy() { return new Value(definition_); } 86 Value* Copy() { return new Value(definition_); }
84 87
85 RawAbstractType* CompileType() const; 88 RawAbstractType* CompileType() const;
86 intptr_t ResultCid() const; 89 intptr_t ResultCid() const;
87 90
88 void PrintTo(BufferFormatter* f) const; 91 void PrintTo(BufferFormatter* f) const;
89 92
90 const char* DebugName() const { return "Value"; } 93 const char* DebugName() const { return "Value"; }
91 94
92 // Return true if the value represents a constant. 95 // Return true if the value represents a constant.
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
245 M(SmiToDouble) \ 248 M(SmiToDouble) \
246 M(CheckClass) \ 249 M(CheckClass) \
247 M(CheckSmi) \ 250 M(CheckSmi) \
248 M(Constant) \ 251 M(Constant) \
249 M(CheckEitherNonSmi) \ 252 M(CheckEitherNonSmi) \
250 M(UnboxedDoubleBinaryOp) \ 253 M(UnboxedDoubleBinaryOp) \
251 M(MathSqrt) \ 254 M(MathSqrt) \
252 M(UnboxDouble) \ 255 M(UnboxDouble) \
253 M(BoxDouble) \ 256 M(BoxDouble) \
254 M(CheckArrayBound) \ 257 M(CheckArrayBound) \
258 M(Constraint) \
255 259
256 260
257 #define FORWARD_DECLARATION(type) class type##Instr; 261 #define FORWARD_DECLARATION(type) class type##Instr;
258 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION) 262 FOR_EACH_INSTRUCTION(FORWARD_DECLARATION)
259 #undef FORWARD_DECLARATION 263 #undef FORWARD_DECLARATION
260 264
261 265
262 // Functions required in all concrete instruction classes. 266 // Functions required in all concrete instruction classes.
263 #define DECLARE_INSTRUCTION(type) \ 267 #define DECLARE_INSTRUCTION(type) \
264 virtual Tag tag() const { return k##type; } \ 268 virtual Tag tag() const { return k##type; } \
(...skipping 451 matching lines...) Expand 10 before | Expand all | Expand 10 after
716 720
717 virtual bool HasSideEffect() const { return false; } 721 virtual bool HasSideEffect() const { return false; }
718 722
719 intptr_t try_index() const { return try_index_; } 723 intptr_t try_index() const { return try_index_; }
720 724
721 BitVector* loop_info() const { return loop_info_; } 725 BitVector* loop_info() const { return loop_info_; }
722 void set_loop_info(BitVector* loop_info) { 726 void set_loop_info(BitVector* loop_info) {
723 loop_info_ = loop_info; 727 loop_info_ = loop_info;
724 } 728 }
725 729
730 virtual BlockEntryInstr* GetBlock() const {
731 return const_cast<BlockEntryInstr*>(this);
732 }
733
726 protected: 734 protected:
727 explicit BlockEntryInstr(intptr_t try_index) 735 explicit BlockEntryInstr(intptr_t try_index)
728 : try_index_(try_index), 736 : try_index_(try_index),
729 preorder_number_(-1), 737 preorder_number_(-1),
730 postorder_number_(-1), 738 postorder_number_(-1),
731 block_id_(-1), 739 block_id_(-1),
732 dominator_(NULL), 740 dominator_(NULL),
733 dominated_blocks_(1), 741 dominated_blocks_(1),
734 last_instruction_(NULL), 742 last_instruction_(NULL),
735 parallel_move_(NULL), 743 parallel_move_(NULL),
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
922 930
923 GrowableArray<BlockEntryInstr*> predecessors_; 931 GrowableArray<BlockEntryInstr*> predecessors_;
924 ZoneGrowableArray<PhiInstr*>* phis_; 932 ZoneGrowableArray<PhiInstr*>* phis_;
925 intptr_t phi_count_; 933 intptr_t phi_count_;
926 GrowableArray<BlockEntryInstr*> stale_predecessors_; 934 GrowableArray<BlockEntryInstr*> stale_predecessors_;
927 935
928 DISALLOW_COPY_AND_ASSIGN(JoinEntryInstr); 936 DISALLOW_COPY_AND_ASSIGN(JoinEntryInstr);
929 }; 937 };
930 938
931 939
940 class PhiIterator : public ValueObject {
941 public:
942 explicit PhiIterator(JoinEntryInstr* join)
943 : phis_(join->phis()), index_(-1) {
944 if (!Done()) Advance(); // Advance to the first smi.
945 }
946
947 void Advance() {
948 ASSERT(!Done());
949 do {
950 index_++;
951 } while (!Done() && (Current() == NULL));
952 }
953
954 bool Done() const {
955 return (phis_ == NULL) || (index_ >= phis_->length());
956 }
957
958 PhiInstr* Current() const {
959 return (*phis_)[index_];
960 }
961
962 private:
963 ZoneGrowableArray<PhiInstr*>* phis_;
964 intptr_t index_;
965 };
966
967
932 class TargetEntryInstr : public BlockEntryInstr { 968 class TargetEntryInstr : public BlockEntryInstr {
933 public: 969 public:
934 explicit TargetEntryInstr(intptr_t try_index) 970 explicit TargetEntryInstr(intptr_t try_index)
935 : BlockEntryInstr(try_index), 971 : BlockEntryInstr(try_index),
936 predecessor_(NULL), 972 predecessor_(NULL),
937 catch_try_index_(CatchClauseNode::kInvalidTryIndex) { } 973 catch_try_index_(CatchClauseNode::kInvalidTryIndex) { }
938 974
939 // Used for exception catch entries. 975 // Used for exception catch entries.
940 TargetEntryInstr(intptr_t try_index, intptr_t catch_try_index) 976 TargetEntryInstr(intptr_t try_index, intptr_t catch_try_index)
941 : BlockEntryInstr(try_index), 977 : BlockEntryInstr(try_index),
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
1071 virtual void PrintTo(BufferFormatter* f) const; 1107 virtual void PrintTo(BufferFormatter* f) const;
1072 virtual void PrintOperandsTo(BufferFormatter* f) const; 1108 virtual void PrintOperandsTo(BufferFormatter* f) const;
1073 virtual void PrintToVisualizer(BufferFormatter* f) const; 1109 virtual void PrintToVisualizer(BufferFormatter* f) const;
1074 1110
1075 // A value in the constant propagation lattice. 1111 // A value in the constant propagation lattice.
1076 // - non-constant sentinel 1112 // - non-constant sentinel
1077 // - a constant (any non-sentinel value) 1113 // - a constant (any non-sentinel value)
1078 // - unknown sentinel 1114 // - unknown sentinel
1079 Object& constant_value() const { return constant_value_; } 1115 Object& constant_value() const { return constant_value_; }
1080 1116
1117 virtual bool InferRange();
1118
1119 Range* range() const { return range_; }
1120
1081 // Definitions can be canonicalized only into definitions to ensure 1121 // Definitions can be canonicalized only into definitions to ensure
1082 // this check statically we override base Canonicalize with a Canonicalize 1122 // this check statically we override base Canonicalize with a Canonicalize
1083 // returning Definition (return type is covariant). 1123 // returning Definition (return type is covariant).
1084 virtual Definition* Canonicalize(); 1124 virtual Definition* Canonicalize();
1085 1125
1126 protected:
1127 Range* range_;
1128
1086 private: 1129 private:
1087 intptr_t temp_index_; 1130 intptr_t temp_index_;
1088 intptr_t ssa_temp_index_; 1131 intptr_t ssa_temp_index_;
1089 // TODO(regis): GrowableArray<const AbstractType*> propagated_types_; 1132 // TODO(regis): GrowableArray<const AbstractType*> propagated_types_;
1090 // For now: 1133 // For now:
1091 AbstractType& propagated_type_; 1134 AbstractType& propagated_type_;
1092 intptr_t propagated_cid_; 1135 intptr_t propagated_cid_;
1093 Value* input_use_list_; 1136 Value* input_use_list_;
1094 Value* env_use_list_; 1137 Value* env_use_list_;
1095 UseKind use_kind_; 1138 UseKind use_kind_;
1096 1139
1097 Object& constant_value_; 1140 Object& constant_value_;
1098 1141
1099 DISALLOW_COPY_AND_ASSIGN(Definition); 1142 DISALLOW_COPY_AND_ASSIGN(Definition);
1100 }; 1143 };
1101 1144
1102 1145
1103 class PhiInstr : public Definition { 1146 class PhiInstr : public Definition {
1104 public: 1147 public:
1105 explicit PhiInstr(JoinEntryInstr* block, intptr_t num_inputs) 1148 explicit PhiInstr(JoinEntryInstr* block, intptr_t num_inputs)
1106 : block_(block), 1149 : block_(block),
1107 inputs_(num_inputs), 1150 inputs_(num_inputs),
1108 is_alive_(false), 1151 is_alive_(false),
1109 representation_(kTagged) { 1152 representation_(kTagged),
1153 has_inputs_without_range_(true) {
1110 for (intptr_t i = 0; i < num_inputs; ++i) { 1154 for (intptr_t i = 0; i < num_inputs; ++i) {
1111 inputs_.Add(NULL); 1155 inputs_.Add(NULL);
1112 } 1156 }
1113 } 1157 }
1114 1158
1115 // Get the block entry for that instruction. 1159 // Get the block entry for that instruction.
1116 virtual BlockEntryInstr* GetBlock() const { return block(); } 1160 virtual BlockEntryInstr* GetBlock() const { return block(); }
1117 JoinEntryInstr* block() const { return block_; } 1161 JoinEntryInstr* block() const { return block_; }
1118 1162
1119 virtual RawAbstractType* CompileType() const; 1163 virtual RawAbstractType* CompileType() const;
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1158 virtual intptr_t ResultCid() const { 1202 virtual intptr_t ResultCid() const {
1159 UNREACHABLE(); 1203 UNREACHABLE();
1160 return kIllegalCid; 1204 return kIllegalCid;
1161 } 1205 }
1162 1206
1163 DECLARE_INSTRUCTION(Phi) 1207 DECLARE_INSTRUCTION(Phi)
1164 1208
1165 virtual void PrintTo(BufferFormatter* f) const; 1209 virtual void PrintTo(BufferFormatter* f) const;
1166 virtual void PrintToVisualizer(BufferFormatter* f) const; 1210 virtual void PrintToVisualizer(BufferFormatter* f) const;
1167 1211
1212 virtual bool InferRange();
1213
1168 private: 1214 private:
1169 friend class JoinEntryInstr; // Direct access to inputs_ array. 1215 friend class JoinEntryInstr; // Direct access to inputs_ array.
1170 1216
1171 JoinEntryInstr* block_; 1217 JoinEntryInstr* block_;
1172 GrowableArray<Value*> inputs_; 1218 GrowableArray<Value*> inputs_;
1173 bool is_alive_; 1219 bool is_alive_;
1174 Representation representation_; 1220 Representation representation_;
1175 1221
1222 // Used to determine an interation of a range analysis after all phi inputs
ngeoffray 2012/09/24 21:44:15 interation -> iteration
1223 // were initialized to apply widening.
1224 bool has_inputs_without_range_;
1225
1176 DISALLOW_COPY_AND_ASSIGN(PhiInstr); 1226 DISALLOW_COPY_AND_ASSIGN(PhiInstr);
1177 }; 1227 };
1178 1228
1179 1229
1180 class ParameterInstr : public Definition { 1230 class ParameterInstr : public Definition {
1181 public: 1231 public:
1182 explicit ParameterInstr(intptr_t index, GraphEntryInstr* block) 1232 explicit ParameterInstr(intptr_t index, GraphEntryInstr* block)
1183 : index_(index), block_(block) { } 1233 : index_(index), block_(block) { }
1184 1234
1185 DECLARE_INSTRUCTION(Parameter) 1235 DECLARE_INSTRUCTION(Parameter)
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
1523 protected: 1573 protected:
1524 EmbeddedArray<Value*, N> inputs_; 1574 EmbeddedArray<Value*, N> inputs_;
1525 1575
1526 private: 1576 private:
1527 friend class BranchInstr; 1577 friend class BranchInstr;
1528 1578
1529 LocationSummary* locs_; 1579 LocationSummary* locs_;
1530 }; 1580 };
1531 1581
1532 1582
1583 class RangeBoundary : public ValueObject {
1584 public:
1585 enum Kind { kUnknown, kSymbol, kConstant };
1586
1587 RangeBoundary() : kind_(kUnknown), value_(0), offset_(0) { }
1588
1589 static RangeBoundary FromConstant(intptr_t val) {
1590 return RangeBoundary(kConstant, val, 0);
1591 }
1592
1593 static RangeBoundary FromDefinition(Definition* defn, intptr_t offs = 0) {
1594 return RangeBoundary(kSymbol, reinterpret_cast<intptr_t>(defn), offs);
1595 }
1596
1597 static RangeBoundary MinSmi() {
1598 return FromConstant(Smi::kMinValue);
1599 }
1600
1601 static RangeBoundary MaxSmi() {
1602 return FromConstant(Smi::kMaxValue);
1603 }
1604
1605 static RangeBoundary OverflowedMinSmi() {
1606 return FromConstant(Smi::kMinValue - 1);
1607 }
1608
1609 static RangeBoundary OverflowedMaxSmi() {
1610 return FromConstant(Smi::kMaxValue + 1);
1611 }
1612
1613 static RangeBoundary Min(RangeBoundary a, RangeBoundary b) {
1614 const intptr_t min_a = a.LowerBound().value();
1615 const intptr_t min_b = b.LowerBound().value();
1616
1617 return RangeBoundary::FromConstant(Utils::Minimum(min_a, min_b));
1618 }
1619
1620 static RangeBoundary Max(RangeBoundary a, RangeBoundary b) {
1621 const intptr_t max_a = a.UpperBound().value();
1622 const intptr_t max_b = b.UpperBound().value();
1623
1624 return RangeBoundary::FromConstant(Utils::Maximum(max_a, max_b));
1625 }
1626
1627 bool Overflowed() const {
1628 return !Smi::IsValid(value());
1629 }
1630
1631 RangeBoundary Clamp() const {
1632 if (IsConstant()) {
1633 if (value() < Smi::kMinValue) return MinSmi();
1634 if (value() > Smi::kMaxValue) return MaxSmi();
1635 }
1636 return *this;
1637 }
1638
1639 bool Equals(const RangeBoundary& other) const {
1640 return (kind_ == other.kind_) && (value_ == other.value_);
1641 }
1642
1643 bool IsUnknown() const { return kind_ == kUnknown; }
1644 bool IsConstant() const { return kind_ == kConstant; }
1645 bool IsSymbol() const { return kind_ == kSymbol; }
1646
1647 intptr_t value() const {
1648 ASSERT(IsConstant());
1649 return value_;
1650 }
1651
1652 Definition* symbol() const {
1653 ASSERT(IsSymbol());
1654 return reinterpret_cast<Definition*>(value_);
1655 }
1656
1657 RangeBoundary LowerBound() const;
1658 RangeBoundary UpperBound() const;
1659
1660 static RangeBoundary WidenMin(const RangeBoundary& old_min,
1661 const RangeBoundary& new_min) {
1662 if (new_min.LowerBound().value() < old_min.LowerBound().value()) {
1663 return MinSmi();
1664 }
1665 return new_min;
1666 }
1667
1668 static RangeBoundary WidenMax(const RangeBoundary& old_max,
1669 const RangeBoundary& new_max) {
1670 if (new_max.UpperBound().value() > old_max.UpperBound().value()) {
1671 return MaxSmi();
1672 }
1673 return new_max;
1674 }
1675
1676 void PrintTo(BufferFormatter* f) const;
1677
1678 static RangeBoundary Add(const RangeBoundary& a,
1679 const RangeBoundary& b,
1680 const RangeBoundary& overflow) {
1681 ASSERT(a.IsConstant() && b.IsConstant());
1682
1683 intptr_t result = a.value() + b.value();
1684 if (!Smi::IsValid(result)) {
1685 return overflow;
1686 }
1687 return RangeBoundary::FromConstant(result);
1688 }
1689
1690 static RangeBoundary Sub(const RangeBoundary& a,
1691 const RangeBoundary& b,
1692 const RangeBoundary& overflow) {
1693 ASSERT(a.IsConstant() && b.IsConstant());
1694
1695 intptr_t result = a.value() - b.value();
1696 if (!Smi::IsValid(result)) {
1697 return overflow;
1698 }
1699 return RangeBoundary::FromConstant(result);
1700 }
1701
1702 private:
1703 RangeBoundary(Kind kind, intptr_t value, intptr_t offset)
1704 : kind_(kind), value_(value), offset_(offset) { }
1705
1706 Kind kind_;
1707 intptr_t value_;
1708 intptr_t offset_;
1709 };
1710
1711
1712 class Range : public ZoneAllocated {
1713 public:
1714 Range(RangeBoundary min, RangeBoundary max) : min_(min), max_(max) { }
1715
1716 static Range* Unknown() {
1717 return new Range(RangeBoundary::MinSmi(), RangeBoundary::MaxSmi());
1718 }
1719
1720 void PrintTo(BufferFormatter* f) const;
1721
1722 const RangeBoundary& min() { return min_; }
1723 const RangeBoundary& max() { return max_; }
1724
1725 bool Equals(Range* other) {
1726 return min_.Equals(other->min_) && max_.Equals(other->max_);
1727 }
1728
1729 static bool Update(Range** range_slot,
1730 const RangeBoundary& min,
1731 const RangeBoundary& max) {
1732 if (*range_slot == NULL) {
1733 *range_slot = new Range(min, max);
1734 return true;
1735 }
1736
1737 Range* range = *range_slot;
1738 if (range->min_.Equals(min) && range->max_.Equals(max)) {
1739 return false;
1740 }
1741
1742 range->min_ = min;
1743 range->max_ = max;
1744
1745 return true;
1746 }
1747
1748 static RangeBoundary ConstantMin(Range* range) {
1749 if (range == NULL) return RangeBoundary::MinSmi();
1750 return range->min().LowerBound();
1751 }
1752
1753 static RangeBoundary ConstantMax(Range* range) {
1754 if (range == NULL) return RangeBoundary::MaxSmi();
1755 return range->max().UpperBound();
1756 }
1757
1758 private:
1759 RangeBoundary min_;
1760 RangeBoundary max_;
1761 };
1762
1763
1764 class ConstraintInstr : public TemplateDefinition<2> {
1765 public:
1766 ConstraintInstr(Value* value, Range* constraint)
1767 : constraint_(constraint) {
1768 inputs_[0] = value;
1769 inputs_[1] = NULL; // Dependency.
1770 }
1771
1772 DECLARE_INSTRUCTION(Constraint)
1773
1774 virtual RawAbstractType* CompileType() const {
1775 return Type::SmiType();
1776 }
1777
1778 virtual bool CanDeoptimize() const { return false; }
1779
1780 virtual bool HasSideEffect() const { return false; }
1781
1782 virtual intptr_t ResultCid() const { return kSmiCid; }
1783
1784 virtual bool AttributesEqual(Definition* other) const {
1785 UNREACHABLE();
1786 return false;
1787 }
1788
1789 virtual void PrintOperandsTo(BufferFormatter* f) const;
1790
1791 Value* value() const { return inputs_[0]; }
1792 Range* constraint() const { return constraint_; }
1793
1794 virtual bool InferRange();
1795
1796 void AddDependency(Definition* defn) {
1797 Value* val = new Value(defn);
1798 val->set_use_index(1);
1799 val->set_instruction(this);
1800 val->AddToInputUseList();
1801 set_dependency(val);
1802 }
1803
1804 void RemoveDependency() {
1805 if (dependency() != NULL) {
1806 dependency()->RemoveFromInputUseList();
1807 set_dependency(NULL);
1808 }
1809 }
1810
1811 private:
1812 Value* dependency() {
1813 return inputs_[1];
1814 }
1815
1816 void set_dependency(Value* value) {
1817 inputs_[1] = value;
1818 }
1819
1820 Range* constraint_;
1821
1822 DISALLOW_COPY_AND_ASSIGN(ConstraintInstr);
1823 };
1824
1825
1533 class ConstantInstr : public TemplateDefinition<0> { 1826 class ConstantInstr : public TemplateDefinition<0> {
1534 public: 1827 public:
1535 explicit ConstantInstr(const Object& value) : value_(value) { } 1828 explicit ConstantInstr(const Object& value)
1829 : value_(value) { }
1536 1830
1537 DECLARE_INSTRUCTION(Constant) 1831 DECLARE_INSTRUCTION(Constant)
1538 virtual RawAbstractType* CompileType() const; 1832 virtual RawAbstractType* CompileType() const;
1539 1833
1540 const Object& value() const { return value_; } 1834 const Object& value() const { return value_; }
1541 1835
1542 virtual void PrintOperandsTo(BufferFormatter* f) const; 1836 virtual void PrintOperandsTo(BufferFormatter* f) const;
1543 1837
1544 virtual bool CanDeoptimize() const { return false; } 1838 virtual bool CanDeoptimize() const { return false; }
1545 1839
1546 virtual bool HasSideEffect() const { return false; } 1840 virtual bool HasSideEffect() const { return false; }
1547 1841
1548 virtual intptr_t ResultCid() const; 1842 virtual intptr_t ResultCid() const;
1549 1843
1550 virtual bool AttributesEqual(Instruction* other) const; 1844 virtual bool AttributesEqual(Instruction* other) const;
1551 virtual bool AffectedBySideEffect() const { return false; } 1845 virtual bool AffectedBySideEffect() const { return false; }
1552 1846
1847 virtual bool InferRange();
1848
1553 private: 1849 private:
1554 const Object& value_; 1850 const Object& value_;
1555 1851
1556 DISALLOW_COPY_AND_ASSIGN(ConstantInstr); 1852 DISALLOW_COPY_AND_ASSIGN(ConstantInstr);
1557 }; 1853 };
1558 1854
1559 1855
1560 class AssertAssignableInstr : public TemplateDefinition<3> { 1856 class AssertAssignableInstr : public TemplateDefinition<3> {
1561 public: 1857 public:
1562 AssertAssignableInstr(intptr_t token_pos, 1858 AssertAssignableInstr(intptr_t token_pos,
(...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after
1848 InstanceCallInstr* instance_call_; 2144 InstanceCallInstr* instance_call_;
1849 const ICData& ic_data_; 2145 const ICData& ic_data_;
1850 const bool with_checks_; 2146 const bool with_checks_;
1851 2147
1852 DISALLOW_COPY_AND_ASSIGN(PolymorphicInstanceCallInstr); 2148 DISALLOW_COPY_AND_ASSIGN(PolymorphicInstanceCallInstr);
1853 }; 2149 };
1854 2150
1855 2151
1856 class ComparisonInstr : public TemplateDefinition<2> { 2152 class ComparisonInstr : public TemplateDefinition<2> {
1857 public: 2153 public:
1858 ComparisonInstr(Token::Kind kind, Value* left, Value* right) : kind_(kind) { 2154 ComparisonInstr(Token::Kind kind, Value* left, Value* right)
2155 : kind_(kind) {
1859 ASSERT(left != NULL); 2156 ASSERT(left != NULL);
1860 ASSERT(right != NULL); 2157 ASSERT(right != NULL);
1861 inputs_[0] = left; 2158 inputs_[0] = left;
1862 inputs_[1] = right; 2159 inputs_[1] = right;
1863 } 2160 }
1864 2161
1865 Value* left() const { return inputs_[0]; } 2162 Value* left() const { return inputs_[0]; }
1866 Value* right() const { return inputs_[1]; } 2163 Value* right() const { return inputs_[1]; }
1867 2164
1868 virtual ComparisonInstr* AsComparison() { return this; } 2165 virtual ComparisonInstr* AsComparison() { return this; }
(...skipping 1275 matching lines...) Expand 10 before | Expand all | Expand 10 after
3144 }; 3441 };
3145 3442
3146 3443
3147 class BinarySmiOpInstr : public TemplateDefinition<2> { 3444 class BinarySmiOpInstr : public TemplateDefinition<2> {
3148 public: 3445 public:
3149 BinarySmiOpInstr(Token::Kind op_kind, 3446 BinarySmiOpInstr(Token::Kind op_kind,
3150 InstanceCallInstr* instance_call, 3447 InstanceCallInstr* instance_call,
3151 Value* left, 3448 Value* left,
3152 Value* right) 3449 Value* right)
3153 : op_kind_(op_kind), 3450 : op_kind_(op_kind),
3154 instance_call_(instance_call) { 3451 instance_call_(instance_call),
3452 overflow_(true) {
3155 ASSERT(left != NULL); 3453 ASSERT(left != NULL);
3156 ASSERT(right != NULL); 3454 ASSERT(right != NULL);
3157 inputs_[0] = left; 3455 inputs_[0] = left;
3158 inputs_[1] = right; 3456 inputs_[1] = right;
3159 } 3457 }
3160 3458
3161 Value* left() const { return inputs_[0]; } 3459 Value* left() const { return inputs_[0]; }
3162 Value* right() const { return inputs_[1]; } 3460 Value* right() const { return inputs_[1]; }
3163 3461
3164 Token::Kind op_kind() const { return op_kind_; } 3462 Token::Kind op_kind() const { return op_kind_; }
3165 3463
3166 InstanceCallInstr* instance_call() const { return instance_call_; } 3464 InstanceCallInstr* instance_call() const { return instance_call_; }
3167 3465
3168 const ICData* ic_data() const { return instance_call()->ic_data(); } 3466 const ICData* ic_data() const { return instance_call()->ic_data(); }
3169 3467
3170 virtual void PrintOperandsTo(BufferFormatter* f) const; 3468 virtual void PrintOperandsTo(BufferFormatter* f) const;
3171 3469
3172 DECLARE_INSTRUCTION(BinarySmiOp) 3470 DECLARE_INSTRUCTION(BinarySmiOp)
3173 virtual RawAbstractType* CompileType() const; 3471 virtual RawAbstractType* CompileType() const;
3174 3472
3175 virtual bool CanDeoptimize() const; 3473 virtual bool CanDeoptimize() const;
3176 3474
3177 virtual bool HasSideEffect() const { return false; } 3475 virtual bool HasSideEffect() const { return false; }
3178 3476
3179 virtual bool AffectedBySideEffect() const { return false; } 3477 virtual bool AffectedBySideEffect() const { return false; }
3180 virtual bool AttributesEqual(Instruction* other) const; 3478 virtual bool AttributesEqual(Instruction* other) const;
3181 3479
3182 virtual intptr_t ResultCid() const; 3480 virtual intptr_t ResultCid() const;
3183 3481
3482 void set_overflow(bool overflow) {
3483 overflow_ = overflow;
3484 }
3485
3486 void PrintTo(BufferFormatter* f) const;
3487
3488 virtual bool InferRange();
3489
3184 private: 3490 private:
3185 const Token::Kind op_kind_; 3491 const Token::Kind op_kind_;
3186 InstanceCallInstr* instance_call_; 3492 InstanceCallInstr* instance_call_;
3493 bool overflow_;
3187 3494
3188 DISALLOW_COPY_AND_ASSIGN(BinarySmiOpInstr); 3495 DISALLOW_COPY_AND_ASSIGN(BinarySmiOpInstr);
3189 }; 3496 };
3190 3497
3191 3498
3192 class BinaryMintOpInstr : public TemplateDefinition<2> { 3499 class BinaryMintOpInstr : public TemplateDefinition<2> {
3193 public: 3500 public:
3194 BinaryMintOpInstr(Token::Kind op_kind, 3501 BinaryMintOpInstr(Token::Kind op_kind,
3195 InstanceCallInstr* instance_call, 3502 InstanceCallInstr* instance_call,
3196 Value* left, 3503 Value* left,
(...skipping 462 matching lines...) Expand 10 before | Expand all | Expand 10 after
3659 ForwardInstructionIterator* current_iterator_; 3966 ForwardInstructionIterator* current_iterator_;
3660 3967
3661 private: 3968 private:
3662 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); 3969 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor);
3663 }; 3970 };
3664 3971
3665 3972
3666 } // namespace dart 3973 } // namespace dart
3667 3974
3668 #endif // VM_INTERMEDIATE_LANGUAGE_H_ 3975 #endif // VM_INTERMEDIATE_LANGUAGE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698