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 // Functions to support CSE. | |
srdjan
2012/08/17 22:30:22
Please document these functions briefly.
Florian Schneider
2012/08/20 12:09:37
Done.
| |
158 bool Equals(Computation* other) const; | |
159 virtual intptr_t Hashcode() const; | |
160 virtual bool AttributesEqual(Computation* other) const { return true; } | |
161 virtual bool HasSideEffect() const { return true; } | |
162 | |
156 // Compile time type of the computation, which typically depends on the | 163 // Compile time type of the computation, which typically depends on the |
157 // compile time types (and possibly propagated types) of its inputs. | 164 // compile time types (and possibly propagated types) of its inputs. |
158 virtual RawAbstractType* CompileType() const = 0; | 165 virtual RawAbstractType* CompileType() const = 0; |
159 virtual intptr_t ResultCid() const { return kDynamicCid; } | 166 virtual intptr_t ResultCid() const { return kDynamicCid; } |
160 | 167 |
161 // Mutate assigned_vars to add the local variable index for all | 168 // Mutate assigned_vars to add the local variable index for all |
162 // frame-allocated locals assigned to by the computation. | 169 // frame-allocated locals assigned to by the computation. |
163 virtual void RecordAssignedVars(BitVector* assigned_vars, | 170 virtual void RecordAssignedVars(BitVector* assigned_vars, |
164 intptr_t fixed_parameter_count); | 171 intptr_t fixed_parameter_count); |
165 | 172 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
207 // Declare predicate for each computation. | 214 // Declare predicate for each computation. |
208 #define DECLARE_PREDICATE(ShortName, ClassName) \ | 215 #define DECLARE_PREDICATE(ShortName, ClassName) \ |
209 inline bool Is##ShortName() const; \ | 216 inline bool Is##ShortName() const; \ |
210 inline const ClassName* As##ShortName() const; \ | 217 inline const ClassName* As##ShortName() const; \ |
211 inline ClassName* As##ShortName(); | 218 inline ClassName* As##ShortName(); |
212 FOR_EACH_COMPUTATION(DECLARE_PREDICATE) | 219 FOR_EACH_COMPUTATION(DECLARE_PREDICATE) |
213 #undef DECLARE_PREDICATE | 220 #undef DECLARE_PREDICATE |
214 | 221 |
215 private: | 222 private: |
216 intptr_t deopt_id_; | 223 intptr_t deopt_id_; |
217 ICData* ic_data_; | 224 const ICData* ic_data_; |
218 LocationSummary* locs_; | 225 LocationSummary* locs_; |
219 | 226 |
220 DISALLOW_COPY_AND_ASSIGN(Computation); | 227 DISALLOW_COPY_AND_ASSIGN(Computation); |
221 }; | 228 }; |
222 | 229 |
223 | 230 |
224 // An embedded container with N elements of type T. Used (with partial | 231 // An embedded container with N elements of type T. Used (with partial |
225 // specialization for N=0) because embedded arrays cannot have size 0. | 232 // specialization for N=0) because embedded arrays cannot have size 0. |
226 template<typename T, intptr_t N> | 233 template<typename T, intptr_t N> |
227 class EmbeddedArray { | 234 class EmbeddedArray { |
(...skipping 715 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
943 } | 950 } |
944 | 951 |
945 DECLARE_COMPUTATION(LoadInstanceField) | 952 DECLARE_COMPUTATION(LoadInstanceField) |
946 | 953 |
947 const Field& field() const { return field_; } | 954 const Field& field() const { return field_; } |
948 Value* instance() const { return inputs_[0]; } | 955 Value* instance() const { return inputs_[0]; } |
949 const InstanceCallComp* original() const { return original_; } | 956 const InstanceCallComp* original() const { return original_; } |
950 | 957 |
951 virtual void PrintOperandsTo(BufferFormatter* f) const; | 958 virtual void PrintOperandsTo(BufferFormatter* f) const; |
952 | 959 |
953 virtual bool CanDeoptimize() const { return true; } | 960 virtual bool CanDeoptimize() const { return true; } |
srdjan
2012/08/17 22:30:22
Should this be false if we have added a CheckClass
Florian Schneider
2012/08/20 12:09:37
Yes. I'll add a TODO to change it when we remove t
| |
954 | 961 |
955 private: | 962 private: |
956 const Field& field_; | 963 const Field& field_; |
957 const InstanceCallComp* original_; // For optimizations. | 964 const InstanceCallComp* original_; // For optimizations. |
958 | 965 |
959 DISALLOW_COPY_AND_ASSIGN(LoadInstanceFieldComp); | 966 DISALLOW_COPY_AND_ASSIGN(LoadInstanceFieldComp); |
960 }; | 967 }; |
961 | 968 |
962 | 969 |
963 class StoreInstanceFieldComp : public TemplateComputation<2> { | 970 class StoreInstanceFieldComp : public TemplateComputation<2> { |
(...skipping 802 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1766 virtual bool CanDeoptimize() const { return true; } | 1773 virtual bool CanDeoptimize() const { return true; } |
1767 virtual intptr_t ResultCid() const { return kDoubleCid; } | 1774 virtual intptr_t ResultCid() const { return kDoubleCid; } |
1768 | 1775 |
1769 private: | 1776 private: |
1770 InstanceCallComp* instance_call_; | 1777 InstanceCallComp* instance_call_; |
1771 | 1778 |
1772 DISALLOW_COPY_AND_ASSIGN(SmiToDoubleComp); | 1779 DISALLOW_COPY_AND_ASSIGN(SmiToDoubleComp); |
1773 }; | 1780 }; |
1774 | 1781 |
1775 | 1782 |
1783 class CheckClassComp : public TemplateComputation<1> { | |
srdjan
2012/08/17 22:30:22
Consider renaming it to CheckClassesComp since it
Florian Schneider
2012/08/20 12:09:37
Done.
| |
1784 public: | |
1785 CheckClassComp(Value* value, InstanceCallComp* original) | |
1786 : original_(original) { | |
1787 ASSERT(value != NULL); | |
1788 inputs_[0] = value; | |
1789 } | |
1790 | |
1791 DECLARE_COMPUTATION(CheckClass) | |
1792 | |
1793 virtual bool CanDeoptimize() const { return true; } | |
1794 | |
1795 virtual bool AttributesEqual(Computation* other) const; | |
1796 | |
1797 virtual bool HasSideEffect() const { return false; } | |
srdjan
2012/08/17 22:30:22
Why is CheckClassComp the only computation that do
Florian Schneider
2012/08/20 12:09:37
Currently only CheckClass participates in CSE, but
| |
1798 | |
1799 Value* value() const { return inputs_[0]; } | |
1800 | |
1801 intptr_t deopt_id() const { return original_->deopt_id(); } | |
1802 intptr_t try_index() const { return original_->try_index(); } | |
1803 | |
1804 private: | |
1805 InstanceCallComp* original_; | |
1806 | |
1807 DISALLOW_COPY_AND_ASSIGN(CheckClassComp); | |
1808 }; | |
1809 | |
1810 | |
1776 #undef DECLARE_COMPUTATION | 1811 #undef DECLARE_COMPUTATION |
1777 | 1812 |
1778 | 1813 |
1779 // Implementation of type testers and cast functins. | 1814 // Implementation of type testers and cast functins. |
1780 #define DEFINE_PREDICATE(ShortName, ClassName) \ | 1815 #define DEFINE_PREDICATE(ShortName, ClassName) \ |
1781 bool Computation::Is##ShortName() const { \ | 1816 bool Computation::Is##ShortName() const { \ |
1782 return computation_kind() == k##ShortName; \ | 1817 return computation_kind() == k##ShortName; \ |
1783 } \ | 1818 } \ |
1784 const ClassName* Computation::As##ShortName() const { \ | 1819 const ClassName* Computation::As##ShortName() const { \ |
1785 if (!Is##ShortName()) return NULL; \ | 1820 if (!Is##ShortName()) return NULL; \ |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1875 ASSERT(instr == NULL || !instr->IsBlockEntry()); | 1910 ASSERT(instr == NULL || !instr->IsBlockEntry()); |
1876 // TODO(fschneider): Also add Throw and ReThrow to the list of instructions | 1911 // 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 | 1912 // 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 | 1913 // to append instruction in case of a Throw inside an expression. This |
1879 // condition should be handled in the graph builder | 1914 // condition should be handled in the graph builder |
1880 next_ = instr; | 1915 next_ = instr; |
1881 } | 1916 } |
1882 | 1917 |
1883 // Removed this instruction from the graph. | 1918 // Removed this instruction from the graph. |
1884 Instruction* RemoveFromGraph(bool return_previous = true); | 1919 Instruction* RemoveFromGraph(bool return_previous = true); |
1920 | |
1885 // Remove value uses within this instruction and its inputs. | 1921 // Remove value uses within this instruction and its inputs. |
1886 virtual void RemoveInputUses() = 0; | 1922 virtual void RemoveInputUses() = 0; |
1887 | 1923 |
1924 // Insert this instruction before 'next'. | |
1925 void InsertBefore(Instruction* next); | |
1926 | |
1888 // Normal instructions can have 0 (inside a block) or 1 (last instruction in | 1927 // Normal instructions can have 0 (inside a block) or 1 (last instruction in |
1889 // a block) successors. Branch instruction with >1 successors override this | 1928 // a block) successors. Branch instruction with >1 successors override this |
1890 // function. | 1929 // function. |
1891 virtual intptr_t SuccessorCount() const; | 1930 virtual intptr_t SuccessorCount() const; |
1892 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; | 1931 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; |
1893 | 1932 |
1894 void Goto(JoinEntryInstr* entry); | 1933 void Goto(JoinEntryInstr* entry); |
1895 | 1934 |
1896 // Discover basic-block structure by performing a recursive depth first | 1935 // Discover basic-block structure by performing a recursive depth first |
1897 // traversal of the instruction graph reachable from this instruction. As | 1936 // traversal of the instruction graph reachable from this instruction. As |
(...skipping 598 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2496 Computation* computation() const { return computation_; } | 2535 Computation* computation() const { return computation_; } |
2497 void set_computation(Computation* value) { computation_ = value; } | 2536 void set_computation(Computation* value) { computation_ = value; } |
2498 bool is_used() const { return is_used_; } | 2537 bool is_used() const { return is_used_; } |
2499 | 2538 |
2500 virtual RawAbstractType* CompileType() const; | 2539 virtual RawAbstractType* CompileType() const; |
2501 virtual intptr_t GetPropagatedCid(); | 2540 virtual intptr_t GetPropagatedCid(); |
2502 | 2541 |
2503 virtual void RecordAssignedVars(BitVector* assigned_vars, | 2542 virtual void RecordAssignedVars(BitVector* assigned_vars, |
2504 intptr_t fixed_parameter_count); | 2543 intptr_t fixed_parameter_count); |
2505 | 2544 |
2545 intptr_t Hashcode() const { return computation()->Hashcode(); } | |
2546 | |
2547 bool Equals(BindInstr* other) const { | |
2548 return computation()->Equals(other->computation()); | |
2549 } | |
2550 | |
2506 virtual LocationSummary* locs() { | 2551 virtual LocationSummary* locs() { |
2507 return computation()->locs(); | 2552 return computation()->locs(); |
2508 } | 2553 } |
2509 | 2554 |
2510 virtual void EmitNativeCode(FlowGraphCompiler* compiler); | 2555 virtual void EmitNativeCode(FlowGraphCompiler* compiler); |
2511 | 2556 |
2512 virtual void RemoveInputUses() { computation()->RemoveInputUses(); } | 2557 virtual void RemoveInputUses() { computation()->RemoveInputUses(); } |
2513 | 2558 |
2514 private: | 2559 private: |
2515 Computation* computation_; | 2560 Computation* computation_; |
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2964 ForwardInstructionIterator* current_iterator_; | 3009 ForwardInstructionIterator* current_iterator_; |
2965 | 3010 |
2966 private: | 3011 private: |
2967 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 3012 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
2968 }; | 3013 }; |
2969 | 3014 |
2970 | 3015 |
2971 } // namespace dart | 3016 } // namespace dart |
2972 | 3017 |
2973 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 3018 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
OLD | NEW |