Chromium Code Reviews| 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 |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 89 | 89 |
| 90 // Visit instructions in the postorder and build live ranges for | 90 // Visit instructions in the postorder and build live ranges for |
| 91 // all SSA values. | 91 // all SSA values. |
| 92 void BuildLiveRanges(); | 92 void BuildLiveRanges(); |
| 93 Instruction* ConnectOutgoingPhiMoves(BlockEntryInstr* block); | 93 Instruction* ConnectOutgoingPhiMoves(BlockEntryInstr* block); |
| 94 void ProcessEnvironmentUses(BlockEntryInstr* block, Instruction* current); | 94 void ProcessEnvironmentUses(BlockEntryInstr* block, Instruction* current); |
| 95 void ProcessOneInstruction(BlockEntryInstr* block, Instruction* instr); | 95 void ProcessOneInstruction(BlockEntryInstr* block, Instruction* instr); |
| 96 void ConnectIncomingPhiMoves(BlockEntryInstr* block); | 96 void ConnectIncomingPhiMoves(BlockEntryInstr* block); |
| 97 void BlockLocation(Location loc, intptr_t from, intptr_t to); | 97 void BlockLocation(Location loc, intptr_t from, intptr_t to); |
| 98 | 98 |
| 99 // Find all safepoints that are covered by this live range. | |
| 100 void AssignSafepoints(LiveRange* range); | |
| 101 | |
| 99 // Process live ranges sorted by their start and assign registers | 102 // Process live ranges sorted by their start and assign registers |
| 100 // to them | 103 // to them |
| 101 void AllocateCPURegisters(); | 104 void AllocateCPURegisters(); |
| 102 void AdvanceActiveIntervals(const intptr_t start); | 105 void AdvanceActiveIntervals(const intptr_t start); |
| 103 | 106 |
| 104 // Connect split siblings over non-linear control flow edges. | 107 // Connect split siblings over non-linear control flow edges. |
| 105 void ResolveControlFlow(); | 108 void ResolveControlFlow(); |
| 106 void ConnectSplitSiblings(LiveRange* range, | 109 void ConnectSplitSiblings(LiveRange* range, |
| 107 BlockEntryInstr* source_block, | 110 BlockEntryInstr* source_block, |
| 108 BlockEntryInstr* target_block); | 111 BlockEntryInstr* target_block); |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 206 GrowableArray<LiveRange*> live_ranges_; | 209 GrowableArray<LiveRange*> live_ranges_; |
| 207 | 210 |
| 208 // Worklist for register allocator. Always maintained sorted according | 211 // Worklist for register allocator. Always maintained sorted according |
| 209 // to ShouldBeAllocatedBefore predicate. | 212 // to ShouldBeAllocatedBefore predicate. |
| 210 GrowableArray<LiveRange*> unallocated_; | 213 GrowableArray<LiveRange*> unallocated_; |
| 211 | 214 |
| 212 #if defined(DEBUG) | 215 #if defined(DEBUG) |
| 213 GrowableArray<LiveRange*> temporaries_; | 216 GrowableArray<LiveRange*> temporaries_; |
| 214 #endif | 217 #endif |
| 215 | 218 |
| 219 // List of spilled live ranges. | |
| 216 GrowableArray<LiveRange*> spilled_; | 220 GrowableArray<LiveRange*> spilled_; |
| 217 | 221 |
| 222 // List of instructions containing calls. | |
| 223 GrowableArray<Instruction*> safepoints_; | |
| 224 | |
| 218 // Per register lists of allocated live ranges. Contain only those | 225 // Per register lists of allocated live ranges. Contain only those |
| 219 // ranges that can be affected by future allocation decisions. | 226 // ranges that can be affected by future allocation decisions. |
| 220 // Those live ranges that end before the start of the current live range are | 227 // Those live ranges that end before the start of the current live range are |
| 221 // removed from the list and will not be affected. | 228 // removed from the list and will not be affected. |
| 222 GrowableArray<LiveRange*> cpu_regs_[kNumberOfCpuRegisters]; | 229 GrowableArray<LiveRange*> cpu_regs_[kNumberOfCpuRegisters]; |
| 223 | 230 |
| 224 // List of used spill slots. Contains positions after which spill slots | 231 // List of used spill slots. Contains positions after which spill slots |
| 225 // become free and can be reused for allocation. | 232 // become free and can be reused for allocation. |
| 226 GrowableArray<intptr_t> spill_slots_; | 233 GrowableArray<intptr_t> spill_slots_; |
| 227 | 234 |
| 228 // List of safepoints. | |
| 229 struct Safepoint { | |
| 230 intptr_t position; | |
| 231 BitmapBuilder* stack_bitmap; | |
| 232 }; | |
| 233 GrowableArray<Safepoint> safepoints_; | |
| 234 | |
| 235 bool blocked_cpu_regs_[kNumberOfCpuRegisters]; | 235 bool blocked_cpu_regs_[kNumberOfCpuRegisters]; |
| 236 | 236 |
| 237 DISALLOW_COPY_AND_ASSIGN(FlowGraphAllocator); | 237 DISALLOW_COPY_AND_ASSIGN(FlowGraphAllocator); |
| 238 }; | 238 }; |
| 239 | 239 |
| 240 | 240 |
| 241 // Additional information about a block that is not contained in a | 241 // Additional information about a block that is not contained in a |
| 242 // block entry. | 242 // block entry. |
| 243 class BlockInfo : public ZoneAllocated { | 243 class BlockInfo : public ZoneAllocated { |
| 244 public: | 244 public: |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 380 private: | 380 private: |
| 381 UseInterval* first_pending_use_interval_; | 381 UseInterval* first_pending_use_interval_; |
| 382 UsePosition* first_register_use_; | 382 UsePosition* first_register_use_; |
| 383 UsePosition* first_register_beneficial_use_; | 383 UsePosition* first_register_beneficial_use_; |
| 384 UsePosition* first_hinted_use_; | 384 UsePosition* first_hinted_use_; |
| 385 | 385 |
| 386 DISALLOW_COPY_AND_ASSIGN(AllocationFinger); | 386 DISALLOW_COPY_AND_ASSIGN(AllocationFinger); |
| 387 }; | 387 }; |
| 388 | 388 |
| 389 | 389 |
| 390 class SafepointPosition : public ZoneAllocated { | |
|
srdjan
2012/08/15 00:12:03
Make a common superclass PositionsList (subclasses
| |
| 391 public: | |
| 392 SafepointPosition(intptr_t pos, | |
| 393 LocationSummary* locs) | |
| 394 : pos_(pos), locs_(locs), next_(NULL) { } | |
| 395 | |
| 396 void set_next(SafepointPosition* next) { next_ = next; } | |
| 397 SafepointPosition* next() const { return next_; } | |
| 398 | |
| 399 intptr_t pos() const { return pos_; } | |
| 400 | |
| 401 LocationSummary* locs() const { return locs_; } | |
| 402 | |
| 403 private: | |
| 404 const intptr_t pos_; | |
| 405 LocationSummary* const locs_; | |
| 406 | |
| 407 SafepointPosition* next_; | |
| 408 }; | |
| 409 | |
| 410 | |
| 390 // LiveRange represents a sequence of UseIntervals for a given SSA value. | 411 // LiveRange represents a sequence of UseIntervals for a given SSA value. |
| 391 class LiveRange : public ZoneAllocated { | 412 class LiveRange : public ZoneAllocated { |
| 392 public: | 413 public: |
| 393 explicit LiveRange(intptr_t vreg) | 414 explicit LiveRange(intptr_t vreg) |
| 394 : vreg_(vreg), | 415 : vreg_(vreg), |
| 395 assigned_location_(), | 416 assigned_location_(), |
| 396 spill_slot_(), | 417 spill_slot_(), |
| 397 uses_(NULL), | 418 uses_(NULL), |
| 398 first_use_interval_(NULL), | 419 first_use_interval_(NULL), |
| 399 last_use_interval_(NULL), | 420 last_use_interval_(NULL), |
| 421 first_safepoint_(NULL), | |
| 422 last_safepoint_(NULL), | |
| 400 next_sibling_(NULL), | 423 next_sibling_(NULL), |
| 401 finger_() { | 424 finger_() { |
| 402 } | 425 } |
| 403 | 426 |
| 404 static LiveRange* MakeTemp(intptr_t pos, Location* location_slot); | 427 static LiveRange* MakeTemp(intptr_t pos, Location* location_slot); |
| 405 | 428 |
| 406 intptr_t vreg() const { return vreg_; } | 429 intptr_t vreg() const { return vreg_; } |
| 407 LiveRange* next_sibling() const { return next_sibling_; } | 430 LiveRange* next_sibling() const { return next_sibling_; } |
| 408 UsePosition* first_use() const { return uses_; } | 431 UsePosition* first_use() const { return uses_; } |
| 409 void set_first_use(UsePosition* use) { uses_ = use; } | 432 void set_first_use(UsePosition* use) { uses_ = use; } |
| 410 UseInterval* first_use_interval() const { return first_use_interval_; } | 433 UseInterval* first_use_interval() const { return first_use_interval_; } |
| 411 UseInterval* last_use_interval() const { return last_use_interval_; } | 434 UseInterval* last_use_interval() const { return last_use_interval_; } |
| 412 Location assigned_location() const { return assigned_location_; } | 435 Location assigned_location() const { return assigned_location_; } |
| 413 intptr_t Start() const { return first_use_interval()->start(); } | 436 intptr_t Start() const { return first_use_interval()->start(); } |
| 414 intptr_t End() const { return last_use_interval()->end(); } | 437 intptr_t End() const { return last_use_interval()->end(); } |
| 415 | 438 |
| 439 SafepointPosition* first_safepoint() const { return first_safepoint_; } | |
| 440 | |
| 416 AllocationFinger* finger() { return &finger_; } | 441 AllocationFinger* finger() { return &finger_; } |
| 417 | 442 |
| 418 void set_assigned_location(Location location) { | 443 void set_assigned_location(Location location) { |
| 419 assigned_location_ = location; | 444 assigned_location_ = location; |
| 420 } | 445 } |
| 421 | 446 |
| 422 void set_spill_slot(Location spill_slot) { | 447 void set_spill_slot(Location spill_slot) { |
| 423 spill_slot_ = spill_slot; | 448 spill_slot_ = spill_slot; |
| 424 } | 449 } |
| 425 | 450 |
| 426 void DefineAt(intptr_t pos); | 451 void DefineAt(intptr_t pos); |
| 427 | 452 |
| 453 void AddSafepoint(intptr_t pos, LocationSummary* locs); | |
| 454 | |
| 428 void AddUse(intptr_t pos, Location* location_slot); | 455 void AddUse(intptr_t pos, Location* location_slot); |
| 429 void AddHintedUse(intptr_t pos, Location* location_slot, Location* hint); | 456 void AddHintedUse(intptr_t pos, Location* location_slot, Location* hint); |
| 430 | 457 |
| 431 void AddUseInterval(intptr_t start, intptr_t end); | 458 void AddUseInterval(intptr_t start, intptr_t end); |
| 432 | 459 |
| 433 void Print(); | 460 void Print(); |
| 434 | 461 |
| 435 void AssignLocation(UseInterval* use, Location loc); | 462 void AssignLocation(UseInterval* use, Location loc); |
| 436 | 463 |
| 437 LiveRange* SplitAt(intptr_t pos); | 464 LiveRange* SplitAt(intptr_t pos); |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 448 | 475 |
| 449 Location spill_slot() const { | 476 Location spill_slot() const { |
| 450 return spill_slot_; | 477 return spill_slot_; |
| 451 } | 478 } |
| 452 | 479 |
| 453 private: | 480 private: |
| 454 LiveRange(intptr_t vreg, | 481 LiveRange(intptr_t vreg, |
| 455 UsePosition* uses, | 482 UsePosition* uses, |
| 456 UseInterval* first_use_interval, | 483 UseInterval* first_use_interval, |
| 457 UseInterval* last_use_interval, | 484 UseInterval* last_use_interval, |
| 485 SafepointPosition* first_safepoint, | |
| 458 LiveRange* next_sibling) | 486 LiveRange* next_sibling) |
| 459 : vreg_(vreg), | 487 : vreg_(vreg), |
| 460 assigned_location_(), | 488 assigned_location_(), |
| 461 uses_(uses), | 489 uses_(uses), |
| 462 first_use_interval_(first_use_interval), | 490 first_use_interval_(first_use_interval), |
| 463 last_use_interval_(last_use_interval), | 491 last_use_interval_(last_use_interval), |
| 492 first_safepoint_(first_safepoint), | |
| 493 last_safepoint_(NULL), | |
| 464 next_sibling_(next_sibling), | 494 next_sibling_(next_sibling), |
| 465 finger_() { | 495 finger_() { |
| 466 } | 496 } |
| 467 | 497 |
| 468 const intptr_t vreg_; | 498 const intptr_t vreg_; |
| 469 Location assigned_location_; | 499 Location assigned_location_; |
| 470 Location spill_slot_; | 500 Location spill_slot_; |
| 471 | 501 |
| 472 UsePosition* uses_; | 502 UsePosition* uses_; |
| 473 UseInterval* first_use_interval_; | 503 UseInterval* first_use_interval_; |
| 474 UseInterval* last_use_interval_; | 504 UseInterval* last_use_interval_; |
| 475 | 505 |
| 506 SafepointPosition* first_safepoint_; | |
| 507 SafepointPosition* last_safepoint_; | |
| 508 | |
| 476 LiveRange* next_sibling_; | 509 LiveRange* next_sibling_; |
| 477 | 510 |
| 478 AllocationFinger finger_; | 511 AllocationFinger finger_; |
| 479 | 512 |
| 480 DISALLOW_COPY_AND_ASSIGN(LiveRange); | 513 DISALLOW_COPY_AND_ASSIGN(LiveRange); |
| 481 }; | 514 }; |
| 482 | 515 |
| 483 | 516 |
| 484 } // namespace dart | 517 } // namespace dart |
| 485 | 518 |
| 486 #endif // VM_FLOW_GRAPH_ALLOCATOR_H_ | 519 #endif // VM_FLOW_GRAPH_ALLOCATOR_H_ |
| OLD | NEW |