| 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 BlockInfo; |
| 15 class FlowGraph; | 15 class FlowGraph; |
| 16 class LiveRange; | 16 class LiveRange; |
| 17 class UseInterval; | 17 class UseInterval; |
| 18 class UsePosition; | 18 class UsePosition; |
| 19 | 19 |
| 20 |
| 21 class ReachingDefs : public ValueObject { |
| 22 public: |
| 23 explicit ReachingDefs(const FlowGraph& flow_graph) |
| 24 : flow_graph_(flow_graph), |
| 25 phis_(10) { } |
| 26 |
| 27 BitVector* Get(PhiInstr* phi); |
| 28 |
| 29 private: |
| 30 void AddPhi(PhiInstr* phi); |
| 31 void Compute(); |
| 32 |
| 33 const FlowGraph& flow_graph_; |
| 34 GrowableArray<PhiInstr*> phis_; |
| 35 }; |
| 36 |
| 37 |
| 20 class FlowGraphAllocator : public ValueObject { | 38 class FlowGraphAllocator : public ValueObject { |
| 21 public: | 39 public: |
| 22 // Number of stack slots needed for a double spill slot. | 40 // Number of stack slots needed for a double spill slot. |
| 23 static const intptr_t kDoubleSpillSlotFactor = kDoubleSize / kWordSize; | 41 static const intptr_t kDoubleSpillSlotFactor = kDoubleSize / kWordSize; |
| 24 | 42 |
| 25 explicit FlowGraphAllocator(const FlowGraph& flow_graph); | 43 explicit FlowGraphAllocator(const FlowGraph& flow_graph); |
| 26 | 44 |
| 27 void AllocateRegisters(); | 45 void AllocateRegisters(); |
| 28 | 46 |
| 29 // Build live-in and live-out sets for each block. | 47 // Build live-in and live-out sets for each block. |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 // Discover structural (reducible) loops nesting structure. | 105 // Discover structural (reducible) loops nesting structure. |
| 88 // It will be used later in SplitBetween heuristic that selects an | 106 // It will be used later in SplitBetween heuristic that selects an |
| 89 // optimal splitting position. | 107 // optimal splitting position. |
| 90 void DiscoverLoops(); | 108 void DiscoverLoops(); |
| 91 | 109 |
| 92 LiveRange* MakeLiveRangeForTemporary(); | 110 LiveRange* MakeLiveRangeForTemporary(); |
| 93 | 111 |
| 94 // Visit instructions in the postorder and build live ranges for | 112 // Visit instructions in the postorder and build live ranges for |
| 95 // all SSA values. | 113 // all SSA values. |
| 96 void BuildLiveRanges(); | 114 void BuildLiveRanges(); |
| 97 Instruction* ConnectOutgoingPhiMoves(BlockEntryInstr* block); | 115 Instruction* ConnectOutgoingPhiMoves(BlockEntryInstr* block, |
| 116 BitVector* interference_set); |
| 98 void ProcessEnvironmentUses(BlockEntryInstr* block, Instruction* current); | 117 void ProcessEnvironmentUses(BlockEntryInstr* block, Instruction* current); |
| 99 void ProcessOneInstruction(BlockEntryInstr* block, Instruction* instr); | 118 void ProcessOneInstruction(BlockEntryInstr* block, |
| 119 Instruction* instr, |
| 120 BitVector* interference_set); |
| 100 void ConnectIncomingPhiMoves(BlockEntryInstr* block); | 121 void ConnectIncomingPhiMoves(BlockEntryInstr* block); |
| 101 void BlockLocation(Location loc, intptr_t from, intptr_t to); | 122 void BlockLocation(Location loc, intptr_t from, intptr_t to); |
| 102 void BlockRegisterLocation(Location loc, | 123 void BlockRegisterLocation(Location loc, |
| 103 intptr_t from, | 124 intptr_t from, |
| 104 intptr_t to, | 125 intptr_t to, |
| 105 bool* blocked_registers, | 126 bool* blocked_registers, |
| 106 LiveRange** blocking_ranges); | 127 LiveRange** blocking_ranges); |
| 107 | 128 |
| 108 intptr_t NumberOfRegisters() const { return number_of_registers_; } | 129 intptr_t NumberOfRegisters() const { return number_of_registers_; } |
| 109 | 130 |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 MoveOperands* AddMoveAt(intptr_t pos, Location to, Location from); | 228 MoveOperands* AddMoveAt(intptr_t pos, Location to, Location from); |
| 208 | 229 |
| 209 Location MakeRegisterLocation(intptr_t reg, Location::Representation rep) { | 230 Location MakeRegisterLocation(intptr_t reg, Location::Representation rep) { |
| 210 return Location::MachineRegisterLocation(register_kind_, reg, rep); | 231 return Location::MachineRegisterLocation(register_kind_, reg, rep); |
| 211 } | 232 } |
| 212 | 233 |
| 213 void PrintLiveRanges(); | 234 void PrintLiveRanges(); |
| 214 | 235 |
| 215 const FlowGraph& flow_graph_; | 236 const FlowGraph& flow_graph_; |
| 216 | 237 |
| 238 ReachingDefs reaching_defs_; |
| 239 |
| 217 // Set of SSA values that have unboxed mint representation. Indexed | 240 // Set of SSA values that have unboxed mint representation. Indexed |
| 218 // by SSA temp index. | 241 // by SSA temp index. |
| 219 BitVector* mint_values_; | 242 BitVector* mint_values_; |
| 220 | 243 |
| 221 const GrowableArray<BlockEntryInstr*>& block_order_; | 244 const GrowableArray<BlockEntryInstr*>& block_order_; |
| 222 const GrowableArray<BlockEntryInstr*>& postorder_; | 245 const GrowableArray<BlockEntryInstr*>& postorder_; |
| 223 | 246 |
| 224 // Mapping between lifetime positions and instructions. | 247 // Mapping between lifetime positions and instructions. |
| 225 GrowableArray<Instruction*> instructions_; | 248 GrowableArray<Instruction*> instructions_; |
| 226 | 249 |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 292 | 315 |
| 293 DISALLOW_COPY_AND_ASSIGN(FlowGraphAllocator); | 316 DISALLOW_COPY_AND_ASSIGN(FlowGraphAllocator); |
| 294 }; | 317 }; |
| 295 | 318 |
| 296 | 319 |
| 297 // Additional information about a block that is not contained in a | 320 // Additional information about a block that is not contained in a |
| 298 // block entry. | 321 // block entry. |
| 299 class BlockInfo : public ZoneAllocated { | 322 class BlockInfo : public ZoneAllocated { |
| 300 public: | 323 public: |
| 301 explicit BlockInfo(BlockEntryInstr* entry) | 324 explicit BlockInfo(BlockEntryInstr* entry) |
| 302 : entry_(entry), loop_(NULL), is_loop_header_(false) { | 325 : entry_(entry), |
| 326 loop_(NULL), |
| 327 is_loop_header_(false), |
| 328 backedge_interference_(NULL) { |
| 303 } | 329 } |
| 304 | 330 |
| 305 BlockEntryInstr* entry() const { return entry_; } | 331 BlockEntryInstr* entry() const { return entry_; } |
| 306 | 332 |
| 307 // Returns true is this node is a header of a structural loop. | 333 // Returns true is this node is a header of a structural loop. |
| 308 bool is_loop_header() const { return is_loop_header_; } | 334 bool is_loop_header() const { return is_loop_header_; } |
| 309 | 335 |
| 336 // Returns header of the innermost loop containing this block. |
| 337 BlockInfo* loop_header() { |
| 338 if (is_loop_header()) { |
| 339 return this; |
| 340 } else if (loop() != NULL) { |
| 341 return loop(); |
| 342 } else { |
| 343 return NULL; |
| 344 } |
| 345 } |
| 346 |
| 310 // Innermost reducible loop containing this node. Loop headers point to | 347 // Innermost reducible loop containing this node. Loop headers point to |
| 311 // outer loop not to themselves. | 348 // outer loop not to themselves. |
| 312 BlockInfo* loop() const { return loop_; } | 349 BlockInfo* loop() const { return loop_; } |
| 313 | 350 |
| 314 void mark_loop_header() { is_loop_header_ = true; } | 351 void mark_loop_header() { is_loop_header_ = true; } |
| 315 void set_loop(BlockInfo* loop) { | 352 void set_loop(BlockInfo* loop) { |
| 316 ASSERT(loop_ == NULL); | 353 ASSERT(loop_ == NULL); |
| 317 ASSERT((loop == NULL) || loop->is_loop_header()); | 354 ASSERT((loop == NULL) || loop->is_loop_header()); |
| 318 loop_ = loop; | 355 loop_ = loop; |
| 319 } | 356 } |
| 320 | 357 |
| 321 BlockEntryInstr* last_block() const { return last_block_; } | 358 BlockEntryInstr* last_block() const { return last_block_; } |
| 322 void set_last_block(BlockEntryInstr* last_block) { | 359 void set_last_block(BlockEntryInstr* last_block) { |
| 323 last_block_ = last_block; | 360 last_block_ = last_block; |
| 324 } | 361 } |
| 325 | 362 |
| 326 intptr_t loop_id() const { return loop_id_; } | 363 intptr_t loop_id() const { return loop_id_; } |
| 327 void set_loop_id(intptr_t loop_id) { loop_id_ = loop_id; } | 364 void set_loop_id(intptr_t loop_id) { loop_id_ = loop_id; } |
| 328 | 365 |
| 366 BitVector* backedge_interference() const { |
| 367 return backedge_interference_; |
| 368 } |
| 369 |
| 370 void set_backedge_interference(BitVector* backedge_interference) { |
| 371 backedge_interference_ = backedge_interference; |
| 372 } |
| 373 |
| 329 private: | 374 private: |
| 330 BlockEntryInstr* entry_; | 375 BlockEntryInstr* entry_; |
| 331 BlockInfo* loop_; | 376 BlockInfo* loop_; |
| 332 bool is_loop_header_; | 377 bool is_loop_header_; |
| 333 | 378 |
| 334 BlockEntryInstr* last_block_; | 379 BlockEntryInstr* last_block_; |
| 335 intptr_t loop_id_; | 380 intptr_t loop_id_; |
| 336 | 381 |
| 382 BitVector* backedge_interference_; |
| 383 |
| 337 DISALLOW_COPY_AND_ASSIGN(BlockInfo); | 384 DISALLOW_COPY_AND_ASSIGN(BlockInfo); |
| 338 }; | 385 }; |
| 339 | 386 |
| 340 | 387 |
| 341 // UsePosition represents a single use of an SSA value by some instruction. | 388 // UsePosition represents a single use of an SSA value by some instruction. |
| 342 // It points to a location slot which either tells register allocator | 389 // It points to a location slot which either tells register allocator |
| 343 // where instruction expects the value (if slot contains a fixed location) or | 390 // where instruction expects the value (if slot contains a fixed location) or |
| 344 // asks register allocator to allocate storage (register or spill slot) for | 391 // asks register allocator to allocate storage (register or spill slot) for |
| 345 // this use with certain properties (if slot contains an unallocated location). | 392 // this use with certain properties (if slot contains an unallocated location). |
| 346 class UsePosition : public ZoneAllocated { | 393 class UsePosition : public ZoneAllocated { |
| (...skipping 263 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 610 | 657 |
| 611 AllocationFinger finger_; | 658 AllocationFinger finger_; |
| 612 | 659 |
| 613 DISALLOW_COPY_AND_ASSIGN(LiveRange); | 660 DISALLOW_COPY_AND_ASSIGN(LiveRange); |
| 614 }; | 661 }; |
| 615 | 662 |
| 616 | 663 |
| 617 } // namespace dart | 664 } // namespace dart |
| 618 | 665 |
| 619 #endif // VM_FLOW_GRAPH_ALLOCATOR_H_ | 666 #endif // VM_FLOW_GRAPH_ALLOCATOR_H_ |
| OLD | NEW |