| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef VM_INTERMEDIATE_LANGUAGE_H_ | 5 #ifndef VM_INTERMEDIATE_LANGUAGE_H_ |
| 6 #define VM_INTERMEDIATE_LANGUAGE_H_ | 6 #define VM_INTERMEDIATE_LANGUAGE_H_ |
| 7 | 7 |
| 8 #include "vm/allocation.h" | 8 #include "vm/allocation.h" |
| 9 #include "vm/ast.h" | 9 #include "vm/ast.h" |
| 10 #include "vm/growable_array.h" | 10 #include "vm/growable_array.h" |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 94 M(AllocateContext, AllocateContextComp) \ | 94 M(AllocateContext, AllocateContextComp) \ |
| 95 M(ChainContext, ChainContextComp) \ | 95 M(ChainContext, ChainContextComp) \ |
| 96 M(CloneContext, CloneContextComp) \ | 96 M(CloneContext, CloneContextComp) \ |
| 97 M(CatchEntry, CatchEntryComp) \ | 97 M(CatchEntry, CatchEntryComp) \ |
| 98 M(BinaryOp, BinaryOpComp) \ | 98 M(BinaryOp, BinaryOpComp) \ |
| 99 M(DoubleBinaryOp, DoubleBinaryOpComp) \ | 99 M(DoubleBinaryOp, DoubleBinaryOpComp) \ |
| 100 M(UnarySmiOp, UnarySmiOpComp) \ | 100 M(UnarySmiOp, UnarySmiOpComp) \ |
| 101 M(NumberNegate, NumberNegateComp) \ | 101 M(NumberNegate, NumberNegateComp) \ |
| 102 M(CheckStackOverflow, CheckStackOverflowComp) \ | 102 M(CheckStackOverflow, CheckStackOverflowComp) \ |
| 103 M(DoubleToDouble, DoubleToDoubleComp) \ | 103 M(DoubleToDouble, DoubleToDoubleComp) \ |
| 104 M(SmiToDouble, SmiToDoubleComp) | 104 M(SmiToDouble, SmiToDoubleComp) \ |
| 105 M(CheckClass, CheckClassComp) |
| 105 | 106 |
| 106 | 107 |
| 107 #define FORWARD_DECLARATION(ShortName, ClassName) class ClassName; | 108 #define FORWARD_DECLARATION(ShortName, ClassName) class ClassName; |
| 108 FOR_EACH_COMPUTATION(FORWARD_DECLARATION) | 109 FOR_EACH_COMPUTATION(FORWARD_DECLARATION) |
| 109 #undef FORWARD_DECLARATION | 110 #undef FORWARD_DECLARATION |
| 110 | 111 |
| 111 // Forward declarations. | 112 // Forward declarations. |
| 112 class BindInstr; | 113 class BindInstr; |
| 113 class BranchInstr; | 114 class BranchInstr; |
| 114 class BufferFormatter; | 115 class BufferFormatter; |
| 115 class ComparisonComp; | 116 class ComparisonComp; |
| 116 class Definition; | 117 class Definition; |
| 117 class Instruction; | 118 class Instruction; |
| 118 class PushArgumentInstr; | 119 class PushArgumentInstr; |
| 119 class Value; | 120 class Value; |
| 120 | 121 |
| 121 class Computation : public ZoneAllocated { | 122 class Computation : public ZoneAllocated { |
| 122 public: | 123 public: |
| 123 Computation() : deopt_id_(Isolate::kNoDeoptId), ic_data_(NULL), locs_(NULL) { | 124 Computation() : deopt_id_(Isolate::kNoDeoptId), ic_data_(NULL), locs_(NULL) { |
| 124 Isolate* isolate = Isolate::Current(); | 125 Isolate* isolate = Isolate::Current(); |
| 125 deopt_id_ = isolate->GetNextDeoptId(); | 126 deopt_id_ = isolate->GetNextDeoptId(); |
| 126 ic_data_ = isolate->GetICDataForDeoptId(deopt_id_); | 127 ic_data_ = isolate->GetICDataForDeoptId(deopt_id_); |
| 127 } | 128 } |
| 128 | 129 |
| 129 // Unique id used for deoptimization. | 130 // Unique id used for deoptimization. |
| 130 intptr_t deopt_id() const { return deopt_id_; } | 131 intptr_t deopt_id() const { return deopt_id_; } |
| 131 | 132 |
| 132 ICData* ic_data() const { return ic_data_; } | 133 const ICData* ic_data() const { return ic_data_; } |
| 133 void set_ic_data(ICData* value) { ic_data_ = value; } | 134 void set_ic_data(const ICData* value) { ic_data_ = value; } |
| 134 bool HasICData() const { | 135 bool HasICData() const { |
| 135 return (ic_data() != NULL) && !ic_data()->IsNull(); | 136 return (ic_data() != NULL) && !ic_data()->IsNull(); |
| 136 } | 137 } |
| 137 | 138 |
| 138 // Visiting support. | 139 // Visiting support. |
| 139 virtual void Accept(FlowGraphVisitor* visitor, BindInstr* instr) = 0; | 140 virtual void Accept(FlowGraphVisitor* visitor, BindInstr* instr) = 0; |
| 140 | 141 |
| 141 virtual intptr_t InputCount() const = 0; | 142 virtual intptr_t InputCount() const = 0; |
| 142 virtual Value* InputAt(intptr_t i) const = 0; | 143 virtual Value* InputAt(intptr_t i) const = 0; |
| 143 virtual void SetInputAt(intptr_t i, Value* value) = 0; | 144 virtual void SetInputAt(intptr_t i, Value* value) = 0; |
| 144 | 145 |
| 145 // Call computations override this function and return the | 146 // Call computations override this function and return the |
| 146 // number of pushed arguments. | 147 // number of pushed arguments. |
| 147 virtual intptr_t ArgumentCount() const = 0; | 148 virtual intptr_t ArgumentCount() const = 0; |
| 148 | 149 |
| 149 // Returns true, if this computation can deoptimize. | 150 // Returns true, if this computation can deoptimize. |
| 150 virtual bool CanDeoptimize() const = 0; | 151 virtual bool CanDeoptimize() const = 0; |
| 151 | 152 |
| 152 // Optimize this computation. Returns a replacement for the instruction | 153 // Optimize this computation. Returns a replacement for the instruction |
| 153 // that wraps this computation or NULL if nothing to replace. | 154 // that wraps this computation or NULL if nothing to replace. |
| 154 virtual Definition* TryReplace(BindInstr* instr) { return NULL; } | 155 virtual Definition* TryReplace(BindInstr* instr) { return NULL; } |
| 155 | 156 |
| 157 // Compares two computations. Returns true, if: |
| 158 // 1. They are of the same kind. |
| 159 // 2. All input operands match. |
| 160 // 3. All other attributes match. |
| 161 bool Equals(Computation* other) const; |
| 162 |
| 163 // Returns a hash code for use with hash maps. |
| 164 virtual intptr_t Hashcode() const; |
| 165 |
| 166 // Compare attributes of an computation (except input operands and kind). |
| 167 // TODO(fschneider): Make this abstract and implement for all computations. |
| 168 virtual bool AttributesEqual(Computation* other) const { return true; } |
| 169 |
| 170 // Returns true if the instruction may have side effects. |
| 171 // TODO(fschneider): Make this abstract and implement for all computations |
| 172 // instead of returning the safe default (true). |
| 173 virtual bool HasSideEffect() const { return true; } |
| 174 |
| 156 // Compile time type of the computation, which typically depends on the | 175 // Compile time type of the computation, which typically depends on the |
| 157 // compile time types (and possibly propagated types) of its inputs. | 176 // compile time types (and possibly propagated types) of its inputs. |
| 158 virtual RawAbstractType* CompileType() const = 0; | 177 virtual RawAbstractType* CompileType() const = 0; |
| 159 virtual intptr_t ResultCid() const { return kDynamicCid; } | 178 virtual intptr_t ResultCid() const { return kDynamicCid; } |
| 160 | 179 |
| 161 // Mutate assigned_vars to add the local variable index for all | 180 // Mutate assigned_vars to add the local variable index for all |
| 162 // frame-allocated locals assigned to by the computation. | 181 // frame-allocated locals assigned to by the computation. |
| 163 virtual void RecordAssignedVars(BitVector* assigned_vars, | 182 virtual void RecordAssignedVars(BitVector* assigned_vars, |
| 164 intptr_t fixed_parameter_count); | 183 intptr_t fixed_parameter_count); |
| 165 | 184 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 // Declare predicate for each computation. | 226 // Declare predicate for each computation. |
| 208 #define DECLARE_PREDICATE(ShortName, ClassName) \ | 227 #define DECLARE_PREDICATE(ShortName, ClassName) \ |
| 209 inline bool Is##ShortName() const; \ | 228 inline bool Is##ShortName() const; \ |
| 210 inline const ClassName* As##ShortName() const; \ | 229 inline const ClassName* As##ShortName() const; \ |
| 211 inline ClassName* As##ShortName(); | 230 inline ClassName* As##ShortName(); |
| 212 FOR_EACH_COMPUTATION(DECLARE_PREDICATE) | 231 FOR_EACH_COMPUTATION(DECLARE_PREDICATE) |
| 213 #undef DECLARE_PREDICATE | 232 #undef DECLARE_PREDICATE |
| 214 | 233 |
| 215 private: | 234 private: |
| 216 intptr_t deopt_id_; | 235 intptr_t deopt_id_; |
| 217 ICData* ic_data_; | 236 const ICData* ic_data_; |
| 218 LocationSummary* locs_; | 237 LocationSummary* locs_; |
| 219 | 238 |
| 220 DISALLOW_COPY_AND_ASSIGN(Computation); | 239 DISALLOW_COPY_AND_ASSIGN(Computation); |
| 221 }; | 240 }; |
| 222 | 241 |
| 223 | 242 |
| 224 // An embedded container with N elements of type T. Used (with partial | 243 // An embedded container with N elements of type T. Used (with partial |
| 225 // specialization for N=0) because embedded arrays cannot have size 0. | 244 // specialization for N=0) because embedded arrays cannot have size 0. |
| 226 template<typename T, intptr_t N> | 245 template<typename T, intptr_t N> |
| 227 class EmbeddedArray { | 246 class EmbeddedArray { |
| (...skipping 701 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 929 const intptr_t try_index_; | 948 const intptr_t try_index_; |
| 930 | 949 |
| 931 DISALLOW_COPY_AND_ASSIGN(NativeCallComp); | 950 DISALLOW_COPY_AND_ASSIGN(NativeCallComp); |
| 932 }; | 951 }; |
| 933 | 952 |
| 934 | 953 |
| 935 class LoadInstanceFieldComp : public TemplateComputation<1> { | 954 class LoadInstanceFieldComp : public TemplateComputation<1> { |
| 936 public: | 955 public: |
| 937 LoadInstanceFieldComp(const Field& field, | 956 LoadInstanceFieldComp(const Field& field, |
| 938 Value* instance, | 957 Value* instance, |
| 939 InstanceCallComp* original) // Maybe NULL. | 958 InstanceCallComp* original, // Maybe NULL. |
| 940 : field_(field), original_(original) { | 959 bool can_deoptimize) |
| 960 : field_(field), original_(original), can_deoptimize_(can_deoptimize) { |
| 941 ASSERT(instance != NULL); | 961 ASSERT(instance != NULL); |
| 942 inputs_[0] = instance; | 962 inputs_[0] = instance; |
| 943 } | 963 } |
| 944 | 964 |
| 945 DECLARE_COMPUTATION(LoadInstanceField) | 965 DECLARE_COMPUTATION(LoadInstanceField) |
| 946 | 966 |
| 947 const Field& field() const { return field_; } | 967 const Field& field() const { return field_; } |
| 948 Value* instance() const { return inputs_[0]; } | 968 Value* instance() const { return inputs_[0]; } |
| 949 const InstanceCallComp* original() const { return original_; } | 969 const InstanceCallComp* original() const { return original_; } |
| 950 | 970 |
| 951 virtual void PrintOperandsTo(BufferFormatter* f) const; | 971 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 952 | 972 |
| 953 virtual bool CanDeoptimize() const { return true; } | 973 virtual bool CanDeoptimize() const { return can_deoptimize_; } |
| 954 | 974 |
| 955 private: | 975 private: |
| 956 const Field& field_; | 976 const Field& field_; |
| 957 const InstanceCallComp* original_; // For optimizations. | 977 const InstanceCallComp* original_; // For optimizations. |
| 978 const bool can_deoptimize_; |
| 958 | 979 |
| 959 DISALLOW_COPY_AND_ASSIGN(LoadInstanceFieldComp); | 980 DISALLOW_COPY_AND_ASSIGN(LoadInstanceFieldComp); |
| 960 }; | 981 }; |
| 961 | 982 |
| 962 | 983 |
| 963 class StoreInstanceFieldComp : public TemplateComputation<2> { | 984 class StoreInstanceFieldComp : public TemplateComputation<2> { |
| 964 public: | 985 public: |
| 965 StoreInstanceFieldComp(const Field& field, | 986 StoreInstanceFieldComp(const Field& field, |
| 966 Value* instance, | 987 Value* instance, |
| 967 Value* value, | 988 Value* value, |
| (...skipping 798 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1766 virtual bool CanDeoptimize() const { return true; } | 1787 virtual bool CanDeoptimize() const { return true; } |
| 1767 virtual intptr_t ResultCid() const { return kDoubleCid; } | 1788 virtual intptr_t ResultCid() const { return kDoubleCid; } |
| 1768 | 1789 |
| 1769 private: | 1790 private: |
| 1770 InstanceCallComp* instance_call_; | 1791 InstanceCallComp* instance_call_; |
| 1771 | 1792 |
| 1772 DISALLOW_COPY_AND_ASSIGN(SmiToDoubleComp); | 1793 DISALLOW_COPY_AND_ASSIGN(SmiToDoubleComp); |
| 1773 }; | 1794 }; |
| 1774 | 1795 |
| 1775 | 1796 |
| 1797 class CheckClassComp : public TemplateComputation<1> { |
| 1798 public: |
| 1799 CheckClassComp(Value* value, InstanceCallComp* original) |
| 1800 : original_(original) { |
| 1801 ASSERT(value != NULL); |
| 1802 inputs_[0] = value; |
| 1803 } |
| 1804 |
| 1805 DECLARE_COMPUTATION(CheckClass) |
| 1806 |
| 1807 virtual bool CanDeoptimize() const { return true; } |
| 1808 |
| 1809 virtual bool AttributesEqual(Computation* other) const; |
| 1810 |
| 1811 virtual bool HasSideEffect() const { return false; } |
| 1812 |
| 1813 Value* value() const { return inputs_[0]; } |
| 1814 |
| 1815 intptr_t deopt_id() const { return original_->deopt_id(); } |
| 1816 intptr_t try_index() const { return original_->try_index(); } |
| 1817 |
| 1818 private: |
| 1819 InstanceCallComp* original_; |
| 1820 |
| 1821 DISALLOW_COPY_AND_ASSIGN(CheckClassComp); |
| 1822 }; |
| 1823 |
| 1824 |
| 1776 #undef DECLARE_COMPUTATION | 1825 #undef DECLARE_COMPUTATION |
| 1777 | 1826 |
| 1778 | 1827 |
| 1779 // Implementation of type testers and cast functins. | 1828 // Implementation of type testers and cast functins. |
| 1780 #define DEFINE_PREDICATE(ShortName, ClassName) \ | 1829 #define DEFINE_PREDICATE(ShortName, ClassName) \ |
| 1781 bool Computation::Is##ShortName() const { \ | 1830 bool Computation::Is##ShortName() const { \ |
| 1782 return computation_kind() == k##ShortName; \ | 1831 return computation_kind() == k##ShortName; \ |
| 1783 } \ | 1832 } \ |
| 1784 const ClassName* Computation::As##ShortName() const { \ | 1833 const ClassName* Computation::As##ShortName() const { \ |
| 1785 if (!Is##ShortName()) return NULL; \ | 1834 if (!Is##ShortName()) return NULL; \ |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1875 ASSERT(instr == NULL || !instr->IsBlockEntry()); | 1924 ASSERT(instr == NULL || !instr->IsBlockEntry()); |
| 1876 // TODO(fschneider): Also add Throw and ReThrow to the list of instructions | 1925 // TODO(fschneider): Also add Throw and ReThrow to the list of instructions |
| 1877 // that do not have a successor. Currently, the graph builder will continue | 1926 // that do not have a successor. Currently, the graph builder will continue |
| 1878 // to append instruction in case of a Throw inside an expression. This | 1927 // to append instruction in case of a Throw inside an expression. This |
| 1879 // condition should be handled in the graph builder | 1928 // condition should be handled in the graph builder |
| 1880 next_ = instr; | 1929 next_ = instr; |
| 1881 } | 1930 } |
| 1882 | 1931 |
| 1883 // Removed this instruction from the graph. | 1932 // Removed this instruction from the graph. |
| 1884 Instruction* RemoveFromGraph(bool return_previous = true); | 1933 Instruction* RemoveFromGraph(bool return_previous = true); |
| 1934 |
| 1885 // Remove value uses within this instruction and its inputs. | 1935 // Remove value uses within this instruction and its inputs. |
| 1886 virtual void RemoveInputUses() = 0; | 1936 virtual void RemoveInputUses() = 0; |
| 1887 | 1937 |
| 1888 // Normal instructions can have 0 (inside a block) or 1 (last instruction in | 1938 // Normal instructions can have 0 (inside a block) or 1 (last instruction in |
| 1889 // a block) successors. Branch instruction with >1 successors override this | 1939 // a block) successors. Branch instruction with >1 successors override this |
| 1890 // function. | 1940 // function. |
| 1891 virtual intptr_t SuccessorCount() const; | 1941 virtual intptr_t SuccessorCount() const; |
| 1892 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; | 1942 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; |
| 1893 | 1943 |
| 1894 void Goto(JoinEntryInstr* entry); | 1944 void Goto(JoinEntryInstr* entry); |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1948 | 1998 |
| 1949 Environment* env() const { return env_; } | 1999 Environment* env() const { return env_; } |
| 1950 void set_env(Environment* env) { env_ = env; } | 2000 void set_env(Environment* env) { env_ = env; } |
| 1951 | 2001 |
| 1952 intptr_t lifetime_position() const { return lifetime_position_; } | 2002 intptr_t lifetime_position() const { return lifetime_position_; } |
| 1953 void set_lifetime_position(intptr_t pos) { | 2003 void set_lifetime_position(intptr_t pos) { |
| 1954 lifetime_position_ = pos; | 2004 lifetime_position_ = pos; |
| 1955 } | 2005 } |
| 1956 | 2006 |
| 1957 private: | 2007 private: |
| 2008 friend class BindInstr; // Needed for BindInstr::InsertBefore. |
| 2009 |
| 1958 intptr_t lifetime_position_; // Position used by register allocator. | 2010 intptr_t lifetime_position_; // Position used by register allocator. |
| 1959 Instruction* previous_; | 2011 Instruction* previous_; |
| 1960 Instruction* next_; | 2012 Instruction* next_; |
| 1961 Environment* env_; | 2013 Environment* env_; |
| 1962 DISALLOW_COPY_AND_ASSIGN(Instruction); | 2014 DISALLOW_COPY_AND_ASSIGN(Instruction); |
| 1963 }; | 2015 }; |
| 1964 | 2016 |
| 1965 | 2017 |
| 1966 template<intptr_t N> | 2018 template<intptr_t N> |
| 1967 class TemplateInstruction: public Instruction { | 2019 class TemplateInstruction: public Instruction { |
| (...skipping 528 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2496 Computation* computation() const { return computation_; } | 2548 Computation* computation() const { return computation_; } |
| 2497 void set_computation(Computation* value) { computation_ = value; } | 2549 void set_computation(Computation* value) { computation_ = value; } |
| 2498 bool is_used() const { return is_used_; } | 2550 bool is_used() const { return is_used_; } |
| 2499 | 2551 |
| 2500 virtual RawAbstractType* CompileType() const; | 2552 virtual RawAbstractType* CompileType() const; |
| 2501 virtual intptr_t GetPropagatedCid(); | 2553 virtual intptr_t GetPropagatedCid(); |
| 2502 | 2554 |
| 2503 virtual void RecordAssignedVars(BitVector* assigned_vars, | 2555 virtual void RecordAssignedVars(BitVector* assigned_vars, |
| 2504 intptr_t fixed_parameter_count); | 2556 intptr_t fixed_parameter_count); |
| 2505 | 2557 |
| 2558 intptr_t Hashcode() const { return computation()->Hashcode(); } |
| 2559 |
| 2560 bool Equals(BindInstr* other) const { |
| 2561 return computation()->Equals(other->computation()); |
| 2562 } |
| 2563 |
| 2506 virtual LocationSummary* locs() { | 2564 virtual LocationSummary* locs() { |
| 2507 return computation()->locs(); | 2565 return computation()->locs(); |
| 2508 } | 2566 } |
| 2509 | 2567 |
| 2510 virtual void EmitNativeCode(FlowGraphCompiler* compiler); | 2568 virtual void EmitNativeCode(FlowGraphCompiler* compiler); |
| 2511 | 2569 |
| 2512 virtual void RemoveInputUses() { computation()->RemoveInputUses(); } | 2570 virtual void RemoveInputUses() { computation()->RemoveInputUses(); } |
| 2513 | 2571 |
| 2572 // Insert this instruction before 'next'. |
| 2573 void InsertBefore(BindInstr* next); |
| 2574 |
| 2514 private: | 2575 private: |
| 2515 Computation* computation_; | 2576 Computation* computation_; |
| 2516 const bool is_used_; | 2577 const bool is_used_; |
| 2517 | 2578 |
| 2518 DISALLOW_COPY_AND_ASSIGN(BindInstr); | 2579 DISALLOW_COPY_AND_ASSIGN(BindInstr); |
| 2519 }; | 2580 }; |
| 2520 | 2581 |
| 2521 | 2582 |
| 2522 class PhiInstr : public Definition { | 2583 class PhiInstr : public Definition { |
| 2523 public: | 2584 public: |
| (...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2964 ForwardInstructionIterator* current_iterator_; | 3025 ForwardInstructionIterator* current_iterator_; |
| 2965 | 3026 |
| 2966 private: | 3027 private: |
| 2967 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 3028 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
| 2968 }; | 3029 }; |
| 2969 | 3030 |
| 2970 | 3031 |
| 2971 } // namespace dart | 3032 } // namespace dart |
| 2972 | 3033 |
| 2973 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 3034 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
| OLD | NEW |