| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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/flow_graph.h" |
| 8 #include "vm/growable_array.h" | 9 #include "vm/growable_array.h" |
| 9 #include "vm/intermediate_language.h" | 10 #include "vm/intermediate_language.h" |
| 10 | 11 |
| 11 namespace dart { | 12 namespace dart { |
| 12 | 13 |
| 13 class AllocationFinger; | 14 class AllocationFinger; |
| 14 class BlockInfo; | 15 class BlockInfo; |
| 15 class FlowGraph; | 16 class FlowGraph; |
| 16 class LiveRange; | 17 class LiveRange; |
| 17 class UseInterval; | 18 class UseInterval; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 28 | 29 |
| 29 private: | 30 private: |
| 30 void AddPhi(PhiInstr* phi); | 31 void AddPhi(PhiInstr* phi); |
| 31 void Compute(); | 32 void Compute(); |
| 32 | 33 |
| 33 const FlowGraph& flow_graph_; | 34 const FlowGraph& flow_graph_; |
| 34 GrowableArray<PhiInstr*> phis_; | 35 GrowableArray<PhiInstr*> phis_; |
| 35 }; | 36 }; |
| 36 | 37 |
| 37 | 38 |
| 39 class SSALivenessAnalysis : public LivenessAnalysis { |
| 40 public: |
| 41 explicit SSALivenessAnalysis(const FlowGraph& flow_graph) |
| 42 : LivenessAnalysis(flow_graph.max_virtual_register_number(), |
| 43 flow_graph.postorder()), |
| 44 graph_entry_(flow_graph.graph_entry()) { } |
| 45 |
| 46 private: |
| 47 // Compute initial values for live-out, kill and live-in sets. |
| 48 virtual void ComputeInitialSets(); |
| 49 |
| 50 GraphEntryInstr* graph_entry_; |
| 51 }; |
| 52 |
| 53 |
| 38 class FlowGraphAllocator : public ValueObject { | 54 class FlowGraphAllocator : public ValueObject { |
| 39 public: | 55 public: |
| 40 // Number of stack slots needed for a double spill slot. | 56 // Number of stack slots needed for a double spill slot. |
| 41 static const intptr_t kDoubleSpillSlotFactor = kDoubleSize / kWordSize; | 57 static const intptr_t kDoubleSpillSlotFactor = kDoubleSize / kWordSize; |
| 42 | 58 |
| 43 explicit FlowGraphAllocator(const FlowGraph& flow_graph); | 59 explicit FlowGraphAllocator(const FlowGraph& flow_graph); |
| 44 | 60 |
| 45 void AllocateRegisters(); | 61 void AllocateRegisters(); |
| 46 | 62 |
| 47 // Build live-in and live-out sets for each block. | |
| 48 void AnalyzeLiveness(); | |
| 49 | |
| 50 // Map a virtual register number to its live range. | 63 // Map a virtual register number to its live range. |
| 51 LiveRange* GetLiveRange(intptr_t vreg); | 64 LiveRange* GetLiveRange(intptr_t vreg); |
| 52 | 65 |
| 53 private: | 66 private: |
| 54 void CollectRepresentations(); | 67 void CollectRepresentations(); |
| 55 | 68 |
| 56 // Eliminate unnecessary environments from the IL. | 69 // Eliminate unnecessary environments from the IL. |
| 57 void EliminateEnvironments(); | 70 void EliminateEnvironments(); |
| 58 | 71 |
| 59 // Compute initial values for live-out, kill and live-in sets. | |
| 60 void ComputeInitialSets(); | |
| 61 | |
| 62 // Update live-out set for the given block: live-out should contain | |
| 63 // all values that are live-in for block's successors. | |
| 64 // Returns true if live-out set was changed. | |
| 65 bool UpdateLiveOut(const BlockEntryInstr& instr); | |
| 66 | |
| 67 // Update live-in set for the given block: live-in should contain | |
| 68 // all values that are live-out from the block and are not defined | |
| 69 // by this block. | |
| 70 // Returns true if live-in set was changed. | |
| 71 bool UpdateLiveIn(const BlockEntryInstr& instr); | |
| 72 | |
| 73 // Perform fix-point iteration updating live-out and live-in sets | |
| 74 // for blocks until they stop changing. | |
| 75 void ComputeLiveInAndLiveOutSets(); | |
| 76 | |
| 77 // Print results of liveness analysis. | |
| 78 void DumpLiveness(); | |
| 79 | |
| 80 // Visit blocks in the code generation order (reverse post order) and | 72 // Visit blocks in the code generation order (reverse post order) and |
| 81 // linearly assign consequent lifetime positions to every instruction. | 73 // linearly assign consequent lifetime positions to every instruction. |
| 82 // We assign position as follows: | 74 // We assign position as follows: |
| 83 // | 75 // |
| 84 // 2 * n - even position corresponding to instruction's start; | 76 // 2 * n - even position corresponding to instruction's start; |
| 85 // | 77 // |
| 86 // 2 * n + 1 - odd position corresponding to instruction's end; | 78 // 2 * n + 1 - odd position corresponding to instruction's end; |
| 87 // | 79 // |
| 88 // Having two positions per instruction allows us to capture non-trivial | 80 // Having two positions per instruction allows us to capture non-trivial |
| 89 // shapes of use intervals: e.g. by placing a use at the start or the | 81 // shapes of use intervals: e.g. by placing a use at the start or the |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 242 | 234 |
| 243 const GrowableArray<BlockEntryInstr*>& block_order_; | 235 const GrowableArray<BlockEntryInstr*>& block_order_; |
| 244 const GrowableArray<BlockEntryInstr*>& postorder_; | 236 const GrowableArray<BlockEntryInstr*>& postorder_; |
| 245 | 237 |
| 246 // Mapping between lifetime positions and instructions. | 238 // Mapping between lifetime positions and instructions. |
| 247 GrowableArray<Instruction*> instructions_; | 239 GrowableArray<Instruction*> instructions_; |
| 248 | 240 |
| 249 // Mapping between lifetime positions and blocks containing them. | 241 // Mapping between lifetime positions and blocks containing them. |
| 250 GrowableArray<BlockInfo*> block_info_; | 242 GrowableArray<BlockInfo*> block_info_; |
| 251 | 243 |
| 252 // Live-out sets for each block. They contain indices of SSA values | 244 SSALivenessAnalysis liveness_; |
| 253 // that are live out from this block: that is values that were either | |
| 254 // defined in this block or live into it and that are used in some | |
| 255 // successor block. | |
| 256 GrowableArray<BitVector*> live_out_; | |
| 257 | |
| 258 // Kill sets for each block. They contain indices of SSA values that | |
| 259 // are defined by this block. | |
| 260 GrowableArray<BitVector*> kill_; | |
| 261 | |
| 262 // Live-in sets for each block. They contain indices of SSA values | |
| 263 // that are used by this block or its successors. | |
| 264 GrowableArray<BitVector*> live_in_; | |
| 265 | 245 |
| 266 // Number of virtual registers. Currently equal to the number of | 246 // Number of virtual registers. Currently equal to the number of |
| 267 // SSA values. | 247 // SSA values. |
| 268 const intptr_t vreg_count_; | 248 const intptr_t vreg_count_; |
| 269 | 249 |
| 270 // LiveRanges corresponding to SSA values. | 250 // LiveRanges corresponding to SSA values. |
| 271 GrowableArray<LiveRange*> live_ranges_; | 251 GrowableArray<LiveRange*> live_ranges_; |
| 272 | 252 |
| 273 GrowableArray<LiveRange*> unallocated_cpu_; | 253 GrowableArray<LiveRange*> unallocated_cpu_; |
| 274 GrowableArray<LiveRange*> unallocated_xmm_; | 254 GrowableArray<LiveRange*> unallocated_xmm_; |
| (...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 656 | 636 |
| 657 AllocationFinger finger_; | 637 AllocationFinger finger_; |
| 658 | 638 |
| 659 DISALLOW_COPY_AND_ASSIGN(LiveRange); | 639 DISALLOW_COPY_AND_ASSIGN(LiveRange); |
| 660 }; | 640 }; |
| 661 | 641 |
| 662 | 642 |
| 663 } // namespace dart | 643 } // namespace dart |
| 664 | 644 |
| 665 #endif // VM_FLOW_GRAPH_ALLOCATOR_H_ | 645 #endif // VM_FLOW_GRAPH_ALLOCATOR_H_ |
| OLD | NEW |