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

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

Powered by Google App Engine
This is Rietveld 408576698