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 |