| 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" |
| 11 #include "vm/intermediate_language.h" | 11 #include "vm/intermediate_language.h" |
| 12 | 12 |
| 13 namespace dart { | 13 namespace dart { |
| 14 | 14 |
| 15 class FlowGraph; | 15 class FlowGraph; |
| 16 class Instruction; | 16 class Instruction; |
| 17 class ParsedFunction; | 17 class ParsedFunction; |
| 18 | 18 |
| 19 // An InliningContext collects the exits from an inlined function during | 19 // An class to collect the exits from an inlined function during graph |
| 20 // graph construction so they can be plugged into the caller's flow graph. | 20 // construction so they can be plugged into the caller's flow graph. |
| 21 class InliningContext: public ValueObject { | 21 class InlineExitCollector: public ZoneAllocated { |
| 22 public: | 22 public: |
| 23 InliningContext(FlowGraph* caller_graph, Definition* call) | 23 InlineExitCollector(FlowGraph* caller_graph, Definition* call) |
| 24 : caller_graph_(caller_graph), call_(call), exits_(4) { } | 24 : caller_graph_(caller_graph), call_(call), exits_(4) { } |
| 25 | 25 |
| 26 void AddExit(ReturnInstr* exit); | 26 void AddExit(ReturnInstr* exit); |
| 27 | 27 |
| 28 // Inline a flow graph at a call site. | 28 // Before replacing a call with a graph, the outer environment needs to be |
| 29 // attached to each instruction in the callee graph and the caller graph |
| 30 // needs to have its block and instruction ID state updated. |
| 31 void PrepareGraphs(FlowGraph* callee_graph); |
| 32 |
| 33 // Inline a graph at a call site. |
| 29 // | 34 // |
| 30 // Assumes the callee graph was computed by BuildGraph with an inlining | 35 // Assumes the callee is in SSA with a correct dominator tree and use |
| 31 // context and transformed to SSA with ComputeSSA with a correct virtual | 36 // lists. |
| 32 // register number, and that the use lists have been correctly computed. | |
| 33 // | 37 // |
| 34 // After inlining the caller graph will have correctly adjusted the use | 38 // After inlining the caller graph will have correctly adjusted the use |
| 35 // lists. The block orders will need to be recomputed, and the dominator | 39 // lists. The block orders will need to be recomputed. |
| 36 // tree will need to be recomputed if it is marked invalid in the caller | 40 void ReplaceCall(TargetEntryInstr* callee_entry); |
| 37 // graph. | |
| 38 void ReplaceCall(FlowGraph* callee_graph); | |
| 39 | 41 |
| 40 private: | 42 private: |
| 41 struct Data { | 43 struct Data { |
| 42 BlockEntryInstr* exit_block; | 44 BlockEntryInstr* exit_block; |
| 43 ReturnInstr* exit_return; | 45 ReturnInstr* exit_return; |
| 44 }; | 46 }; |
| 45 | 47 |
| 46 void PrepareGraphs(FlowGraph* caller_graph); | |
| 47 | |
| 48 BlockEntryInstr* ExitBlockAt(intptr_t i) const { | 48 BlockEntryInstr* ExitBlockAt(intptr_t i) const { |
| 49 ASSERT(exits_[i].exit_block != NULL); | 49 ASSERT(exits_[i].exit_block != NULL); |
| 50 return exits_[i].exit_block; | 50 return exits_[i].exit_block; |
| 51 } | 51 } |
| 52 | 52 |
| 53 Instruction* LastInstructionAt(intptr_t i) const { | 53 Instruction* LastInstructionAt(intptr_t i) const { |
| 54 return ReturnAt(i)->previous(); | 54 return ReturnAt(i)->previous(); |
| 55 } | 55 } |
| 56 | 56 |
| 57 Value* ValueAt(intptr_t i) const { | 57 Value* ValueAt(intptr_t i) const { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 72 Definition* call_; | 72 Definition* call_; |
| 73 GrowableArray<Data> exits_; | 73 GrowableArray<Data> exits_; |
| 74 }; | 74 }; |
| 75 | 75 |
| 76 | 76 |
| 77 // Build a flow graph from a parsed function's AST. | 77 // Build a flow graph from a parsed function's AST. |
| 78 class FlowGraphBuilder: public ValueObject { | 78 class FlowGraphBuilder: public ValueObject { |
| 79 public: | 79 public: |
| 80 // The inlining context is NULL if not inlining. | 80 // The inlining context is NULL if not inlining. |
| 81 FlowGraphBuilder(const ParsedFunction& parsed_function, | 81 FlowGraphBuilder(const ParsedFunction& parsed_function, |
| 82 InliningContext* inlining_context); | 82 InlineExitCollector* exit_collector); |
| 83 | 83 |
| 84 FlowGraph* BuildGraph(); | 84 FlowGraph* BuildGraph(); |
| 85 | 85 |
| 86 const ParsedFunction& parsed_function() const { return parsed_function_; } | 86 const ParsedFunction& parsed_function() const { return parsed_function_; } |
| 87 | 87 |
| 88 void Bailout(const char* reason); | 88 void Bailout(const char* reason); |
| 89 | 89 |
| 90 intptr_t AllocateBlockId() { return ++last_used_block_id_; } | 90 intptr_t AllocateBlockId() { return ++last_used_block_id_; } |
| 91 void SetInitialBlockId(intptr_t id) { last_used_block_id_ = id; } | 91 void SetInitialBlockId(intptr_t id) { last_used_block_id_ = id; } |
| 92 | 92 |
| (...skipping 12 matching lines...) Expand all Loading... |
| 105 intptr_t num_copied_params() const { | 105 intptr_t num_copied_params() const { |
| 106 return num_copied_params_; | 106 return num_copied_params_; |
| 107 } | 107 } |
| 108 intptr_t num_non_copied_params() const { | 108 intptr_t num_non_copied_params() const { |
| 109 return num_non_copied_params_; | 109 return num_non_copied_params_; |
| 110 } | 110 } |
| 111 intptr_t num_stack_locals() const { | 111 intptr_t num_stack_locals() const { |
| 112 return num_stack_locals_; | 112 return num_stack_locals_; |
| 113 } | 113 } |
| 114 | 114 |
| 115 bool InInliningContext() const { return (inlining_context_ != NULL); } | 115 bool IsInlining() const { return (exit_collector_ != NULL); } |
| 116 InliningContext* inlining_context() const { return inlining_context_; } | 116 InlineExitCollector* exit_collector() const { return exit_collector_; } |
| 117 | 117 |
| 118 private: | 118 private: |
| 119 intptr_t parameter_count() const { | 119 intptr_t parameter_count() const { |
| 120 return num_copied_params_ + num_non_copied_params_; | 120 return num_copied_params_ + num_non_copied_params_; |
| 121 } | 121 } |
| 122 intptr_t variable_count() const { | 122 intptr_t variable_count() const { |
| 123 return parameter_count() + num_stack_locals_; | 123 return parameter_count() + num_stack_locals_; |
| 124 } | 124 } |
| 125 | 125 |
| 126 const ParsedFunction& parsed_function_; | 126 const ParsedFunction& parsed_function_; |
| 127 | 127 |
| 128 const intptr_t num_copied_params_; | 128 const intptr_t num_copied_params_; |
| 129 const intptr_t num_non_copied_params_; | 129 const intptr_t num_non_copied_params_; |
| 130 const intptr_t num_stack_locals_; // Does not include any parameters. | 130 const intptr_t num_stack_locals_; // Does not include any parameters. |
| 131 InliningContext* const inlining_context_; | 131 InlineExitCollector* const exit_collector_; |
| 132 | 132 |
| 133 intptr_t last_used_block_id_; | 133 intptr_t last_used_block_id_; |
| 134 intptr_t context_level_; | 134 intptr_t context_level_; |
| 135 intptr_t last_used_try_index_; | 135 intptr_t last_used_try_index_; |
| 136 intptr_t try_index_; | 136 intptr_t try_index_; |
| 137 GraphEntryInstr* graph_entry_; | 137 GraphEntryInstr* graph_entry_; |
| 138 | 138 |
| 139 DISALLOW_IMPLICIT_CONSTRUCTORS(FlowGraphBuilder); | 139 DISALLOW_IMPLICIT_CONSTRUCTORS(FlowGraphBuilder); |
| 140 }; | 140 }; |
| 141 | 141 |
| (...skipping 315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 457 // Output parameters. | 457 // Output parameters. |
| 458 GrowableArray<TargetEntryInstr**> true_successor_addresses_; | 458 GrowableArray<TargetEntryInstr**> true_successor_addresses_; |
| 459 GrowableArray<TargetEntryInstr**> false_successor_addresses_; | 459 GrowableArray<TargetEntryInstr**> false_successor_addresses_; |
| 460 | 460 |
| 461 intptr_t condition_token_pos_; | 461 intptr_t condition_token_pos_; |
| 462 }; | 462 }; |
| 463 | 463 |
| 464 } // namespace dart | 464 } // namespace dart |
| 465 | 465 |
| 466 #endif // VM_FLOW_GRAPH_BUILDER_H_ | 466 #endif // VM_FLOW_GRAPH_BUILDER_H_ |
| OLD | NEW |