| 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_FLOW_GRAPH_BUILDER_H_ | 5 #ifndef VM_FLOW_GRAPH_BUILDER_H_ |
| 6 #define VM_FLOW_GRAPH_BUILDER_H_ | 6 #define VM_FLOW_GRAPH_BUILDER_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 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 119 Instruction* exit() const { return exit_; } | 119 Instruction* exit() const { return exit_; } |
| 120 | 120 |
| 121 bool is_empty() const { return entry_ == NULL; } | 121 bool is_empty() const { return entry_ == NULL; } |
| 122 bool is_open() const { return is_empty() || exit_ != NULL; } | 122 bool is_open() const { return is_empty() || exit_ != NULL; } |
| 123 | 123 |
| 124 void Bailout(const char* reason); | 124 void Bailout(const char* reason); |
| 125 void InlineBailout(const char* reason); | 125 void InlineBailout(const char* reason); |
| 126 | 126 |
| 127 // Append a graph fragment to this graph. Assumes this graph is open. | 127 // Append a graph fragment to this graph. Assumes this graph is open. |
| 128 void Append(const EffectGraphVisitor& other_fragment); | 128 void Append(const EffectGraphVisitor& other_fragment); |
| 129 // Append a definition that can have uses. Assumes this graph is open. | 129 // Append a computation with one use. Assumes this graph is open. |
| 130 Value* Bind(Definition* definition); | 130 Value* Bind(Computation* computation); |
| 131 // Append a computation with no uses. Assumes this graph is open. | 131 // Append a computation with no uses. Assumes this graph is open. |
| 132 void Do(Definition* definition); | 132 void Do(Computation* computation); |
| 133 // Append a single (non-Definition, non-Entry) instruction. Assumes this | 133 // Append a single (non-Definition, non-Entry) instruction. Assumes this |
| 134 // graph is open. | 134 // graph is open. |
| 135 void AddInstruction(Instruction* instruction); | 135 void AddInstruction(Instruction* instruction); |
| 136 // Append a Goto (unconditional control flow) instruction and close | 136 // Append a Goto (unconditional control flow) instruction and close |
| 137 // the graph fragment. Assumes this graph fragment is open. | 137 // the graph fragment. Assumes this graph fragment is open. |
| 138 void Goto(JoinEntryInstr* join); | 138 void Goto(JoinEntryInstr* join); |
| 139 | 139 |
| 140 // Append a 'diamond' branch and join to this graph, depending on which | 140 // Append a 'diamond' branch and join to this graph, depending on which |
| 141 // parts are reachable. Assumes this graph is open. | 141 // parts are reachable. Assumes this graph is open. |
| 142 void Join(const TestGraphVisitor& test_fragment, | 142 void Join(const TestGraphVisitor& test_fragment, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 154 PushArgumentInstr* PushArgument(Value* value); | 154 PushArgumentInstr* PushArgument(Value* value); |
| 155 | 155 |
| 156 // This implementation shares state among visitors by using the builder. | 156 // This implementation shares state among visitors by using the builder. |
| 157 // The implementation is incorrect if a visitor that hits a return is not | 157 // The implementation is incorrect if a visitor that hits a return is not |
| 158 // actually added to the graph. | 158 // actually added to the graph. |
| 159 void AddReturnExit(ReturnInstr* return_instr) { | 159 void AddReturnExit(ReturnInstr* return_instr) { |
| 160 owner()->AddReturnExit(return_instr); | 160 owner()->AddReturnExit(return_instr); |
| 161 } | 161 } |
| 162 | 162 |
| 163 protected: | 163 protected: |
| 164 Definition* BuildStoreLocal(const LocalVariable& local, Value* value); | 164 Computation* BuildStoreLocal(const LocalVariable& local, Value* value); |
| 165 Definition* BuildLoadLocal(const LocalVariable& local); | 165 Computation* BuildLoadLocal(const LocalVariable& local); |
| 166 | 166 |
| 167 // Helpers for translating parts of the AST. | 167 // Helpers for translating parts of the AST. |
| 168 void TranslateArgumentList(const ArgumentListNode& node, | 168 void TranslateArgumentList(const ArgumentListNode& node, |
| 169 ZoneGrowableArray<Value*>* values); | 169 ZoneGrowableArray<Value*>* values); |
| 170 void BuildPushArguments(const ArgumentListNode& node, | 170 void BuildPushArguments(const ArgumentListNode& node, |
| 171 ZoneGrowableArray<PushArgumentInstr*>* values); | 171 ZoneGrowableArray<PushArgumentInstr*>* values); |
| 172 | 172 |
| 173 // Creates an instantiated type argument vector used in preparation of an | 173 // Creates an instantiated type argument vector used in preparation of an |
| 174 // allocation call. | 174 // allocation call. |
| 175 // May be called only if allocating an object of a parameterized class. | 175 // May be called only if allocating an object of a parameterized class. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 188 ZoneGrowableArray<PushArgumentInstr*>* call_arguments); | 188 ZoneGrowableArray<PushArgumentInstr*>* call_arguments); |
| 189 | 189 |
| 190 void BuildTypecheckArguments(intptr_t token_pos, | 190 void BuildTypecheckArguments(intptr_t token_pos, |
| 191 Value** instantiator, | 191 Value** instantiator, |
| 192 Value** instantiator_type_arguments); | 192 Value** instantiator_type_arguments); |
| 193 Value* BuildInstantiator(); | 193 Value* BuildInstantiator(); |
| 194 Value* BuildInstantiatorTypeArguments(intptr_t token_pos, | 194 Value* BuildInstantiatorTypeArguments(intptr_t token_pos, |
| 195 Value* instantiator); | 195 Value* instantiator); |
| 196 | 196 |
| 197 // Perform a type check on the given value. | 197 // Perform a type check on the given value. |
| 198 AssertAssignableInstr* BuildAssertAssignable(intptr_t token_pos, | 198 AssertAssignableComp* BuildAssertAssignable(intptr_t token_pos, |
| 199 Value* value, | 199 Value* value, |
| 200 const AbstractType& dst_type, | 200 const AbstractType& dst_type, |
| 201 const String& dst_name); | 201 const String& dst_name); |
| 202 | 202 |
| 203 // Perform a type check on the given value and return it. | 203 // Perform a type check on the given value and return it. |
| 204 Value* BuildAssignableValue(intptr_t token_pos, | 204 Value* BuildAssignableValue(intptr_t token_pos, |
| 205 Value* value, | 205 Value* value, |
| 206 const AbstractType& dst_type, | 206 const AbstractType& dst_type, |
| 207 const String& dst_name); | 207 const String& dst_name); |
| 208 | 208 |
| 209 enum ResultKind { | 209 enum ResultKind { |
| 210 kResultNotNeeded, | 210 kResultNotNeeded, |
| 211 kResultNeeded | 211 kResultNeeded |
| 212 }; | 212 }; |
| 213 | 213 |
| 214 Definition* BuildStoreIndexedValues(StoreIndexedNode* node, | 214 Computation* BuildStoreIndexedValues(StoreIndexedNode* node, |
| 215 bool result_is_needed); | 215 bool result_is_needed); |
| 216 | 216 |
| 217 void BuildInstanceSetterArguments( | 217 void BuildInstanceSetterArguments( |
| 218 InstanceSetterNode* node, | 218 InstanceSetterNode* node, |
| 219 ZoneGrowableArray<PushArgumentInstr*>* arguments, | 219 ZoneGrowableArray<PushArgumentInstr*>* arguments, |
| 220 bool result_is_needed); | 220 bool result_is_needed); |
| 221 | 221 |
| 222 virtual void BuildTypeTest(ComparisonNode* node); | 222 virtual void BuildTypeTest(ComparisonNode* node); |
| 223 virtual void BuildTypeCast(ComparisonNode* node); | 223 virtual void BuildTypeCast(ComparisonNode* node); |
| 224 | 224 |
| 225 bool MustSaveRestoreContext(SequenceNode* node) const; | 225 bool MustSaveRestoreContext(SequenceNode* node) const; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 238 void BuildConstructorCall(ConstructorCallNode* node, | 238 void BuildConstructorCall(ConstructorCallNode* node, |
| 239 PushArgumentInstr* alloc_value); | 239 PushArgumentInstr* alloc_value); |
| 240 | 240 |
| 241 void BuildStoreContext(const LocalVariable& variable); | 241 void BuildStoreContext(const LocalVariable& variable); |
| 242 void BuildLoadContext(const LocalVariable& variable); | 242 void BuildLoadContext(const LocalVariable& variable); |
| 243 | 243 |
| 244 void BuildThrowNode(ThrowNode* node); | 244 void BuildThrowNode(ThrowNode* node); |
| 245 | 245 |
| 246 void BuildStaticSetter(StaticSetterNode* node, bool result_is_needed); | 246 void BuildStaticSetter(StaticSetterNode* node, bool result_is_needed); |
| 247 | 247 |
| 248 ClosureCallInstr* BuildClosureCall(ClosureCallNode* node); | 248 ClosureCallComp* BuildClosureCall(ClosureCallNode* node); |
| 249 | 249 |
| 250 Value* BuildNullValue(); | 250 Value* BuildNullValue(); |
| 251 | 251 |
| 252 private: | 252 private: |
| 253 // Specify a definition of the final result. Adds the definition to | 253 // Specify a computation as the final result. Adds a Do instruction to |
| 254 // the graph, but normally overridden in subclasses. | 254 // the graph, but normally overridden in subclasses. |
| 255 virtual void ReturnDefinition(Definition* definition) { | 255 virtual void ReturnComputation(Computation* computation) { |
| 256 Do(definition); | 256 Do(computation); |
| 257 } | 257 } |
| 258 | 258 |
| 259 // Returns true if the run-time type check can be eliminated. | 259 // Returns true if the run-time type check can be eliminated. |
| 260 bool CanSkipTypeCheck(intptr_t token_pos, | 260 bool CanSkipTypeCheck(intptr_t token_pos, |
| 261 Value* value, | 261 Value* value, |
| 262 const AbstractType& dst_type, | 262 const AbstractType& dst_type, |
| 263 const String& dst_name); | 263 const String& dst_name); |
| 264 | 264 |
| 265 // Shared global state. | 265 // Shared global state. |
| 266 FlowGraphBuilder* owner_; | 266 FlowGraphBuilder* owner_; |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 301 Value* value() const { return value_; } | 301 Value* value() const { return value_; } |
| 302 | 302 |
| 303 protected: | 303 protected: |
| 304 // Output parameters. | 304 // Output parameters. |
| 305 Value* value_; | 305 Value* value_; |
| 306 | 306 |
| 307 private: | 307 private: |
| 308 // Helper to set the output state to return a Value. | 308 // Helper to set the output state to return a Value. |
| 309 virtual void ReturnValue(Value* value) { value_ = value; } | 309 virtual void ReturnValue(Value* value) { value_ = value; } |
| 310 | 310 |
| 311 // Specify a definition of the final result. Adds the definition to | 311 // Specify a computation as the final result. Adds a Bind instruction to |
| 312 // the graph and returns a use of it (i.e., set the visitor's output | 312 // the graph and returns its temporary value (i.e., set the output |
| 313 // parameters). | 313 // parameters). |
| 314 virtual void ReturnDefinition(Definition* definition) { | 314 virtual void ReturnComputation(Computation* computation) { |
| 315 ReturnValue(Bind(definition)); | 315 ReturnValue(Bind(computation)); |
| 316 } | 316 } |
| 317 | 317 |
| 318 virtual void BuildTypeTest(ComparisonNode* node); | 318 virtual void BuildTypeTest(ComparisonNode* node); |
| 319 virtual void BuildTypeCast(ComparisonNode* node); | 319 virtual void BuildTypeCast(ComparisonNode* node); |
| 320 }; | 320 }; |
| 321 | 321 |
| 322 | 322 |
| 323 // Translate an AstNode to a control-flow graph fragment for both its | 323 // Translate an AstNode to a control-flow graph fragment for both its |
| 324 // effects and true/false control flow (e.g., for an expression in a test | 324 // effects and true/false control flow (e.g., for an expression in a test |
| 325 // context). The resulting graph is always closed (even if it is empty) | 325 // context). The resulting graph is always closed (even if it is empty) |
| (...skipping 30 matching lines...) Expand all Loading... |
| 356 return false_successor_address_; | 356 return false_successor_address_; |
| 357 } | 357 } |
| 358 | 358 |
| 359 intptr_t condition_token_pos() const { return condition_token_pos_; } | 359 intptr_t condition_token_pos() const { return condition_token_pos_; } |
| 360 | 360 |
| 361 private: | 361 private: |
| 362 // Construct and concatenate a Branch instruction to this graph fragment. | 362 // Construct and concatenate a Branch instruction to this graph fragment. |
| 363 // Closes the fragment and sets the output parameters. | 363 // Closes the fragment and sets the output parameters. |
| 364 virtual void ReturnValue(Value* value); | 364 virtual void ReturnValue(Value* value); |
| 365 | 365 |
| 366 // Either merges the definition into a BranchInstr (Comparison, BooleanNegate) | 366 // Either merges the computation into BranchInstr (Comparison, BooleanNegate) |
| 367 // or adds the definition to the graph and returns a use of its value. | 367 // or adds a Bind instruction to the graph and returns its temporary value. |
| 368 virtual void ReturnDefinition(Definition* definition); | 368 virtual void ReturnComputation(Computation* computation); |
| 369 | 369 |
| 370 void MergeBranchWithComparison(ComparisonInstr* comp); | 370 void MergeBranchWithComparison(ComparisonComp* comp); |
| 371 void MergeBranchWithNegate(BooleanNegateInstr* comp); | 371 void MergeBranchWithNegate(BooleanNegateComp* comp); |
| 372 | 372 |
| 373 // Output parameters. | 373 // Output parameters. |
| 374 TargetEntryInstr** true_successor_address_; | 374 TargetEntryInstr** true_successor_address_; |
| 375 TargetEntryInstr** false_successor_address_; | 375 TargetEntryInstr** false_successor_address_; |
| 376 | 376 |
| 377 intptr_t condition_token_pos_; | 377 intptr_t condition_token_pos_; |
| 378 }; | 378 }; |
| 379 | 379 |
| 380 } // namespace dart | 380 } // namespace dart |
| 381 | 381 |
| 382 #endif // VM_FLOW_GRAPH_BUILDER_H_ | 382 #endif // VM_FLOW_GRAPH_BUILDER_H_ |
| OLD | NEW |