| 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_ALLOCATOR_H_ | 5 #ifndef VM_FLOW_GRAPH_ALLOCATOR_H_ |
| 6 #define VM_FLOW_GRAPH_ALLOCATOR_H_ | 6 #define VM_FLOW_GRAPH_ALLOCATOR_H_ |
| 7 | 7 |
| 8 #include "vm/growable_array.h" | 8 #include "vm/growable_array.h" |
| 9 #include "vm/intermediate_language.h" | 9 #include "vm/intermediate_language.h" |
| 10 | 10 |
| 11 namespace dart { | 11 namespace dart { |
| 12 | 12 |
| 13 class AllocationFinger; | 13 class AllocationFinger; |
| 14 class BlockInfo; |
| 14 class FlowGraphBuilder; | 15 class FlowGraphBuilder; |
| 15 class LiveRange; | 16 class LiveRange; |
| 16 class UseInterval; | 17 class UseInterval; |
| 17 class UsePosition; | 18 class UsePosition; |
| 18 | 19 |
| 19 class FlowGraphAllocator : public ValueObject { | 20 class FlowGraphAllocator : public ValueObject { |
| 20 public: | 21 public: |
| 21 FlowGraphAllocator(const GrowableArray<BlockEntryInstr*>& block_order, | 22 FlowGraphAllocator(const GrowableArray<BlockEntryInstr*>& block_order, |
| 22 FlowGraphBuilder* builder); | 23 FlowGraphBuilder* builder); |
| 23 | 24 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 66 // need value in the register until the end of instruction's body. | 67 // need value in the register until the end of instruction's body. |
| 67 // Register allocator can perform splitting of live ranges at any position. | 68 // Register allocator can perform splitting of live ranges at any position. |
| 68 // An implicit ParallelMove will be inserted by ConnectSplitSiblings where | 69 // An implicit ParallelMove will be inserted by ConnectSplitSiblings where |
| 69 // required to resolve data flow between split siblings when allocation | 70 // required to resolve data flow between split siblings when allocation |
| 70 // is finished. | 71 // is finished. |
| 71 // For specific examples see comments inside ProcessOneInstruction. | 72 // For specific examples see comments inside ProcessOneInstruction. |
| 72 // Additionally creates parallel moves at the joins' predecessors | 73 // Additionally creates parallel moves at the joins' predecessors |
| 73 // that will be used for phi resolution. | 74 // that will be used for phi resolution. |
| 74 void NumberInstructions(); | 75 void NumberInstructions(); |
| 75 Instruction* InstructionAt(intptr_t pos) const; | 76 Instruction* InstructionAt(intptr_t pos) const; |
| 77 BlockInfo* BlockInfoAt(intptr_t pos) const; |
| 76 bool IsBlockEntry(intptr_t pos) const; | 78 bool IsBlockEntry(intptr_t pos) const; |
| 77 | 79 |
| 80 // Discover structural (reducible) loops nesting structure. |
| 81 // It will be used later in SplitBetween heuristic that selects an |
| 82 // optimal splitting position. |
| 83 void DiscoverLoops(); |
| 84 |
| 78 LiveRange* GetLiveRange(intptr_t vreg); | 85 LiveRange* GetLiveRange(intptr_t vreg); |
| 79 LiveRange* MakeLiveRangeForTemporary(); | 86 LiveRange* MakeLiveRangeForTemporary(); |
| 80 | 87 |
| 81 // Visit instructions in the postorder and build live ranges for | 88 // Visit instructions in the postorder and build live ranges for |
| 82 // all SSA values. | 89 // all SSA values. |
| 83 void BuildLiveRanges(); | 90 void BuildLiveRanges(); |
| 84 Instruction* ConnectOutgoingPhiMoves(BlockEntryInstr* block); | 91 Instruction* ConnectOutgoingPhiMoves(BlockEntryInstr* block); |
| 85 void ProcessOneInstruction(BlockEntryInstr* block, Instruction* instr); | 92 void ProcessOneInstruction(BlockEntryInstr* block, Instruction* instr); |
| 86 void ConnectIncomingPhiMoves(BlockEntryInstr* block); | 93 void ConnectIncomingPhiMoves(BlockEntryInstr* block); |
| 87 void BlockLocation(Location loc, intptr_t pos); | 94 void BlockLocation(Location loc, intptr_t pos); |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 143 // Find a spill slot that can be used by the given live range. | 150 // Find a spill slot that can be used by the given live range. |
| 144 void AllocateSpillSlotFor(LiveRange* range); | 151 void AllocateSpillSlotFor(LiveRange* range); |
| 145 | 152 |
| 146 // Allocate the given live range to a spill slot. | 153 // Allocate the given live range to a spill slot. |
| 147 void Spill(LiveRange* range); | 154 void Spill(LiveRange* range); |
| 148 | 155 |
| 149 // Spill the given live range from the given position onwards. | 156 // Spill the given live range from the given position onwards. |
| 150 void SpillAfter(LiveRange* range, intptr_t from); | 157 void SpillAfter(LiveRange* range, intptr_t from); |
| 151 | 158 |
| 152 // Spill the given live range from the given position until some | 159 // Spill the given live range from the given position until some |
| 153 // position preceeding the to position. | 160 // position preceding the to position. |
| 154 void SpillBetween(LiveRange* range, intptr_t from, intptr_t to); | 161 void SpillBetween(LiveRange* range, intptr_t from, intptr_t to); |
| 155 | 162 |
| 156 MoveOperands* AddMoveAt(intptr_t pos, Location to, Location from); | 163 MoveOperands* AddMoveAt(intptr_t pos, Location to, Location from); |
| 157 | 164 |
| 158 void PrintLiveRanges(); | 165 void PrintLiveRanges(); |
| 159 | 166 |
| 160 // TODO(vegorov): this field is used only to call Bailout. Remove when | 167 // TODO(vegorov): this field is used only to call Bailout. Remove when |
| 161 // all bailouts are gone. | 168 // all bailouts are gone. |
| 162 FlowGraphBuilder* builder_; | 169 FlowGraphBuilder* builder_; |
| 163 | 170 |
| 164 const GrowableArray<BlockEntryInstr*>& block_order_; | 171 const GrowableArray<BlockEntryInstr*>& block_order_; |
| 165 const GrowableArray<BlockEntryInstr*>& postorder_; | 172 const GrowableArray<BlockEntryInstr*>& postorder_; |
| 166 | 173 |
| 174 // Mapping between lifetime positions and instructions. |
| 167 GrowableArray<Instruction*> instructions_; | 175 GrowableArray<Instruction*> instructions_; |
| 168 | 176 |
| 177 // Mapping between lifetime positions and blocks containing them. |
| 178 GrowableArray<BlockInfo*> block_info_; |
| 179 |
| 169 // Live-out sets for each block. They contain indices of SSA values | 180 // Live-out sets for each block. They contain indices of SSA values |
| 170 // that are live out from this block: that is values that were either | 181 // that are live out from this block: that is values that were either |
| 171 // defined in this block or live into it and that are used in some | 182 // defined in this block or live into it and that are used in some |
| 172 // successor block. | 183 // successor block. |
| 173 GrowableArray<BitVector*> live_out_; | 184 GrowableArray<BitVector*> live_out_; |
| 174 | 185 |
| 175 // Kill sets for each block. They contain indices of SSA values that | 186 // Kill sets for each block. They contain indices of SSA values that |
| 176 // are defined by this block. | 187 // are defined by this block. |
| 177 GrowableArray<BitVector*> kill_; | 188 GrowableArray<BitVector*> kill_; |
| 178 | 189 |
| (...skipping 27 matching lines...) Expand all Loading... |
| 206 // List of used spill slots. Contain positions after which spill slots | 217 // List of used spill slots. Contain positions after which spill slots |
| 207 // become free and can be reused for allocation. | 218 // become free and can be reused for allocation. |
| 208 GrowableArray<intptr_t> spill_slots_; | 219 GrowableArray<intptr_t> spill_slots_; |
| 209 | 220 |
| 210 bool blocked_cpu_regs_[kNumberOfCpuRegisters]; | 221 bool blocked_cpu_regs_[kNumberOfCpuRegisters]; |
| 211 | 222 |
| 212 DISALLOW_COPY_AND_ASSIGN(FlowGraphAllocator); | 223 DISALLOW_COPY_AND_ASSIGN(FlowGraphAllocator); |
| 213 }; | 224 }; |
| 214 | 225 |
| 215 | 226 |
| 227 // Additional information about a block that is not contained in a |
| 228 // block entry. |
| 229 class BlockInfo : public ZoneAllocated { |
| 230 public: |
| 231 explicit BlockInfo(BlockEntryInstr* entry) |
| 232 : entry_(entry), loop_(NULL), is_loop_header_(false) { |
| 233 } |
| 234 |
| 235 BlockEntryInstr* entry() const { return entry_; } |
| 236 |
| 237 // Returns true is this node is a header of a structural loop. |
| 238 bool is_loop_header() const { return is_loop_header_; } |
| 239 |
| 240 // Innermost reducible loop containing this node. Loop headers point to |
| 241 // outer loop not to themselves. |
| 242 BlockInfo* loop() const { return loop_; } |
| 243 |
| 244 void mark_loop_header() { is_loop_header_ = true; } |
| 245 void set_loop(BlockInfo* loop) { |
| 246 ASSERT(loop_ == NULL); |
| 247 ASSERT((loop == NULL) || loop->is_loop_header()); |
| 248 loop_ = loop; |
| 249 } |
| 250 |
| 251 private: |
| 252 BlockEntryInstr* entry_; |
| 253 BlockInfo* loop_; |
| 254 bool is_loop_header_; |
| 255 |
| 256 DISALLOW_COPY_AND_ASSIGN(BlockInfo); |
| 257 }; |
| 258 |
| 259 |
| 216 // UsePosition represents a single use of an SSA value by some instruction. | 260 // UsePosition represents a single use of an SSA value by some instruction. |
| 217 // It points to a location slot which either tells register allocator | 261 // It points to a location slot which either tells register allocator |
| 218 // where instruction expects the value (if slot contains a fixed location) or | 262 // where instruction expects the value (if slot contains a fixed location) or |
| 219 // asks register allocator to allocate storage (register or spill slot) for | 263 // asks register allocator to allocate storage (register or spill slot) for |
| 220 // this use with certain properties (if slot contains an unallocated location). | 264 // this use with certain properties (if slot contains an unallocated location). |
| 221 class UsePosition : public ZoneAllocated { | 265 class UsePosition : public ZoneAllocated { |
| 222 public: | 266 public: |
| 223 UsePosition(intptr_t pos, UsePosition* next, Location* location_slot) | 267 UsePosition(intptr_t pos, UsePosition* next, Location* location_slot) |
| 224 : pos_(pos), location_slot_(location_slot), next_(next) { } | 268 : pos_(pos), location_slot_(location_slot), next_(next) { } |
| 225 | 269 |
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 404 | 448 |
| 405 AllocationFinger finger_; | 449 AllocationFinger finger_; |
| 406 | 450 |
| 407 DISALLOW_COPY_AND_ASSIGN(LiveRange); | 451 DISALLOW_COPY_AND_ASSIGN(LiveRange); |
| 408 }; | 452 }; |
| 409 | 453 |
| 410 | 454 |
| 411 } // namespace dart | 455 } // namespace dart |
| 412 | 456 |
| 413 #endif // VM_FLOW_GRAPH_ALLOCATOR_H_ | 457 #endif // VM_FLOW_GRAPH_ALLOCATOR_H_ |
| OLD | NEW |