| 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 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 57 }; | 57 }; |
| 58 | 58 |
| 59 | 59 |
| 60 // Build a flow graph from a parsed function's AST. | 60 // Build a flow graph from a parsed function's AST. |
| 61 class FlowGraphBuilder: public ValueObject { | 61 class FlowGraphBuilder: public ValueObject { |
| 62 public: | 62 public: |
| 63 // The inlining context is NULL if not inlining. | 63 // The inlining context is NULL if not inlining. |
| 64 FlowGraphBuilder(const ParsedFunction& parsed_function, | 64 FlowGraphBuilder(const ParsedFunction& parsed_function, |
| 65 InliningContext* inlining_context); | 65 InliningContext* inlining_context); |
| 66 | 66 |
| 67 FlowGraph* BuildGraph(intptr_t initial_loop_depth); | 67 FlowGraph* BuildGraph(); |
| 68 | 68 |
| 69 const ParsedFunction& parsed_function() const { return parsed_function_; } | 69 const ParsedFunction& parsed_function() const { return parsed_function_; } |
| 70 | 70 |
| 71 void Bailout(const char* reason); | 71 void Bailout(const char* reason); |
| 72 | 72 |
| 73 intptr_t AllocateBlockId() { return ++last_used_block_id_; } | 73 intptr_t AllocateBlockId() { return ++last_used_block_id_; } |
| 74 void SetInitialBlockId(intptr_t id) { last_used_block_id_ = id; } | 74 void SetInitialBlockId(intptr_t id) { last_used_block_id_ = id; } |
| 75 | 75 |
| 76 void set_context_level(intptr_t value) { context_level_ = value; } | 76 void set_context_level(intptr_t value) { context_level_ = value; } |
| 77 intptr_t context_level() const { return context_level_; } | 77 intptr_t context_level() const { return context_level_; } |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 // function from an AstNode and next temporary index to a graph fragment | 130 // function from an AstNode and next temporary index to a graph fragment |
| 131 // with a single entry and at most one exit. The fragment is represented by | 131 // with a single entry and at most one exit. The fragment is represented by |
| 132 // an (entry, exit) pair of Instruction pointers: | 132 // an (entry, exit) pair of Instruction pointers: |
| 133 // | 133 // |
| 134 // - (NULL, NULL): an empty and open graph fragment | 134 // - (NULL, NULL): an empty and open graph fragment |
| 135 // - (i0, NULL): a closed graph fragment which has only non-local exits | 135 // - (i0, NULL): a closed graph fragment which has only non-local exits |
| 136 // - (i0, i1): an open graph fragment | 136 // - (i0, i1): an open graph fragment |
| 137 class EffectGraphVisitor : public AstNodeVisitor { | 137 class EffectGraphVisitor : public AstNodeVisitor { |
| 138 public: | 138 public: |
| 139 EffectGraphVisitor(FlowGraphBuilder* owner, | 139 EffectGraphVisitor(FlowGraphBuilder* owner, |
| 140 intptr_t temp_index, | 140 intptr_t temp_index) |
| 141 intptr_t loop_depth) | |
| 142 : owner_(owner), | 141 : owner_(owner), |
| 143 temp_index_(temp_index), | 142 temp_index_(temp_index), |
| 144 entry_(NULL), | 143 entry_(NULL), |
| 145 exit_(NULL), | 144 exit_(NULL) { } |
| 146 loop_depth_(loop_depth) { } | |
| 147 | 145 |
| 148 #define DEFINE_VISIT(type, name) virtual void Visit##type(type* node); | 146 #define DEFINE_VISIT(type, name) virtual void Visit##type(type* node); |
| 149 NODE_LIST(DEFINE_VISIT) | 147 NODE_LIST(DEFINE_VISIT) |
| 150 #undef DEFINE_VISIT | 148 #undef DEFINE_VISIT |
| 151 | 149 |
| 152 FlowGraphBuilder* owner() const { return owner_; } | 150 FlowGraphBuilder* owner() const { return owner_; } |
| 153 intptr_t temp_index() const { return temp_index_; } | 151 intptr_t temp_index() const { return temp_index_; } |
| 154 intptr_t loop_depth() const { return loop_depth_; } | |
| 155 Instruction* entry() const { return entry_; } | 152 Instruction* entry() const { return entry_; } |
| 156 Instruction* exit() const { return exit_; } | 153 Instruction* exit() const { return exit_; } |
| 157 | 154 |
| 158 bool is_empty() const { return entry_ == NULL; } | 155 bool is_empty() const { return entry_ == NULL; } |
| 159 bool is_open() const { return is_empty() || exit_ != NULL; } | 156 bool is_open() const { return is_empty() || exit_ != NULL; } |
| 160 | 157 |
| 161 void Bailout(const char* reason); | 158 void Bailout(const char* reason); |
| 162 void InlineBailout(const char* reason); | 159 void InlineBailout(const char* reason); |
| 163 | 160 |
| 164 // Append a graph fragment to this graph. Assumes this graph is open. | 161 // Append a graph fragment to this graph. Assumes this graph is open. |
| (...skipping 156 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 | 318 |
| 322 // Shared global state. | 319 // Shared global state. |
| 323 FlowGraphBuilder* owner_; | 320 FlowGraphBuilder* owner_; |
| 324 | 321 |
| 325 // Input parameters. | 322 // Input parameters. |
| 326 intptr_t temp_index_; | 323 intptr_t temp_index_; |
| 327 | 324 |
| 328 // Output parameters. | 325 // Output parameters. |
| 329 Instruction* entry_; | 326 Instruction* entry_; |
| 330 Instruction* exit_; | 327 Instruction* exit_; |
| 331 | |
| 332 // Internal state. | |
| 333 const intptr_t loop_depth_; | |
| 334 }; | 328 }; |
| 335 | 329 |
| 336 | 330 |
| 337 // Translate an AstNode to a control-flow graph fragment for both its effects | 331 // Translate an AstNode to a control-flow graph fragment for both its effects |
| 338 // and value (e.g., for an expression in a value context). Implements a | 332 // and value (e.g., for an expression in a value context). Implements a |
| 339 // function from an AstNode and next temporary index to a graph fragment (as | 333 // function from an AstNode and next temporary index to a graph fragment (as |
| 340 // in the EffectGraphVisitor), a next temporary index, and an intermediate | 334 // in the EffectGraphVisitor), a next temporary index, and an intermediate |
| 341 // language Value. | 335 // language Value. |
| 342 class ValueGraphVisitor : public EffectGraphVisitor { | 336 class ValueGraphVisitor : public EffectGraphVisitor { |
| 343 public: | 337 public: |
| 344 ValueGraphVisitor(FlowGraphBuilder* owner, | 338 ValueGraphVisitor(FlowGraphBuilder* owner, |
| 345 intptr_t temp_index, | 339 intptr_t temp_index) |
| 346 intptr_t loop_depth) | 340 : EffectGraphVisitor(owner, temp_index), value_(NULL) { } |
| 347 : EffectGraphVisitor(owner, temp_index, loop_depth), value_(NULL) { } | |
| 348 | 341 |
| 349 // Visit functions overridden by this class. | 342 // Visit functions overridden by this class. |
| 350 virtual void VisitLiteralNode(LiteralNode* node); | 343 virtual void VisitLiteralNode(LiteralNode* node); |
| 351 virtual void VisitAssignableNode(AssignableNode* node); | 344 virtual void VisitAssignableNode(AssignableNode* node); |
| 352 virtual void VisitConstructorCallNode(ConstructorCallNode* node); | 345 virtual void VisitConstructorCallNode(ConstructorCallNode* node); |
| 353 virtual void VisitBinaryOpNode(BinaryOpNode* node); | 346 virtual void VisitBinaryOpNode(BinaryOpNode* node); |
| 354 virtual void VisitConditionalExprNode(ConditionalExprNode* node); | 347 virtual void VisitConditionalExprNode(ConditionalExprNode* node); |
| 355 virtual void VisitLoadLocalNode(LoadLocalNode* node); | 348 virtual void VisitLoadLocalNode(LoadLocalNode* node); |
| 356 virtual void VisitStoreLocalNode(StoreLocalNode* node); | 349 virtual void VisitStoreLocalNode(StoreLocalNode* node); |
| 357 virtual void VisitStoreIndexedNode(StoreIndexedNode* node); | 350 virtual void VisitStoreIndexedNode(StoreIndexedNode* node); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 399 // | 392 // |
| 400 // We expect that AstNode in test contexts either have only nonlocal exits | 393 // We expect that AstNode in test contexts either have only nonlocal exits |
| 401 // or else control flow has both true and false successors. | 394 // or else control flow has both true and false successors. |
| 402 // | 395 // |
| 403 // The cis and token_pos are used in checked mode to verify that the | 396 // The cis and token_pos are used in checked mode to verify that the |
| 404 // condition of the test is of type bool. | 397 // condition of the test is of type bool. |
| 405 class TestGraphVisitor : public ValueGraphVisitor { | 398 class TestGraphVisitor : public ValueGraphVisitor { |
| 406 public: | 399 public: |
| 407 TestGraphVisitor(FlowGraphBuilder* owner, | 400 TestGraphVisitor(FlowGraphBuilder* owner, |
| 408 intptr_t temp_index, | 401 intptr_t temp_index, |
| 409 intptr_t loop_depth, | |
| 410 intptr_t condition_token_pos) | 402 intptr_t condition_token_pos) |
| 411 : ValueGraphVisitor(owner, temp_index, loop_depth), | 403 : ValueGraphVisitor(owner, temp_index), |
| 412 true_successor_addresses_(1), | 404 true_successor_addresses_(1), |
| 413 false_successor_addresses_(1), | 405 false_successor_addresses_(1), |
| 414 condition_token_pos_(condition_token_pos) { } | 406 condition_token_pos_(condition_token_pos) { } |
| 415 | 407 |
| 416 void IfFalseGoto(JoinEntryInstr* join) const; | 408 void IfFalseGoto(JoinEntryInstr* join) const; |
| 417 void IfTrueGoto(JoinEntryInstr* join) const; | 409 void IfTrueGoto(JoinEntryInstr* join) const; |
| 418 | 410 |
| 419 BlockEntryInstr* CreateTrueSuccessor() const; | 411 BlockEntryInstr* CreateTrueSuccessor() const; |
| 420 BlockEntryInstr* CreateFalseSuccessor() const; | 412 BlockEntryInstr* CreateFalseSuccessor() const; |
| 421 | 413 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 445 // Output parameters. | 437 // Output parameters. |
| 446 GrowableArray<TargetEntryInstr**> true_successor_addresses_; | 438 GrowableArray<TargetEntryInstr**> true_successor_addresses_; |
| 447 GrowableArray<TargetEntryInstr**> false_successor_addresses_; | 439 GrowableArray<TargetEntryInstr**> false_successor_addresses_; |
| 448 | 440 |
| 449 intptr_t condition_token_pos_; | 441 intptr_t condition_token_pos_; |
| 450 }; | 442 }; |
| 451 | 443 |
| 452 } // namespace dart | 444 } // namespace dart |
| 453 | 445 |
| 454 #endif // VM_FLOW_GRAPH_BUILDER_H_ | 446 #endif // VM_FLOW_GRAPH_BUILDER_H_ |
| OLD | NEW |