| 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 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 101 M(NumberNegate, NumberNegateComp) \ | 101 M(NumberNegate, NumberNegateComp) \ |
| 102 M(CheckStackOverflow, CheckStackOverflowComp) \ | 102 M(CheckStackOverflow, CheckStackOverflowComp) \ |
| 103 M(ToDouble, ToDoubleComp) \ | 103 M(ToDouble, ToDoubleComp) \ |
| 104 | 104 |
| 105 | 105 |
| 106 #define FORWARD_DECLARATION(ShortName, ClassName) class ClassName; | 106 #define FORWARD_DECLARATION(ShortName, ClassName) class ClassName; |
| 107 FOR_EACH_COMPUTATION(FORWARD_DECLARATION) | 107 FOR_EACH_COMPUTATION(FORWARD_DECLARATION) |
| 108 #undef FORWARD_DECLARATION | 108 #undef FORWARD_DECLARATION |
| 109 | 109 |
| 110 // Forward declarations. | 110 // Forward declarations. |
| 111 class BindInstr; |
| 112 class BranchInstr; |
| 111 class BufferFormatter; | 113 class BufferFormatter; |
| 112 class BranchInstr; | |
| 113 class Instruction; | 114 class Instruction; |
| 114 class Value; | 115 class Value; |
| 115 | 116 |
| 116 | |
| 117 class Computation : public ZoneAllocated { | 117 class Computation : public ZoneAllocated { |
| 118 public: | 118 public: |
| 119 static const int kNoCid = -1; | 119 static const int kNoCid = -1; |
| 120 | 120 |
| 121 Computation() : cid_(-1), ic_data_(NULL), instr_(NULL), locs_(NULL) { | 121 Computation() : cid_(-1), ic_data_(NULL), instr_(NULL), locs_(NULL) { |
| 122 Isolate* isolate = Isolate::Current(); | 122 Isolate* isolate = Isolate::Current(); |
| 123 cid_ = GetNextCid(isolate); | 123 cid_ = GetNextCid(isolate); |
| 124 ic_data_ = GetICDataForCid(cid_, isolate); | 124 ic_data_ = GetICDataForCid(cid_, isolate); |
| 125 } | 125 } |
| 126 | 126 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 156 | 156 |
| 157 // Returns structure describing location constraints required | 157 // Returns structure describing location constraints required |
| 158 // to emit native code for this computation. | 158 // to emit native code for this computation. |
| 159 LocationSummary* locs() { | 159 LocationSummary* locs() { |
| 160 if (locs_ == NULL) { | 160 if (locs_ == NULL) { |
| 161 locs_ = MakeLocationSummary(); | 161 locs_ = MakeLocationSummary(); |
| 162 } | 162 } |
| 163 return locs_; | 163 return locs_; |
| 164 } | 164 } |
| 165 | 165 |
| 166 // TODO(srdjan): Eliminate Instructions hierarchy. If 'use' is NULL | 166 void set_instr(BindInstr* instr) { instr_ = instr; } |
| 167 // it acts as a DoInstr, otherwise a BindInstr. | 167 BindInstr* instr() const { return instr_; } |
| 168 void set_instr(Instruction* value) { instr_ = value; } | |
| 169 Instruction* instr() const { return instr_; } | |
| 170 | 168 |
| 171 // Create a location summary for this computation. | 169 // Create a location summary for this computation. |
| 172 // TODO(fschneider): Temporarily returns NULL for instructions | 170 // TODO(fschneider): Temporarily returns NULL for instructions |
| 173 // that are not yet converted to the location based code generation. | 171 // that are not yet converted to the location based code generation. |
| 174 virtual LocationSummary* MakeLocationSummary() const = 0; | 172 virtual LocationSummary* MakeLocationSummary() const = 0; |
| 175 | 173 |
| 176 // TODO(fschneider): Make EmitNativeCode and locs const. | 174 // TODO(fschneider): Make EmitNativeCode and locs const. |
| 177 virtual void EmitNativeCode(FlowGraphCompiler* compiler) = 0; | 175 virtual void EmitNativeCode(FlowGraphCompiler* compiler) = 0; |
| 178 | 176 |
| 179 static LocationSummary* MakeCallSummary(); | 177 static LocationSummary* MakeCallSummary(); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 215 return NULL; | 213 return NULL; |
| 216 } | 214 } |
| 217 ICData& ic_data_handle = ICData::ZoneHandle(); | 215 ICData& ic_data_handle = ICData::ZoneHandle(); |
| 218 ic_data_handle ^= array_handle.At(cid); | 216 ic_data_handle ^= array_handle.At(cid); |
| 219 return &ic_data_handle; | 217 return &ic_data_handle; |
| 220 } | 218 } |
| 221 } | 219 } |
| 222 | 220 |
| 223 intptr_t cid_; | 221 intptr_t cid_; |
| 224 ICData* ic_data_; | 222 ICData* ic_data_; |
| 225 Instruction* instr_; | 223 BindInstr* instr_; |
| 226 LocationSummary* locs_; | 224 LocationSummary* locs_; |
| 227 | 225 |
| 228 DISALLOW_COPY_AND_ASSIGN(Computation); | 226 DISALLOW_COPY_AND_ASSIGN(Computation); |
| 229 }; | 227 }; |
| 230 | 228 |
| 231 | 229 |
| 232 // An embedded container with N elements of type T. Used (with partial | 230 // An embedded container with N elements of type T. Used (with partial |
| 233 // specialization for N=0) because embedded arrays cannot have size 0. | 231 // specialization for N=0) because embedded arrays cannot have size 0. |
| 234 template<typename T, intptr_t N> | 232 template<typename T, intptr_t N> |
| 235 class EmbeddedArray { | 233 class EmbeddedArray { |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 312 virtual LocationSummary* MakeLocationSummary() const; \ | 310 virtual LocationSummary* MakeLocationSummary() const; \ |
| 313 virtual void EmitNativeCode(FlowGraphCompiler* compiler); | 311 virtual void EmitNativeCode(FlowGraphCompiler* compiler); |
| 314 | 312 |
| 315 // Functions defined in all concrete value classes. | 313 // Functions defined in all concrete value classes. |
| 316 #define DECLARE_VALUE(ShortName) \ | 314 #define DECLARE_VALUE(ShortName) \ |
| 317 DECLARE_COMPUTATION(ShortName) \ | 315 DECLARE_COMPUTATION(ShortName) \ |
| 318 virtual void PrintTo(BufferFormatter* f) const; | 316 virtual void PrintTo(BufferFormatter* f) const; |
| 319 | 317 |
| 320 | 318 |
| 321 class Definition; | 319 class Definition; |
| 322 class BindInstr; | |
| 323 class PhiInstr; | 320 class PhiInstr; |
| 324 | 321 |
| 325 class UseVal : public Value { | 322 class UseVal : public Value { |
| 326 public: | 323 public: |
| 327 explicit UseVal(Definition* definition) : definition_(definition) {} | 324 explicit UseVal(Definition* definition) : definition_(definition) {} |
| 328 | 325 |
| 329 DECLARE_VALUE(Use) | 326 DECLARE_VALUE(Use) |
| 330 | 327 |
| 331 inline Definition* definition() const; | 328 inline Definition* definition() const; |
| 332 void set_definition(Definition* definition) { | 329 void set_definition(Definition* definition) { |
| (...skipping 1345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1678 } \ | 1675 } \ |
| 1679 ClassName* Computation::As##ShortName() { \ | 1676 ClassName* Computation::As##ShortName() { \ |
| 1680 if (!Is##ShortName()) return NULL; \ | 1677 if (!Is##ShortName()) return NULL; \ |
| 1681 return static_cast<ClassName*>(this); \ | 1678 return static_cast<ClassName*>(this); \ |
| 1682 } | 1679 } |
| 1683 FOR_EACH_COMPUTATION(DEFINE_PREDICATE) | 1680 FOR_EACH_COMPUTATION(DEFINE_PREDICATE) |
| 1684 #undef DEFINE_PREDICATE | 1681 #undef DEFINE_PREDICATE |
| 1685 | 1682 |
| 1686 | 1683 |
| 1687 // Instructions. | 1684 // Instructions. |
| 1688 // | |
| 1689 // <Instruction> ::= JoinEntry <Instruction> | |
| 1690 // | TargetEntry <Instruction> | |
| 1691 // | Do <Computation> <Instruction> | |
| 1692 // | Return <Value> | |
| 1693 // | Branch <Value> <Instruction> <Instruction> | |
| 1694 // <Definition> ::= Bind <int> <Computation> <Instruction> | |
| 1695 | 1685 |
| 1696 // M is a single argument macro. It is applied to each concrete instruction | 1686 // M is a single argument macro. It is applied to each concrete instruction |
| 1697 // type name. The concrete instruction classes are the name with Instr | 1687 // type name. The concrete instruction classes are the name with Instr |
| 1698 // concatenated. | 1688 // concatenated. |
| 1699 #define FOR_EACH_INSTRUCTION(M) \ | 1689 #define FOR_EACH_INSTRUCTION(M) \ |
| 1700 M(GraphEntry) \ | 1690 M(GraphEntry) \ |
| 1701 M(JoinEntry) \ | 1691 M(JoinEntry) \ |
| 1702 M(TargetEntry) \ | 1692 M(TargetEntry) \ |
| 1703 M(Do) \ | |
| 1704 M(Bind) \ | 1693 M(Bind) \ |
| 1705 M(Phi) \ | 1694 M(Phi) \ |
| 1706 M(Return) \ | 1695 M(Return) \ |
| 1707 M(Throw) \ | 1696 M(Throw) \ |
| 1708 M(ReThrow) \ | 1697 M(ReThrow) \ |
| 1709 M(Branch) \ | 1698 M(Branch) \ |
| 1710 M(ParallelMove) \ | 1699 M(ParallelMove) \ |
| 1711 M(Parameter) | 1700 M(Parameter) |
| 1712 | 1701 |
| 1713 | 1702 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1789 // Remove instruction from the graph and return the instruction following the | 1778 // Remove instruction from the graph and return the instruction following the |
| 1790 // removed instruction. | 1779 // removed instruction. |
| 1791 Instruction* RemoveFromGraph(); | 1780 Instruction* RemoveFromGraph(); |
| 1792 | 1781 |
| 1793 // Normal instructions can have 0 (inside a block) or 1 (last instruction in | 1782 // Normal instructions can have 0 (inside a block) or 1 (last instruction in |
| 1794 // a block) successors. Branch instruction with >1 successors override this | 1783 // a block) successors. Branch instruction with >1 successors override this |
| 1795 // function. | 1784 // function. |
| 1796 virtual intptr_t SuccessorCount() const; | 1785 virtual intptr_t SuccessorCount() const; |
| 1797 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; | 1786 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; |
| 1798 | 1787 |
| 1799 virtual void replace_computation(Computation* value) { | |
| 1800 UNREACHABLE(); | |
| 1801 } | |
| 1802 // Discover basic-block structure by performing a recursive depth first | 1788 // Discover basic-block structure by performing a recursive depth first |
| 1803 // traversal of the instruction graph reachable from this instruction. As | 1789 // traversal of the instruction graph reachable from this instruction. As |
| 1804 // a side effect, the block entry instructions in the graph are assigned | 1790 // a side effect, the block entry instructions in the graph are assigned |
| 1805 // numbers in both preorder and postorder. The array 'preorder' maps | 1791 // numbers in both preorder and postorder. The array 'preorder' maps |
| 1806 // preorder block numbers to the block entry instruction with that number | 1792 // preorder block numbers to the block entry instruction with that number |
| 1807 // and analogously for the array 'postorder'. The depth first spanning | 1793 // and analogously for the array 'postorder'. The depth first spanning |
| 1808 // tree is recorded in the array 'parent', which maps preorder block | 1794 // tree is recorded in the array 'parent', which maps preorder block |
| 1809 // numbers to the preorder number of the block's spanning-tree parent. | 1795 // numbers to the preorder number of the block's spanning-tree parent. |
| 1810 // The array 'assigned_vars' maps preorder block numbers to the set of | 1796 // The array 'assigned_vars' maps preorder block numbers to the set of |
| 1811 // assigned frame-allocated local variables in the block. As a side | 1797 // assigned frame-allocated local variables in the block. As a side |
| (...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2074 virtual void PrepareEntry(FlowGraphCompiler* compiler); | 2060 virtual void PrepareEntry(FlowGraphCompiler* compiler); |
| 2075 | 2061 |
| 2076 private: | 2062 private: |
| 2077 BlockEntryInstr* predecessor_; | 2063 BlockEntryInstr* predecessor_; |
| 2078 const intptr_t try_index_; | 2064 const intptr_t try_index_; |
| 2079 | 2065 |
| 2080 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr); | 2066 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr); |
| 2081 }; | 2067 }; |
| 2082 | 2068 |
| 2083 | 2069 |
| 2084 class DoInstr : public Instruction { | |
| 2085 public: | |
| 2086 explicit DoInstr(Computation* computation) | |
| 2087 : computation_(computation) { | |
| 2088 ASSERT(computation != NULL); | |
| 2089 computation->set_instr(this); | |
| 2090 } | |
| 2091 | |
| 2092 DECLARE_INSTRUCTION(Do) | |
| 2093 | |
| 2094 Computation* computation() const { return computation_; } | |
| 2095 virtual void replace_computation(Computation* value) { computation_ = value; } | |
| 2096 | |
| 2097 virtual void RecordAssignedVars(BitVector* assigned_vars); | |
| 2098 | |
| 2099 virtual LocationSummary* locs() { | |
| 2100 return computation()->locs(); | |
| 2101 } | |
| 2102 | |
| 2103 virtual void EmitNativeCode(FlowGraphCompiler* compiler) { | |
| 2104 computation()->EmitNativeCode(compiler); | |
| 2105 } | |
| 2106 | |
| 2107 private: | |
| 2108 Computation* computation_; | |
| 2109 | |
| 2110 DISALLOW_COPY_AND_ASSIGN(DoInstr); | |
| 2111 }; | |
| 2112 | |
| 2113 | |
| 2114 // Abstract super-class of all instructions that define a value (Bind, Phi). | 2070 // Abstract super-class of all instructions that define a value (Bind, Phi). |
| 2115 class Definition : public Instruction { | 2071 class Definition : public Instruction { |
| 2116 public: | 2072 public: |
| 2117 Definition() : temp_index_(-1), ssa_temp_index_(-1) { } | 2073 Definition() : temp_index_(-1), ssa_temp_index_(-1) { } |
| 2118 | 2074 |
| 2119 virtual bool IsDefinition() const { return true; } | 2075 virtual bool IsDefinition() const { return true; } |
| 2120 virtual Definition* AsDefinition() { return this; } | 2076 virtual Definition* AsDefinition() { return this; } |
| 2121 | 2077 |
| 2122 intptr_t temp_index() const { return temp_index_; } | 2078 intptr_t temp_index() const { return temp_index_; } |
| 2123 void set_temp_index(intptr_t index) { temp_index_ = index; } | 2079 void set_temp_index(intptr_t index) { temp_index_ = index; } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2135 | 2091 |
| 2136 Definition* UseVal::definition() const { | 2092 Definition* UseVal::definition() const { |
| 2137 // Check that the definition is either a Phi or a linked in the the IR. | 2093 // Check that the definition is either a Phi or a linked in the the IR. |
| 2138 ASSERT(definition_ != NULL); | 2094 ASSERT(definition_ != NULL); |
| 2139 return definition_; | 2095 return definition_; |
| 2140 } | 2096 } |
| 2141 | 2097 |
| 2142 | 2098 |
| 2143 class BindInstr : public Definition { | 2099 class BindInstr : public Definition { |
| 2144 public: | 2100 public: |
| 2145 explicit BindInstr(Computation* computation) | 2101 enum UseKind { kUnused, kUsed }; |
| 2146 : computation_(computation) { | 2102 |
| 2103 BindInstr(UseKind used, Computation* computation) |
| 2104 : computation_(computation), is_used_(used != kUnused) { |
| 2147 ASSERT(computation != NULL); | 2105 ASSERT(computation != NULL); |
| 2148 computation->set_instr(this); | 2106 computation->set_instr(this); |
| 2149 } | 2107 } |
| 2150 | 2108 |
| 2151 DECLARE_INSTRUCTION(Bind) | 2109 DECLARE_INSTRUCTION(Bind) |
| 2152 | 2110 |
| 2153 Computation* computation() const { return computation_; } | 2111 Computation* computation() const { return computation_; } |
| 2154 virtual void replace_computation(Computation* value) { computation_ = value; } | 2112 void replace_computation(Computation* value) { computation_ = value; } |
| 2113 bool is_used() const { return is_used_; } |
| 2155 | 2114 |
| 2156 // Static type of the underlying computation. | 2115 // Static type of the underlying computation. |
| 2157 virtual RawAbstractType* StaticType() const { | 2116 virtual RawAbstractType* StaticType() const { |
| 2158 return computation()->StaticType(); | 2117 return computation()->StaticType(); |
| 2159 } | 2118 } |
| 2160 | 2119 |
| 2161 virtual void RecordAssignedVars(BitVector* assigned_vars); | 2120 virtual void RecordAssignedVars(BitVector* assigned_vars); |
| 2162 | 2121 |
| 2163 virtual LocationSummary* locs() { | 2122 virtual LocationSummary* locs() { |
| 2164 return computation()->locs(); | 2123 return computation()->locs(); |
| 2165 } | 2124 } |
| 2166 | 2125 |
| 2167 virtual void EmitNativeCode(FlowGraphCompiler* compiler); | 2126 virtual void EmitNativeCode(FlowGraphCompiler* compiler); |
| 2168 | 2127 |
| 2169 private: | 2128 private: |
| 2170 Computation* computation_; | 2129 Computation* computation_; |
| 2130 bool is_used_; |
| 2171 | 2131 |
| 2172 DISALLOW_COPY_AND_ASSIGN(BindInstr); | 2132 DISALLOW_COPY_AND_ASSIGN(BindInstr); |
| 2173 }; | 2133 }; |
| 2174 | 2134 |
| 2175 | 2135 |
| 2176 class PhiInstr: public Definition { | 2136 class PhiInstr: public Definition { |
| 2177 public: | 2137 public: |
| 2178 explicit PhiInstr(intptr_t num_inputs) : inputs_(num_inputs) { | 2138 explicit PhiInstr(intptr_t num_inputs) : inputs_(num_inputs) { |
| 2179 for (intptr_t i = 0; i < num_inputs; ++i) { | 2139 for (intptr_t i = 0; i < num_inputs; ++i) { |
| 2180 inputs_.Add(NULL); | 2140 inputs_.Add(NULL); |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2436 const GrowableArray<BlockEntryInstr*>& block_order_; | 2396 const GrowableArray<BlockEntryInstr*>& block_order_; |
| 2437 | 2397 |
| 2438 private: | 2398 private: |
| 2439 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 2399 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
| 2440 }; | 2400 }; |
| 2441 | 2401 |
| 2442 | 2402 |
| 2443 } // namespace dart | 2403 } // namespace dart |
| 2444 | 2404 |
| 2445 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 2405 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
| OLD | NEW |