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

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

Issue 14021016: Track side-effect free paths in the graph to allow CSE and LICM for instructions that depend on som… (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 7 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 263 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 274
275 virtual void Update() { 275 virtual void Update() {
276 type_ = source_->CopyNonNullable(); 276 type_ = source_->CopyNonNullable();
277 } 277 }
278 278
279 private: 279 private:
280 CompileType* source_; 280 CompileType* source_;
281 }; 281 };
282 282
283 283
284 class EffectSet : public ValueObject {
285 public:
286 enum Effects {
287 kNoEffects = 0,
288 kExternalization = 1,
289 kLastEffect = kExternalization
290 };
291
292 EffectSet(const EffectSet& other)
293 : ValueObject(), effects_(other.effects_) {
294 }
295
296 bool IsNone() const { return effects_ == kNoEffects; }
297
298 static EffectSet None() { return EffectSet(kNoEffects); }
299 static EffectSet All() {
300 ASSERT(EffectSet::kLastEffect == 1);
301 return EffectSet(kExternalization);
302 }
303
304 bool ToInt() { return effects_; }
305
306 private:
307 explicit EffectSet(intptr_t effects) : effects_(effects) { }
308
309 intptr_t effects_;
310 };
311
312
284 class Value : public ZoneAllocated { 313 class Value : public ZoneAllocated {
285 public: 314 public:
286 // A forward iterator that allows removing the current value from the 315 // A forward iterator that allows removing the current value from the
287 // underlying use list during iteration. 316 // underlying use list during iteration.
288 class Iterator { 317 class Iterator {
289 public: 318 public:
290 explicit Iterator(Value* head) : next_(head) { Advance(); } 319 explicit Iterator(Value* head) : next_(head) { Advance(); }
291 Value* Current() const { return current_; } 320 Value* Current() const { return current_; }
292 bool Done() const { return current_ == NULL; } 321 bool Done() const { return current_ == NULL; }
293 void Advance() { 322 void Advance() {
(...skipping 293 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 virtual intptr_t ArgumentCount() const = 0; 616 virtual intptr_t ArgumentCount() const = 0;
588 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const { 617 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const {
589 UNREACHABLE(); 618 UNREACHABLE();
590 return NULL; 619 return NULL;
591 } 620 }
592 inline Definition* ArgumentAt(intptr_t index) const; 621 inline Definition* ArgumentAt(intptr_t index) const;
593 622
594 // Returns true, if this instruction can deoptimize. 623 // Returns true, if this instruction can deoptimize.
595 virtual bool CanDeoptimize() const = 0; 624 virtual bool CanDeoptimize() const = 0;
596 625
597 // Returns true if the instruction may have side effects.
598 virtual bool HasSideEffect() const = 0;
599
600 // Visiting support. 626 // Visiting support.
601 virtual void Accept(FlowGraphVisitor* visitor) = 0; 627 virtual void Accept(FlowGraphVisitor* visitor) = 0;
602 628
603 Instruction* previous() const { return previous_; } 629 Instruction* previous() const { return previous_; }
604 void set_previous(Instruction* instr) { 630 void set_previous(Instruction* instr) {
605 ASSERT(!IsBlockEntry()); 631 ASSERT(!IsBlockEntry());
606 previous_ = instr; 632 previous_ = instr;
607 } 633 }
608 634
609 Instruction* next() const { return next_; } 635 Instruction* next() const { return next_; }
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
706 virtual Instruction* Canonicalize(FlowGraphOptimizer* optimizer); 732 virtual Instruction* Canonicalize(FlowGraphOptimizer* optimizer);
707 733
708 // Insert this instruction before 'next' after use lists are computed. 734 // Insert this instruction before 'next' after use lists are computed.
709 // Instructions cannot be inserted before a block entry or any other 735 // Instructions cannot be inserted before a block entry or any other
710 // instruction without a previous instruction. 736 // instruction without a previous instruction.
711 void InsertBefore(Instruction* next) { InsertAfter(next->previous()); } 737 void InsertBefore(Instruction* next) { InsertAfter(next->previous()); }
712 738
713 // Insert this instruction after 'prev' after use lists are computed. 739 // Insert this instruction after 'prev' after use lists are computed.
714 void InsertAfter(Instruction* prev); 740 void InsertAfter(Instruction* prev);
715 741
716 // Returns true if the instruction is affected by side effects. 742 // Returns true if CSE and LICM are allowed for this instruction.
717 // Only instructions that are not affected by side effects can participate 743 virtual bool AllowsCSE() const {
718 // in redundancy elimination or loop invariant code motion. 744 return false;
719 // TODO(fschneider): Make this abstract and implement for all instructions 745 }
720 // instead of returning the safe default (true). 746
721 virtual bool AffectedBySideEffect() const { return true; } 747 // Returns true if the instruction may have side effects.
Florian Schneider 2013/04/29 12:11:54 Returns set of effects created by this instruction
Vyacheslav Egorov (Google) 2013/04/30 14:01:33 Done.
748 virtual EffectSet Effects() const = 0;
749
750 // Returns set of effects that affect this instruction.
751 virtual EffectSet Dependencies() const {
752 UNREACHABLE();
753 return EffectSet::All();
754 }
722 755
723 // Get the block entry for this instruction. 756 // Get the block entry for this instruction.
724 virtual BlockEntryInstr* GetBlock() const; 757 virtual BlockEntryInstr* GetBlock() const;
725 758
726 // Id for instructions used in CSE. 759 // Id for instructions used in CSE.
727 intptr_t expr_id() const { return expr_id_; } 760 intptr_t expr_id() const { return expr_id_; }
728 void set_expr_id(intptr_t expr_id) { expr_id_ = expr_id; } 761 void set_expr_id(intptr_t expr_id) { expr_id_ = expr_id; }
729 762
730 // Returns a hash code for use with hash maps. 763 // Returns a hash code for use with hash maps.
731 virtual intptr_t Hashcode() const; 764 virtual intptr_t Hashcode() const;
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
901 class ParallelMoveInstr : public TemplateInstruction<0> { 934 class ParallelMoveInstr : public TemplateInstruction<0> {
902 public: 935 public:
903 ParallelMoveInstr() : moves_(4) { } 936 ParallelMoveInstr() : moves_(4) { }
904 937
905 DECLARE_INSTRUCTION(ParallelMove) 938 DECLARE_INSTRUCTION(ParallelMove)
906 939
907 virtual intptr_t ArgumentCount() const { return 0; } 940 virtual intptr_t ArgumentCount() const { return 0; }
908 941
909 virtual bool CanDeoptimize() const { return false; } 942 virtual bool CanDeoptimize() const { return false; }
910 943
911 virtual bool HasSideEffect() const { return false; } 944 virtual EffectSet Effects() const {
945 UNREACHABLE(); // This instruction never visited by optimization passes.
946 return EffectSet::None();
947 }
948
949 virtual EffectSet Dependencies() const {
950 UNREACHABLE(); // This instruction never visited by optimization passes.
951 return EffectSet::None();
952 }
912 953
913 MoveOperands* AddMove(Location dest, Location src) { 954 MoveOperands* AddMove(Location dest, Location src) {
914 MoveOperands* move = new MoveOperands(dest, src); 955 MoveOperands* move = new MoveOperands(dest, src);
915 moves_.Add(move); 956 moves_.Add(move);
916 return move; 957 return move;
917 } 958 }
918 959
919 MoveOperands* MoveOperandsAt(intptr_t index) const { return moves_[index]; } 960 MoveOperands* MoveOperandsAt(intptr_t index) const { return moves_[index]; }
920 961
921 void SetSrcSlotAt(intptr_t index, const Location& loc); 962 void SetSrcSlotAt(intptr_t index, const Location& loc);
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
1020 virtual intptr_t ArgumentCount() const { return 0; } 1061 virtual intptr_t ArgumentCount() const { return 0; }
1021 1062
1022 virtual bool CanBeDeoptimizationTarget() const { 1063 virtual bool CanBeDeoptimizationTarget() const {
1023 // BlockEntry environment is copied to Goto and Branch instructions 1064 // BlockEntry environment is copied to Goto and Branch instructions
1024 // when we insert new blocks targeting this block. 1065 // when we insert new blocks targeting this block.
1025 return true; 1066 return true;
1026 } 1067 }
1027 1068
1028 virtual bool CanDeoptimize() const { return false; } 1069 virtual bool CanDeoptimize() const { return false; }
1029 1070
1030 virtual bool HasSideEffect() const { return false; } 1071 virtual EffectSet Effects() const { return EffectSet::None(); }
1072 virtual EffectSet Dependencies() const { return EffectSet::None(); }
1031 1073
1032 intptr_t try_index() const { return try_index_; } 1074 intptr_t try_index() const { return try_index_; }
1033 1075
1034 BitVector* loop_info() const { return loop_info_; } 1076 BitVector* loop_info() const { return loop_info_; }
1035 void set_loop_info(BitVector* loop_info) { 1077 void set_loop_info(BitVector* loop_info) {
1036 loop_info_ = loop_info; 1078 loop_info_ = loop_info;
1037 } 1079 }
1038 1080
1039 virtual BlockEntryInstr* GetBlock() const { 1081 virtual BlockEntryInstr* GetBlock() const {
1040 return const_cast<BlockEntryInstr*>(this); 1082 return const_cast<BlockEntryInstr*>(this);
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
1209 1251
1210 virtual void PrepareEntry(FlowGraphCompiler* compiler); 1252 virtual void PrepareEntry(FlowGraphCompiler* compiler);
1211 1253
1212 void InsertPhi(intptr_t var_index, intptr_t var_count); 1254 void InsertPhi(intptr_t var_index, intptr_t var_count);
1213 void RemoveDeadPhis(Definition* replacement); 1255 void RemoveDeadPhis(Definition* replacement);
1214 1256
1215 void InsertPhi(PhiInstr* phi); 1257 void InsertPhi(PhiInstr* phi);
1216 1258
1217 virtual void PrintTo(BufferFormatter* f) const; 1259 virtual void PrintTo(BufferFormatter* f) const;
1218 1260
1261 virtual EffectSet Effects() const { return EffectSet::None(); }
1262 virtual EffectSet Dependencies() const { return EffectSet::None(); }
1263
1219 private: 1264 private:
1220 // Classes that have access to predecessors_ when inlining. 1265 // Classes that have access to predecessors_ when inlining.
1221 friend class BlockEntryInstr; 1266 friend class BlockEntryInstr;
1222 friend class InlineExitCollector; 1267 friend class InlineExitCollector;
1223 1268
1224 // Direct access to phis_ in order to resize it due to phi elimination. 1269 // Direct access to phis_ in order to resize it due to phi elimination.
1225 friend class ConstantPropagator; 1270 friend class ConstantPropagator;
1226 1271
1227 virtual void ClearPredecessors() { predecessors_.Clear(); } 1272 virtual void ClearPredecessors() { predecessors_.Clear(); }
1228 virtual void AddPredecessor(BlockEntryInstr* predecessor); 1273 virtual void AddPredecessor(BlockEntryInstr* predecessor);
(...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after
1519 virtual bool RecomputeType(); 1564 virtual bool RecomputeType();
1520 1565
1521 virtual intptr_t ArgumentCount() const { return 0; } 1566 virtual intptr_t ArgumentCount() const { return 0; }
1522 1567
1523 intptr_t InputCount() const { return inputs_.length(); } 1568 intptr_t InputCount() const { return inputs_.length(); }
1524 1569
1525 Value* InputAt(intptr_t i) const { return inputs_[i]; } 1570 Value* InputAt(intptr_t i) const { return inputs_[i]; }
1526 1571
1527 virtual bool CanDeoptimize() const { return false; } 1572 virtual bool CanDeoptimize() const { return false; }
1528 1573
1529 virtual bool HasSideEffect() const { return false; } 1574 virtual EffectSet Effects() const { return EffectSet::None(); }
1530 1575
1531 // Phi is alive if it reaches a non-environment use. 1576 // Phi is alive if it reaches a non-environment use.
1532 bool is_alive() const { return is_alive_; } 1577 bool is_alive() const { return is_alive_; }
1533 void mark_alive() { is_alive_ = true; } 1578 void mark_alive() { is_alive_ = true; }
1534 1579
1535 virtual Representation RequiredInputRepresentation(intptr_t i) const { 1580 virtual Representation RequiredInputRepresentation(intptr_t i) const {
1536 return representation_; 1581 return representation_;
1537 } 1582 }
1538 1583
1539 virtual Representation representation() const { 1584 virtual Representation representation() const {
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1596 virtual intptr_t ArgumentCount() const { return 0; } 1641 virtual intptr_t ArgumentCount() const { return 0; }
1597 1642
1598 intptr_t InputCount() const { return 0; } 1643 intptr_t InputCount() const { return 0; }
1599 Value* InputAt(intptr_t i) const { 1644 Value* InputAt(intptr_t i) const {
1600 UNREACHABLE(); 1645 UNREACHABLE();
1601 return NULL; 1646 return NULL;
1602 } 1647 }
1603 1648
1604 virtual bool CanDeoptimize() const { return false; } 1649 virtual bool CanDeoptimize() const { return false; }
1605 1650
1606 virtual bool HasSideEffect() const { return false; } 1651 virtual EffectSet Effects() const { return EffectSet::None(); }
1652 virtual EffectSet Dependencies() const { return EffectSet::None(); }
1607 1653
1608 virtual intptr_t Hashcode() const { 1654 virtual intptr_t Hashcode() const {
1609 UNREACHABLE(); 1655 UNREACHABLE();
1610 return 0; 1656 return 0;
1611 } 1657 }
1612 1658
1613 virtual void PrintOperandsTo(BufferFormatter* f) const; 1659 virtual void PrintOperandsTo(BufferFormatter* f) const;
1614 1660
1615 virtual CompileType ComputeType() const; 1661 virtual CompileType ComputeType() const;
1616 1662
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
1652 return locs_; 1698 return locs_;
1653 } 1699 }
1654 1700
1655 virtual intptr_t Hashcode() const { 1701 virtual intptr_t Hashcode() const {
1656 UNREACHABLE(); 1702 UNREACHABLE();
1657 return 0; 1703 return 0;
1658 } 1704 }
1659 1705
1660 virtual bool CanDeoptimize() const { return false; } 1706 virtual bool CanDeoptimize() const { return false; }
1661 1707
1662 virtual bool HasSideEffect() const { return false; } 1708 virtual EffectSet Effects() const { return EffectSet::None(); }
1663 1709
1664 virtual void PrintOperandsTo(BufferFormatter* f) const; 1710 virtual void PrintOperandsTo(BufferFormatter* f) const;
1665 1711
1666 private: 1712 private:
1667 virtual void RawSetInputAt(intptr_t i, Value* value) { 1713 virtual void RawSetInputAt(intptr_t i, Value* value) {
1668 ASSERT(i == 0); 1714 ASSERT(i == 0);
1669 value_ = value; 1715 value_ = value;
1670 } 1716 }
1671 1717
1672 Value* value_; 1718 Value* value_;
(...skipping 23 matching lines...) Expand all
1696 Value* value() const { return inputs_[0]; } 1742 Value* value() const { return inputs_[0]; }
1697 1743
1698 virtual bool CanBeDeoptimizationTarget() const { 1744 virtual bool CanBeDeoptimizationTarget() const {
1699 // Return instruction might turn into a Goto instruction after inlining. 1745 // Return instruction might turn into a Goto instruction after inlining.
1700 // Every Goto must have an environment. 1746 // Every Goto must have an environment.
1701 return true; 1747 return true;
1702 } 1748 }
1703 1749
1704 virtual bool CanDeoptimize() const { return false; } 1750 virtual bool CanDeoptimize() const { return false; }
1705 1751
1706 virtual bool HasSideEffect() const { return false; } 1752 virtual EffectSet Effects() const { return EffectSet::None(); }
1707 1753
1708 private: 1754 private:
1709 const intptr_t token_pos_; 1755 const intptr_t token_pos_;
1710 1756
1711 DISALLOW_COPY_AND_ASSIGN(ReturnInstr); 1757 DISALLOW_COPY_AND_ASSIGN(ReturnInstr);
1712 }; 1758 };
1713 1759
1714 1760
1715 class ThrowInstr : public TemplateInstruction<0> { 1761 class ThrowInstr : public TemplateInstruction<0> {
1716 public: 1762 public:
1717 explicit ThrowInstr(intptr_t token_pos) : token_pos_(token_pos) { } 1763 explicit ThrowInstr(intptr_t token_pos) : token_pos_(token_pos) { }
1718 1764
1719 DECLARE_INSTRUCTION(Throw) 1765 DECLARE_INSTRUCTION(Throw)
1720 1766
1721 virtual intptr_t ArgumentCount() const { return 1; } 1767 virtual intptr_t ArgumentCount() const { return 1; }
1722 1768
1723 intptr_t token_pos() const { return token_pos_; } 1769 intptr_t token_pos() const { return token_pos_; }
1724 1770
1725 virtual bool CanDeoptimize() const { return true; } 1771 virtual bool CanDeoptimize() const { return true; }
1726 1772
1727 virtual bool HasSideEffect() const { return true; } 1773 virtual EffectSet Effects() const { return EffectSet::None(); }
1728 1774
1729 private: 1775 private:
1730 const intptr_t token_pos_; 1776 const intptr_t token_pos_;
1731 1777
1732 DISALLOW_COPY_AND_ASSIGN(ThrowInstr); 1778 DISALLOW_COPY_AND_ASSIGN(ThrowInstr);
1733 }; 1779 };
1734 1780
1735 1781
1736 class ReThrowInstr : public TemplateInstruction<0> { 1782 class ReThrowInstr : public TemplateInstruction<0> {
1737 public: 1783 public:
1738 explicit ReThrowInstr(intptr_t token_pos) : token_pos_(token_pos) { } 1784 explicit ReThrowInstr(intptr_t token_pos) : token_pos_(token_pos) { }
1739 1785
1740 DECLARE_INSTRUCTION(ReThrow) 1786 DECLARE_INSTRUCTION(ReThrow)
1741 1787
1742 virtual intptr_t ArgumentCount() const { return 2; } 1788 virtual intptr_t ArgumentCount() const { return 2; }
1743 1789
1744 intptr_t token_pos() const { return token_pos_; } 1790 intptr_t token_pos() const { return token_pos_; }
1745 1791
1746 virtual bool CanDeoptimize() const { return true; } 1792 virtual bool CanDeoptimize() const { return true; }
1747 1793
1748 virtual bool HasSideEffect() const { return true; } 1794 virtual EffectSet Effects() const { return EffectSet::None(); }
1749 1795
1750 private: 1796 private:
1751 const intptr_t token_pos_; 1797 const intptr_t token_pos_;
1752 1798
1753 DISALLOW_COPY_AND_ASSIGN(ReThrowInstr); 1799 DISALLOW_COPY_AND_ASSIGN(ReThrowInstr);
1754 }; 1800 };
1755 1801
1756 1802
1757 class GotoInstr : public TemplateInstruction<0> { 1803 class GotoInstr : public TemplateInstruction<0> {
1758 public: 1804 public:
(...skipping 11 matching lines...) Expand all
1770 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; 1816 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const;
1771 1817
1772 virtual bool CanBeDeoptimizationTarget() const { 1818 virtual bool CanBeDeoptimizationTarget() const {
1773 // Goto instruction can be used as a deoptimization target when LICM 1819 // Goto instruction can be used as a deoptimization target when LICM
1774 // hoists instructions out of the loop. 1820 // hoists instructions out of the loop.
1775 return true; 1821 return true;
1776 } 1822 }
1777 1823
1778 virtual bool CanDeoptimize() const { return false; } 1824 virtual bool CanDeoptimize() const { return false; }
1779 1825
1780 virtual bool HasSideEffect() const { return false; } 1826 virtual EffectSet Effects() const { return EffectSet::None(); }
1781 1827
1782 ParallelMoveInstr* parallel_move() const { 1828 ParallelMoveInstr* parallel_move() const {
1783 return parallel_move_; 1829 return parallel_move_;
1784 } 1830 }
1785 1831
1786 bool HasParallelMove() const { 1832 bool HasParallelMove() const {
1787 return parallel_move_ != NULL; 1833 return parallel_move_ != NULL;
1788 } 1834 }
1789 1835
1790 ParallelMoveInstr* GetParallelMove() { 1836 ParallelMoveInstr* GetParallelMove() {
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1838 explicit BranchInstr(ComparisonInstr* comparison, bool is_checked = false); 1884 explicit BranchInstr(ComparisonInstr* comparison, bool is_checked = false);
1839 1885
1840 DECLARE_INSTRUCTION(Branch) 1886 DECLARE_INSTRUCTION(Branch)
1841 1887
1842 virtual intptr_t ArgumentCount() const; 1888 virtual intptr_t ArgumentCount() const;
1843 intptr_t InputCount() const; 1889 intptr_t InputCount() const;
1844 Value* InputAt(intptr_t i) const; 1890 Value* InputAt(intptr_t i) const;
1845 virtual bool CanDeoptimize() const; 1891 virtual bool CanDeoptimize() const;
1846 virtual bool CanBeDeoptimizationTarget() const; 1892 virtual bool CanBeDeoptimizationTarget() const;
1847 1893
1848 virtual bool HasSideEffect() const; 1894 virtual EffectSet Effects() const;
1849 1895
1850 ComparisonInstr* comparison() const { return comparison_; } 1896 ComparisonInstr* comparison() const { return comparison_; }
1851 void SetComparison(ComparisonInstr* comp); 1897 void SetComparison(ComparisonInstr* comp);
1852 1898
1853 bool is_checked() const { return is_checked_; } 1899 bool is_checked() const { return is_checked_; }
1854 1900
1855 virtual LocationSummary* locs(); 1901 virtual LocationSummary* locs();
1856 virtual intptr_t DeoptimizationTarget() const; 1902 virtual intptr_t DeoptimizationTarget() const;
1857 virtual Representation RequiredInputRepresentation(intptr_t i) const; 1903 virtual Representation RequiredInputRepresentation(intptr_t i) const;
1858 1904
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1911 } 1957 }
1912 1958
1913 DECLARE_INSTRUCTION(StoreContext); 1959 DECLARE_INSTRUCTION(StoreContext);
1914 1960
1915 virtual intptr_t ArgumentCount() const { return 0; } 1961 virtual intptr_t ArgumentCount() const { return 0; }
1916 1962
1917 Value* value() const { return inputs_[0]; } 1963 Value* value() const { return inputs_[0]; }
1918 1964
1919 virtual bool CanDeoptimize() const { return false; } 1965 virtual bool CanDeoptimize() const { return false; }
1920 1966
1921 virtual bool HasSideEffect() const { return false; } 1967 virtual EffectSet Effects() const { return EffectSet::None(); }
1922 1968
1923 private: 1969 private:
1924 DISALLOW_COPY_AND_ASSIGN(StoreContextInstr); 1970 DISALLOW_COPY_AND_ASSIGN(StoreContextInstr);
1925 }; 1971 };
1926 1972
1927 1973
1928 template<intptr_t N> 1974 template<intptr_t N>
1929 class TemplateDefinition : public Definition { 1975 class TemplateDefinition : public Definition {
1930 public: 1976 public:
1931 TemplateDefinition<N>() : locs_(NULL) { } 1977 TemplateDefinition<N>() : locs_(NULL) { }
(...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after
2128 DECLARE_INSTRUCTION(Constraint) 2174 DECLARE_INSTRUCTION(Constraint)
2129 2175
2130 virtual intptr_t InputCount() const { 2176 virtual intptr_t InputCount() const {
2131 return (inputs_[1] == NULL) ? 1 : 2; 2177 return (inputs_[1] == NULL) ? 1 : 2;
2132 } 2178 }
2133 2179
2134 virtual CompileType ComputeType() const; 2180 virtual CompileType ComputeType() const;
2135 2181
2136 virtual bool CanDeoptimize() const { return false; } 2182 virtual bool CanDeoptimize() const { return false; }
2137 2183
2138 virtual bool HasSideEffect() const { return false; } 2184 virtual EffectSet Effects() const { return EffectSet::None(); }
2139 2185
2140 virtual bool AttributesEqual(Instruction* other) const { 2186 virtual bool AttributesEqual(Instruction* other) const {
2141 UNREACHABLE(); 2187 UNREACHABLE();
2142 return false; 2188 return false;
2143 } 2189 }
2144 2190
2145 virtual void PrintOperandsTo(BufferFormatter* f) const; 2191 virtual void PrintOperandsTo(BufferFormatter* f) const;
2146 2192
2147 Value* value() const { return inputs_[0]; } 2193 Value* value() const { return inputs_[0]; }
2148 Range* constraint() const { return constraint_; } 2194 Range* constraint() const { return constraint_; }
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
2186 virtual CompileType ComputeType() const; 2232 virtual CompileType ComputeType() const;
2187 2233
2188 virtual Definition* Canonicalize(FlowGraphOptimizer* optimizer); 2234 virtual Definition* Canonicalize(FlowGraphOptimizer* optimizer);
2189 2235
2190 const Object& value() const { return value_; } 2236 const Object& value() const { return value_; }
2191 2237
2192 virtual void PrintOperandsTo(BufferFormatter* f) const; 2238 virtual void PrintOperandsTo(BufferFormatter* f) const;
2193 2239
2194 virtual bool CanDeoptimize() const { return false; } 2240 virtual bool CanDeoptimize() const { return false; }
2195 2241
2196 virtual bool HasSideEffect() const { return false; } 2242 virtual void InferRange();
2197 2243
2244 virtual bool AllowsCSE() const { return true; }
2245 virtual EffectSet Effects() const { return EffectSet::None(); }
2246 virtual EffectSet Dependencies() const { return EffectSet::None(); }
2198 virtual bool AttributesEqual(Instruction* other) const; 2247 virtual bool AttributesEqual(Instruction* other) const;
2199 virtual bool AffectedBySideEffect() const { return false; }
2200
2201 virtual void InferRange();
2202 2248
2203 private: 2249 private:
2204 const Object& value_; 2250 const Object& value_;
2205 2251
2206 DISALLOW_COPY_AND_ASSIGN(ConstantInstr); 2252 DISALLOW_COPY_AND_ASSIGN(ConstantInstr);
2207 }; 2253 };
2208 2254
2209 2255
2210 class AssertAssignableInstr : public TemplateDefinition<3> { 2256 class AssertAssignableInstr : public TemplateDefinition<3> {
2211 public: 2257 public:
(...skipping 25 matching lines...) Expand all
2237 const AbstractType& dst_type() const { return dst_type_; } 2283 const AbstractType& dst_type() const { return dst_type_; }
2238 void set_dst_type(const AbstractType& dst_type) { 2284 void set_dst_type(const AbstractType& dst_type) {
2239 dst_type_ = dst_type.raw(); 2285 dst_type_ = dst_type.raw();
2240 } 2286 }
2241 const String& dst_name() const { return dst_name_; } 2287 const String& dst_name() const { return dst_name_; }
2242 2288
2243 virtual void PrintOperandsTo(BufferFormatter* f) const; 2289 virtual void PrintOperandsTo(BufferFormatter* f) const;
2244 2290
2245 virtual bool CanDeoptimize() const { return true; } 2291 virtual bool CanDeoptimize() const { return true; }
2246 2292
2247 virtual bool HasSideEffect() const { return false; } 2293 virtual Definition* Canonicalize(FlowGraphOptimizer* optimizer);
2248 2294
2249 virtual bool AffectedBySideEffect() const { return false; } 2295 virtual bool AllowsCSE() const { return true; }
2296 virtual EffectSet Effects() const { return EffectSet::None(); }
2297 virtual EffectSet Dependencies() const { return EffectSet::None(); }
2250 virtual bool AttributesEqual(Instruction* other) const; 2298 virtual bool AttributesEqual(Instruction* other) const;
2251 2299
2252 virtual Definition* Canonicalize(FlowGraphOptimizer* optimizer);
2253
2254 private: 2300 private:
2255 const intptr_t token_pos_; 2301 const intptr_t token_pos_;
2256 AbstractType& dst_type_; 2302 AbstractType& dst_type_;
2257 const String& dst_name_; 2303 const String& dst_name_;
2258 2304
2259 DISALLOW_COPY_AND_ASSIGN(AssertAssignableInstr); 2305 DISALLOW_COPY_AND_ASSIGN(AssertAssignableInstr);
2260 }; 2306 };
2261 2307
2262 2308
2263 class AssertBooleanInstr : public TemplateDefinition<1> { 2309 class AssertBooleanInstr : public TemplateDefinition<1> {
2264 public: 2310 public:
2265 AssertBooleanInstr(intptr_t token_pos, Value* value) 2311 AssertBooleanInstr(intptr_t token_pos, Value* value)
2266 : token_pos_(token_pos) { 2312 : token_pos_(token_pos) {
2267 SetInputAt(0, value); 2313 SetInputAt(0, value);
2268 } 2314 }
2269 2315
2270 DECLARE_INSTRUCTION(AssertBoolean) 2316 DECLARE_INSTRUCTION(AssertBoolean)
2271 virtual CompileType ComputeType() const; 2317 virtual CompileType ComputeType() const;
2272 2318
2273 intptr_t token_pos() const { return token_pos_; } 2319 intptr_t token_pos() const { return token_pos_; }
2274 Value* value() const { return inputs_[0]; } 2320 Value* value() const { return inputs_[0]; }
2275 2321
2276 virtual void PrintOperandsTo(BufferFormatter* f) const; 2322 virtual void PrintOperandsTo(BufferFormatter* f) const;
2277 2323
2278 virtual bool CanDeoptimize() const { return true; } 2324 virtual bool CanDeoptimize() const { return true; }
2279 2325
2280 virtual bool HasSideEffect() const { return false; } 2326 virtual Definition* Canonicalize(FlowGraphOptimizer* optimizer);
2281 2327
2282 virtual bool AffectedBySideEffect() const { return false; } 2328 virtual bool AllowsCSE() const { return true; }
2329 virtual EffectSet Effects() const { return EffectSet::None(); }
2330 virtual EffectSet Dependencies() const { return EffectSet::None(); }
2283 virtual bool AttributesEqual(Instruction* other) const { return true; } 2331 virtual bool AttributesEqual(Instruction* other) const { return true; }
2284 2332
2285 virtual Definition* Canonicalize(FlowGraphOptimizer* optimizer);
2286
2287 private: 2333 private:
2288 const intptr_t token_pos_; 2334 const intptr_t token_pos_;
2289 2335
2290 DISALLOW_COPY_AND_ASSIGN(AssertBooleanInstr); 2336 DISALLOW_COPY_AND_ASSIGN(AssertBooleanInstr);
2291 }; 2337 };
2292 2338
2293 2339
2294 class ArgumentDefinitionTestInstr : public TemplateDefinition<1> { 2340 class ArgumentDefinitionTestInstr : public TemplateDefinition<1> {
2295 public: 2341 public:
2296 ArgumentDefinitionTestInstr(ArgumentDefinitionTestNode* node, 2342 ArgumentDefinitionTestInstr(ArgumentDefinitionTestNode* node,
(...skipping 12 matching lines...) Expand all
2309 const String& formal_parameter_name() const { 2355 const String& formal_parameter_name() const {
2310 return ast_node_.formal_parameter_name(); 2356 return ast_node_.formal_parameter_name();
2311 } 2357 }
2312 2358
2313 Value* saved_arguments_descriptor() const { return inputs_[0]; } 2359 Value* saved_arguments_descriptor() const { return inputs_[0]; }
2314 2360
2315 virtual void PrintOperandsTo(BufferFormatter* f) const; 2361 virtual void PrintOperandsTo(BufferFormatter* f) const;
2316 2362
2317 virtual bool CanDeoptimize() const { return true; } 2363 virtual bool CanDeoptimize() const { return true; }
2318 2364
2319 virtual bool HasSideEffect() const { return true; } 2365 virtual EffectSet Effects() const { return EffectSet::None(); }
2320 2366
2321 private: 2367 private:
2322 const ArgumentDefinitionTestNode& ast_node_; 2368 const ArgumentDefinitionTestNode& ast_node_;
2323 2369
2324 DISALLOW_COPY_AND_ASSIGN(ArgumentDefinitionTestInstr); 2370 DISALLOW_COPY_AND_ASSIGN(ArgumentDefinitionTestInstr);
2325 }; 2371 };
2326 2372
2327 2373
2328 // Denotes the current context, normally held in a register. This is 2374 // Denotes the current context, normally held in a register. This is
2329 // a computation, not a value, because it's mutable. 2375 // a computation, not a value, because it's mutable.
2330 class CurrentContextInstr : public TemplateDefinition<0> { 2376 class CurrentContextInstr : public TemplateDefinition<0> {
2331 public: 2377 public:
2332 CurrentContextInstr() { } 2378 CurrentContextInstr() { }
2333 2379
2334 DECLARE_INSTRUCTION(CurrentContext) 2380 DECLARE_INSTRUCTION(CurrentContext)
2335 virtual CompileType ComputeType() const; 2381 virtual CompileType ComputeType() const;
2336 2382
2337 virtual bool CanDeoptimize() const { return false; } 2383 virtual bool CanDeoptimize() const { return false; }
2338 2384
2339 virtual bool HasSideEffect() const { return false; } 2385 virtual EffectSet Effects() const { return EffectSet::None(); }
2340 2386 virtual EffectSet Dependencies() const { return EffectSet::None(); }
2341 virtual bool AttributesEqual(Instruction* other) const { return true; } 2387 virtual bool AttributesEqual(Instruction* other) const { return true; }
2342 2388
2343 private: 2389 private:
2344 DISALLOW_COPY_AND_ASSIGN(CurrentContextInstr); 2390 DISALLOW_COPY_AND_ASSIGN(CurrentContextInstr);
2345 }; 2391 };
2346 2392
2347 2393
2348 class ClosureCallInstr : public TemplateDefinition<0> { 2394 class ClosureCallInstr : public TemplateDefinition<0> {
2349 public: 2395 public:
2350 ClosureCallInstr(ClosureCallNode* node, 2396 ClosureCallInstr(ClosureCallNode* node,
2351 ZoneGrowableArray<PushArgumentInstr*>* arguments) 2397 ZoneGrowableArray<PushArgumentInstr*>* arguments)
2352 : ast_node_(*node), 2398 : ast_node_(*node),
2353 arguments_(arguments) { } 2399 arguments_(arguments) { }
2354 2400
2355 DECLARE_INSTRUCTION(ClosureCall) 2401 DECLARE_INSTRUCTION(ClosureCall)
2356 2402
2357 const Array& argument_names() const { return ast_node_.arguments()->names(); } 2403 const Array& argument_names() const { return ast_node_.arguments()->names(); }
2358 intptr_t token_pos() const { return ast_node_.token_pos(); } 2404 intptr_t token_pos() const { return ast_node_.token_pos(); }
2359 2405
2360 virtual intptr_t ArgumentCount() const { return arguments_->length(); } 2406 virtual intptr_t ArgumentCount() const { return arguments_->length(); }
2361 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const { 2407 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const {
2362 return (*arguments_)[index]; 2408 return (*arguments_)[index];
2363 } 2409 }
2364 2410
2365 virtual void PrintOperandsTo(BufferFormatter* f) const; 2411 virtual void PrintOperandsTo(BufferFormatter* f) const;
2366 2412
2367 virtual bool CanDeoptimize() const { return true; } 2413 virtual bool CanDeoptimize() const { return true; }
2368 2414
2369 virtual bool HasSideEffect() const { return true; } 2415 virtual EffectSet Effects() const { return EffectSet::All(); }
2370 2416
2371 private: 2417 private:
2372 const ClosureCallNode& ast_node_; 2418 const ClosureCallNode& ast_node_;
2373 ZoneGrowableArray<PushArgumentInstr*>* arguments_; 2419 ZoneGrowableArray<PushArgumentInstr*>* arguments_;
2374 2420
2375 DISALLOW_COPY_AND_ASSIGN(ClosureCallInstr); 2421 DISALLOW_COPY_AND_ASSIGN(ClosureCallInstr);
2376 }; 2422 };
2377 2423
2378 2424
2379 class InstanceCallInstr : public TemplateDefinition<0> { 2425 class InstanceCallInstr : public TemplateDefinition<0> {
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
2421 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const { 2467 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const {
2422 return (*arguments_)[index]; 2468 return (*arguments_)[index];
2423 } 2469 }
2424 const Array& argument_names() const { return argument_names_; } 2470 const Array& argument_names() const { return argument_names_; }
2425 intptr_t checked_argument_count() const { return checked_argument_count_; } 2471 intptr_t checked_argument_count() const { return checked_argument_count_; }
2426 2472
2427 virtual void PrintOperandsTo(BufferFormatter* f) const; 2473 virtual void PrintOperandsTo(BufferFormatter* f) const;
2428 2474
2429 virtual bool CanDeoptimize() const { return true; } 2475 virtual bool CanDeoptimize() const { return true; }
2430 2476
2431 virtual bool HasSideEffect() const { return true; } 2477 virtual EffectSet Effects() const { return EffectSet::All(); }
2432 2478
2433 protected: 2479 protected:
2434 friend class FlowGraphOptimizer; 2480 friend class FlowGraphOptimizer;
2435 void set_ic_data(ICData* value) { ic_data_ = value; } 2481 void set_ic_data(ICData* value) { ic_data_ = value; }
2436 2482
2437 private: 2483 private:
2438 const ICData* ic_data_; 2484 const ICData* ic_data_;
2439 const intptr_t token_pos_; 2485 const intptr_t token_pos_;
2440 const String& function_name_; 2486 const String& function_name_;
2441 const Token::Kind token_kind_; // Binary op, unary op, kGET or kILLEGAL. 2487 const Token::Kind token_kind_; // Binary op, unary op, kGET or kILLEGAL.
(...skipping 25 matching lines...) Expand all
2467 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const { 2513 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const {
2468 return instance_call()->PushArgumentAt(index); 2514 return instance_call()->PushArgumentAt(index);
2469 } 2515 }
2470 2516
2471 DECLARE_INSTRUCTION(PolymorphicInstanceCall) 2517 DECLARE_INSTRUCTION(PolymorphicInstanceCall)
2472 2518
2473 const ICData& ic_data() const { return ic_data_; } 2519 const ICData& ic_data() const { return ic_data_; }
2474 2520
2475 virtual bool CanDeoptimize() const { return true; } 2521 virtual bool CanDeoptimize() const { return true; }
2476 2522
2477 virtual bool HasSideEffect() const { return true; } 2523 virtual EffectSet Effects() const { return EffectSet::All(); }
2478 2524
2479 virtual void PrintOperandsTo(BufferFormatter* f) const; 2525 virtual void PrintOperandsTo(BufferFormatter* f) const;
2480 2526
2481 private: 2527 private:
2482 InstanceCallInstr* instance_call_; 2528 InstanceCallInstr* instance_call_;
2483 const ICData& ic_data_; 2529 const ICData& ic_data_;
2484 const bool with_checks_; 2530 const bool with_checks_;
2485 2531
2486 DISALLOW_COPY_AND_ASSIGN(PolymorphicInstanceCallInstr); 2532 DISALLOW_COPY_AND_ASSIGN(PolymorphicInstanceCallInstr);
2487 }; 2533 };
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2535 // can throw a type check error. 2581 // can throw a type check error.
2536 return comparison()->CanDeoptimize() || is_checked(); 2582 return comparison()->CanDeoptimize() || is_checked();
2537 } 2583 }
2538 2584
2539 2585
2540 inline bool BranchInstr::CanBeDeoptimizationTarget() const { 2586 inline bool BranchInstr::CanBeDeoptimizationTarget() const {
2541 return comparison()->CanBeDeoptimizationTarget(); 2587 return comparison()->CanBeDeoptimizationTarget();
2542 } 2588 }
2543 2589
2544 2590
2545 inline bool BranchInstr::HasSideEffect() const { 2591 inline EffectSet BranchInstr::Effects() const {
2546 return comparison()->HasSideEffect(); 2592 return comparison()->Effects();
2547 } 2593 }
2548 2594
2549 2595
2550 inline LocationSummary* BranchInstr::locs() { 2596 inline LocationSummary* BranchInstr::locs() {
2551 if (comparison()->locs_ == NULL) { 2597 if (comparison()->locs_ == NULL) {
2552 LocationSummary* summary = comparison()->MakeLocationSummary(); 2598 LocationSummary* summary = comparison()->MakeLocationSummary();
2553 // Branches don't produce a result. 2599 // Branches don't produce a result.
2554 summary->set_out(Location::NoLocation()); 2600 summary->set_out(Location::NoLocation());
2555 comparison()->locs_ = summary; 2601 comparison()->locs_ = summary;
2556 } 2602 }
(...skipping 21 matching lines...) Expand all
2578 2624
2579 virtual void PrintOperandsTo(BufferFormatter* f) const; 2625 virtual void PrintOperandsTo(BufferFormatter* f) const;
2580 2626
2581 virtual bool CanBeDeoptimizationTarget() const { 2627 virtual bool CanBeDeoptimizationTarget() const {
2582 // StrictCompare can be merged into Branch and thus needs an environment. 2628 // StrictCompare can be merged into Branch and thus needs an environment.
2583 return true; 2629 return true;
2584 } 2630 }
2585 2631
2586 virtual bool CanDeoptimize() const { return false; } 2632 virtual bool CanDeoptimize() const { return false; }
2587 2633
2588 virtual bool HasSideEffect() const { return false; }
2589
2590 virtual bool AttributesEqual(Instruction* other) const;
2591 virtual bool AffectedBySideEffect() const { return false; }
2592
2593 virtual Definition* Canonicalize(FlowGraphOptimizer* optimizer); 2634 virtual Definition* Canonicalize(FlowGraphOptimizer* optimizer);
2594 2635
2595 virtual void EmitBranchCode(FlowGraphCompiler* compiler, 2636 virtual void EmitBranchCode(FlowGraphCompiler* compiler,
2596 BranchInstr* branch); 2637 BranchInstr* branch);
2597 2638
2598 bool needs_number_check() const { return needs_number_check_; } 2639 bool needs_number_check() const { return needs_number_check_; }
2599 void set_needs_number_check(bool value) { needs_number_check_ = value; } 2640 void set_needs_number_check(bool value) { needs_number_check_ = value; }
2600 void set_kind(Token::Kind value) { kind_ = value; } 2641 void set_kind(Token::Kind value) { kind_ = value; }
2601 2642
2643 virtual bool AllowsCSE() const { return true; }
2644 virtual EffectSet Effects() const { return EffectSet::None(); }
2645 virtual EffectSet Dependencies() const { return EffectSet::None(); }
2646 virtual bool AttributesEqual(Instruction* other) const;
2647
2602 private: 2648 private:
2603 // True if the comparison must check for double, Mint or Bigint and 2649 // True if the comparison must check for double, Mint or Bigint and
2604 // use value comparison instead. 2650 // use value comparison instead.
2605 bool needs_number_check_; 2651 bool needs_number_check_;
2606 2652
2607 DISALLOW_COPY_AND_ASSIGN(StrictCompareInstr); 2653 DISALLOW_COPY_AND_ASSIGN(StrictCompareInstr);
2608 }; 2654 };
2609 2655
2610 2656
2611 class EqualityCompareInstr : public ComparisonInstr { 2657 class EqualityCompareInstr : public ComparisonInstr {
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
2643 || (receiver_class_id() == kMintCid) 2689 || (receiver_class_id() == kMintCid)
2644 || (receiver_class_id() == kSmiCid); 2690 || (receiver_class_id() == kSmiCid);
2645 } 2691 }
2646 2692
2647 virtual void PrintOperandsTo(BufferFormatter* f) const; 2693 virtual void PrintOperandsTo(BufferFormatter* f) const;
2648 2694
2649 virtual bool CanDeoptimize() const { 2695 virtual bool CanDeoptimize() const {
2650 return !IsInlinedNumericComparison(); 2696 return !IsInlinedNumericComparison();
2651 } 2697 }
2652 2698
2653 virtual bool HasSideEffect() const {
2654 return !IsInlinedNumericComparison();
2655 }
2656
2657 virtual void EmitBranchCode(FlowGraphCompiler* compiler, 2699 virtual void EmitBranchCode(FlowGraphCompiler* compiler,
2658 BranchInstr* branch); 2700 BranchInstr* branch);
2659 2701
2660 virtual intptr_t DeoptimizationTarget() const { 2702 virtual intptr_t DeoptimizationTarget() const {
2661 return GetDeoptId(); 2703 return GetDeoptId();
2662 } 2704 }
2663 2705
2664 virtual Representation RequiredInputRepresentation(intptr_t idx) const { 2706 virtual Representation RequiredInputRepresentation(intptr_t idx) const {
2665 ASSERT((idx == 0) || (idx == 1)); 2707 ASSERT((idx == 0) || (idx == 1));
2666 if (receiver_class_id() == kDoubleCid) return kUnboxedDouble; 2708 if (receiver_class_id() == kDoubleCid) return kUnboxedDouble;
2667 if (receiver_class_id() == kMintCid) return kUnboxedMint; 2709 if (receiver_class_id() == kMintCid) return kUnboxedMint;
2668 return kTagged; 2710 return kTagged;
2669 } 2711 }
2670 2712
2671 bool IsPolymorphic() const; 2713 bool IsPolymorphic() const;
2672 2714
2715 virtual EffectSet Effects() const {
2716 return IsInlinedNumericComparison() ? EffectSet::None() : EffectSet::All();
2717 }
2718
2673 private: 2719 private:
2674 const ICData* ic_data_; 2720 const ICData* ic_data_;
2675 const intptr_t token_pos_; 2721 const intptr_t token_pos_;
2676 intptr_t receiver_class_id_; // Set by optimizer. 2722 intptr_t receiver_class_id_; // Set by optimizer.
2677 2723
2678 DISALLOW_COPY_AND_ASSIGN(EqualityCompareInstr); 2724 DISALLOW_COPY_AND_ASSIGN(EqualityCompareInstr);
2679 }; 2725 };
2680 2726
2681 2727
2682 class RelationalOpInstr : public ComparisonInstr { 2728 class RelationalOpInstr : public ComparisonInstr {
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2717 return (operands_class_id() == kDoubleCid) 2763 return (operands_class_id() == kDoubleCid)
2718 || (operands_class_id() == kMintCid) 2764 || (operands_class_id() == kMintCid)
2719 || (operands_class_id() == kSmiCid); 2765 || (operands_class_id() == kSmiCid);
2720 } 2766 }
2721 2767
2722 virtual void PrintOperandsTo(BufferFormatter* f) const; 2768 virtual void PrintOperandsTo(BufferFormatter* f) const;
2723 2769
2724 virtual bool CanDeoptimize() const { 2770 virtual bool CanDeoptimize() const {
2725 return !IsInlinedNumericComparison(); 2771 return !IsInlinedNumericComparison();
2726 } 2772 }
2727 virtual bool HasSideEffect() const {
2728 return !IsInlinedNumericComparison();
2729 }
2730 2773
2731 virtual void EmitBranchCode(FlowGraphCompiler* compiler, 2774 virtual void EmitBranchCode(FlowGraphCompiler* compiler,
2732 BranchInstr* branch); 2775 BranchInstr* branch);
2733 2776
2734 2777
2735 virtual intptr_t DeoptimizationTarget() const { 2778 virtual intptr_t DeoptimizationTarget() const {
2736 return GetDeoptId(); 2779 return GetDeoptId();
2737 } 2780 }
2738 2781
2739 virtual Representation RequiredInputRepresentation(intptr_t idx) const { 2782 virtual Representation RequiredInputRepresentation(intptr_t idx) const {
2740 ASSERT((idx == 0) || (idx == 1)); 2783 ASSERT((idx == 0) || (idx == 1));
2741 if (operands_class_id() == kDoubleCid) return kUnboxedDouble; 2784 if (operands_class_id() == kDoubleCid) return kUnboxedDouble;
2742 if (operands_class_id() == kMintCid) return kUnboxedMint; 2785 if (operands_class_id() == kMintCid) return kUnboxedMint;
2743 return kTagged; 2786 return kTagged;
2744 } 2787 }
2745 2788
2789 virtual EffectSet Effects() const {
2790 return IsInlinedNumericComparison() ? EffectSet::None() : EffectSet::All();
2791 }
2792
2746 private: 2793 private:
2747 const ICData* ic_data_; 2794 const ICData* ic_data_;
2748 const intptr_t token_pos_; 2795 const intptr_t token_pos_;
2749 intptr_t operands_class_id_; // class id of both operands. 2796 intptr_t operands_class_id_; // class id of both operands.
2750 2797
2751 DISALLOW_COPY_AND_ASSIGN(RelationalOpInstr); 2798 DISALLOW_COPY_AND_ASSIGN(RelationalOpInstr);
2752 }; 2799 };
2753 2800
2754 2801
2755 // TODO(vegorov): ComparisonInstr should be switched to use IfTheElseInstr for 2802 // TODO(vegorov): ComparisonInstr should be switched to use IfTheElseInstr for
(...skipping 22 matching lines...) Expand all
2778 2825
2779 DECLARE_INSTRUCTION(IfThenElse) 2826 DECLARE_INSTRUCTION(IfThenElse)
2780 2827
2781 virtual void PrintOperandsTo(BufferFormatter* f) const; 2828 virtual void PrintOperandsTo(BufferFormatter* f) const;
2782 2829
2783 virtual CompileType ComputeType() const; 2830 virtual CompileType ComputeType() const;
2784 2831
2785 virtual void InferRange(); 2832 virtual void InferRange();
2786 2833
2787 virtual bool CanDeoptimize() const { return false; } 2834 virtual bool CanDeoptimize() const { return false; }
2788 virtual bool HasSideEffect() const { return false; }
2789
2790 virtual bool AttributesEqual(Instruction* other) const {
2791 IfThenElseInstr* other_if_then_else = other->AsIfThenElse();
2792 return (kind_ == other_if_then_else->kind_) &&
2793 (if_true_ == other_if_then_else->if_true_) &&
2794 (if_false_ == other_if_then_else->if_false_);
2795 }
2796
2797 virtual bool AffectedBySideEffect() const {
2798 return false;
2799 }
2800 2835
2801 Value* left() const { return inputs_[0]; } 2836 Value* left() const { return inputs_[0]; }
2802 Value* right() const { return inputs_[1]; } 2837 Value* right() const { return inputs_[1]; }
2803 intptr_t if_true() const { return if_true_; } 2838 intptr_t if_true() const { return if_true_; }
2804 intptr_t if_false() const { return if_false_; } 2839 intptr_t if_false() const { return if_false_; }
2805 2840
2806 Token::Kind kind() const { return kind_; } 2841 Token::Kind kind() const { return kind_; }
2807 2842
2843 virtual bool AllowsCSE() const { return true; }
2844 virtual EffectSet Effects() const { return EffectSet::None(); }
2845 virtual EffectSet Dependencies() const { return EffectSet::None(); }
2846 virtual bool AttributesEqual(Instruction* other) const {
2847 IfThenElseInstr* other_if_then_else = other->AsIfThenElse();
2848 return (kind_ == other_if_then_else->kind_) &&
2849 (if_true_ == other_if_then_else->if_true_) &&
2850 (if_false_ == other_if_then_else->if_false_);
2851 }
2852
2808 private: 2853 private:
2809 const Token::Kind kind_; 2854 const Token::Kind kind_;
2810 const intptr_t if_true_; 2855 const intptr_t if_true_;
2811 const intptr_t if_false_; 2856 const intptr_t if_false_;
2812 2857
2813 DISALLOW_COPY_AND_ASSIGN(IfThenElseInstr); 2858 DISALLOW_COPY_AND_ASSIGN(IfThenElseInstr);
2814 }; 2859 };
2815 2860
2816 2861
2817 class StaticCallInstr : public TemplateDefinition<0> { 2862 class StaticCallInstr : public TemplateDefinition<0> {
(...skipping 20 matching lines...) Expand all
2838 const Array& argument_names() const { return argument_names_; } 2883 const Array& argument_names() const { return argument_names_; }
2839 intptr_t token_pos() const { return token_pos_; } 2884 intptr_t token_pos() const { return token_pos_; }
2840 2885
2841 virtual intptr_t ArgumentCount() const { return arguments_->length(); } 2886 virtual intptr_t ArgumentCount() const { return arguments_->length(); }
2842 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const { 2887 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const {
2843 return (*arguments_)[index]; 2888 return (*arguments_)[index];
2844 } 2889 }
2845 2890
2846 virtual void PrintOperandsTo(BufferFormatter* f) const; 2891 virtual void PrintOperandsTo(BufferFormatter* f) const;
2847 2892
2893
Florian Schneider 2013/04/29 12:11:54 Extra \n?
Vyacheslav Egorov (Google) 2013/04/30 14:01:33 Done.
2848 virtual bool CanDeoptimize() const { return true; } 2894 virtual bool CanDeoptimize() const { return true; }
2849 2895
2850 virtual bool HasSideEffect() const { return true; } 2896 virtual EffectSet Effects() const { return EffectSet::All(); }
2851 2897
2852 void set_result_cid(intptr_t value) { result_cid_ = value; } 2898 void set_result_cid(intptr_t value) { result_cid_ = value; }
2853 2899
2854 bool is_known_list_constructor() const { return is_known_list_constructor_; } 2900 bool is_known_list_constructor() const { return is_known_list_constructor_; }
2855 void set_is_known_list_constructor(bool value) { 2901 void set_is_known_list_constructor(bool value) {
2856 is_known_list_constructor_ = value; 2902 is_known_list_constructor_ = value;
2857 } 2903 }
2858 2904
2859 private: 2905 private:
2860 const intptr_t token_pos_; 2906 const intptr_t token_pos_;
(...skipping 16 matching lines...) Expand all
2877 2923
2878 DECLARE_INSTRUCTION(LoadLocal) 2924 DECLARE_INSTRUCTION(LoadLocal)
2879 virtual CompileType ComputeType() const; 2925 virtual CompileType ComputeType() const;
2880 2926
2881 const LocalVariable& local() const { return local_; } 2927 const LocalVariable& local() const { return local_; }
2882 2928
2883 virtual void PrintOperandsTo(BufferFormatter* f) const; 2929 virtual void PrintOperandsTo(BufferFormatter* f) const;
2884 2930
2885 virtual bool CanDeoptimize() const { return false; } 2931 virtual bool CanDeoptimize() const { return false; }
2886 2932
2887 virtual bool HasSideEffect() const { 2933 virtual EffectSet Effects() const {
2888 UNREACHABLE(); 2934 UNREACHABLE();
Florian Schneider 2013/04/29 12:11:54 Maybe add a comment: // Never used in optimizing c
Vyacheslav Egorov (Google) 2013/04/30 14:01:33 Done.
2889 return false; 2935 return EffectSet::None();
2890 } 2936 }
2891 2937
2892 void mark_last() { is_last_ = true; } 2938 void mark_last() { is_last_ = true; }
2893 bool is_last() const { return is_last_; } 2939 bool is_last() const { return is_last_; }
2894 2940
2895 private: 2941 private:
2896 const LocalVariable& local_; 2942 const LocalVariable& local_;
2897 bool is_last_; 2943 bool is_last_;
2898 2944
2899 DISALLOW_COPY_AND_ASSIGN(LoadLocalInstr); 2945 DISALLOW_COPY_AND_ASSIGN(LoadLocalInstr);
(...skipping 10 matching lines...) Expand all
2910 DECLARE_INSTRUCTION(StoreLocal) 2956 DECLARE_INSTRUCTION(StoreLocal)
2911 virtual CompileType* ComputeInitialType() const; 2957 virtual CompileType* ComputeInitialType() const;
2912 2958
2913 const LocalVariable& local() const { return local_; } 2959 const LocalVariable& local() const { return local_; }
2914 Value* value() const { return inputs_[0]; } 2960 Value* value() const { return inputs_[0]; }
2915 2961
2916 virtual void PrintOperandsTo(BufferFormatter* f) const; 2962 virtual void PrintOperandsTo(BufferFormatter* f) const;
2917 2963
2918 virtual bool CanDeoptimize() const { return false; } 2964 virtual bool CanDeoptimize() const { return false; }
2919 2965
2920 virtual bool HasSideEffect() const {
2921 UNREACHABLE();
2922 return false;
2923 }
2924
2925 void mark_dead() { is_dead_ = true; } 2966 void mark_dead() { is_dead_ = true; }
2926 bool is_dead() const { return is_dead_; } 2967 bool is_dead() const { return is_dead_; }
2927 2968
2928 void mark_last() { is_last_ = true; } 2969 void mark_last() { is_last_ = true; }
2929 bool is_last() const { return is_last_; } 2970 bool is_last() const { return is_last_; }
2930 2971
2972 virtual EffectSet Effects() const {
2973 UNREACHABLE();
Florian Schneider 2013/04/29 12:11:54 Maybe add a comment: // Never used in optimizing c
Vyacheslav Egorov (Google) 2013/04/30 14:01:33 Done.
2974 return EffectSet::None();
2975 }
2976
2931 private: 2977 private:
2932 const LocalVariable& local_; 2978 const LocalVariable& local_;
2933 bool is_dead_; 2979 bool is_dead_;
2934 bool is_last_; 2980 bool is_last_;
2935 2981
2936 DISALLOW_COPY_AND_ASSIGN(StoreLocalInstr); 2982 DISALLOW_COPY_AND_ASSIGN(StoreLocalInstr);
2937 }; 2983 };
2938 2984
2939 2985
2940 class NativeCallInstr : public TemplateDefinition<0> { 2986 class NativeCallInstr : public TemplateDefinition<0> {
(...skipping 12 matching lines...) Expand all
2953 } 2999 }
2954 3000
2955 NativeFunction native_c_function() const { 3001 NativeFunction native_c_function() const {
2956 return ast_node_.native_c_function(); 3002 return ast_node_.native_c_function();
2957 } 3003 }
2958 3004
2959 virtual void PrintOperandsTo(BufferFormatter* f) const; 3005 virtual void PrintOperandsTo(BufferFormatter* f) const;
2960 3006
2961 virtual bool CanDeoptimize() const { return false; } 3007 virtual bool CanDeoptimize() const { return false; }
2962 3008
2963 virtual bool HasSideEffect() const { return true; } 3009 virtual EffectSet Effects() const { return EffectSet::All(); }
2964 3010
2965 private: 3011 private:
2966 const NativeBodyNode& ast_node_; 3012 const NativeBodyNode& ast_node_;
2967 3013
2968 DISALLOW_COPY_AND_ASSIGN(NativeCallInstr); 3014 DISALLOW_COPY_AND_ASSIGN(NativeCallInstr);
2969 }; 3015 };
2970 3016
2971 3017
2972 enum StoreBarrierType { 3018 enum StoreBarrierType {
2973 kNoStoreBarrier, 3019 kNoStoreBarrier,
(...skipping 22 matching lines...) Expand all
2996 Value* value() const { return inputs_[1]; } 3042 Value* value() const { return inputs_[1]; }
2997 bool ShouldEmitStoreBarrier() const { 3043 bool ShouldEmitStoreBarrier() const {
2998 return value()->NeedsStoreBuffer() 3044 return value()->NeedsStoreBuffer()
2999 && (emit_store_barrier_ == kEmitStoreBarrier); 3045 && (emit_store_barrier_ == kEmitStoreBarrier);
3000 } 3046 }
3001 3047
3002 virtual void PrintOperandsTo(BufferFormatter* f) const; 3048 virtual void PrintOperandsTo(BufferFormatter* f) const;
3003 3049
3004 virtual bool CanDeoptimize() const { return false; } 3050 virtual bool CanDeoptimize() const { return false; }
3005 3051
3006 virtual bool HasSideEffect() const { return true; } 3052 virtual EffectSet Effects() const { return EffectSet::None(); }
Florian Schneider 2013/04/29 12:11:54 Add a comment why stores are excluded from side ef
Vyacheslav Egorov (Google) 2013/04/30 14:01:33 Done.
3007 3053
3008 private: 3054 private:
3009 bool CanValueBeSmi() const { 3055 bool CanValueBeSmi() const {
3010 const intptr_t cid = value()->Type()->ToNullableCid(); 3056 const intptr_t cid = value()->Type()->ToNullableCid();
3011 // Write barrier is skipped for nullable and non-nullable smis. 3057 // Write barrier is skipped for nullable and non-nullable smis.
3012 ASSERT(cid != kSmiCid); 3058 ASSERT(cid != kSmiCid);
3013 return (cid == kDynamicCid); 3059 return (cid == kDynamicCid);
3014 } 3060 }
3015 3061
3016 const Field& field_; 3062 const Field& field_;
3017 const StoreBarrierType emit_store_barrier_; 3063 const StoreBarrierType emit_store_barrier_;
3018 3064
3019 DISALLOW_COPY_AND_ASSIGN(StoreInstanceFieldInstr); 3065 DISALLOW_COPY_AND_ASSIGN(StoreInstanceFieldInstr);
3020 }; 3066 };
3021 3067
3022 3068
3023 class GuardFieldInstr : public TemplateInstruction<1> { 3069 class GuardFieldInstr : public TemplateInstruction<1> {
3024 public: 3070 public:
3025 GuardFieldInstr(Value* value, 3071 GuardFieldInstr(Value* value,
3026 const Field& field, 3072 const Field& field,
3027 intptr_t deopt_id) 3073 intptr_t deopt_id)
3028 : field_(field) { 3074 : field_(field) {
3029 deopt_id_ = deopt_id; 3075 deopt_id_ = deopt_id;
3030 SetInputAt(0, value); 3076 SetInputAt(0, value);
3031 } 3077 }
3032 3078
3079 Value* value() const { return inputs_[0]; }
3080
3081 const Field& field() const { return field_; }
3082
3033 DECLARE_INSTRUCTION(GuardField) 3083 DECLARE_INSTRUCTION(GuardField)
3034 3084
3035 virtual intptr_t ArgumentCount() const { return 0; } 3085 virtual intptr_t ArgumentCount() const { return 0; }
3036 3086
3037 virtual bool CanDeoptimize() const { return true; } 3087 virtual bool CanDeoptimize() const { return true; }
3038 3088
3039 virtual bool HasSideEffect() const { return false; }
3040
3041 virtual bool AttributesEqual(Instruction* other) const;
3042
3043 virtual bool AffectedBySideEffect() const;
3044
3045 Value* value() const { return inputs_[0]; }
3046
3047 virtual Instruction* Canonicalize(FlowGraphOptimizer* optimizer); 3089 virtual Instruction* Canonicalize(FlowGraphOptimizer* optimizer);
3048 3090
3049 virtual void PrintOperandsTo(BufferFormatter* f) const; 3091 virtual void PrintOperandsTo(BufferFormatter* f) const;
3050 3092
3051 const Field& field() const { return field_; } 3093 virtual bool AllowsCSE() const { return true; }
3094 virtual EffectSet Effects() const { return EffectSet::None(); }
3095 virtual EffectSet Dependencies() const { return EffectSet::None(); }
3096 virtual bool AttributesEqual(Instruction* other) const;
3052 3097
3053 private: 3098 private:
3054 const Field& field_; 3099 const Field& field_;
3055 3100
3056 DISALLOW_COPY_AND_ASSIGN(GuardFieldInstr); 3101 DISALLOW_COPY_AND_ASSIGN(GuardFieldInstr);
3057 }; 3102 };
3058 3103
3059 3104
3060 class LoadStaticFieldInstr : public TemplateDefinition<0> { 3105 class LoadStaticFieldInstr : public TemplateDefinition<0> {
3061 public: 3106 public:
3062 explicit LoadStaticFieldInstr(const Field& field) : field_(field) {} 3107 explicit LoadStaticFieldInstr(const Field& field) : field_(field) {}
3063 3108
3064 DECLARE_INSTRUCTION(LoadStaticField); 3109 DECLARE_INSTRUCTION(LoadStaticField);
3065 virtual CompileType ComputeType() const; 3110 virtual CompileType ComputeType() const;
3066 3111
3067 const Field& field() const { return field_; } 3112 const Field& field() const { return field_; }
3068 3113
3069 virtual void PrintOperandsTo(BufferFormatter* f) const; 3114 virtual void PrintOperandsTo(BufferFormatter* f) const;
3070 3115
3071 virtual bool CanDeoptimize() const { return false; } 3116 virtual bool CanDeoptimize() const { return false; }
3072 3117
3073 virtual bool HasSideEffect() const { return false; } 3118 virtual bool AllowsCSE() const { return field_.is_final(); }
3074 3119 virtual EffectSet Effects() const { return EffectSet::None(); }
3075 virtual bool AffectedBySideEffect() const { return !field().is_final(); } 3120 virtual EffectSet Dependencies() const;
3076 virtual bool AttributesEqual(Instruction* other) const; 3121 virtual bool AttributesEqual(Instruction* other) const;
3077 3122
3078 private: 3123 private:
3079 const Field& field_; 3124 const Field& field_;
3080 3125
3081 DISALLOW_COPY_AND_ASSIGN(LoadStaticFieldInstr); 3126 DISALLOW_COPY_AND_ASSIGN(LoadStaticFieldInstr);
3082 }; 3127 };
3083 3128
3084 3129
3085 class StoreStaticFieldInstr : public TemplateDefinition<1> { 3130 class StoreStaticFieldInstr : public TemplateDefinition<1> {
3086 public: 3131 public:
3087 StoreStaticFieldInstr(const Field& field, Value* value) 3132 StoreStaticFieldInstr(const Field& field, Value* value)
3088 : field_(field) { 3133 : field_(field) {
3089 ASSERT(field.IsZoneHandle()); 3134 ASSERT(field.IsZoneHandle());
3090 SetInputAt(0, value); 3135 SetInputAt(0, value);
3091 } 3136 }
3092 3137
3093 DECLARE_INSTRUCTION(StoreStaticField); 3138 DECLARE_INSTRUCTION(StoreStaticField);
3094 virtual CompileType* ComputeInitialType() const; 3139 virtual CompileType* ComputeInitialType() const;
3095 3140
3096 const Field& field() const { return field_; } 3141 const Field& field() const { return field_; }
3097 Value* value() const { return inputs_[0]; } 3142 Value* value() const { return inputs_[0]; }
3098 3143
3099 virtual void PrintOperandsTo(BufferFormatter* f) const; 3144 virtual void PrintOperandsTo(BufferFormatter* f) const;
3100 3145
3101 virtual bool CanDeoptimize() const { return false; } 3146 virtual bool CanDeoptimize() const { return false; }
3102 3147
3103 virtual bool HasSideEffect() const { return true; } 3148 virtual EffectSet Effects() const { return EffectSet::None(); }
Florian Schneider 2013/04/29 12:11:54 Add a comment why stores are excluded from side ef
Vyacheslav Egorov (Google) 2013/04/30 14:01:33 Done.
3104 3149
3105 private: 3150 private:
3106 bool CanValueBeSmi() const { 3151 bool CanValueBeSmi() const {
3107 const intptr_t cid = value()->Type()->ToNullableCid(); 3152 const intptr_t cid = value()->Type()->ToNullableCid();
3108 // Write barrier is skipped for nullable and non-nullable smis. 3153 // Write barrier is skipped for nullable and non-nullable smis.
3109 ASSERT(cid != kSmiCid); 3154 ASSERT(cid != kSmiCid);
3110 return (cid == kDynamicCid); 3155 return (cid == kDynamicCid);
3111 } 3156 }
3112 3157
3113 const Field& field_; 3158 const Field& field_;
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
3145 3190
3146 Value* array() const { return inputs_[0]; } 3191 Value* array() const { return inputs_[0]; }
3147 Value* index() const { return inputs_[1]; } 3192 Value* index() const { return inputs_[1]; }
3148 intptr_t index_scale() const { return index_scale_; } 3193 intptr_t index_scale() const { return index_scale_; }
3149 intptr_t class_id() const { return class_id_; } 3194 intptr_t class_id() const { return class_id_; }
3150 3195
3151 virtual bool CanDeoptimize() const { 3196 virtual bool CanDeoptimize() const {
3152 return deopt_id_ != Isolate::kNoDeoptId; 3197 return deopt_id_ != Isolate::kNoDeoptId;
3153 } 3198 }
3154 3199
3155 virtual bool HasSideEffect() const { return false; }
3156 3200
3157 virtual Representation representation() const; 3201 virtual Representation representation() const;
3202 virtual void InferRange();
3158 3203
3204 virtual bool AllowsCSE() const { return false; }
3205 virtual EffectSet Effects() const { return EffectSet::None(); }
3206 virtual EffectSet Dependencies() const;
3159 virtual bool AttributesEqual(Instruction* other) const; 3207 virtual bool AttributesEqual(Instruction* other) const;
3160 3208
3161 virtual bool AffectedBySideEffect() const { return true; }
3162
3163 virtual void InferRange();
3164
3165 private: 3209 private:
3166 const intptr_t index_scale_; 3210 const intptr_t index_scale_;
3167 const intptr_t class_id_; 3211 const intptr_t class_id_;
3168 3212
3169 DISALLOW_COPY_AND_ASSIGN(LoadIndexedInstr); 3213 DISALLOW_COPY_AND_ASSIGN(LoadIndexedInstr);
3170 }; 3214 };
3171 3215
3172 3216
3173 class StringFromCharCodeInstr : public TemplateDefinition<1> { 3217 class StringFromCharCodeInstr : public TemplateDefinition<1> {
3174 public: 3218 public:
3175 StringFromCharCodeInstr(Value* char_code, intptr_t cid) : cid_(cid) { 3219 StringFromCharCodeInstr(Value* char_code, intptr_t cid) : cid_(cid) {
3176 ASSERT(char_code != NULL); 3220 ASSERT(char_code != NULL);
3177 ASSERT(char_code->definition()->IsLoadIndexed() && 3221 ASSERT(char_code->definition()->IsLoadIndexed() &&
3178 (char_code->definition()->AsLoadIndexed()->class_id() == 3222 (char_code->definition()->AsLoadIndexed()->class_id() ==
3179 kOneByteStringCid)); 3223 kOneByteStringCid));
3180 SetInputAt(0, char_code); 3224 SetInputAt(0, char_code);
3181 } 3225 }
3182 3226
3183 DECLARE_INSTRUCTION(StringFromCharCode) 3227 DECLARE_INSTRUCTION(StringFromCharCode)
3184 virtual CompileType ComputeType() const; 3228 virtual CompileType ComputeType() const;
3185 3229
3186 Value* char_code() const { return inputs_[0]; } 3230 Value* char_code() const { return inputs_[0]; }
3187 3231
3188 virtual bool CanDeoptimize() const { return false; } 3232 virtual bool CanDeoptimize() const { return false; }
3189 3233
3190 virtual bool HasSideEffect() const { return false; } 3234 virtual bool AllowsCSE() const { return true; }
3191 3235 virtual EffectSet Effects() const { return EffectSet::None(); }
3192 virtual bool AttributesEqual(Instruction* other) const { return true; } 3236 virtual EffectSet Dependencies() const { return EffectSet::None(); }
3193 3237 virtual bool AttributesEqual(Instruction* other) const {
3194 virtual bool AffectedBySideEffect() const { return false; } 3238 return other->AsStringFromCharCode()->cid_ == cid_;
3239 }
3195 3240
3196 private: 3241 private:
3197 const intptr_t cid_; 3242 const intptr_t cid_;
3198 3243
3199 DISALLOW_COPY_AND_ASSIGN(StringFromCharCodeInstr); 3244 DISALLOW_COPY_AND_ASSIGN(StringFromCharCodeInstr);
3200 }; 3245 };
3201 3246
3202 3247
3203 class StoreIndexedInstr : public TemplateDefinition<3> { 3248 class StoreIndexedInstr : public TemplateDefinition<3> {
3204 public: 3249 public:
(...skipping 21 matching lines...) Expand all
3226 intptr_t index_scale() const { return index_scale_; } 3271 intptr_t index_scale() const { return index_scale_; }
3227 intptr_t class_id() const { return class_id_; } 3272 intptr_t class_id() const { return class_id_; }
3228 3273
3229 bool ShouldEmitStoreBarrier() const { 3274 bool ShouldEmitStoreBarrier() const {
3230 return value()->NeedsStoreBuffer() 3275 return value()->NeedsStoreBuffer()
3231 && (emit_store_barrier_ == kEmitStoreBarrier); 3276 && (emit_store_barrier_ == kEmitStoreBarrier);
3232 } 3277 }
3233 3278
3234 virtual bool CanDeoptimize() const { return false; } 3279 virtual bool CanDeoptimize() const { return false; }
3235 3280
3236 virtual bool HasSideEffect() const { return true; }
3237
3238 virtual Representation RequiredInputRepresentation(intptr_t idx) const; 3281 virtual Representation RequiredInputRepresentation(intptr_t idx) const;
3239 3282
3240 bool IsExternal() const { 3283 bool IsExternal() const {
3241 return array()->definition()->representation() == kUntagged; 3284 return array()->definition()->representation() == kUntagged;
3242 } 3285 }
3243 3286
3244 virtual intptr_t DeoptimizationTarget() const { 3287 virtual intptr_t DeoptimizationTarget() const {
3245 // Direct access since this instruction cannot deoptimize, and the deopt-id 3288 // Direct access since this instruction cannot deoptimize, and the deopt-id
3246 // was inherited from another instruction that could deoptimize. 3289 // was inherited from another instruction that could deoptimize.
3247 return deopt_id_; 3290 return deopt_id_;
3248 } 3291 }
3249 3292
3293 virtual EffectSet Effects() const { return EffectSet::None(); }
3294
3250 private: 3295 private:
3251 const StoreBarrierType emit_store_barrier_; 3296 const StoreBarrierType emit_store_barrier_;
3252 const intptr_t index_scale_; 3297 const intptr_t index_scale_;
3253 const intptr_t class_id_; 3298 const intptr_t class_id_;
3254 3299
3255 DISALLOW_COPY_AND_ASSIGN(StoreIndexedInstr); 3300 DISALLOW_COPY_AND_ASSIGN(StoreIndexedInstr);
3256 }; 3301 };
3257 3302
3258 3303
3259 // Note overrideable, built-in: value? false : true. 3304 // Note overrideable, built-in: value? false : true.
3260 class BooleanNegateInstr : public TemplateDefinition<1> { 3305 class BooleanNegateInstr : public TemplateDefinition<1> {
3261 public: 3306 public:
3262 explicit BooleanNegateInstr(Value* value) { 3307 explicit BooleanNegateInstr(Value* value) {
3263 SetInputAt(0, value); 3308 SetInputAt(0, value);
3264 } 3309 }
3265 3310
3266 DECLARE_INSTRUCTION(BooleanNegate) 3311 DECLARE_INSTRUCTION(BooleanNegate)
3267 virtual CompileType ComputeType() const; 3312 virtual CompileType ComputeType() const;
3268 3313
3269 Value* value() const { return inputs_[0]; } 3314 Value* value() const { return inputs_[0]; }
3270 3315
3271 virtual bool CanDeoptimize() const { return false; } 3316 virtual bool CanDeoptimize() const { return false; }
3272 3317
3273 virtual bool HasSideEffect() const { return false; } 3318 virtual EffectSet Effects() const { return EffectSet::None(); }
3274 3319
3275 private: 3320 private:
3276 DISALLOW_COPY_AND_ASSIGN(BooleanNegateInstr); 3321 DISALLOW_COPY_AND_ASSIGN(BooleanNegateInstr);
3277 }; 3322 };
3278 3323
3279 3324
3280 class InstanceOfInstr : public TemplateDefinition<3> { 3325 class InstanceOfInstr : public TemplateDefinition<3> {
3281 public: 3326 public:
3282 InstanceOfInstr(intptr_t token_pos, 3327 InstanceOfInstr(intptr_t token_pos,
3283 Value* value, 3328 Value* value,
(...skipping 20 matching lines...) Expand all
3304 Value* instantiator_type_arguments() const { return inputs_[2]; } 3349 Value* instantiator_type_arguments() const { return inputs_[2]; }
3305 3350
3306 bool negate_result() const { return negate_result_; } 3351 bool negate_result() const { return negate_result_; }
3307 const AbstractType& type() const { return type_; } 3352 const AbstractType& type() const { return type_; }
3308 intptr_t token_pos() const { return token_pos_; } 3353 intptr_t token_pos() const { return token_pos_; }
3309 3354
3310 virtual void PrintOperandsTo(BufferFormatter* f) const; 3355 virtual void PrintOperandsTo(BufferFormatter* f) const;
3311 3356
3312 virtual bool CanDeoptimize() const { return true; } 3357 virtual bool CanDeoptimize() const { return true; }
3313 3358
3314 virtual bool HasSideEffect() const { return true; } 3359 virtual EffectSet Effects() const { return EffectSet::None(); }
3315 3360
3316 private: 3361 private:
3317 const intptr_t token_pos_; 3362 const intptr_t token_pos_;
3318 Value* value_; 3363 Value* value_;
3319 Value* instantiator_; 3364 Value* instantiator_;
3320 Value* type_arguments_; 3365 Value* type_arguments_;
3321 const AbstractType& type_; 3366 const AbstractType& type_;
3322 const bool negate_result_; 3367 const bool negate_result_;
3323 3368
3324 DISALLOW_COPY_AND_ASSIGN(InstanceOfInstr); 3369 DISALLOW_COPY_AND_ASSIGN(InstanceOfInstr);
(...skipping 19 matching lines...) Expand all
3344 return (*arguments_)[index]; 3389 return (*arguments_)[index];
3345 } 3390 }
3346 3391
3347 const Function& constructor() const { return ast_node_.constructor(); } 3392 const Function& constructor() const { return ast_node_.constructor(); }
3348 intptr_t token_pos() const { return ast_node_.token_pos(); } 3393 intptr_t token_pos() const { return ast_node_.token_pos(); }
3349 3394
3350 virtual void PrintOperandsTo(BufferFormatter* f) const; 3395 virtual void PrintOperandsTo(BufferFormatter* f) const;
3351 3396
3352 virtual bool CanDeoptimize() const { return false; } 3397 virtual bool CanDeoptimize() const { return false; }
3353 3398
3354 virtual bool HasSideEffect() const { return true; } 3399 virtual EffectSet Effects() const { return EffectSet::None(); }
3355 3400
3356 private: 3401 private:
3357 const ConstructorCallNode& ast_node_; 3402 const ConstructorCallNode& ast_node_;
3358 ZoneGrowableArray<PushArgumentInstr*>* const arguments_; 3403 ZoneGrowableArray<PushArgumentInstr*>* const arguments_;
3359 const intptr_t cid_; 3404 const intptr_t cid_;
3360 3405
3361 DISALLOW_COPY_AND_ASSIGN(AllocateObjectInstr); 3406 DISALLOW_COPY_AND_ASSIGN(AllocateObjectInstr);
3362 }; 3407 };
3363 3408
3364 3409
3365 class AllocateObjectWithBoundsCheckInstr : public TemplateDefinition<2> { 3410 class AllocateObjectWithBoundsCheckInstr : public TemplateDefinition<2> {
3366 public: 3411 public:
3367 AllocateObjectWithBoundsCheckInstr(ConstructorCallNode* node, 3412 AllocateObjectWithBoundsCheckInstr(ConstructorCallNode* node,
3368 Value* type_arguments, 3413 Value* type_arguments,
3369 Value* instantiator) 3414 Value* instantiator)
3370 : ast_node_(*node) { 3415 : ast_node_(*node) {
3371 SetInputAt(0, type_arguments); 3416 SetInputAt(0, type_arguments);
3372 SetInputAt(1, instantiator); 3417 SetInputAt(1, instantiator);
3373 } 3418 }
3374 3419
3375 DECLARE_INSTRUCTION(AllocateObjectWithBoundsCheck) 3420 DECLARE_INSTRUCTION(AllocateObjectWithBoundsCheck)
3376 3421
3377 const Function& constructor() const { return ast_node_.constructor(); } 3422 const Function& constructor() const { return ast_node_.constructor(); }
3378 intptr_t token_pos() const { return ast_node_.token_pos(); } 3423 intptr_t token_pos() const { return ast_node_.token_pos(); }
3379 3424
3380 virtual void PrintOperandsTo(BufferFormatter* f) const; 3425 virtual void PrintOperandsTo(BufferFormatter* f) const;
3381 3426
3382 virtual bool CanDeoptimize() const { return true; } 3427 virtual bool CanDeoptimize() const { return true; }
3383 3428
3384 virtual bool HasSideEffect() const { return true; } 3429 virtual EffectSet Effects() const { return EffectSet::None(); }
3385 3430
3386 private: 3431 private:
3387 const ConstructorCallNode& ast_node_; 3432 const ConstructorCallNode& ast_node_;
3388 3433
3389 DISALLOW_COPY_AND_ASSIGN(AllocateObjectWithBoundsCheckInstr); 3434 DISALLOW_COPY_AND_ASSIGN(AllocateObjectWithBoundsCheckInstr);
3390 }; 3435 };
3391 3436
3392 3437
3393 class CreateArrayInstr : public TemplateDefinition<1> { 3438 class CreateArrayInstr : public TemplateDefinition<1> {
3394 public: 3439 public:
(...skipping 16 matching lines...) Expand all
3411 intptr_t num_elements() const { return num_elements_; } 3456 intptr_t num_elements() const { return num_elements_; }
3412 3457
3413 intptr_t token_pos() const { return token_pos_; } 3458 intptr_t token_pos() const { return token_pos_; }
3414 const AbstractType& type() const { return type_; } 3459 const AbstractType& type() const { return type_; }
3415 Value* element_type() const { return inputs_[0]; } 3460 Value* element_type() const { return inputs_[0]; }
3416 3461
3417 virtual void PrintOperandsTo(BufferFormatter* f) const; 3462 virtual void PrintOperandsTo(BufferFormatter* f) const;
3418 3463
3419 virtual bool CanDeoptimize() const { return false; } 3464 virtual bool CanDeoptimize() const { return false; }
3420 3465
3421 virtual bool HasSideEffect() const { return true; } 3466 virtual EffectSet Effects() const { return EffectSet::None(); }
3422 3467
3423 private: 3468 private:
3424 const intptr_t token_pos_; 3469 const intptr_t token_pos_;
3425 const intptr_t num_elements_; 3470 const intptr_t num_elements_;
3426 const AbstractType& type_; 3471 const AbstractType& type_;
3427 3472
3428 DISALLOW_COPY_AND_ASSIGN(CreateArrayInstr); 3473 DISALLOW_COPY_AND_ASSIGN(CreateArrayInstr);
3429 }; 3474 };
3430 3475
3431 3476
(...skipping 14 matching lines...) Expand all
3446 3491
3447 virtual intptr_t ArgumentCount() const { return arguments_->length(); } 3492 virtual intptr_t ArgumentCount() const { return arguments_->length(); }
3448 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const { 3493 virtual PushArgumentInstr* PushArgumentAt(intptr_t index) const {
3449 return (*arguments_)[index]; 3494 return (*arguments_)[index];
3450 } 3495 }
3451 3496
3452 virtual void PrintOperandsTo(BufferFormatter* f) const; 3497 virtual void PrintOperandsTo(BufferFormatter* f) const;
3453 3498
3454 virtual bool CanDeoptimize() const { return false; } 3499 virtual bool CanDeoptimize() const { return false; }
3455 3500
3456 virtual bool HasSideEffect() const { return true; } 3501 virtual EffectSet Effects() const { return EffectSet::None(); }
3457 3502
3458 private: 3503 private:
3459 const Function& function_; 3504 const Function& function_;
3460 ZoneGrowableArray<PushArgumentInstr*>* arguments_; 3505 ZoneGrowableArray<PushArgumentInstr*>* arguments_;
3461 intptr_t token_pos_; 3506 intptr_t token_pos_;
3462 3507
3463 DISALLOW_COPY_AND_ASSIGN(CreateClosureInstr); 3508 DISALLOW_COPY_AND_ASSIGN(CreateClosureInstr);
3464 }; 3509 };
3465 3510
3466 3511
3467 class LoadUntaggedInstr : public TemplateDefinition<1> { 3512 class LoadUntaggedInstr : public TemplateDefinition<1> {
3468 public: 3513 public:
3469 explicit LoadUntaggedInstr(Value* object, intptr_t offset) : offset_(offset) { 3514 explicit LoadUntaggedInstr(Value* object, intptr_t offset) : offset_(offset) {
3470 SetInputAt(0, object); 3515 SetInputAt(0, object);
3471 } 3516 }
3472 3517
3473 virtual Representation representation() const { 3518 virtual Representation representation() const {
3474 return kUntagged; 3519 return kUntagged;
3475 } 3520 }
3476 DECLARE_INSTRUCTION(LoadUntagged) 3521 DECLARE_INSTRUCTION(LoadUntagged)
3477 virtual CompileType ComputeType() const; 3522 virtual CompileType ComputeType() const;
3478 3523
3479 Value* object() const { return inputs_[0]; } 3524 Value* object() const { return inputs_[0]; }
3480 intptr_t offset() const { return offset_; } 3525 intptr_t offset() const { return offset_; }
3481 3526
3482 virtual bool CanDeoptimize() const { return false; } 3527 virtual bool CanDeoptimize() const { return false; }
3483 3528
3484 virtual bool HasSideEffect() const { return false; }
3485
3486 virtual bool AttributesEqual(Instruction* other) const { return true; }
3487
3488 // This instruction must not be moved without the indexed access that 3529 // This instruction must not be moved without the indexed access that
3489 // depends on it (e.g. out of loops). GC may cause collect 3530 // depends on it (e.g. out of loops). GC may cause collect
3490 // the array while the external data-array is still accessed. 3531 // the array while the external data-array is still accessed.
3491 virtual bool AffectedBySideEffect() const { return true; } 3532 virtual bool AllowsCSE() const { return false; }
3533 virtual EffectSet Effects() const { return EffectSet::None(); }
3534 virtual EffectSet Dependencies() const { return EffectSet::None(); }
3535 virtual bool AttributesEqual(Instruction* other) const { return true; }
3492 3536
3493 private: 3537 private:
3494 intptr_t offset_; 3538 intptr_t offset_;
3495 3539
3496 DISALLOW_COPY_AND_ASSIGN(LoadUntaggedInstr); 3540 DISALLOW_COPY_AND_ASSIGN(LoadUntaggedInstr);
3497 }; 3541 };
3498 3542
3499 3543
3500 class LoadFieldInstr : public TemplateDefinition<1> { 3544 class LoadFieldInstr : public TemplateDefinition<1> {
3501 public: 3545 public:
3502 LoadFieldInstr(Value* value, 3546 LoadFieldInstr(Value* value,
3503 intptr_t offset_in_bytes, 3547 intptr_t offset_in_bytes,
3504 const AbstractType& type, 3548 const AbstractType& type,
3505 bool immutable = false) 3549 bool immutable = false)
3506 : offset_in_bytes_(offset_in_bytes), 3550 : offset_in_bytes_(offset_in_bytes),
3507 type_(type), 3551 type_(type),
3508 result_cid_(kDynamicCid), 3552 result_cid_(kDynamicCid),
3509 immutable_(immutable), 3553 immutable_(immutable),
3510 recognized_kind_(MethodRecognizer::kUnknown), 3554 recognized_kind_(MethodRecognizer::kUnknown),
3511 field_name_(NULL), 3555 field_name_(NULL),
3512 field_(NULL) { 3556 field_(NULL) {
3513 ASSERT(type.IsZoneHandle()); // May be null if field is not an instance. 3557 ASSERT(type.IsZoneHandle()); // May be null if field is not an instance.
3514 SetInputAt(0, value); 3558 SetInputAt(0, value);
3515 } 3559 }
3516 3560
3517 DECLARE_INSTRUCTION(LoadField)
3518 virtual CompileType ComputeType() const;
3519
3520 Value* value() const { return inputs_[0]; } 3561 Value* value() const { return inputs_[0]; }
3521 intptr_t offset_in_bytes() const { return offset_in_bytes_; } 3562 intptr_t offset_in_bytes() const { return offset_in_bytes_; }
3522 const AbstractType& type() const { return type_; } 3563 const AbstractType& type() const { return type_; }
3523 void set_result_cid(intptr_t value) { result_cid_ = value; } 3564 void set_result_cid(intptr_t value) { result_cid_ = value; }
3524 intptr_t result_cid() const { return result_cid_; } 3565 intptr_t result_cid() const { return result_cid_; }
3525 3566
3526 virtual void PrintOperandsTo(BufferFormatter* f) const; 3567 void set_field_name(const char* name) { field_name_ = name; }
3568 const char* field_name() const { return field_name_; }
3527 3569
3528 virtual bool CanDeoptimize() const { return false; } 3570 Field* field() const { return field_; }
3529 3571 void set_field(Field* field) { field_ = field; }
3530 virtual bool HasSideEffect() const { return false; }
3531
3532 virtual bool AttributesEqual(Instruction* other) const;
3533
3534 virtual bool AffectedBySideEffect() const { return !immutable_; }
3535
3536 virtual void InferRange();
3537 3572
3538 void set_recognized_kind(MethodRecognizer::Kind kind) { 3573 void set_recognized_kind(MethodRecognizer::Kind kind) {
3539 recognized_kind_ = kind; 3574 recognized_kind_ = kind;
3540 } 3575 }
3541 3576
3542 MethodRecognizer::Kind recognized_kind() const { 3577 MethodRecognizer::Kind recognized_kind() const {
3543 return recognized_kind_; 3578 return recognized_kind_;
3544 } 3579 }
3545 3580
3581 DECLARE_INSTRUCTION(LoadField)
3582 virtual CompileType ComputeType() const;
3583
3584 virtual void PrintOperandsTo(BufferFormatter* f) const;
3585
3586 virtual bool CanDeoptimize() const { return false; }
3587
3588 virtual void InferRange();
3589
3546 bool IsImmutableLengthLoad() const; 3590 bool IsImmutableLengthLoad() const;
3547 3591
3548 virtual Definition* Canonicalize(FlowGraphOptimizer* optimizer); 3592 virtual Definition* Canonicalize(FlowGraphOptimizer* optimizer);
3549 3593
3550 static MethodRecognizer::Kind RecognizedKindFromArrayCid(intptr_t cid); 3594 static MethodRecognizer::Kind RecognizedKindFromArrayCid(intptr_t cid);
3551 3595
3552 static bool IsFixedLengthArrayCid(intptr_t cid); 3596 static bool IsFixedLengthArrayCid(intptr_t cid);
3553 3597
3554 void set_field_name(const char* name) { field_name_ = name; } 3598 virtual bool AllowsCSE() const { return immutable_; }
3555 const char* field_name() const { return field_name_; } 3599 virtual EffectSet Effects() const { return EffectSet::None(); }
3556 3600 virtual EffectSet Dependencies() const;
3557 Field* field() const { return field_; } 3601 virtual bool AttributesEqual(Instruction* other) const;
3558 void set_field(Field* field) { field_ = field; }
3559 3602
3560 private: 3603 private:
3561 const intptr_t offset_in_bytes_; 3604 const intptr_t offset_in_bytes_;
3562 const AbstractType& type_; 3605 const AbstractType& type_;
3563 intptr_t result_cid_; 3606 intptr_t result_cid_;
3564 const bool immutable_; 3607 const bool immutable_;
3565 3608
3566 MethodRecognizer::Kind recognized_kind_; 3609 MethodRecognizer::Kind recognized_kind_;
3567 3610
3568 const char* field_name_; 3611 const char* field_name_;
(...skipping 20 matching lines...) Expand all
3589 3632
3590 Value* value() const { return inputs_[0]; } 3633 Value* value() const { return inputs_[0]; }
3591 Value* dest() const { return inputs_[1]; } 3634 Value* dest() const { return inputs_[1]; }
3592 intptr_t offset_in_bytes() const { return offset_in_bytes_; } 3635 intptr_t offset_in_bytes() const { return offset_in_bytes_; }
3593 const AbstractType& type() const { return type_; } 3636 const AbstractType& type() const { return type_; }
3594 3637
3595 virtual void PrintOperandsTo(BufferFormatter* f) const; 3638 virtual void PrintOperandsTo(BufferFormatter* f) const;
3596 3639
3597 virtual bool CanDeoptimize() const { return false; } 3640 virtual bool CanDeoptimize() const { return false; }
3598 3641
3599 virtual bool HasSideEffect() const { return true; } 3642 virtual EffectSet Effects() const { return EffectSet::None(); }
3600 3643
3601 private: 3644 private:
3602 const intptr_t offset_in_bytes_; 3645 const intptr_t offset_in_bytes_;
3603 const AbstractType& type_; 3646 const AbstractType& type_;
3604 3647
3605 DISALLOW_COPY_AND_ASSIGN(StoreVMFieldInstr); 3648 DISALLOW_COPY_AND_ASSIGN(StoreVMFieldInstr);
3606 }; 3649 };
3607 3650
3608 3651
3609 class InstantiateTypeArgumentsInstr : public TemplateDefinition<1> { 3652 class InstantiateTypeArgumentsInstr : public TemplateDefinition<1> {
(...skipping 12 matching lines...) Expand all
3622 Value* instantiator() const { return inputs_[0]; } 3665 Value* instantiator() const { return inputs_[0]; }
3623 const AbstractTypeArguments& type_arguments() const { 3666 const AbstractTypeArguments& type_arguments() const {
3624 return type_arguments_; 3667 return type_arguments_;
3625 } 3668 }
3626 intptr_t token_pos() const { return token_pos_; } 3669 intptr_t token_pos() const { return token_pos_; }
3627 3670
3628 virtual void PrintOperandsTo(BufferFormatter* f) const; 3671 virtual void PrintOperandsTo(BufferFormatter* f) const;
3629 3672
3630 virtual bool CanDeoptimize() const { return true; } 3673 virtual bool CanDeoptimize() const { return true; }
3631 3674
3632 virtual bool HasSideEffect() const { return true; } 3675 virtual EffectSet Effects() const { return EffectSet::All(); }
Florian Schneider 2013/04/29 12:11:54 It seems this could be ::None() as well.
Vyacheslav Egorov (Google) 2013/04/30 14:01:33 Done.
3633 3676
3634 private: 3677 private:
3635 const intptr_t token_pos_; 3678 const intptr_t token_pos_;
3636 const AbstractTypeArguments& type_arguments_; 3679 const AbstractTypeArguments& type_arguments_;
3637 3680
3638 DISALLOW_COPY_AND_ASSIGN(InstantiateTypeArgumentsInstr); 3681 DISALLOW_COPY_AND_ASSIGN(InstantiateTypeArgumentsInstr);
3639 }; 3682 };
3640 3683
3641 3684
3642 class ExtractConstructorTypeArgumentsInstr : public TemplateDefinition<1> { 3685 class ExtractConstructorTypeArgumentsInstr : public TemplateDefinition<1> {
(...skipping 12 matching lines...) Expand all
3655 Value* instantiator() const { return inputs_[0]; } 3698 Value* instantiator() const { return inputs_[0]; }
3656 const AbstractTypeArguments& type_arguments() const { 3699 const AbstractTypeArguments& type_arguments() const {
3657 return type_arguments_; 3700 return type_arguments_;
3658 } 3701 }
3659 intptr_t token_pos() const { return token_pos_; } 3702 intptr_t token_pos() const { return token_pos_; }
3660 3703
3661 virtual void PrintOperandsTo(BufferFormatter* f) const; 3704 virtual void PrintOperandsTo(BufferFormatter* f) const;
3662 3705
3663 virtual bool CanDeoptimize() const { return false; } 3706 virtual bool CanDeoptimize() const { return false; }
3664 3707
3665 virtual bool HasSideEffect() const { return false; } 3708 virtual EffectSet Effects() const { return EffectSet::None(); }
3666 3709
3667 private: 3710 private:
3668 const intptr_t token_pos_; 3711 const intptr_t token_pos_;
3669 const AbstractTypeArguments& type_arguments_; 3712 const AbstractTypeArguments& type_arguments_;
3670 3713
3671 DISALLOW_COPY_AND_ASSIGN(ExtractConstructorTypeArgumentsInstr); 3714 DISALLOW_COPY_AND_ASSIGN(ExtractConstructorTypeArgumentsInstr);
3672 }; 3715 };
3673 3716
3674 3717
3675 class ExtractConstructorInstantiatorInstr : public TemplateDefinition<1> { 3718 class ExtractConstructorInstantiatorInstr : public TemplateDefinition<1> {
3676 public: 3719 public:
3677 ExtractConstructorInstantiatorInstr(ConstructorCallNode* ast_node, 3720 ExtractConstructorInstantiatorInstr(ConstructorCallNode* ast_node,
3678 Value* instantiator) 3721 Value* instantiator)
3679 : ast_node_(*ast_node) { 3722 : ast_node_(*ast_node) {
3680 SetInputAt(0, instantiator); 3723 SetInputAt(0, instantiator);
3681 } 3724 }
3682 3725
3683 DECLARE_INSTRUCTION(ExtractConstructorInstantiator) 3726 DECLARE_INSTRUCTION(ExtractConstructorInstantiator)
3684 3727
3685 Value* instantiator() const { return inputs_[0]; } 3728 Value* instantiator() const { return inputs_[0]; }
3686 const AbstractTypeArguments& type_arguments() const { 3729 const AbstractTypeArguments& type_arguments() const {
3687 return ast_node_.type_arguments(); 3730 return ast_node_.type_arguments();
3688 } 3731 }
3689 const Function& constructor() const { return ast_node_.constructor(); } 3732 const Function& constructor() const { return ast_node_.constructor(); }
3690 intptr_t token_pos() const { return ast_node_.token_pos(); } 3733 intptr_t token_pos() const { return ast_node_.token_pos(); }
3691 3734
3692 virtual bool CanDeoptimize() const { return false; } 3735 virtual bool CanDeoptimize() const { return false; }
3693 3736
3694 virtual bool HasSideEffect() const { return false; } 3737 virtual EffectSet Effects() const { return EffectSet::None(); }
3695 3738
3696 private: 3739 private:
3697 const ConstructorCallNode& ast_node_; 3740 const ConstructorCallNode& ast_node_;
3698 3741
3699 DISALLOW_COPY_AND_ASSIGN(ExtractConstructorInstantiatorInstr); 3742 DISALLOW_COPY_AND_ASSIGN(ExtractConstructorInstantiatorInstr);
3700 }; 3743 };
3701 3744
3702 3745
3703 class AllocateContextInstr : public TemplateDefinition<0> { 3746 class AllocateContextInstr : public TemplateDefinition<0> {
3704 public: 3747 public:
3705 AllocateContextInstr(intptr_t token_pos, 3748 AllocateContextInstr(intptr_t token_pos,
3706 intptr_t num_context_variables) 3749 intptr_t num_context_variables)
3707 : token_pos_(token_pos), 3750 : token_pos_(token_pos),
3708 num_context_variables_(num_context_variables) {} 3751 num_context_variables_(num_context_variables) {}
3709 3752
3710 DECLARE_INSTRUCTION(AllocateContext); 3753 DECLARE_INSTRUCTION(AllocateContext);
3711 virtual CompileType ComputeType() const; 3754 virtual CompileType ComputeType() const;
3712 3755
3713 intptr_t token_pos() const { return token_pos_; } 3756 intptr_t token_pos() const { return token_pos_; }
3714 intptr_t num_context_variables() const { return num_context_variables_; } 3757 intptr_t num_context_variables() const { return num_context_variables_; }
3715 3758
3716 virtual void PrintOperandsTo(BufferFormatter* f) const; 3759 virtual void PrintOperandsTo(BufferFormatter* f) const;
3717 3760
3718 virtual bool CanDeoptimize() const { return false; } 3761 virtual bool CanDeoptimize() const { return false; }
3719 3762
3720 virtual bool HasSideEffect() const { return false; } 3763 virtual EffectSet Effects() const { return EffectSet::None(); }
3721 3764
3722 private: 3765 private:
3723 const intptr_t token_pos_; 3766 const intptr_t token_pos_;
3724 const intptr_t num_context_variables_; 3767 const intptr_t num_context_variables_;
3725 3768
3726 DISALLOW_COPY_AND_ASSIGN(AllocateContextInstr); 3769 DISALLOW_COPY_AND_ASSIGN(AllocateContextInstr);
3727 }; 3770 };
3728 3771
3729 3772
3730 class ChainContextInstr : public TemplateInstruction<1> { 3773 class ChainContextInstr : public TemplateInstruction<1> {
3731 public: 3774 public:
3732 explicit ChainContextInstr(Value* context_value) { 3775 explicit ChainContextInstr(Value* context_value) {
3733 SetInputAt(0, context_value); 3776 SetInputAt(0, context_value);
3734 } 3777 }
3735 3778
3736 DECLARE_INSTRUCTION(ChainContext) 3779 DECLARE_INSTRUCTION(ChainContext)
3737 3780
3738 virtual intptr_t ArgumentCount() const { return 0; } 3781 virtual intptr_t ArgumentCount() const { return 0; }
3739 3782
3740 Value* context_value() const { return inputs_[0]; } 3783 Value* context_value() const { return inputs_[0]; }
3741 3784
3742 virtual bool CanDeoptimize() const { return false; } 3785 virtual bool CanDeoptimize() const { return false; }
3743 3786
3744 virtual bool HasSideEffect() const { return true; } 3787 virtual EffectSet Effects() const { return EffectSet::None(); }
3745 3788
3746 private: 3789 private:
3747 DISALLOW_COPY_AND_ASSIGN(ChainContextInstr); 3790 DISALLOW_COPY_AND_ASSIGN(ChainContextInstr);
3748 }; 3791 };
3749 3792
3750 3793
3751 class CloneContextInstr : public TemplateDefinition<1> { 3794 class CloneContextInstr : public TemplateDefinition<1> {
3752 public: 3795 public:
3753 CloneContextInstr(intptr_t token_pos, Value* context_value) 3796 CloneContextInstr(intptr_t token_pos, Value* context_value)
3754 : token_pos_(token_pos) { 3797 : token_pos_(token_pos) {
3755 SetInputAt(0, context_value); 3798 SetInputAt(0, context_value);
3756 } 3799 }
3757 3800
3758 intptr_t token_pos() const { return token_pos_; } 3801 intptr_t token_pos() const { return token_pos_; }
3759 Value* context_value() const { return inputs_[0]; } 3802 Value* context_value() const { return inputs_[0]; }
3760 3803
3761 DECLARE_INSTRUCTION(CloneContext) 3804 DECLARE_INSTRUCTION(CloneContext)
3762 virtual CompileType ComputeType() const; 3805 virtual CompileType ComputeType() const;
3763 3806
3764 virtual bool CanDeoptimize() const { return true; } 3807 virtual bool CanDeoptimize() const { return true; }
3765 3808
3766 virtual bool HasSideEffect() const { return false; } 3809 virtual EffectSet Effects() const { return EffectSet::None(); }
3767 3810
3768 private: 3811 private:
3769 const intptr_t token_pos_; 3812 const intptr_t token_pos_;
3770 3813
3771 DISALLOW_COPY_AND_ASSIGN(CloneContextInstr); 3814 DISALLOW_COPY_AND_ASSIGN(CloneContextInstr);
3772 }; 3815 };
3773 3816
3774 3817
3775 class CatchEntryInstr : public TemplateInstruction<0> { 3818 class CatchEntryInstr : public TemplateInstruction<0> {
3776 public: 3819 public:
3777 CatchEntryInstr(const LocalVariable& exception_var, 3820 CatchEntryInstr(const LocalVariable& exception_var,
3778 const LocalVariable& stacktrace_var) 3821 const LocalVariable& stacktrace_var)
3779 : exception_var_(exception_var), stacktrace_var_(stacktrace_var) {} 3822 : exception_var_(exception_var), stacktrace_var_(stacktrace_var) {}
3780 3823
3781 const LocalVariable& exception_var() const { return exception_var_; } 3824 const LocalVariable& exception_var() const { return exception_var_; }
3782 const LocalVariable& stacktrace_var() const { return stacktrace_var_; } 3825 const LocalVariable& stacktrace_var() const { return stacktrace_var_; }
3783 3826
3784 DECLARE_INSTRUCTION(CatchEntry) 3827 DECLARE_INSTRUCTION(CatchEntry)
3785 3828
3786 virtual intptr_t ArgumentCount() const { return 0; } 3829 virtual intptr_t ArgumentCount() const { return 0; }
3787 3830
3788 virtual void PrintOperandsTo(BufferFormatter* f) const; 3831 virtual void PrintOperandsTo(BufferFormatter* f) const;
3789 3832
3790 virtual bool CanDeoptimize() const { return false; } 3833 virtual bool CanDeoptimize() const { return false; }
3791 3834
3792 virtual bool HasSideEffect() const { return true; } 3835 virtual EffectSet Effects() const { return EffectSet::All(); }
3793 3836
3794 private: 3837 private:
3795 const LocalVariable& exception_var_; 3838 const LocalVariable& exception_var_;
3796 const LocalVariable& stacktrace_var_; 3839 const LocalVariable& stacktrace_var_;
3797 3840
3798 DISALLOW_COPY_AND_ASSIGN(CatchEntryInstr); 3841 DISALLOW_COPY_AND_ASSIGN(CatchEntryInstr);
3799 }; 3842 };
3800 3843
3801 3844
3802 class CheckEitherNonSmiInstr : public TemplateInstruction<2> { 3845 class CheckEitherNonSmiInstr : public TemplateInstruction<2> {
3803 public: 3846 public:
3804 CheckEitherNonSmiInstr(Value* left, 3847 CheckEitherNonSmiInstr(Value* left,
3805 Value* right, 3848 Value* right,
3806 InstanceCallInstr* instance_call) { 3849 InstanceCallInstr* instance_call) {
3807 SetInputAt(0, left); 3850 SetInputAt(0, left);
3808 SetInputAt(1, right); 3851 SetInputAt(1, right);
3809 deopt_id_ = instance_call->deopt_id(); 3852 deopt_id_ = instance_call->deopt_id();
3810 } 3853 }
3811 3854
3855 Value* left() const { return inputs_[0]; }
3856 Value* right() const { return inputs_[1]; }
3857
3812 DECLARE_INSTRUCTION(CheckEitherNonSmi) 3858 DECLARE_INSTRUCTION(CheckEitherNonSmi)
3813 3859
3814 virtual intptr_t ArgumentCount() const { return 0; } 3860 virtual intptr_t ArgumentCount() const { return 0; }
3815 3861
3816 virtual bool CanDeoptimize() const { return true; } 3862 virtual bool CanDeoptimize() const { return true; }
3817 3863
3818 virtual bool HasSideEffect() const { return false; } 3864 virtual Instruction* Canonicalize(FlowGraphOptimizer* optimizer);
3819 3865
3866 virtual bool AllowsCSE() const { return true; }
3867 virtual EffectSet Effects() const { return EffectSet::None(); }
3868 virtual EffectSet Dependencies() const { return EffectSet::None(); }
3820 virtual bool AttributesEqual(Instruction* other) const { return true; } 3869 virtual bool AttributesEqual(Instruction* other) const { return true; }
3821 3870
3822 virtual bool AffectedBySideEffect() const { return false; }
3823
3824 Value* left() const { return inputs_[0]; }
3825
3826 Value* right() const { return inputs_[1]; }
3827
3828 virtual Instruction* Canonicalize(FlowGraphOptimizer* optimizer);
3829
3830 private: 3871 private:
3831 DISALLOW_COPY_AND_ASSIGN(CheckEitherNonSmiInstr); 3872 DISALLOW_COPY_AND_ASSIGN(CheckEitherNonSmiInstr);
3832 }; 3873 };
3833 3874
3834 3875
3835 class BoxDoubleInstr : public TemplateDefinition<1> { 3876 class BoxDoubleInstr : public TemplateDefinition<1> {
3836 public: 3877 public:
3837 explicit BoxDoubleInstr(Value* value) { 3878 explicit BoxDoubleInstr(Value* value) {
3838 SetInputAt(0, value); 3879 SetInputAt(0, value);
3839 } 3880 }
3840 3881
3841 Value* value() const { return inputs_[0]; } 3882 Value* value() const { return inputs_[0]; }
3842 3883
3884 DECLARE_INSTRUCTION(BoxDouble)
3885 virtual CompileType ComputeType() const;
3886
3843 virtual bool CanDeoptimize() const { return false; } 3887 virtual bool CanDeoptimize() const { return false; }
3844 3888
3845 virtual bool HasSideEffect() const { return false; }
3846
3847 virtual bool AffectedBySideEffect() const { return false; }
3848 virtual bool AttributesEqual(Instruction* other) const { return true; }
3849
3850 virtual Representation RequiredInputRepresentation(intptr_t idx) const { 3889 virtual Representation RequiredInputRepresentation(intptr_t idx) const {
3851 ASSERT(idx == 0); 3890 ASSERT(idx == 0);
3852 return kUnboxedDouble; 3891 return kUnboxedDouble;
3853 } 3892 }
3854 3893
3855 DECLARE_INSTRUCTION(BoxDouble) 3894 virtual bool AllowsCSE() const { return true; }
3856 virtual CompileType ComputeType() const; 3895 virtual EffectSet Effects() const { return EffectSet::None(); }
3896 virtual EffectSet Dependencies() const { return EffectSet::None(); }
3897 virtual bool AttributesEqual(Instruction* other) const { return true; }
3857 3898
3858 private: 3899 private:
3859 DISALLOW_COPY_AND_ASSIGN(BoxDoubleInstr); 3900 DISALLOW_COPY_AND_ASSIGN(BoxDoubleInstr);
3860 }; 3901 };
3861 3902
3862 3903
3863 class BoxFloat32x4Instr : public TemplateDefinition<1> { 3904 class BoxFloat32x4Instr : public TemplateDefinition<1> {
3864 public: 3905 public:
3865 explicit BoxFloat32x4Instr(Value* value) { 3906 explicit BoxFloat32x4Instr(Value* value) {
3866 SetInputAt(0, value); 3907 SetInputAt(0, value);
3867 } 3908 }
3868 3909
3869 Value* value() const { return inputs_[0]; } 3910 Value* value() const { return inputs_[0]; }
3870 3911
3871 virtual bool CanDeoptimize() const { return false; } 3912 virtual bool CanDeoptimize() const { return false; }
3872 3913
3873 virtual bool HasSideEffect() const { return false; }
3874
3875 virtual bool AffectedBySideEffect() const { return false; }
3876 virtual bool AttributesEqual(Instruction* other) const { return true; }
3877
3878 virtual Representation RequiredInputRepresentation(intptr_t idx) const { 3914 virtual Representation RequiredInputRepresentation(intptr_t idx) const {
3879 ASSERT(idx == 0); 3915 ASSERT(idx == 0);
3880 return kUnboxedFloat32x4; 3916 return kUnboxedFloat32x4;
3881 } 3917 }
3882 3918
3883 DECLARE_INSTRUCTION(BoxFloat32x4) 3919 DECLARE_INSTRUCTION(BoxFloat32x4)
3884 virtual CompileType ComputeType() const; 3920 virtual CompileType ComputeType() const;
3885 3921
3922 virtual bool AllowsCSE() const { return true; }
3923 virtual EffectSet Effects() const { return EffectSet::None(); }
3924 virtual EffectSet Dependencies() const { return EffectSet::None(); }
3925 virtual bool AttributesEqual(Instruction* other) const { return true; }
3926
3886 private: 3927 private:
3887 DISALLOW_COPY_AND_ASSIGN(BoxFloat32x4Instr); 3928 DISALLOW_COPY_AND_ASSIGN(BoxFloat32x4Instr);
3888 }; 3929 };
3889 3930
3890 3931
3891 class BoxIntegerInstr : public TemplateDefinition<1> { 3932 class BoxIntegerInstr : public TemplateDefinition<1> {
3892 public: 3933 public:
3893 explicit BoxIntegerInstr(Value* value) { 3934 explicit BoxIntegerInstr(Value* value) {
3894 SetInputAt(0, value); 3935 SetInputAt(0, value);
3895 } 3936 }
3896 3937
3897 Value* value() const { return inputs_[0]; } 3938 Value* value() const { return inputs_[0]; }
3898 3939
3899 virtual bool CanDeoptimize() const { return false; } 3940 virtual bool CanDeoptimize() const { return false; }
3900 3941
3901 virtual bool HasSideEffect() const { return false; }
3902
3903 virtual bool AffectedBySideEffect() const { return false; }
3904 virtual bool AttributesEqual(Instruction* other) const { return true; }
3905
3906 virtual Representation RequiredInputRepresentation(intptr_t idx) const { 3942 virtual Representation RequiredInputRepresentation(intptr_t idx) const {
3907 ASSERT(idx == 0); 3943 ASSERT(idx == 0);
3908 return kUnboxedMint; 3944 return kUnboxedMint;
3909 } 3945 }
3910 3946
3911 DECLARE_INSTRUCTION(BoxInteger) 3947 DECLARE_INSTRUCTION(BoxInteger)
3912 virtual CompileType ComputeType() const; 3948 virtual CompileType ComputeType() const;
3913 3949
3950 virtual bool AllowsCSE() const { return true; }
3951 virtual EffectSet Effects() const { return EffectSet::None(); }
3952 virtual EffectSet Dependencies() const { return EffectSet::None(); }
3953 virtual bool AttributesEqual(Instruction* other) const { return true; }
3954
3914 private: 3955 private:
3915 DISALLOW_COPY_AND_ASSIGN(BoxIntegerInstr); 3956 DISALLOW_COPY_AND_ASSIGN(BoxIntegerInstr);
3916 }; 3957 };
3917 3958
3918 3959
3919 class UnboxDoubleInstr : public TemplateDefinition<1> { 3960 class UnboxDoubleInstr : public TemplateDefinition<1> {
3920 public: 3961 public:
3921 UnboxDoubleInstr(Value* value, intptr_t deopt_id) { 3962 UnboxDoubleInstr(Value* value, intptr_t deopt_id) {
3922 SetInputAt(0, value); 3963 SetInputAt(0, value);
3923 deopt_id_ = deopt_id; 3964 deopt_id_ = deopt_id;
3924 } 3965 }
3925 3966
3926 Value* value() const { return inputs_[0]; } 3967 Value* value() const { return inputs_[0]; }
3927 3968
3928 virtual bool CanDeoptimize() const { 3969 virtual bool CanDeoptimize() const {
3929 return (value()->Type()->ToCid() != kDoubleCid) 3970 return (value()->Type()->ToCid() != kDoubleCid)
3930 && (value()->Type()->ToCid() != kSmiCid); 3971 && (value()->Type()->ToCid() != kSmiCid);
3931 } 3972 }
3932 3973
3933 virtual bool HasSideEffect() const { return false; }
3934
3935 virtual Representation representation() const { 3974 virtual Representation representation() const {
3936 return kUnboxedDouble; 3975 return kUnboxedDouble;
3937 } 3976 }
3938 3977
3939 virtual bool AffectedBySideEffect() const { return false; }
3940 virtual bool AttributesEqual(Instruction* other) const { return true; }
3941
3942 DECLARE_INSTRUCTION(UnboxDouble) 3978 DECLARE_INSTRUCTION(UnboxDouble)
3943 virtual CompileType ComputeType() const; 3979 virtual CompileType ComputeType() const;
3944 3980
3981 virtual bool AllowsCSE() const { return true; }
3982 virtual EffectSet Effects() const { return EffectSet::None(); }
3983 virtual EffectSet Dependencies() const { return EffectSet::None(); }
3984 virtual bool AttributesEqual(Instruction* other) const { return true; }
3985
3945 private: 3986 private:
3946 DISALLOW_COPY_AND_ASSIGN(UnboxDoubleInstr); 3987 DISALLOW_COPY_AND_ASSIGN(UnboxDoubleInstr);
3947 }; 3988 };
3948 3989
3949 3990
3950 class UnboxFloat32x4Instr : public TemplateDefinition<1> { 3991 class UnboxFloat32x4Instr : public TemplateDefinition<1> {
3951 public: 3992 public:
3952 UnboxFloat32x4Instr(Value* value, intptr_t deopt_id) { 3993 UnboxFloat32x4Instr(Value* value, intptr_t deopt_id) {
3953 SetInputAt(0, value); 3994 SetInputAt(0, value);
3954 deopt_id_ = deopt_id; 3995 deopt_id_ = deopt_id;
3955 } 3996 }
3956 3997
3957 Value* value() const { return inputs_[0]; } 3998 Value* value() const { return inputs_[0]; }
3958 3999
3959 virtual bool CanDeoptimize() const { 4000 virtual bool CanDeoptimize() const {
3960 return (value()->Type()->ToCid() != kFloat32x4Cid); 4001 return (value()->Type()->ToCid() != kFloat32x4Cid);
3961 } 4002 }
3962 4003
3963 virtual bool HasSideEffect() const { return false; }
3964
3965 virtual Representation representation() const { 4004 virtual Representation representation() const {
3966 return kUnboxedFloat32x4; 4005 return kUnboxedFloat32x4;
3967 } 4006 }
3968 4007
3969 virtual bool AffectedBySideEffect() const { return false; }
3970 virtual bool AttributesEqual(Instruction* other) const { return true; }
3971
3972 DECLARE_INSTRUCTION(UnboxFloat32x4) 4008 DECLARE_INSTRUCTION(UnboxFloat32x4)
3973 virtual CompileType ComputeType() const; 4009 virtual CompileType ComputeType() const;
3974 4010
4011 virtual bool AllowsCSE() const { return true; }
4012 virtual EffectSet Effects() const { return EffectSet::None(); }
4013 virtual EffectSet Dependencies() const { return EffectSet::None(); }
4014 virtual bool AttributesEqual(Instruction* other) const { return true; }
4015
3975 private: 4016 private:
3976 DISALLOW_COPY_AND_ASSIGN(UnboxFloat32x4Instr); 4017 DISALLOW_COPY_AND_ASSIGN(UnboxFloat32x4Instr);
3977 }; 4018 };
3978 4019
3979 4020
3980 class UnboxIntegerInstr : public TemplateDefinition<1> { 4021 class UnboxIntegerInstr : public TemplateDefinition<1> {
3981 public: 4022 public:
3982 UnboxIntegerInstr(Value* value, intptr_t deopt_id) { 4023 UnboxIntegerInstr(Value* value, intptr_t deopt_id) {
3983 SetInputAt(0, value); 4024 SetInputAt(0, value);
3984 deopt_id_ = deopt_id; 4025 deopt_id_ = deopt_id;
3985 } 4026 }
3986 4027
3987 Value* value() const { return inputs_[0]; } 4028 Value* value() const { return inputs_[0]; }
3988 4029
3989 virtual bool CanDeoptimize() const { 4030 virtual bool CanDeoptimize() const {
3990 return (value()->Type()->ToCid() != kSmiCid) 4031 return (value()->Type()->ToCid() != kSmiCid)
3991 && (value()->Type()->ToCid() != kMintCid); 4032 && (value()->Type()->ToCid() != kMintCid);
3992 } 4033 }
3993 4034
3994 virtual bool HasSideEffect() const { return false; }
3995
3996 virtual CompileType ComputeType() const;
3997
3998 virtual Representation representation() const { 4035 virtual Representation representation() const {
3999 return kUnboxedMint; 4036 return kUnboxedMint;
4000 } 4037 }
4001 4038
4002 4039
4003 virtual bool AffectedBySideEffect() const { return false; } 4040 DECLARE_INSTRUCTION(UnboxInteger)
4041 virtual CompileType ComputeType() const;
4042
4043 virtual bool AllowsCSE() const { return true; }
4044 virtual EffectSet Effects() const { return EffectSet::None(); }
4045 virtual EffectSet Dependencies() const { return EffectSet::None(); }
4004 virtual bool AttributesEqual(Instruction* other) const { return true; } 4046 virtual bool AttributesEqual(Instruction* other) const { return true; }
4005 4047
4006 DECLARE_INSTRUCTION(UnboxInteger)
4007
4008 private: 4048 private:
4009 DISALLOW_COPY_AND_ASSIGN(UnboxIntegerInstr); 4049 DISALLOW_COPY_AND_ASSIGN(UnboxIntegerInstr);
4010 }; 4050 };
4011 4051
4012 4052
4013 class MathSqrtInstr : public TemplateDefinition<1> { 4053 class MathSqrtInstr : public TemplateDefinition<1> {
4014 public: 4054 public:
4015 MathSqrtInstr(Value* value, StaticCallInstr* instance_call) { 4055 MathSqrtInstr(Value* value, StaticCallInstr* instance_call) {
4016 SetInputAt(0, value); 4056 SetInputAt(0, value);
4017 deopt_id_ = instance_call->deopt_id(); 4057 deopt_id_ = instance_call->deopt_id();
4018 } 4058 }
4019 4059
4020 Value* value() const { return inputs_[0]; } 4060 Value* value() const { return inputs_[0]; }
4021 4061
4022 virtual bool CanDeoptimize() const { return false; } 4062 virtual bool CanDeoptimize() const { return false; }
4023 4063
4024 virtual bool HasSideEffect() const { return false; }
4025
4026 virtual bool AttributesEqual(Instruction* other) const {
4027 return true;
4028 }
4029
4030 virtual Representation representation() const { 4064 virtual Representation representation() const {
4031 return kUnboxedDouble; 4065 return kUnboxedDouble;
4032 } 4066 }
4033 4067
4034 virtual Representation RequiredInputRepresentation(intptr_t idx) const { 4068 virtual Representation RequiredInputRepresentation(intptr_t idx) const {
4035 ASSERT(idx == 0); 4069 ASSERT(idx == 0);
4036 return kUnboxedDouble; 4070 return kUnboxedDouble;
4037 } 4071 }
4038 4072
4039 virtual intptr_t DeoptimizationTarget() const { 4073 virtual intptr_t DeoptimizationTarget() const {
4040 // Direct access since this instruction cannot deoptimize, and the deopt-id 4074 // Direct access since this instruction cannot deoptimize, and the deopt-id
4041 // was inherited from another instruction that could deoptimize. 4075 // was inherited from another instruction that could deoptimize.
4042 return deopt_id_; 4076 return deopt_id_;
4043 } 4077 }
4044 4078
4045 DECLARE_INSTRUCTION(MathSqrt) 4079 DECLARE_INSTRUCTION(MathSqrt)
4046 virtual CompileType ComputeType() const; 4080 virtual CompileType ComputeType() const;
4047 4081
4082 virtual bool AllowsCSE() const { return true; }
4083 virtual EffectSet Effects() const { return EffectSet::None(); }
4084 virtual EffectSet Dependencies() const { return EffectSet::None(); }
4085 virtual bool AttributesEqual(Instruction* other) const { return true; }
4086
4048 private: 4087 private:
4049 DISALLOW_COPY_AND_ASSIGN(MathSqrtInstr); 4088 DISALLOW_COPY_AND_ASSIGN(MathSqrtInstr);
4050 }; 4089 };
4051 4090
4052 4091
4053 class BinaryDoubleOpInstr : public TemplateDefinition<2> { 4092 class BinaryDoubleOpInstr : public TemplateDefinition<2> {
4054 public: 4093 public:
4055 BinaryDoubleOpInstr(Token::Kind op_kind, 4094 BinaryDoubleOpInstr(Token::Kind op_kind,
4056 Value* left, 4095 Value* left,
4057 Value* right, 4096 Value* right,
4058 InstanceCallInstr* instance_call) 4097 InstanceCallInstr* instance_call)
4059 : op_kind_(op_kind) { 4098 : op_kind_(op_kind) {
4060 SetInputAt(0, left); 4099 SetInputAt(0, left);
4061 SetInputAt(1, right); 4100 SetInputAt(1, right);
4062 deopt_id_ = instance_call->deopt_id(); 4101 deopt_id_ = instance_call->deopt_id();
4063 } 4102 }
4064 4103
4065 Value* left() const { return inputs_[0]; } 4104 Value* left() const { return inputs_[0]; }
4066 Value* right() const { return inputs_[1]; } 4105 Value* right() const { return inputs_[1]; }
4067 4106
4068 Token::Kind op_kind() const { return op_kind_; } 4107 Token::Kind op_kind() const { return op_kind_; }
4069 4108
4070 virtual void PrintOperandsTo(BufferFormatter* f) const; 4109 virtual void PrintOperandsTo(BufferFormatter* f) const;
4071 4110
4072 virtual bool CanDeoptimize() const { return false; } 4111 virtual bool CanDeoptimize() const { return false; }
4073 4112
4074 virtual bool HasSideEffect() const { return false; }
4075
4076 virtual bool AffectedBySideEffect() const { return false; }
4077
4078 virtual bool AttributesEqual(Instruction* other) const {
4079 return op_kind() == other->AsBinaryDoubleOp()->op_kind();
4080 }
4081
4082 virtual Representation representation() const { 4113 virtual Representation representation() const {
4083 return kUnboxedDouble; 4114 return kUnboxedDouble;
4084 } 4115 }
4085 4116
4086 virtual Representation RequiredInputRepresentation(intptr_t idx) const { 4117 virtual Representation RequiredInputRepresentation(intptr_t idx) const {
4087 ASSERT((idx == 0) || (idx == 1)); 4118 ASSERT((idx == 0) || (idx == 1));
4088 return kUnboxedDouble; 4119 return kUnboxedDouble;
4089 } 4120 }
4090 4121
4091 virtual intptr_t DeoptimizationTarget() const { 4122 virtual intptr_t DeoptimizationTarget() const {
4092 // Direct access since this instruction cannot deoptimize, and the deopt-id 4123 // Direct access since this instruction cannot deoptimize, and the deopt-id
4093 // was inherited from another instruction that could deoptimize. 4124 // was inherited from another instruction that could deoptimize.
4094 return deopt_id_; 4125 return deopt_id_;
4095 } 4126 }
4096 4127
4097 DECLARE_INSTRUCTION(BinaryDoubleOp) 4128 DECLARE_INSTRUCTION(BinaryDoubleOp)
4098 virtual CompileType ComputeType() const; 4129 virtual CompileType ComputeType() const;
4099 4130
4100 virtual Definition* Canonicalize(FlowGraphOptimizer* optimizer); 4131 virtual Definition* Canonicalize(FlowGraphOptimizer* optimizer);
4101 4132
4133 virtual bool AllowsCSE() const { return true; }
4134 virtual EffectSet Effects() const { return EffectSet::None(); }
4135 virtual EffectSet Dependencies() const { return EffectSet::None(); }
4136 virtual bool AttributesEqual(Instruction* other) const {
4137 return op_kind() == other->AsBinaryDoubleOp()->op_kind();
4138 }
4139
4102 private: 4140 private:
4103 const Token::Kind op_kind_; 4141 const Token::Kind op_kind_;
4104 4142
4105 DISALLOW_COPY_AND_ASSIGN(BinaryDoubleOpInstr); 4143 DISALLOW_COPY_AND_ASSIGN(BinaryDoubleOpInstr);
4106 }; 4144 };
4107 4145
4108 4146
4109 class BinaryFloat32x4OpInstr : public TemplateDefinition<2> { 4147 class BinaryFloat32x4OpInstr : public TemplateDefinition<2> {
4110 public: 4148 public:
4111 BinaryFloat32x4OpInstr(Token::Kind op_kind, 4149 BinaryFloat32x4OpInstr(Token::Kind op_kind,
4112 Value* left, 4150 Value* left,
4113 Value* right, 4151 Value* right,
4114 InstanceCallInstr* instance_call) 4152 InstanceCallInstr* instance_call)
4115 : op_kind_(op_kind) { 4153 : op_kind_(op_kind) {
4116 SetInputAt(0, left); 4154 SetInputAt(0, left);
4117 SetInputAt(1, right); 4155 SetInputAt(1, right);
4118 deopt_id_ = instance_call->deopt_id(); 4156 deopt_id_ = instance_call->deopt_id();
4119 } 4157 }
4120 4158
4121 Value* left() const { return inputs_[0]; } 4159 Value* left() const { return inputs_[0]; }
4122 Value* right() const { return inputs_[1]; } 4160 Value* right() const { return inputs_[1]; }
4123 4161
4124 Token::Kind op_kind() const { return op_kind_; } 4162 Token::Kind op_kind() const { return op_kind_; }
4125 4163
4126 virtual void PrintOperandsTo(BufferFormatter* f) const; 4164 virtual void PrintOperandsTo(BufferFormatter* f) const;
4127 4165
4128 virtual bool CanDeoptimize() const { return false; } 4166 virtual bool CanDeoptimize() const { return false; }
4129 4167
4130 virtual bool HasSideEffect() const { return false; }
4131
4132 virtual bool AffectedBySideEffect() const { return false; }
4133
4134 virtual bool AttributesEqual(Instruction* other) const {
4135 return op_kind() == other->AsBinaryFloat32x4Op()->op_kind();
4136 }
4137
4138 virtual Representation representation() const { 4168 virtual Representation representation() const {
4139 return kUnboxedFloat32x4; 4169 return kUnboxedFloat32x4;
4140 } 4170 }
4141 4171
4142 virtual Representation RequiredInputRepresentation(intptr_t idx) const { 4172 virtual Representation RequiredInputRepresentation(intptr_t idx) const {
4143 ASSERT((idx == 0) || (idx == 1)); 4173 ASSERT((idx == 0) || (idx == 1));
4144 return kUnboxedFloat32x4; 4174 return kUnboxedFloat32x4;
4145 } 4175 }
4146 4176
4147 virtual intptr_t DeoptimizationTarget() const { 4177 virtual intptr_t DeoptimizationTarget() const {
4148 // Direct access since this instruction cannot deoptimize, and the deopt-id 4178 // Direct access since this instruction cannot deoptimize, and the deopt-id
4149 // was inherited from another instruction that could deoptimize. 4179 // was inherited from another instruction that could deoptimize.
4150 return deopt_id_; 4180 return deopt_id_;
4151 } 4181 }
4152 4182
4153 DECLARE_INSTRUCTION(BinaryFloat32x4Op) 4183 DECLARE_INSTRUCTION(BinaryFloat32x4Op)
4154 virtual CompileType ComputeType() const; 4184 virtual CompileType ComputeType() const;
4155 4185
4186 virtual bool AllowsCSE() const { return true; }
4187 virtual EffectSet Effects() const { return EffectSet::None(); }
4188 virtual EffectSet Dependencies() const { return EffectSet::None(); }
4189 virtual bool AttributesEqual(Instruction* other) const {
4190 return op_kind() == other->AsBinaryFloat32x4Op()->op_kind();
4191 }
4192
4156 private: 4193 private:
4157 const Token::Kind op_kind_; 4194 const Token::Kind op_kind_;
4158 4195
4159 DISALLOW_COPY_AND_ASSIGN(BinaryFloat32x4OpInstr); 4196 DISALLOW_COPY_AND_ASSIGN(BinaryFloat32x4OpInstr);
4160 }; 4197 };
4161 4198
4162 4199
4163 class Float32x4ShuffleInstr : public TemplateDefinition<1> { 4200 class Float32x4ShuffleInstr : public TemplateDefinition<1> {
4164 public: 4201 public:
4165 Float32x4ShuffleInstr(MethodRecognizer::Kind op_kind, Value* value, 4202 Float32x4ShuffleInstr(MethodRecognizer::Kind op_kind, Value* value,
4166 InstanceCallInstr* instance_call) 4203 InstanceCallInstr* instance_call)
4167 : op_kind_(op_kind) { 4204 : op_kind_(op_kind) {
4168 SetInputAt(0, value); 4205 SetInputAt(0, value);
4169 deopt_id_ = instance_call->deopt_id(); 4206 deopt_id_ = instance_call->deopt_id();
4170 } 4207 }
4171 4208
4172 Value* value() const { return inputs_[0]; } 4209 Value* value() const { return inputs_[0]; }
4173 4210
4174 MethodRecognizer::Kind op_kind() const { return op_kind_; } 4211 MethodRecognizer::Kind op_kind() const { return op_kind_; }
4175 4212
4176 virtual void PrintOperandsTo(BufferFormatter* f) const; 4213 virtual void PrintOperandsTo(BufferFormatter* f) const;
4177 4214
4178 virtual bool CanDeoptimize() const { return false; } 4215 virtual bool CanDeoptimize() const { return false; }
4179 4216
4180 virtual bool HasSideEffect() const { return false; }
4181
4182 virtual bool AffectedBySideEffect() const { return false; }
4183
4184 virtual bool AttributesEqual(Instruction* other) const {
4185 return op_kind() == other->AsFloat32x4Shuffle()->op_kind();
4186 }
4187
4188 virtual Representation representation() const { 4217 virtual Representation representation() const {
4189 if ((op_kind_ == MethodRecognizer::kFloat32x4ShuffleX) || 4218 if ((op_kind_ == MethodRecognizer::kFloat32x4ShuffleX) ||
4190 (op_kind_ == MethodRecognizer::kFloat32x4ShuffleY) || 4219 (op_kind_ == MethodRecognizer::kFloat32x4ShuffleY) ||
4191 (op_kind_ == MethodRecognizer::kFloat32x4ShuffleZ) || 4220 (op_kind_ == MethodRecognizer::kFloat32x4ShuffleZ) ||
4192 (op_kind_ == MethodRecognizer::kFloat32x4ShuffleW)) { 4221 (op_kind_ == MethodRecognizer::kFloat32x4ShuffleW)) {
4193 return kUnboxedDouble; 4222 return kUnboxedDouble;
4194 } 4223 }
4195 return kUnboxedFloat32x4; 4224 return kUnboxedFloat32x4;
4196 } 4225 }
4197 4226
4198 virtual Representation RequiredInputRepresentation(intptr_t idx) const { 4227 virtual Representation RequiredInputRepresentation(intptr_t idx) const {
4199 ASSERT(idx == 0); 4228 ASSERT(idx == 0);
4200 return kUnboxedFloat32x4; 4229 return kUnboxedFloat32x4;
4201 } 4230 }
4202 4231
4203 virtual intptr_t DeoptimizationTarget() const { 4232 virtual intptr_t DeoptimizationTarget() const {
4204 // Direct access since this instruction cannot deoptimize, and the deopt-id 4233 // Direct access since this instruction cannot deoptimize, and the deopt-id
4205 // was inherited from another instruction that could deoptimize. 4234 // was inherited from another instruction that could deoptimize.
4206 return deopt_id_; 4235 return deopt_id_;
4207 } 4236 }
4208 4237
4209 DECLARE_INSTRUCTION(Float32x4Shuffle) 4238 DECLARE_INSTRUCTION(Float32x4Shuffle)
4210 virtual CompileType ComputeType() const; 4239 virtual CompileType ComputeType() const;
4211 4240
4241 virtual bool AllowsCSE() const { return true; }
4242 virtual EffectSet Effects() const { return EffectSet::None(); }
4243 virtual EffectSet Dependencies() const { return EffectSet::None(); }
4244 virtual bool AttributesEqual(Instruction* other) const {
4245 return op_kind() == other->AsFloat32x4Shuffle()->op_kind();
4246 }
4247
4212 private: 4248 private:
4213 const MethodRecognizer::Kind op_kind_; 4249 const MethodRecognizer::Kind op_kind_;
4214 4250
4215 DISALLOW_COPY_AND_ASSIGN(Float32x4ShuffleInstr); 4251 DISALLOW_COPY_AND_ASSIGN(Float32x4ShuffleInstr);
4216 }; 4252 };
4217 4253
4218 4254
4219 class Float32x4ConstructorInstr : public TemplateDefinition<4> { 4255 class Float32x4ConstructorInstr : public TemplateDefinition<4> {
4220 public: 4256 public:
4221 Float32x4ConstructorInstr(Value* value0, Value* value1, Value* value2, 4257 Float32x4ConstructorInstr(Value* value0, Value* value1, Value* value2,
4222 Value* value3, StaticCallInstr* static_call) { 4258 Value* value3, StaticCallInstr* static_call) {
4223 SetInputAt(0, value0); 4259 SetInputAt(0, value0);
4224 SetInputAt(1, value1); 4260 SetInputAt(1, value1);
4225 SetInputAt(2, value2); 4261 SetInputAt(2, value2);
4226 SetInputAt(3, value3); 4262 SetInputAt(3, value3);
4227 deopt_id_ = static_call->deopt_id(); 4263 deopt_id_ = static_call->deopt_id();
4228 } 4264 }
4229 4265
4230 Value* value0() const { return inputs_[0]; } 4266 Value* value0() const { return inputs_[0]; }
4231 Value* value1() const { return inputs_[1]; } 4267 Value* value1() const { return inputs_[1]; }
4232 Value* value2() const { return inputs_[2]; } 4268 Value* value2() const { return inputs_[2]; }
4233 Value* value3() const { return inputs_[3]; } 4269 Value* value3() const { return inputs_[3]; }
4234 4270
4235 virtual void PrintOperandsTo(BufferFormatter* f) const; 4271 virtual void PrintOperandsTo(BufferFormatter* f) const;
4236 4272
4237 virtual bool CanDeoptimize() const { return false; } 4273 virtual bool CanDeoptimize() const { return false; }
4238 4274
4239 virtual bool HasSideEffect() const { return false; }
4240
4241 virtual bool AffectedBySideEffect() const { return false; }
4242
4243 virtual bool AttributesEqual(Instruction* other) const { return true; }
4244
4245 virtual Representation representation() const { 4275 virtual Representation representation() const {
4246 return kUnboxedFloat32x4; 4276 return kUnboxedFloat32x4;
4247 } 4277 }
4248 4278
4249 virtual Representation RequiredInputRepresentation(intptr_t idx) const { 4279 virtual Representation RequiredInputRepresentation(intptr_t idx) const {
4250 ASSERT(idx >= 0 && idx < 4); 4280 ASSERT(idx >= 0 && idx < 4);
4251 return kUnboxedDouble; 4281 return kUnboxedDouble;
4252 } 4282 }
4253 4283
4254 virtual intptr_t DeoptimizationTarget() const { 4284 virtual intptr_t DeoptimizationTarget() const {
4255 // Direct access since this instruction cannot deoptimize, and the deopt-id 4285 // Direct access since this instruction cannot deoptimize, and the deopt-id
4256 // was inherited from another instruction that could deoptimize. 4286 // was inherited from another instruction that could deoptimize.
4257 return deopt_id_; 4287 return deopt_id_;
4258 } 4288 }
4259 4289
4260 DECLARE_INSTRUCTION(Float32x4Constructor) 4290 DECLARE_INSTRUCTION(Float32x4Constructor)
4261 virtual CompileType ComputeType() const; 4291 virtual CompileType ComputeType() const;
4262 4292
4293 virtual bool AllowsCSE() const { return true; }
4294 virtual EffectSet Effects() const { return EffectSet::None(); }
4295 virtual EffectSet Dependencies() const { return EffectSet::None(); }
4296 virtual bool AttributesEqual(Instruction* other) const { return true; }
4297
4263 private: 4298 private:
4264 DISALLOW_COPY_AND_ASSIGN(Float32x4ConstructorInstr); 4299 DISALLOW_COPY_AND_ASSIGN(Float32x4ConstructorInstr);
4265 }; 4300 };
4266 4301
4267 4302
4268 class Float32x4SplatInstr : public TemplateDefinition<1> { 4303 class Float32x4SplatInstr : public TemplateDefinition<1> {
4269 public: 4304 public:
4270 Float32x4SplatInstr(Value* value, StaticCallInstr* static_call) { 4305 Float32x4SplatInstr(Value* value, StaticCallInstr* static_call) {
4271 SetInputAt(0, value); 4306 SetInputAt(0, value);
4272 deopt_id_ = static_call->deopt_id(); 4307 deopt_id_ = static_call->deopt_id();
4273 } 4308 }
4274 4309
4275 Value* value() const { return inputs_[0]; } 4310 Value* value() const { return inputs_[0]; }
4276 4311
4277 virtual void PrintOperandsTo(BufferFormatter* f) const; 4312 virtual void PrintOperandsTo(BufferFormatter* f) const;
4278 4313
4279 virtual bool CanDeoptimize() const { return false; } 4314 virtual bool CanDeoptimize() const { return false; }
4280 4315
4281 virtual bool HasSideEffect() const { return false; }
4282
4283 virtual bool AffectedBySideEffect() const { return false; }
4284
4285 virtual bool AttributesEqual(Instruction* other) const { return true; }
4286
4287 virtual Representation representation() const { 4316 virtual Representation representation() const {
4288 return kUnboxedFloat32x4; 4317 return kUnboxedFloat32x4;
4289 } 4318 }
4290 4319
4291 virtual Representation RequiredInputRepresentation(intptr_t idx) const { 4320 virtual Representation RequiredInputRepresentation(intptr_t idx) const {
4292 ASSERT(idx == 0); 4321 ASSERT(idx == 0);
4293 return kUnboxedDouble; 4322 return kUnboxedDouble;
4294 } 4323 }
4295 4324
4296 virtual intptr_t DeoptimizationTarget() const { 4325 virtual intptr_t DeoptimizationTarget() const {
4297 // Direct access since this instruction cannot deoptimize, and the deopt-id 4326 // Direct access since this instruction cannot deoptimize, and the deopt-id
4298 // was inherited from another instruction that could deoptimize. 4327 // was inherited from another instruction that could deoptimize.
4299 return deopt_id_; 4328 return deopt_id_;
4300 } 4329 }
4301 4330
4302 DECLARE_INSTRUCTION(Float32x4Splat) 4331 DECLARE_INSTRUCTION(Float32x4Splat)
4303 virtual CompileType ComputeType() const; 4332 virtual CompileType ComputeType() const;
4304 4333
4334 virtual bool AllowsCSE() const { return true; }
4335 virtual EffectSet Effects() const { return EffectSet::None(); }
4336 virtual EffectSet Dependencies() const { return EffectSet::None(); }
4337 virtual bool AttributesEqual(Instruction* other) const { return true; }
4338
4305 private: 4339 private:
4306 DISALLOW_COPY_AND_ASSIGN(Float32x4SplatInstr); 4340 DISALLOW_COPY_AND_ASSIGN(Float32x4SplatInstr);
4307 }; 4341 };
4308 4342
4309 4343
4310 class Float32x4ZeroInstr : public TemplateDefinition<0> { 4344 class Float32x4ZeroInstr : public TemplateDefinition<0> {
4311 public: 4345 public:
4312 explicit Float32x4ZeroInstr(StaticCallInstr* static_call) { 4346 explicit Float32x4ZeroInstr(StaticCallInstr* static_call) {
4313 deopt_id_ = static_call->deopt_id(); 4347 deopt_id_ = static_call->deopt_id();
4314 } 4348 }
4315 4349
4316 Value* value() const { return inputs_[0]; } 4350 Value* value() const { return inputs_[0]; }
4317 4351
4318 virtual void PrintOperandsTo(BufferFormatter* f) const; 4352 virtual void PrintOperandsTo(BufferFormatter* f) const;
4319 4353
4320 virtual bool CanDeoptimize() const { return false; } 4354 virtual bool CanDeoptimize() const { return false; }
4321 4355
4322 virtual bool HasSideEffect() const { return false; }
4323
4324 virtual bool AffectedBySideEffect() const { return false; }
4325
4326 virtual bool AttributesEqual(Instruction* other) const { return true; }
4327
4328 virtual Representation representation() const { 4356 virtual Representation representation() const {
4329 return kUnboxedFloat32x4; 4357 return kUnboxedFloat32x4;
4330 } 4358 }
4331 4359
4332 virtual Representation RequiredInputRepresentation(intptr_t idx) const { 4360 virtual Representation RequiredInputRepresentation(intptr_t idx) const {
4333 UNIMPLEMENTED(); 4361 UNIMPLEMENTED();
4334 return kUnboxedFloat32x4; 4362 return kUnboxedFloat32x4;
4335 } 4363 }
4336 4364
4337 virtual intptr_t DeoptimizationTarget() const { 4365 virtual intptr_t DeoptimizationTarget() const {
4338 // Direct access since this instruction cannot deoptimize, and the deopt-id 4366 // Direct access since this instruction cannot deoptimize, and the deopt-id
4339 // was inherited from another instruction that could deoptimize. 4367 // was inherited from another instruction that could deoptimize.
4340 return deopt_id_; 4368 return deopt_id_;
4341 } 4369 }
4342 4370
4343 DECLARE_INSTRUCTION(Float32x4Zero) 4371 DECLARE_INSTRUCTION(Float32x4Zero)
4344 virtual CompileType ComputeType() const; 4372 virtual CompileType ComputeType() const;
4345 4373
4374 virtual bool AllowsCSE() const { return true; }
4375 virtual EffectSet Effects() const { return EffectSet::None(); }
4376 virtual EffectSet Dependencies() const { return EffectSet::None(); }
4377 virtual bool AttributesEqual(Instruction* other) const { return true; }
4378
4346 private: 4379 private:
4347 DISALLOW_COPY_AND_ASSIGN(Float32x4ZeroInstr); 4380 DISALLOW_COPY_AND_ASSIGN(Float32x4ZeroInstr);
4348 }; 4381 };
4349 4382
4350 4383
4351 class BinaryMintOpInstr : public TemplateDefinition<2> { 4384 class BinaryMintOpInstr : public TemplateDefinition<2> {
4352 public: 4385 public:
4353 BinaryMintOpInstr(Token::Kind op_kind, 4386 BinaryMintOpInstr(Token::Kind op_kind,
4354 Value* left, 4387 Value* left,
4355 Value* right, 4388 Value* right,
(...skipping 11 matching lines...) Expand all
4367 Token::Kind op_kind() const { return op_kind_; } 4400 Token::Kind op_kind() const { return op_kind_; }
4368 4401
4369 InstanceCallInstr* instance_call() const { return instance_call_; } 4402 InstanceCallInstr* instance_call() const { return instance_call_; }
4370 4403
4371 virtual void PrintOperandsTo(BufferFormatter* f) const; 4404 virtual void PrintOperandsTo(BufferFormatter* f) const;
4372 4405
4373 virtual bool CanDeoptimize() const { 4406 virtual bool CanDeoptimize() const {
4374 return (op_kind() == Token::kADD) || (op_kind() == Token::kSUB); 4407 return (op_kind() == Token::kADD) || (op_kind() == Token::kSUB);
4375 } 4408 }
4376 4409
4377 virtual bool HasSideEffect() const { return false; }
4378
4379 virtual bool AffectedBySideEffect() const { return false; }
4380
4381 virtual bool AttributesEqual(Instruction* other) const {
4382 ASSERT(other->IsBinaryMintOp());
4383 return op_kind() == other->AsBinaryMintOp()->op_kind();
4384 }
4385
4386 virtual CompileType ComputeType() const;
4387
4388 virtual Representation representation() const { 4410 virtual Representation representation() const {
4389 return kUnboxedMint; 4411 return kUnboxedMint;
4390 } 4412 }
4391 4413
4392 virtual Representation RequiredInputRepresentation(intptr_t idx) const { 4414 virtual Representation RequiredInputRepresentation(intptr_t idx) const {
4393 ASSERT((idx == 0) || (idx == 1)); 4415 ASSERT((idx == 0) || (idx == 1));
4394 return kUnboxedMint; 4416 return kUnboxedMint;
4395 } 4417 }
4396 4418
4397 virtual intptr_t DeoptimizationTarget() const { 4419 virtual intptr_t DeoptimizationTarget() const {
4398 // Direct access since this instruction cannot deoptimize, and the deopt-id 4420 // Direct access since this instruction cannot deoptimize, and the deopt-id
4399 // was inherited from another instruction that could deoptimize. 4421 // was inherited from another instruction that could deoptimize.
4400 return deopt_id_; 4422 return deopt_id_;
4401 } 4423 }
4402 4424
4403 virtual Definition* Canonicalize(FlowGraphOptimizer* optimizer); 4425 virtual Definition* Canonicalize(FlowGraphOptimizer* optimizer);
4404 4426
4405 DECLARE_INSTRUCTION(BinaryMintOp) 4427 DECLARE_INSTRUCTION(BinaryMintOp)
4428 virtual CompileType ComputeType() const;
4429
4430 virtual bool AllowsCSE() const { return true; }
4431 virtual EffectSet Effects() const { return EffectSet::None(); }
4432 virtual EffectSet Dependencies() const { return EffectSet::None(); }
4433 virtual bool AttributesEqual(Instruction* other) const {
4434 ASSERT(other->IsBinaryMintOp());
4435 return op_kind() == other->AsBinaryMintOp()->op_kind();
4436 }
4406 4437
4407 private: 4438 private:
4408 const Token::Kind op_kind_; 4439 const Token::Kind op_kind_;
4409 InstanceCallInstr* instance_call_; 4440 InstanceCallInstr* instance_call_;
4410 4441
4411 DISALLOW_COPY_AND_ASSIGN(BinaryMintOpInstr); 4442 DISALLOW_COPY_AND_ASSIGN(BinaryMintOpInstr);
4412 }; 4443 };
4413 4444
4414 4445
4415 class ShiftMintOpInstr : public TemplateDefinition<2> { 4446 class ShiftMintOpInstr : public TemplateDefinition<2> {
(...skipping 11 matching lines...) Expand all
4427 4458
4428 Value* left() const { return inputs_[0]; } 4459 Value* left() const { return inputs_[0]; }
4429 Value* right() const { return inputs_[1]; } 4460 Value* right() const { return inputs_[1]; }
4430 4461
4431 Token::Kind op_kind() const { return op_kind_; } 4462 Token::Kind op_kind() const { return op_kind_; }
4432 4463
4433 virtual void PrintOperandsTo(BufferFormatter* f) const; 4464 virtual void PrintOperandsTo(BufferFormatter* f) const;
4434 4465
4435 virtual bool CanDeoptimize() const { return true; } 4466 virtual bool CanDeoptimize() const { return true; }
4436 4467
4437 virtual bool HasSideEffect() const { return false; }
4438
4439 virtual bool AffectedBySideEffect() const { return false; }
4440
4441 virtual bool AttributesEqual(Instruction* other) const {
4442 return op_kind() == other->AsShiftMintOp()->op_kind();
4443 }
4444
4445 virtual CompileType ComputeType() const; 4468 virtual CompileType ComputeType() const;
4446 4469
4447 virtual Representation representation() const { 4470 virtual Representation representation() const {
4448 return kUnboxedMint; 4471 return kUnboxedMint;
4449 } 4472 }
4450 4473
4451 virtual Representation RequiredInputRepresentation(intptr_t idx) const { 4474 virtual Representation RequiredInputRepresentation(intptr_t idx) const {
4452 ASSERT((idx == 0) || (idx == 1)); 4475 ASSERT((idx == 0) || (idx == 1));
4453 return (idx == 0) ? kUnboxedMint : kTagged; 4476 return (idx == 0) ? kUnboxedMint : kTagged;
4454 } 4477 }
4455 4478
4456 virtual intptr_t DeoptimizationTarget() const { 4479 virtual intptr_t DeoptimizationTarget() const {
4457 // Direct access since this instruction cannot deoptimize, and the deopt-id 4480 // Direct access since this instruction cannot deoptimize, and the deopt-id
4458 // was inherited from another instruction that could deoptimize. 4481 // was inherited from another instruction that could deoptimize.
4459 return deopt_id_; 4482 return deopt_id_;
4460 } 4483 }
4461 4484
4462 DECLARE_INSTRUCTION(ShiftMintOp) 4485 DECLARE_INSTRUCTION(ShiftMintOp)
4463 4486
4487 virtual bool AllowsCSE() const { return true; }
4488 virtual EffectSet Effects() const { return EffectSet::None(); }
4489 virtual EffectSet Dependencies() const { return EffectSet::None(); }
4490 virtual bool AttributesEqual(Instruction* other) const {
4491 return op_kind() == other->AsShiftMintOp()->op_kind();
4492 }
4493
4464 private: 4494 private:
4465 const Token::Kind op_kind_; 4495 const Token::Kind op_kind_;
4466 4496
4467 DISALLOW_COPY_AND_ASSIGN(ShiftMintOpInstr); 4497 DISALLOW_COPY_AND_ASSIGN(ShiftMintOpInstr);
4468 }; 4498 };
4469 4499
4470 4500
4471 class UnaryMintOpInstr : public TemplateDefinition<1> { 4501 class UnaryMintOpInstr : public TemplateDefinition<1> {
4472 public: 4502 public:
4473 UnaryMintOpInstr(Token::Kind op_kind, 4503 UnaryMintOpInstr(Token::Kind op_kind,
4474 Value* value, 4504 Value* value,
4475 InstanceCallInstr* instance_call) 4505 InstanceCallInstr* instance_call)
4476 : op_kind_(op_kind) { 4506 : op_kind_(op_kind) {
4477 ASSERT(op_kind == Token::kBIT_NOT); 4507 ASSERT(op_kind == Token::kBIT_NOT);
4478 SetInputAt(0, value); 4508 SetInputAt(0, value);
4479 deopt_id_ = instance_call->deopt_id(); 4509 deopt_id_ = instance_call->deopt_id();
4480 } 4510 }
4481 4511
4482 Value* value() const { return inputs_[0]; } 4512 Value* value() const { return inputs_[0]; }
4483 4513
4484 Token::Kind op_kind() const { return op_kind_; } 4514 Token::Kind op_kind() const { return op_kind_; }
4485 4515
4486 virtual void PrintOperandsTo(BufferFormatter* f) const; 4516 virtual void PrintOperandsTo(BufferFormatter* f) const;
4487 4517
4488 virtual bool CanDeoptimize() const { return false; } 4518 virtual bool CanDeoptimize() const { return false; }
4489 4519
4490 virtual bool HasSideEffect() const { return false; }
4491
4492 virtual bool AffectedBySideEffect() const { return false; }
4493
4494 virtual bool AttributesEqual(Instruction* other) const {
4495 return op_kind() == other->AsUnaryMintOp()->op_kind();
4496 }
4497
4498 virtual CompileType ComputeType() const;
4499
4500 virtual Representation representation() const { 4520 virtual Representation representation() const {
4501 return kUnboxedMint; 4521 return kUnboxedMint;
4502 } 4522 }
4503 4523
4504 virtual Representation RequiredInputRepresentation(intptr_t idx) const { 4524 virtual Representation RequiredInputRepresentation(intptr_t idx) const {
4505 ASSERT(idx == 0); 4525 ASSERT(idx == 0);
4506 return kUnboxedMint; 4526 return kUnboxedMint;
4507 } 4527 }
4508 4528
4509 virtual intptr_t DeoptimizationTarget() const { 4529 virtual intptr_t DeoptimizationTarget() const {
4510 // Direct access since this instruction cannot deoptimize, and the deopt-id 4530 // Direct access since this instruction cannot deoptimize, and the deopt-id
4511 // was inherited from another instruction that could deoptimize. 4531 // was inherited from another instruction that could deoptimize.
4512 return deopt_id_; 4532 return deopt_id_;
4513 } 4533 }
4514 4534
4515 DECLARE_INSTRUCTION(UnaryMintOp) 4535 DECLARE_INSTRUCTION(UnaryMintOp)
4536 virtual CompileType ComputeType() const;
4537
4538 virtual bool AllowsCSE() const { return true; }
4539 virtual EffectSet Effects() const { return EffectSet::None(); }
4540 virtual EffectSet Dependencies() const { return EffectSet::None(); }
4541 virtual bool AttributesEqual(Instruction* other) const {
4542 return op_kind() == other->AsUnaryMintOp()->op_kind();
4543 }
4516 4544
4517 private: 4545 private:
4518 const Token::Kind op_kind_; 4546 const Token::Kind op_kind_;
4519 4547
4520 DISALLOW_COPY_AND_ASSIGN(UnaryMintOpInstr); 4548 DISALLOW_COPY_AND_ASSIGN(UnaryMintOpInstr);
4521 }; 4549 };
4522 4550
4523 4551
4524 class BinarySmiOpInstr : public TemplateDefinition<2> { 4552 class BinarySmiOpInstr : public TemplateDefinition<2> {
4525 public: 4553 public:
(...skipping 12 matching lines...) Expand all
4538 4566
4539 Value* left() const { return inputs_[0]; } 4567 Value* left() const { return inputs_[0]; }
4540 Value* right() const { return inputs_[1]; } 4568 Value* right() const { return inputs_[1]; }
4541 4569
4542 Token::Kind op_kind() const { return op_kind_; } 4570 Token::Kind op_kind() const { return op_kind_; }
4543 4571
4544 InstanceCallInstr* instance_call() const { return instance_call_; } 4572 InstanceCallInstr* instance_call() const { return instance_call_; }
4545 4573
4546 const ICData* ic_data() const { return instance_call()->ic_data(); } 4574 const ICData* ic_data() const { return instance_call()->ic_data(); }
4547 4575
4576 void set_overflow(bool overflow) { overflow_ = overflow; }
4577
4578 void set_is_truncating(bool value) { is_truncating_ = value; }
4579 bool is_truncating() const { return is_truncating_; }
4580
4548 virtual void PrintOperandsTo(BufferFormatter* f) const; 4581 virtual void PrintOperandsTo(BufferFormatter* f) const;
4549 4582
4550 DECLARE_INSTRUCTION(BinarySmiOp) 4583 DECLARE_INSTRUCTION(BinarySmiOp)
4551
4552 virtual CompileType ComputeType() const; 4584 virtual CompileType ComputeType() const;
4553 4585
4554 virtual bool CanDeoptimize() const; 4586 virtual bool CanDeoptimize() const;
4555 4587
4556 virtual bool HasSideEffect() const { return false; } 4588 virtual bool AllowsCSE() const { return true; }
4557 4589 virtual EffectSet Effects() const { return EffectSet::None(); }
4558 virtual bool AffectedBySideEffect() const { return false; } 4590 virtual EffectSet Dependencies() const { return EffectSet::None(); }
4559 virtual bool AttributesEqual(Instruction* other) const; 4591 virtual bool AttributesEqual(Instruction* other) const;
4560 4592
4561 void set_overflow(bool overflow) {
4562 overflow_ = overflow;
4563 }
4564
4565 void set_is_truncating(bool value) {
4566 is_truncating_ = value;
4567 }
4568 bool is_truncating() const { return is_truncating_; }
4569
4570 void PrintTo(BufferFormatter* f) const; 4593 void PrintTo(BufferFormatter* f) const;
4571 4594
4572 virtual void InferRange(); 4595 virtual void InferRange();
4573 4596
4574 virtual Definition* Canonicalize(FlowGraphOptimizer* optimizer); 4597 virtual Definition* Canonicalize(FlowGraphOptimizer* optimizer);
4575 4598
4576 // Returns true if right is a non-zero Smi constant which absolute value is 4599 // Returns true if right is a non-zero Smi constant which absolute value is
4577 // a power of two. 4600 // a power of two.
4578 bool RightIsPowerOfTwoConstant() const; 4601 bool RightIsPowerOfTwoConstant() const;
4579 4602
(...skipping 22 matching lines...) Expand all
4602 Value* value() const { return inputs_[0]; } 4625 Value* value() const { return inputs_[0]; }
4603 Token::Kind op_kind() const { return op_kind_; } 4626 Token::Kind op_kind() const { return op_kind_; }
4604 4627
4605 virtual void PrintOperandsTo(BufferFormatter* f) const; 4628 virtual void PrintOperandsTo(BufferFormatter* f) const;
4606 4629
4607 DECLARE_INSTRUCTION(UnarySmiOp) 4630 DECLARE_INSTRUCTION(UnarySmiOp)
4608 virtual CompileType ComputeType() const; 4631 virtual CompileType ComputeType() const;
4609 4632
4610 virtual bool CanDeoptimize() const { return op_kind() == Token::kNEGATE; } 4633 virtual bool CanDeoptimize() const { return op_kind() == Token::kNEGATE; }
4611 4634
4612 virtual bool HasSideEffect() const { return false; } 4635 virtual bool AllowsCSE() const { return true; }
4636 virtual EffectSet Effects() const { return EffectSet::None(); }
4637 virtual EffectSet Dependencies() const { return EffectSet::None(); }
4638 virtual bool AttributesEqual(Instruction* other) const {
4639 return other->AsUnarySmiOp()->op_kind() == op_kind();
4640 }
4613 4641
4614 private: 4642 private:
4615 const Token::Kind op_kind_; 4643 const Token::Kind op_kind_;
4616 4644
4617 DISALLOW_COPY_AND_ASSIGN(UnarySmiOpInstr); 4645 DISALLOW_COPY_AND_ASSIGN(UnarySmiOpInstr);
4618 }; 4646 };
4619 4647
4620 4648
4621 class CheckStackOverflowInstr : public TemplateInstruction<0> { 4649 class CheckStackOverflowInstr : public TemplateInstruction<0> {
4622 public: 4650 public:
4623 explicit CheckStackOverflowInstr(intptr_t token_pos) 4651 explicit CheckStackOverflowInstr(intptr_t token_pos)
4624 : token_pos_(token_pos) {} 4652 : token_pos_(token_pos) {}
4625 4653
4626 intptr_t token_pos() const { return token_pos_; } 4654 intptr_t token_pos() const { return token_pos_; }
4627 4655
4628 DECLARE_INSTRUCTION(CheckStackOverflow) 4656 DECLARE_INSTRUCTION(CheckStackOverflow)
4629 4657
4630 virtual intptr_t ArgumentCount() const { return 0; } 4658 virtual intptr_t ArgumentCount() const { return 0; }
4631 4659
4632 virtual bool CanDeoptimize() const { return true; } 4660 virtual bool CanDeoptimize() const { return true; }
4633 4661
4634 virtual bool HasSideEffect() const { return false; } 4662 virtual EffectSet Effects() const { return EffectSet::None(); }
4635 4663
4636 private: 4664 private:
4637 const intptr_t token_pos_; 4665 const intptr_t token_pos_;
4638 4666
4639 DISALLOW_COPY_AND_ASSIGN(CheckStackOverflowInstr); 4667 DISALLOW_COPY_AND_ASSIGN(CheckStackOverflowInstr);
4640 }; 4668 };
4641 4669
4642 4670
4643 class SmiToDoubleInstr : public TemplateDefinition<1> { 4671 class SmiToDoubleInstr : public TemplateDefinition<1> {
4644 public: 4672 public:
4645 explicit SmiToDoubleInstr(Value* value) { 4673 explicit SmiToDoubleInstr(Value* value) {
4646 SetInputAt(0, value); 4674 SetInputAt(0, value);
4647 } 4675 }
4648 4676
4649 Value* value() const { return inputs_[0]; } 4677 Value* value() const { return inputs_[0]; }
4650 4678
4651 DECLARE_INSTRUCTION(SmiToDouble) 4679 DECLARE_INSTRUCTION(SmiToDouble)
4652 virtual CompileType ComputeType() const; 4680 virtual CompileType ComputeType() const;
4653 4681
4654 virtual Representation representation() const { 4682 virtual Representation representation() const {
4655 return kUnboxedDouble; 4683 return kUnboxedDouble;
4656 } 4684 }
4657 4685
4658 virtual intptr_t ArgumentCount() const { return 1; } 4686 virtual intptr_t ArgumentCount() const { return 1; }
4659 4687
4660 virtual bool CanDeoptimize() const { return false; } 4688 virtual bool CanDeoptimize() const { return false; }
4661 4689
4662 virtual bool HasSideEffect() const { return false; } 4690 virtual bool AllowsCSE() const { return true; }
4663 virtual bool AffectedBySideEffect() const { return false; } 4691 virtual EffectSet Effects() const { return EffectSet::None(); }
4692 virtual EffectSet Dependencies() const { return EffectSet::None(); }
4664 virtual bool AttributesEqual(Instruction* other) const { return true; } 4693 virtual bool AttributesEqual(Instruction* other) const { return true; }
4665 4694
4666 private: 4695 private:
4667 DISALLOW_COPY_AND_ASSIGN(SmiToDoubleInstr); 4696 DISALLOW_COPY_AND_ASSIGN(SmiToDoubleInstr);
4668 }; 4697 };
4669 4698
4670 4699
4671 class DoubleToIntegerInstr : public TemplateDefinition<1> { 4700 class DoubleToIntegerInstr : public TemplateDefinition<1> {
4672 public: 4701 public:
4673 DoubleToIntegerInstr(Value* value, InstanceCallInstr* instance_call) 4702 DoubleToIntegerInstr(Value* value, InstanceCallInstr* instance_call)
4674 : instance_call_(instance_call) { 4703 : instance_call_(instance_call) {
4675 SetInputAt(0, value); 4704 SetInputAt(0, value);
4676 } 4705 }
4677 4706
4678 Value* value() const { return inputs_[0]; } 4707 Value* value() const { return inputs_[0]; }
4679 InstanceCallInstr* instance_call() const { return instance_call_; } 4708 InstanceCallInstr* instance_call() const { return instance_call_; }
4680 4709
4681 DECLARE_INSTRUCTION(DoubleToInteger) 4710 DECLARE_INSTRUCTION(DoubleToInteger)
4682 virtual CompileType ComputeType() const; 4711 virtual CompileType ComputeType() const;
4683 4712
4684 virtual intptr_t ArgumentCount() const { return 1; } 4713 virtual intptr_t ArgumentCount() const { return 1; }
4685 4714
4686 virtual bool CanDeoptimize() const { return true; } 4715 virtual bool CanDeoptimize() const { return true; }
4687 4716
4688 virtual bool HasSideEffect() const { return false; } 4717 virtual EffectSet Effects() const { return EffectSet::None(); }
4689 4718
4690 private: 4719 private:
4691 InstanceCallInstr* instance_call_; 4720 InstanceCallInstr* instance_call_;
4692 4721
4693 DISALLOW_COPY_AND_ASSIGN(DoubleToIntegerInstr); 4722 DISALLOW_COPY_AND_ASSIGN(DoubleToIntegerInstr);
4694 }; 4723 };
4695 4724
4696 4725
4697 // Similar to 'DoubleToIntegerInstr' but expects unboxed double as input 4726 // Similar to 'DoubleToIntegerInstr' but expects unboxed double as input
4698 // and creates a Smi. 4727 // and creates a Smi.
4699 class DoubleToSmiInstr : public TemplateDefinition<1> { 4728 class DoubleToSmiInstr : public TemplateDefinition<1> {
4700 public: 4729 public:
4701 DoubleToSmiInstr(Value* value, InstanceCallInstr* instance_call) { 4730 DoubleToSmiInstr(Value* value, InstanceCallInstr* instance_call) {
4702 SetInputAt(0, value); 4731 SetInputAt(0, value);
4703 deopt_id_ = instance_call->deopt_id(); 4732 deopt_id_ = instance_call->deopt_id();
4704 } 4733 }
4705 4734
4706 Value* value() const { return inputs_[0]; } 4735 Value* value() const { return inputs_[0]; }
4707 4736
4708 DECLARE_INSTRUCTION(DoubleToSmi) 4737 DECLARE_INSTRUCTION(DoubleToSmi)
4709 virtual CompileType ComputeType() const; 4738 virtual CompileType ComputeType() const;
4710 4739
4711 virtual bool CanDeoptimize() const { return true; } 4740 virtual bool CanDeoptimize() const { return true; }
4712 4741
4713 virtual bool HasSideEffect() const { return false; }
4714
4715 virtual Representation RequiredInputRepresentation(intptr_t idx) const { 4742 virtual Representation RequiredInputRepresentation(intptr_t idx) const {
4716 ASSERT(idx == 0); 4743 ASSERT(idx == 0);
4717 return kUnboxedDouble; 4744 return kUnboxedDouble;
4718 } 4745 }
4719 4746
4720 virtual intptr_t DeoptimizationTarget() const { return deopt_id_; } 4747 virtual intptr_t DeoptimizationTarget() const { return deopt_id_; }
4721 4748
4749 virtual EffectSet Effects() const { return EffectSet::None(); }
4750
4722 private: 4751 private:
4723 DISALLOW_COPY_AND_ASSIGN(DoubleToSmiInstr); 4752 DISALLOW_COPY_AND_ASSIGN(DoubleToSmiInstr);
4724 }; 4753 };
4725 4754
4726 4755
4727 class DoubleToDoubleInstr : public TemplateDefinition<1> { 4756 class DoubleToDoubleInstr : public TemplateDefinition<1> {
4728 public: 4757 public:
4729 DoubleToDoubleInstr(Value* value, 4758 DoubleToDoubleInstr(Value* value,
4730 InstanceCallInstr* instance_call, 4759 InstanceCallInstr* instance_call,
4731 MethodRecognizer::Kind recognized_kind) 4760 MethodRecognizer::Kind recognized_kind)
4732 : recognized_kind_(recognized_kind) { 4761 : recognized_kind_(recognized_kind) {
4733 SetInputAt(0, value); 4762 SetInputAt(0, value);
4734 deopt_id_ = instance_call->deopt_id(); 4763 deopt_id_ = instance_call->deopt_id();
4735 } 4764 }
4736 4765
4737 Value* value() const { return inputs_[0]; } 4766 Value* value() const { return inputs_[0]; }
4738 4767
4739 MethodRecognizer::Kind recognized_kind() const { return recognized_kind_; } 4768 MethodRecognizer::Kind recognized_kind() const { return recognized_kind_; }
4740 4769
4741 DECLARE_INSTRUCTION(DoubleToDouble) 4770 DECLARE_INSTRUCTION(DoubleToDouble)
4742 virtual CompileType ComputeType() const; 4771 virtual CompileType ComputeType() const;
4743 4772
4744 virtual bool CanDeoptimize() const { return false; } 4773 virtual bool CanDeoptimize() const { return false; }
4745 4774
4746 virtual bool HasSideEffect() const { return false; }
4747 virtual bool AffectedBySideEffect() const { return false; }
4748 virtual bool AttributesEqual(Instruction* other) const {
4749 return other->AsDoubleToDouble()->recognized_kind() == recognized_kind();
4750 }
4751
4752 virtual Representation representation() const { 4775 virtual Representation representation() const {
4753 return kUnboxedDouble; 4776 return kUnboxedDouble;
4754 } 4777 }
4755 4778
4756 virtual Representation RequiredInputRepresentation(intptr_t idx) const { 4779 virtual Representation RequiredInputRepresentation(intptr_t idx) const {
4757 ASSERT(idx == 0); 4780 ASSERT(idx == 0);
4758 return kUnboxedDouble; 4781 return kUnboxedDouble;
4759 } 4782 }
4760 4783
4761 virtual intptr_t DeoptimizationTarget() const { return deopt_id_; } 4784 virtual intptr_t DeoptimizationTarget() const { return deopt_id_; }
4762 4785
4786 virtual bool AllowsCSE() const { return true; }
4787 virtual EffectSet Effects() const { return EffectSet::None(); }
4788 virtual EffectSet Dependencies() const { return EffectSet::None(); }
4789 virtual bool AttributesEqual(Instruction* other) const {
4790 return other->AsDoubleToDouble()->recognized_kind() == recognized_kind();
4791 }
4792
4763 private: 4793 private:
4764 const MethodRecognizer::Kind recognized_kind_; 4794 const MethodRecognizer::Kind recognized_kind_;
4765 4795
4766 DISALLOW_COPY_AND_ASSIGN(DoubleToDoubleInstr); 4796 DISALLOW_COPY_AND_ASSIGN(DoubleToDoubleInstr);
4767 }; 4797 };
4768 4798
4769 4799
4770 class InvokeMathCFunctionInstr : public Definition { 4800 class InvokeMathCFunctionInstr : public Definition {
4771 public: 4801 public:
4772 InvokeMathCFunctionInstr(ZoneGrowableArray<Value*>* inputs, 4802 InvokeMathCFunctionInstr(ZoneGrowableArray<Value*>* inputs,
4773 InstanceCallInstr* instance_call, 4803 InstanceCallInstr* instance_call,
4774 MethodRecognizer::Kind recognized_kind); 4804 MethodRecognizer::Kind recognized_kind);
4775 4805
4776 static intptr_t ArgumentCountFor(MethodRecognizer::Kind recognized_kind_); 4806 static intptr_t ArgumentCountFor(MethodRecognizer::Kind recognized_kind_);
4777 4807
4778 const RuntimeEntry& TargetFunction() const; 4808 const RuntimeEntry& TargetFunction() const;
4779 4809
4780 MethodRecognizer::Kind recognized_kind() const { return recognized_kind_; } 4810 MethodRecognizer::Kind recognized_kind() const { return recognized_kind_; }
4781 4811
4782 DECLARE_INSTRUCTION(InvokeMathCFunction) 4812 DECLARE_INSTRUCTION(InvokeMathCFunction)
4783 virtual CompileType ComputeType() const; 4813 virtual CompileType ComputeType() const;
4784 virtual void PrintOperandsTo(BufferFormatter* f) const; 4814 virtual void PrintOperandsTo(BufferFormatter* f) const;
4785 4815
4786 virtual bool CanDeoptimize() const { return false; } 4816 virtual bool CanDeoptimize() const { return false; }
4787 4817
4788 virtual bool HasSideEffect() const { return false; }
4789 virtual bool AffectedBySideEffect() const { return false; }
4790 virtual bool AttributesEqual(Instruction* other) const {
4791 return other->AsDoubleToDouble()->recognized_kind() == recognized_kind();
4792 }
4793
4794 virtual Representation representation() const { 4818 virtual Representation representation() const {
4795 return kUnboxedDouble; 4819 return kUnboxedDouble;
4796 } 4820 }
4797 4821
4798 virtual Representation RequiredInputRepresentation(intptr_t idx) const { 4822 virtual Representation RequiredInputRepresentation(intptr_t idx) const {
4799 ASSERT((0 <= idx) && (idx < InputCount())); 4823 ASSERT((0 <= idx) && (idx < InputCount()));
4800 return kUnboxedDouble; 4824 return kUnboxedDouble;
4801 } 4825 }
4802 4826
4803 virtual intptr_t DeoptimizationTarget() const { return deopt_id_; } 4827 virtual intptr_t DeoptimizationTarget() const { return deopt_id_; }
4804 4828
4805 virtual intptr_t InputCount() const { 4829 virtual intptr_t InputCount() const {
4806 return inputs_->length(); 4830 return inputs_->length();
4807 } 4831 }
4808 4832
4809 virtual Value* InputAt(intptr_t i) const { 4833 virtual Value* InputAt(intptr_t i) const {
4810 return (*inputs_)[i]; 4834 return (*inputs_)[i];
4811 } 4835 }
4812 4836
4813 // Returns a structure describing the location constraints required 4837 // Returns a structure describing the location constraints required
4814 // to emit native code for this definition. 4838 // to emit native code for this definition.
4815 LocationSummary* locs() { 4839 LocationSummary* locs() {
4816 if (locs_ == NULL) { 4840 if (locs_ == NULL) {
4817 locs_ = MakeLocationSummary(); 4841 locs_ = MakeLocationSummary();
4818 } 4842 }
4819 return locs_; 4843 return locs_;
4820 } 4844 }
4821 4845
4846 virtual bool AllowsCSE() const { return true; }
4847 virtual EffectSet Effects() const { return EffectSet::None(); }
4848 virtual EffectSet Dependencies() const { return EffectSet::None(); }
4849 virtual bool AttributesEqual(Instruction* other) {
4850 return other->AsInvokeMathCFunction()->recognized_kind() ==
4851 recognized_kind();
4852 }
4853
4822 private: 4854 private:
4823 virtual void RawSetInputAt(intptr_t i, Value* value) { 4855 virtual void RawSetInputAt(intptr_t i, Value* value) {
4824 (*inputs_)[i] = value; 4856 (*inputs_)[i] = value;
4825 } 4857 }
4826 4858
4827 ZoneGrowableArray<Value*>* inputs_; 4859 ZoneGrowableArray<Value*>* inputs_;
4828 4860
4829 LocationSummary* locs_; 4861 LocationSummary* locs_;
4830 4862
4831 const MethodRecognizer::Kind recognized_kind_; 4863 const MethodRecognizer::Kind recognized_kind_;
4832 4864
4833 DISALLOW_COPY_AND_ASSIGN(InvokeMathCFunctionInstr); 4865 DISALLOW_COPY_AND_ASSIGN(InvokeMathCFunctionInstr);
4834 }; 4866 };
4835 4867
4836 4868
4837 class CheckClassInstr : public TemplateInstruction<1> { 4869 class CheckClassInstr : public TemplateInstruction<1> {
4838 public: 4870 public:
4839 CheckClassInstr(Value* value, 4871 CheckClassInstr(Value* value,
4840 intptr_t deopt_id, 4872 intptr_t deopt_id,
4841 const ICData& unary_checks); 4873 const ICData& unary_checks);
4842 4874
4843 DECLARE_INSTRUCTION(CheckClass) 4875 DECLARE_INSTRUCTION(CheckClass)
4844 4876
4845 virtual intptr_t ArgumentCount() const { return 0; } 4877 virtual intptr_t ArgumentCount() const { return 0; }
4846 4878
4847 virtual bool CanDeoptimize() const { return true; } 4879 virtual bool CanDeoptimize() const { return true; }
4848 4880
4849 virtual bool HasSideEffect() const { return false; }
4850
4851 virtual bool AttributesEqual(Instruction* other) const;
4852
4853 virtual bool AffectedBySideEffect() const;
4854
4855 Value* value() const { return inputs_[0]; } 4881 Value* value() const { return inputs_[0]; }
4856 4882
4857 const ICData& unary_checks() const { return unary_checks_; } 4883 const ICData& unary_checks() const { return unary_checks_; }
4858 4884
4859 virtual Instruction* Canonicalize(FlowGraphOptimizer* optimizer); 4885 virtual Instruction* Canonicalize(FlowGraphOptimizer* optimizer);
4860 4886
4861 virtual void PrintOperandsTo(BufferFormatter* f) const; 4887 virtual void PrintOperandsTo(BufferFormatter* f) const;
4862 4888
4863 void set_null_check(bool flag) { null_check_ = flag; } 4889 void set_null_check(bool flag) { null_check_ = flag; }
4864 4890
4865 bool null_check() const { return null_check_; } 4891 bool null_check() const { return null_check_; }
4866 4892
4893 virtual bool AllowsCSE() const { return true; }
4894 virtual EffectSet Effects() const { return EffectSet::None(); }
4895 virtual EffectSet Dependencies() const;
4896 virtual bool AttributesEqual(Instruction* other) const;
4897
4867 private: 4898 private:
4868 const ICData& unary_checks_; 4899 const ICData& unary_checks_;
4869 4900
4870 bool null_check_; 4901 bool null_check_;
4871 4902
4872 DISALLOW_COPY_AND_ASSIGN(CheckClassInstr); 4903 DISALLOW_COPY_AND_ASSIGN(CheckClassInstr);
4873 }; 4904 };
4874 4905
4875 4906
4876 class CheckSmiInstr : public TemplateInstruction<1> { 4907 class CheckSmiInstr : public TemplateInstruction<1> {
4877 public: 4908 public:
4878 CheckSmiInstr(Value* value, intptr_t original_deopt_id) { 4909 CheckSmiInstr(Value* value, intptr_t original_deopt_id) {
4879 ASSERT(original_deopt_id != Isolate::kNoDeoptId); 4910 ASSERT(original_deopt_id != Isolate::kNoDeoptId);
4880 SetInputAt(0, value); 4911 SetInputAt(0, value);
4881 deopt_id_ = original_deopt_id; 4912 deopt_id_ = original_deopt_id;
4882 } 4913 }
4883 4914
4915 Value* value() const { return inputs_[0]; }
4916
4884 DECLARE_INSTRUCTION(CheckSmi) 4917 DECLARE_INSTRUCTION(CheckSmi)
4885 4918
4886 virtual intptr_t ArgumentCount() const { return 0; } 4919 virtual intptr_t ArgumentCount() const { return 0; }
4887 4920
4888 virtual bool CanDeoptimize() const { return true; } 4921 virtual bool CanDeoptimize() const { return true; }
4889 4922
4890 virtual bool HasSideEffect() const { return false; }
4891
4892 virtual bool AttributesEqual(Instruction* other) const { return true; }
4893
4894 virtual bool AffectedBySideEffect() const { return false; }
4895
4896 virtual Instruction* Canonicalize(FlowGraphOptimizer* optimizer); 4923 virtual Instruction* Canonicalize(FlowGraphOptimizer* optimizer);
4897 4924
4898 Value* value() const { return inputs_[0]; } 4925 virtual bool AllowsCSE() const { return true; }
4926 virtual EffectSet Effects() const { return EffectSet::None(); }
4927 virtual EffectSet Dependencies() const { return EffectSet::None(); }
4928 virtual bool AttributesEqual(Instruction* other) const { return true; }
4899 4929
4900 private: 4930 private:
4901 DISALLOW_COPY_AND_ASSIGN(CheckSmiInstr); 4931 DISALLOW_COPY_AND_ASSIGN(CheckSmiInstr);
4902 }; 4932 };
4903 4933
4904 4934
4905 class CheckArrayBoundInstr : public TemplateInstruction<2> { 4935 class CheckArrayBoundInstr : public TemplateInstruction<2> {
4906 public: 4936 public:
4907 CheckArrayBoundInstr(Value* length, 4937 CheckArrayBoundInstr(Value* length,
4908 Value* index, 4938 Value* index,
4909 intptr_t array_type, 4939 intptr_t array_type,
4910 InstanceCallInstr* instance_call) 4940 InstanceCallInstr* instance_call)
4911 : array_type_(array_type) { 4941 : array_type_(array_type) {
4912 SetInputAt(0, length); 4942 SetInputAt(0, length);
4913 SetInputAt(1, index); 4943 SetInputAt(1, index);
4914 deopt_id_ = instance_call->deopt_id(); 4944 deopt_id_ = instance_call->deopt_id();
4915 } 4945 }
4916 4946
4947 Value* length() const { return inputs_[0]; }
4948 Value* index() const { return inputs_[1]; }
4949
4950 intptr_t array_type() const { return array_type_; }
4951
4917 DECLARE_INSTRUCTION(CheckArrayBound) 4952 DECLARE_INSTRUCTION(CheckArrayBound)
4918 4953
4919 virtual intptr_t ArgumentCount() const { return 0; } 4954 virtual intptr_t ArgumentCount() const { return 0; }
4920 4955
4921 virtual bool CanDeoptimize() const { return true; } 4956 virtual bool CanDeoptimize() const { return true; }
4922 4957
4923 virtual bool HasSideEffect() const { return false; }
4924
4925 virtual bool AttributesEqual(Instruction* other) const;
4926
4927 virtual bool AffectedBySideEffect() const { return false; }
4928
4929 Value* length() const { return inputs_[0]; }
4930 Value* index() const { return inputs_[1]; }
4931
4932 intptr_t array_type() const { return array_type_; }
4933
4934 bool IsRedundant(RangeBoundary length); 4958 bool IsRedundant(RangeBoundary length);
4935 4959
4936 // Returns the length offset for array and string types. 4960 // Returns the length offset for array and string types.
4937 static intptr_t LengthOffsetFor(intptr_t class_id); 4961 static intptr_t LengthOffsetFor(intptr_t class_id);
4938 4962
4939 static bool IsFixedLengthArrayType(intptr_t class_id); 4963 static bool IsFixedLengthArrayType(intptr_t class_id);
4940 4964
4965 virtual bool AllowsCSE() const { return true; }
4966 virtual EffectSet Effects() const { return EffectSet::None(); }
4967 virtual EffectSet Dependencies() const { return EffectSet::None(); }
4968 virtual bool AttributesEqual(Instruction* other) const;
4969
4941 private: 4970 private:
4942 intptr_t array_type_; 4971 intptr_t array_type_;
4943 4972
4944 DISALLOW_COPY_AND_ASSIGN(CheckArrayBoundInstr); 4973 DISALLOW_COPY_AND_ASSIGN(CheckArrayBoundInstr);
4945 }; 4974 };
4946 4975
4947 4976
4948 #undef DECLARE_INSTRUCTION 4977 #undef DECLARE_INSTRUCTION
4949 4978
4950 class Environment : public ZoneAllocated { 4979 class Environment : public ZoneAllocated {
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
5162 ForwardInstructionIterator* current_iterator_; 5191 ForwardInstructionIterator* current_iterator_;
5163 5192
5164 private: 5193 private:
5165 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); 5194 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor);
5166 }; 5195 };
5167 5196
5168 5197
5169 } // namespace dart 5198 } // namespace dart
5170 5199
5171 #endif // VM_INTERMEDIATE_LANGUAGE_H_ 5200 #endif // VM_INTERMEDIATE_LANGUAGE_H_
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698