Chromium Code Reviews| 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 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 174 virtual ComparisonComp* AsComparison() { return NULL; } | 174 virtual ComparisonComp* AsComparison() { return NULL; } |
| 175 | 175 |
| 176 // Create a location summary for this computation. | 176 // Create a location summary for this computation. |
| 177 // TODO(fschneider): Temporarily returns NULL for instructions | 177 // TODO(fschneider): Temporarily returns NULL for instructions |
| 178 // that are not yet converted to the location based code generation. | 178 // that are not yet converted to the location based code generation. |
| 179 virtual LocationSummary* MakeLocationSummary() const = 0; | 179 virtual LocationSummary* MakeLocationSummary() const = 0; |
| 180 | 180 |
| 181 // TODO(fschneider): Make EmitNativeCode and locs const. | 181 // TODO(fschneider): Make EmitNativeCode and locs const. |
| 182 virtual void EmitNativeCode(FlowGraphCompiler* compiler) = 0; | 182 virtual void EmitNativeCode(FlowGraphCompiler* compiler) = 0; |
| 183 | 183 |
| 184 virtual void RemoveFromDefUseChain() = 0; | |
| 185 | |
| 184 static LocationSummary* MakeCallSummary(); | 186 static LocationSummary* MakeCallSummary(); |
| 185 | 187 |
| 186 // Declare an enum value used to define type-test predicates. | 188 // Declare an enum value used to define type-test predicates. |
| 187 enum ComputationType { | 189 enum ComputationType { |
| 188 #define DECLARE_COMPUTATION_TYPE(ShortName, ClassName) k##ShortName, | 190 #define DECLARE_COMPUTATION_TYPE(ShortName, ClassName) k##ShortName, |
| 189 | 191 |
| 190 FOR_EACH_COMPUTATION(DECLARE_COMPUTATION_TYPE) | 192 FOR_EACH_COMPUTATION(DECLARE_COMPUTATION_TYPE) |
| 191 | 193 |
| 192 #undef DECLARE_COMPUTATION_TYPE | 194 #undef DECLARE_COMPUTATION_TYPE |
| 193 }; | 195 }; |
| (...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 262 }; | 264 }; |
| 263 | 265 |
| 264 | 266 |
| 265 template<intptr_t N> | 267 template<intptr_t N> |
| 266 class TemplateComputation : public Computation { | 268 class TemplateComputation : public Computation { |
| 267 public: | 269 public: |
| 268 virtual intptr_t InputCount() const { return N; } | 270 virtual intptr_t InputCount() const { return N; } |
| 269 virtual Value* InputAt(intptr_t i) const { return inputs_[i]; } | 271 virtual Value* InputAt(intptr_t i) const { return inputs_[i]; } |
| 270 virtual void SetInputAt(intptr_t i, Value* value) { inputs_[i] = value; } | 272 virtual void SetInputAt(intptr_t i, Value* value) { inputs_[i] = value; } |
| 271 | 273 |
| 274 virtual void RemoveFromDefUseChain() { | |
| 275 for (intptr_t i = 0; i < N; ++i) inputs_[i]->RemoveFromDefUseChain(); | |
|
srdjan
2012/08/09 20:07:52
Can some inputs be NULL? Maybe:
if (inputs_[i] !=
zerny-google
2012/08/10 08:08:29
Indeed, thanks. It is tempting to assert non-null
| |
| 276 } | |
| 277 | |
| 272 protected: | 278 protected: |
| 273 EmbeddedArray<Value*, N> inputs_; | 279 EmbeddedArray<Value*, N> inputs_; |
| 274 }; | 280 }; |
| 275 | 281 |
| 276 | 282 |
| 277 class Value : public TemplateComputation<0> { | 283 class Value : public TemplateComputation<0> { |
| 278 public: | 284 public: |
| 279 Value() { } | 285 Value() { } |
| 280 | 286 |
| 281 bool StaticTypeIsMoreSpecificThan(const AbstractType& dst_type) const; | 287 bool StaticTypeIsMoreSpecificThan(const AbstractType& dst_type) const; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 313 virtual RawAbstractType* StaticType() const; \ | 319 virtual RawAbstractType* StaticType() const; \ |
| 314 virtual LocationSummary* MakeLocationSummary() const; \ | 320 virtual LocationSummary* MakeLocationSummary() const; \ |
| 315 virtual void EmitNativeCode(FlowGraphCompiler* compiler); | 321 virtual void EmitNativeCode(FlowGraphCompiler* compiler); |
| 316 | 322 |
| 317 | 323 |
| 318 class Definition; | 324 class Definition; |
| 319 class PhiInstr; | 325 class PhiInstr; |
| 320 | 326 |
| 321 class UseVal : public Value { | 327 class UseVal : public Value { |
| 322 public: | 328 public: |
| 323 explicit UseVal(Definition* definition) : definition_(definition) {} | 329 explicit UseVal(Definition* definition); |
| 324 | 330 |
| 325 DECLARE_VALUE(Use) | 331 DECLARE_VALUE(Use) |
| 326 | 332 |
| 327 inline Definition* definition() const; | 333 inline Definition* definition() const; |
| 328 void set_definition(Definition* definition) { | 334 void set_definition(Definition* definition); |
|
srdjan
2012/08/09 20:07:52
s/set_definition/SetDefinition/
zerny-google
2012/08/10 08:08:29
Ok.
| |
| 329 definition_ = definition; | |
| 330 } | |
| 331 | 335 |
| 332 virtual bool CanDeoptimize() const { return false; } | 336 virtual bool CanDeoptimize() const { return false; } |
| 333 | 337 |
| 338 UseVal* next_use() { return next_use_; } | |
|
Florian Schneider
2012/08/10 08:35:37
Maybe add const:
UseVal* next_use() const { retur
| |
| 339 UseVal* previous_use() { return previous_use_; } | |
|
Florian Schneider
2012/08/10 08:35:37
Const here as well.
| |
| 340 virtual void RemoveFromDefUseChain(); | |
| 341 | |
| 334 private: | 342 private: |
| 343 void AddToDefUseChain(); | |
| 335 Definition* definition_; | 344 Definition* definition_; |
| 345 UseVal* next_use_; | |
| 346 UseVal* previous_use_; | |
| 336 | 347 |
| 337 DISALLOW_COPY_AND_ASSIGN(UseVal); | 348 DISALLOW_COPY_AND_ASSIGN(UseVal); |
| 338 }; | 349 }; |
| 339 | 350 |
| 340 | 351 |
| 341 class ConstantVal: public Value { | 352 class ConstantVal: public Value { |
| 342 public: | 353 public: |
| 343 explicit ConstantVal(const Object& value) | 354 explicit ConstantVal(const Object& value) |
| 344 : value_(value) { | 355 : value_(value) { |
| 345 ASSERT(value.IsZoneHandle()); | 356 ASSERT(value.IsZoneHandle()); |
| (...skipping 769 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1115 virtual intptr_t InputCount() const; | 1126 virtual intptr_t InputCount() const; |
| 1116 virtual Value* InputAt(intptr_t i) const { return arguments()[i]; } | 1127 virtual Value* InputAt(intptr_t i) const { return arguments()[i]; } |
| 1117 virtual void SetInputAt(intptr_t i, Value* value) { | 1128 virtual void SetInputAt(intptr_t i, Value* value) { |
| 1118 (*arguments_)[i] = value; | 1129 (*arguments_)[i] = value; |
| 1119 } | 1130 } |
| 1120 | 1131 |
| 1121 virtual void PrintOperandsTo(BufferFormatter* f) const; | 1132 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 1122 | 1133 |
| 1123 virtual bool CanDeoptimize() const { return false; } | 1134 virtual bool CanDeoptimize() const { return false; } |
| 1124 | 1135 |
| 1136 virtual void RemoveFromDefUseChain() { | |
| 1137 // TODO(zerny): why are we using an array here? | |
|
Florian Schneider
2012/08/10 08:35:37
You're right, we actually don't need to have an ar
| |
| 1138 arguments()[0]->RemoveFromDefUseChain(); | |
| 1139 arguments()[1]->RemoveFromDefUseChain(); | |
| 1140 } | |
| 1141 | |
| 1125 private: | 1142 private: |
| 1126 const ConstructorCallNode& ast_node_; | 1143 const ConstructorCallNode& ast_node_; |
| 1127 const intptr_t try_index_; | 1144 const intptr_t try_index_; |
| 1128 ZoneGrowableArray<Value*>* const arguments_; | 1145 ZoneGrowableArray<Value*>* const arguments_; |
| 1129 DISALLOW_COPY_AND_ASSIGN(AllocateObjectComp); | 1146 DISALLOW_COPY_AND_ASSIGN(AllocateObjectComp); |
| 1130 }; | 1147 }; |
| 1131 | 1148 |
| 1132 | 1149 |
| 1133 class AllocateObjectWithBoundsCheckComp : public Computation { | 1150 class AllocateObjectWithBoundsCheckComp : public Computation { |
| 1134 public: | 1151 public: |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 1150 virtual intptr_t InputCount() const; | 1167 virtual intptr_t InputCount() const; |
| 1151 virtual Value* InputAt(intptr_t i) const { return arguments()[i]; } | 1168 virtual Value* InputAt(intptr_t i) const { return arguments()[i]; } |
| 1152 virtual void SetInputAt(intptr_t i, Value* value) { | 1169 virtual void SetInputAt(intptr_t i, Value* value) { |
| 1153 (*arguments_)[i] = value; | 1170 (*arguments_)[i] = value; |
| 1154 } | 1171 } |
| 1155 | 1172 |
| 1156 virtual void PrintOperandsTo(BufferFormatter* f) const; | 1173 virtual void PrintOperandsTo(BufferFormatter* f) const; |
| 1157 | 1174 |
| 1158 virtual bool CanDeoptimize() const { return false; } | 1175 virtual bool CanDeoptimize() const { return false; } |
| 1159 | 1176 |
| 1177 virtual void RemoveFromDefUseChain() { | |
| 1178 // TODO(zerny): why are we using an array here? | |
| 1179 arguments()[0]->RemoveFromDefUseChain(); | |
| 1180 arguments()[1]->RemoveFromDefUseChain(); | |
| 1181 } | |
| 1182 | |
| 1160 private: | 1183 private: |
| 1161 const ConstructorCallNode& ast_node_; | 1184 const ConstructorCallNode& ast_node_; |
| 1162 const intptr_t try_index_; | 1185 const intptr_t try_index_; |
| 1163 ZoneGrowableArray<Value*>* const arguments_; | 1186 ZoneGrowableArray<Value*>* const arguments_; |
| 1164 DISALLOW_COPY_AND_ASSIGN(AllocateObjectWithBoundsCheckComp); | 1187 DISALLOW_COPY_AND_ASSIGN(AllocateObjectWithBoundsCheckComp); |
| 1165 }; | 1188 }; |
| 1166 | 1189 |
| 1167 | 1190 |
| 1168 class CreateArrayComp : public TemplateComputation<1> { | 1191 class CreateArrayComp : public TemplateComputation<1> { |
| 1169 public: | 1192 public: |
| (...skipping 608 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1778 ASSERT(instr == NULL || !instr->IsBlockEntry()); | 1801 ASSERT(instr == NULL || !instr->IsBlockEntry()); |
| 1779 // TODO(fschneider): Also add Throw and ReThrow to the list of instructions | 1802 // TODO(fschneider): Also add Throw and ReThrow to the list of instructions |
| 1780 // that do not have a successor. Currently, the graph builder will continue | 1803 // that do not have a successor. Currently, the graph builder will continue |
| 1781 // to append instruction in case of a Throw inside an expression. This | 1804 // to append instruction in case of a Throw inside an expression. This |
| 1782 // condition should be handled in the graph builder | 1805 // condition should be handled in the graph builder |
| 1783 next_ = instr; | 1806 next_ = instr; |
| 1784 } | 1807 } |
| 1785 | 1808 |
| 1786 // Removed this instruction from the graph. | 1809 // Removed this instruction from the graph. |
| 1787 Instruction* RemoveFromGraph(bool return_previous = true); | 1810 Instruction* RemoveFromGraph(bool return_previous = true); |
| 1811 // Remove uses in this instruction from the def-use chains. | |
| 1812 void RemoveFromDefUseChain(); | |
|
Florian Schneider
2012/08/10 08:35:37
This is a declaration without a definition. Is the
| |
| 1788 | 1813 |
| 1789 // Normal instructions can have 0 (inside a block) or 1 (last instruction in | 1814 // Normal instructions can have 0 (inside a block) or 1 (last instruction in |
| 1790 // a block) successors. Branch instruction with >1 successors override this | 1815 // a block) successors. Branch instruction with >1 successors override this |
| 1791 // function. | 1816 // function. |
| 1792 virtual intptr_t SuccessorCount() const; | 1817 virtual intptr_t SuccessorCount() const; |
| 1793 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; | 1818 virtual BlockEntryInstr* SuccessorAt(intptr_t index) const; |
| 1794 | 1819 |
| 1795 void Goto(JoinEntryInstr* entry); | 1820 void Goto(JoinEntryInstr* entry); |
| 1796 | 1821 |
| 1797 // Discover basic-block structure by performing a recursive depth first | 1822 // Discover basic-block structure by performing a recursive depth first |
| (...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1875 | 1900 |
| 1876 virtual LocationSummary* locs() { | 1901 virtual LocationSummary* locs() { |
| 1877 if (locs_ == NULL) { | 1902 if (locs_ == NULL) { |
| 1878 locs_ = MakeLocationSummary(); | 1903 locs_ = MakeLocationSummary(); |
| 1879 } | 1904 } |
| 1880 return locs_; | 1905 return locs_; |
| 1881 } | 1906 } |
| 1882 | 1907 |
| 1883 virtual LocationSummary* MakeLocationSummary() const = 0; | 1908 virtual LocationSummary* MakeLocationSummary() const = 0; |
| 1884 | 1909 |
| 1910 virtual void RemoveFromDefUseChain() { | |
| 1911 for (intptr_t i = 0; i < N; ++i) inputs_[i]->RemoveFromDefUseChain(); | |
|
srdjan
2012/08/09 20:07:52
San some inputs_[i] ne NULL?
| |
| 1912 } | |
| 1913 | |
| 1885 protected: | 1914 protected: |
| 1886 EmbeddedArray<Value*, N> inputs_; | 1915 EmbeddedArray<Value*, N> inputs_; |
| 1887 | 1916 |
| 1888 private: | 1917 private: |
| 1889 LocationSummary* locs_; | 1918 LocationSummary* locs_; |
| 1890 }; | 1919 }; |
| 1891 | 1920 |
| 1892 | 1921 |
| 1893 class MoveOperands : public ZoneAllocated { | 1922 class MoveOperands : public ZoneAllocated { |
| 1894 public: | 1923 public: |
| (...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2272 BlockEntryInstr* predecessor_; | 2301 BlockEntryInstr* predecessor_; |
| 2273 const intptr_t try_index_; | 2302 const intptr_t try_index_; |
| 2274 | 2303 |
| 2275 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr); | 2304 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr); |
| 2276 }; | 2305 }; |
| 2277 | 2306 |
| 2278 | 2307 |
| 2279 // Abstract super-class of all instructions that define a value (Bind, Phi). | 2308 // Abstract super-class of all instructions that define a value (Bind, Phi). |
| 2280 class Definition : public Instruction { | 2309 class Definition : public Instruction { |
| 2281 public: | 2310 public: |
| 2282 Definition() : temp_index_(-1), ssa_temp_index_(-1) { } | 2311 Definition() : temp_index_(-1), ssa_temp_index_(-1), def_use_chain_(NULL) { } |
| 2283 | 2312 |
| 2284 virtual bool IsDefinition() const { return true; } | 2313 virtual bool IsDefinition() const { return true; } |
| 2285 virtual Definition* AsDefinition() { return this; } | 2314 virtual Definition* AsDefinition() { return this; } |
| 2286 | 2315 |
| 2287 intptr_t temp_index() const { return temp_index_; } | 2316 intptr_t temp_index() const { return temp_index_; } |
| 2288 void set_temp_index(intptr_t index) { temp_index_ = index; } | 2317 void set_temp_index(intptr_t index) { temp_index_ = index; } |
| 2289 | 2318 |
| 2290 intptr_t ssa_temp_index() const { return ssa_temp_index_; } | 2319 intptr_t ssa_temp_index() const { return ssa_temp_index_; } |
| 2291 void set_ssa_temp_index(intptr_t index) { | 2320 void set_ssa_temp_index(intptr_t index) { |
| 2292 ASSERT(index >= 0); | 2321 ASSERT(index >= 0); |
| 2293 ssa_temp_index_ = index; | 2322 ssa_temp_index_ = index; |
| 2294 } | 2323 } |
| 2295 bool HasSSATemp() const { return ssa_temp_index_ >= 0; } | 2324 bool HasSSATemp() const { return ssa_temp_index_ >= 0; } |
| 2296 | 2325 |
| 2297 // Static type of the definition. | 2326 // Static type of the definition. |
| 2298 virtual RawAbstractType* StaticType() const = 0; | 2327 virtual RawAbstractType* StaticType() const = 0; |
| 2299 | 2328 |
| 2329 UseVal* def_use_chain() { return def_use_chain_; } | |
| 2330 void set_def_use_chain(UseVal* chain) { def_use_chain_ = chain; } | |
|
srdjan
2012/08/09 20:07:52
Should you assert that chain is head (previous is
zerny-google
2012/08/10 08:08:29
Sure.
| |
| 2331 | |
| 2300 private: | 2332 private: |
| 2301 intptr_t temp_index_; | 2333 intptr_t temp_index_; |
| 2302 intptr_t ssa_temp_index_; | 2334 intptr_t ssa_temp_index_; |
| 2335 UseVal* def_use_chain_; | |
|
srdjan
2012/08/09 20:07:52
This is a chain of uses only, isn't it? Maybe rena
zerny-google
2012/08/10 08:08:29
Ok. What about use_list?
| |
| 2303 | 2336 |
| 2304 DISALLOW_COPY_AND_ASSIGN(Definition); | 2337 DISALLOW_COPY_AND_ASSIGN(Definition); |
| 2305 }; | 2338 }; |
| 2306 | 2339 |
| 2307 | 2340 |
| 2308 Definition* UseVal::definition() const { | 2341 Definition* UseVal::definition() const { |
| 2309 // Check that the definition is either a Phi or a linked in the the IR. | 2342 // Check that the definition is either a Phi or a linked in the the IR. |
| 2310 ASSERT(definition_ != NULL); | 2343 ASSERT(definition_ != NULL); |
| 2311 return definition_; | 2344 return definition_; |
| 2312 } | 2345 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2347 | 2380 |
| 2348 virtual void RecordAssignedVars(BitVector* assigned_vars, | 2381 virtual void RecordAssignedVars(BitVector* assigned_vars, |
| 2349 intptr_t fixed_parameter_count); | 2382 intptr_t fixed_parameter_count); |
| 2350 | 2383 |
| 2351 virtual LocationSummary* locs() { | 2384 virtual LocationSummary* locs() { |
| 2352 return computation()->locs(); | 2385 return computation()->locs(); |
| 2353 } | 2386 } |
| 2354 | 2387 |
| 2355 virtual void EmitNativeCode(FlowGraphCompiler* compiler); | 2388 virtual void EmitNativeCode(FlowGraphCompiler* compiler); |
| 2356 | 2389 |
| 2390 virtual void RemoveFromDefUseChain() { | |
| 2391 computation_->RemoveFromDefUseChain(); | |
| 2392 } | |
| 2393 | |
| 2357 private: | 2394 private: |
| 2358 Computation* computation_; | 2395 Computation* computation_; |
| 2359 const bool is_used_; | 2396 const bool is_used_; |
| 2360 | 2397 |
| 2361 DISALLOW_COPY_AND_ASSIGN(BindInstr); | 2398 DISALLOW_COPY_AND_ASSIGN(BindInstr); |
| 2362 }; | 2399 }; |
| 2363 | 2400 |
| 2364 | 2401 |
| 2365 class PhiInstr : public Definition { | 2402 class PhiInstr : public Definition { |
| 2366 public: | 2403 public: |
| (...skipping 398 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2765 const GrowableArray<BlockEntryInstr*>& block_order_; | 2802 const GrowableArray<BlockEntryInstr*>& block_order_; |
| 2766 | 2803 |
| 2767 private: | 2804 private: |
| 2768 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 2805 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
| 2769 }; | 2806 }; |
| 2770 | 2807 |
| 2771 | 2808 |
| 2772 } // namespace dart | 2809 } // namespace dart |
| 2773 | 2810 |
| 2774 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 2811 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
| OLD | NEW |