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_COMPILER_H_ | 5 #ifndef VM_FLOW_GRAPH_COMPILER_H_ |
6 #define VM_FLOW_GRAPH_COMPILER_H_ | 6 #define VM_FLOW_GRAPH_COMPILER_H_ |
7 | 7 |
8 #include "vm/allocation.h" | 8 #include "vm/allocation.h" |
9 #include "vm/assembler.h" | 9 #include "vm/assembler.h" |
10 #include "vm/assembler_macros.h" | 10 #include "vm/assembler_macros.h" |
(...skipping 14 matching lines...) Expand all Loading... |
25 // fact that IR is stack based and a value produced by a bind instruction | 25 // fact that IR is stack based and a value produced by a bind instruction |
26 // will be used only once. For the register allocator every Bind is a push and | 26 // will be used only once. For the register allocator every Bind is a push and |
27 // every UseVal of a bind is a pop. | 27 // every UseVal of a bind is a pop. |
28 // It can also operate in a non-optimizing mode when every value is pushed | 28 // It can also operate in a non-optimizing mode when every value is pushed |
29 // to the stack immediately after it is produced. | 29 // to the stack immediately after it is produced. |
30 // TODO(vegorov): replace with a linear scan register allocator once SSA is | 30 // TODO(vegorov): replace with a linear scan register allocator once SSA is |
31 // available. | 31 // available. |
32 class FrameRegisterAllocator : public ValueObject { | 32 class FrameRegisterAllocator : public ValueObject { |
33 public: | 33 public: |
34 FrameRegisterAllocator(FlowGraphCompiler* compiler, | 34 FrameRegisterAllocator(FlowGraphCompiler* compiler, |
35 bool keep_values_in_registers) | 35 bool keep_values_in_registers, |
| 36 bool is_ssa) |
36 : compiler_(compiler), | 37 : compiler_(compiler), |
37 stack_(kNumberOfCpuRegisters), | 38 stack_(kNumberOfCpuRegisters), |
38 registers_(), | 39 registers_(), |
39 keep_values_in_registers_(keep_values_in_registers) { | 40 keep_values_in_registers_(keep_values_in_registers && !is_ssa), |
| 41 is_ssa_(is_ssa) { |
40 for (int i = 0; i < kNumberOfCpuRegisters; i++) { | 42 for (int i = 0; i < kNumberOfCpuRegisters; i++) { |
41 registers_[i] = NULL; | 43 registers_[i] = NULL; |
42 } | 44 } |
43 } | 45 } |
44 | 46 |
45 // Notify register allocator that given instruction produced a value | 47 // Notify register allocator that given instruction produced a value |
46 // in the given register. | 48 // in the given register. |
47 void Push(Register reg, BindInstr* val); | 49 void Push(Register reg, BindInstr* val); |
48 | 50 |
49 // Perform a greedy local register allocation. Consider all register free. | 51 // Perform a greedy local register allocation. Consider all register free. |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
83 FlowGraphCompiler* compiler_; | 85 FlowGraphCompiler* compiler_; |
84 | 86 |
85 // List of registers with live values in order from oldest to newest. | 87 // List of registers with live values in order from oldest to newest. |
86 GrowableArray<Register> stack_; | 88 GrowableArray<Register> stack_; |
87 | 89 |
88 // Mapping between live registers and instructions that produced values | 90 // Mapping between live registers and instructions that produced values |
89 // in them. Contains NULL for registers do not have corresponding live value. | 91 // in them. Contains NULL for registers do not have corresponding live value. |
90 BindInstr* registers_[kNumberOfCpuRegisters]; | 92 BindInstr* registers_[kNumberOfCpuRegisters]; |
91 | 93 |
92 const bool keep_values_in_registers_; | 94 const bool keep_values_in_registers_; |
| 95 const bool is_ssa_; |
93 | 96 |
94 DISALLOW_COPY_AND_ASSIGN(FrameRegisterAllocator); | 97 DISALLOW_COPY_AND_ASSIGN(FrameRegisterAllocator); |
95 }; | 98 }; |
96 | 99 |
| 100 |
| 101 class ParallelMoveResolver : public ValueObject { |
| 102 public: |
| 103 explicit ParallelMoveResolver(FlowGraphCompiler* compiler); |
| 104 |
| 105 // Resolve a set of parallel moves, emitting assembler instructions. |
| 106 void EmitNativeCode(ParallelMoveInstr* parallel_move); |
| 107 |
| 108 private: |
| 109 // Build the initial list of moves. |
| 110 void BuildInitialMoveList(ParallelMoveInstr* parallel_move); |
| 111 |
| 112 // Perform the move at the moves_ index in question (possibly requiring |
| 113 // other moves to satisfy dependencies). |
| 114 void PerformMove(int index); |
| 115 |
| 116 // Emit a move and remove it from the move graph. |
| 117 void EmitMove(int index); |
| 118 |
| 119 // Execute a move by emitting a swap of two operands. The move from |
| 120 // source to destination is removed from the move graph. |
| 121 void EmitSwap(int index); |
| 122 |
| 123 // Verify the move list before performing moves. |
| 124 void Verify(); |
| 125 |
| 126 FlowGraphCompiler* compiler_; |
| 127 |
| 128 // List of moves not yet resolved. |
| 129 GrowableArray<MoveOperands> moves_; |
| 130 }; |
| 131 |
| 132 |
| 133 class DeoptimizationStub : public ZoneAllocated { |
| 134 public: |
| 135 DeoptimizationStub(intptr_t deopt_id, |
| 136 intptr_t deopt_token_pos, |
| 137 intptr_t try_index, |
| 138 DeoptReasonId reason) |
| 139 : deopt_id_(deopt_id), |
| 140 deopt_token_pos_(deopt_token_pos), |
| 141 try_index_(try_index), |
| 142 reason_(reason), |
| 143 registers_(2), |
| 144 deoptimization_env_(NULL), |
| 145 entry_label_() {} |
| 146 |
| 147 void Push(Register reg) { registers_.Add(reg); } |
| 148 Label* entry_label() { return &entry_label_; } |
| 149 |
| 150 // Implementation is in architecture specific file. |
| 151 void GenerateCode(FlowGraphCompiler* compiler); |
| 152 |
| 153 void set_deoptimization_env(Environment* env) { |
| 154 deoptimization_env_ = env; |
| 155 } |
| 156 |
| 157 private: |
| 158 const intptr_t deopt_id_; |
| 159 const intptr_t deopt_token_pos_; |
| 160 const intptr_t try_index_; |
| 161 const DeoptReasonId reason_; |
| 162 GrowableArray<Register> registers_; |
| 163 const Environment* deoptimization_env_; |
| 164 Label entry_label_; |
| 165 |
| 166 DISALLOW_COPY_AND_ASSIGN(DeoptimizationStub); |
| 167 }; |
| 168 |
97 } // namespace dart | 169 } // namespace dart |
98 | 170 |
99 #if defined(TARGET_ARCH_IA32) | 171 #if defined(TARGET_ARCH_IA32) |
100 #include "vm/flow_graph_compiler_ia32.h" | 172 #include "vm/flow_graph_compiler_ia32.h" |
101 #elif defined(TARGET_ARCH_X64) | 173 #elif defined(TARGET_ARCH_X64) |
102 #include "vm/flow_graph_compiler_x64.h" | 174 #include "vm/flow_graph_compiler_x64.h" |
103 #elif defined(TARGET_ARCH_ARM) | 175 #elif defined(TARGET_ARCH_ARM) |
104 #include "vm/flow_graph_compiler_arm.h" | 176 #include "vm/flow_graph_compiler_arm.h" |
105 #else | 177 #else |
106 #error Unknown architecture. | 178 #error Unknown architecture. |
107 #endif | 179 #endif |
108 | 180 |
109 #endif // VM_FLOW_GRAPH_COMPILER_H_ | 181 #endif // VM_FLOW_GRAPH_COMPILER_H_ |
OLD | NEW |