| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef V8_REGISTER_ALLOCATOR_H_ | 5 #ifndef V8_REGISTER_ALLOCATOR_H_ |
| 6 #define V8_REGISTER_ALLOCATOR_H_ | 6 #define V8_REGISTER_ALLOCATOR_H_ |
| 7 | 7 |
| 8 #include "src/compiler/instruction.h" | 8 #include "src/compiler/instruction.h" |
| 9 #include "src/ostreams.h" | 9 #include "src/ostreams.h" |
| 10 #include "src/zone-containers.h" | 10 #include "src/zone-containers.h" |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 266 void* hint_; | 266 void* hint_; |
| 267 UsePosition* next_; | 267 UsePosition* next_; |
| 268 LifetimePosition const pos_; | 268 LifetimePosition const pos_; |
| 269 uint32_t flags_; | 269 uint32_t flags_; |
| 270 | 270 |
| 271 DISALLOW_COPY_AND_ASSIGN(UsePosition); | 271 DISALLOW_COPY_AND_ASSIGN(UsePosition); |
| 272 }; | 272 }; |
| 273 | 273 |
| 274 | 274 |
| 275 class SpillRange; | 275 class SpillRange; |
| 276 | 276 class RegisterAllocationData; |
| 277 | 277 |
| 278 // Representation of SSA values' live ranges as a collection of (continuous) | 278 // Representation of SSA values' live ranges as a collection of (continuous) |
| 279 // intervals over the instruction ordering. | 279 // intervals over the instruction ordering. |
| 280 class LiveRange final : public ZoneObject { | 280 class LiveRange final : public ZoneObject { |
| 281 public: | 281 public: |
| 282 explicit LiveRange(int id, MachineType machine_type); | 282 explicit LiveRange(int id, MachineType machine_type); |
| 283 | 283 |
| 284 UseInterval* first_interval() const { return first_interval_; } | 284 UseInterval* first_interval() const { return first_interval_; } |
| 285 UsePosition* first_pos() const { return first_pos_; } | 285 UsePosition* first_pos() const { return first_pos_; } |
| 286 LiveRange* parent() const { return parent_; } | 286 LiveRange* parent() const { return parent_; } |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 348 LifetimePosition start) const; | 348 LifetimePosition start) const; |
| 349 | 349 |
| 350 // Can this live range be spilled at this position. | 350 // Can this live range be spilled at this position. |
| 351 bool CanBeSpilled(LifetimePosition pos) const; | 351 bool CanBeSpilled(LifetimePosition pos) const; |
| 352 | 352 |
| 353 // Split this live range at the given position which must follow the start of | 353 // Split this live range at the given position which must follow the start of |
| 354 // the range. | 354 // the range. |
| 355 // All uses following the given position will be moved from this | 355 // All uses following the given position will be moved from this |
| 356 // live range to the result live range. | 356 // live range to the result live range. |
| 357 void SplitAt(LifetimePosition position, LiveRange* result, Zone* zone); | 357 void SplitAt(LifetimePosition position, LiveRange* result, Zone* zone); |
| 358 void Splinter(LifetimePosition start, LifetimePosition end, LiveRange* result, |
| 359 Zone* zone); |
| 360 void Merge(LiveRange* other, RegisterAllocationData* data); |
| 358 | 361 |
| 359 // Returns nullptr when no register is hinted, otherwise sets register_index. | 362 // Returns nullptr when no register is hinted, otherwise sets register_index. |
| 360 UsePosition* FirstHintPosition(int* register_index) const; | 363 UsePosition* FirstHintPosition(int* register_index) const; |
| 361 UsePosition* FirstHintPosition() const { | 364 UsePosition* FirstHintPosition() const { |
| 362 int register_index; | 365 int register_index; |
| 363 return FirstHintPosition(®ister_index); | 366 return FirstHintPosition(®ister_index); |
| 364 } | 367 } |
| 365 | 368 |
| 366 UsePosition* current_hint_position() const { | 369 UsePosition* current_hint_position() const { |
| 367 DCHECK(current_hint_position_ == FirstHintPosition()); | 370 DCHECK(current_hint_position_ == FirstHintPosition()); |
| 368 return current_hint_position_; | 371 return current_hint_position_; |
| 369 } | 372 } |
| 370 | 373 |
| 371 LifetimePosition Start() const { | 374 LifetimePosition Start() const { |
| 372 DCHECK(!IsEmpty()); | 375 DCHECK(!IsEmpty()); |
| 373 return first_interval()->start(); | 376 return first_interval()->start(); |
| 374 } | 377 } |
| 375 | 378 |
| 376 LifetimePosition End() const { | 379 LifetimePosition End() const { |
| 377 DCHECK(!IsEmpty()); | 380 DCHECK(!IsEmpty()); |
| 378 return last_interval_->end(); | 381 return last_interval_->end(); |
| 379 } | 382 } |
| 380 | 383 |
| 381 enum class SpillType { kNoSpillType, kSpillOperand, kSpillRange }; | 384 enum class SpillType { kNoSpillType, kSpillOperand, kSpillRange }; |
| 382 SpillType spill_type() const { return SpillTypeField::decode(bits_); } | 385 SpillType spill_type() const { return SpillTypeField::decode(bits_); } |
| 383 InstructionOperand* GetSpillOperand() const { | 386 InstructionOperand* GetSpillOperand() const { |
| 384 DCHECK(spill_type() == SpillType::kSpillOperand); | 387 DCHECK(spill_type() == SpillType::kSpillOperand); |
| 385 return spill_operand_; | 388 return spill_operand_; |
| 386 } | 389 } |
| 390 |
| 391 SpillRange* GetAllocatedSpillRange() const { |
| 392 DCHECK(spill_type() != SpillType::kSpillOperand); |
| 393 return spill_range_; |
| 394 } |
| 395 |
| 387 SpillRange* GetSpillRange() const { | 396 SpillRange* GetSpillRange() const { |
| 388 DCHECK(spill_type() == SpillType::kSpillRange); | 397 DCHECK(spill_type() == SpillType::kSpillRange); |
| 389 return spill_range_; | 398 return spill_range_; |
| 390 } | 399 } |
| 391 bool HasNoSpillType() const { | 400 bool HasNoSpillType() const { |
| 392 return spill_type() == SpillType::kNoSpillType; | 401 return spill_type() == SpillType::kNoSpillType; |
| 393 } | 402 } |
| 394 bool HasSpillOperand() const { | 403 bool HasSpillOperand() const { |
| 395 return spill_type() == SpillType::kSpillOperand; | 404 return spill_type() == SpillType::kSpillOperand; |
| 396 } | 405 } |
| 397 bool HasSpillRange() const { return spill_type() == SpillType::kSpillRange; } | 406 bool HasSpillRange() const { return spill_type() == SpillType::kSpillRange; } |
| 407 bool MayRequireSpillRange() const { |
| 408 DCHECK(!IsChild() && !IsSplinter()); |
| 409 return !HasSpillOperand() && spill_range_ == nullptr; |
| 410 } |
| 411 |
| 398 AllocatedOperand GetSpillRangeOperand() const; | 412 AllocatedOperand GetSpillRangeOperand() const; |
| 399 | 413 |
| 400 void SpillAtDefinition(Zone* zone, int gap_index, | 414 void SpillAtDefinition(Zone* zone, int gap_index, |
| 401 InstructionOperand* operand); | 415 InstructionOperand* operand); |
| 402 void SetSpillOperand(InstructionOperand* operand); | 416 void SetSpillOperand(InstructionOperand* operand); |
| 403 void SetSpillRange(SpillRange* spill_range); | 417 void SetSpillRange(SpillRange* spill_range); |
| 404 void CommitSpillsAtDefinition(InstructionSequence* sequence, | 418 void CommitSpillsAtDefinition(InstructionSequence* sequence, |
| 405 const InstructionOperand& operand, | 419 const InstructionOperand& operand, |
| 406 bool might_be_duplicated); | 420 bool might_be_duplicated); |
| 407 // This must be applied on top level ranges. | 421 // This must be applied on top level ranges. |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 451 void set_weight(float weight) { weight_ = weight; } | 465 void set_weight(float weight) { weight_ = weight; } |
| 452 | 466 |
| 453 bool IsSpilledOnlyInDeferredBlocks() const { | 467 bool IsSpilledOnlyInDeferredBlocks() const { |
| 454 return spilled_in_deferred_block_; | 468 return spilled_in_deferred_block_; |
| 455 } | 469 } |
| 456 | 470 |
| 457 static const int kInvalidSize = -1; | 471 static const int kInvalidSize = -1; |
| 458 static const float kInvalidWeight; | 472 static const float kInvalidWeight; |
| 459 static const float kMaxWeight; | 473 static const float kMaxWeight; |
| 460 | 474 |
| 461 private: | 475 LiveRange* splintered_from() const { |
| 476 DCHECK(!IsChild()); |
| 477 return splintered_from_; |
| 478 } |
| 479 bool IsSplinter() const { |
| 480 DCHECK(!IsChild()); |
| 481 return splintered_from_ != nullptr; |
| 482 } |
| 483 |
| 462 void set_spill_type(SpillType value) { | 484 void set_spill_type(SpillType value) { |
| 463 bits_ = SpillTypeField::update(bits_, value); | 485 bits_ = SpillTypeField::update(bits_, value); |
| 464 } | 486 } |
| 465 | 487 |
| 488 private: |
| 489 void AppendChild(LiveRange* other); |
| 490 void UpdateParentForAllChildren(LiveRange* new_parent); |
| 491 void UpdateSpillRangePostMerge(LiveRange* merged); |
| 492 |
| 493 void SetSplinteredFrom(LiveRange* splinter_parent); |
| 494 |
| 495 |
| 466 void set_spilled(bool value) { bits_ = SpilledField::update(bits_, value); } | 496 void set_spilled(bool value) { bits_ = SpilledField::update(bits_, value); } |
| 467 | 497 |
| 468 UseInterval* FirstSearchIntervalForPosition(LifetimePosition position) const; | 498 UseInterval* FirstSearchIntervalForPosition(LifetimePosition position) const; |
| 469 void AdvanceLastProcessedMarker(UseInterval* to_start_of, | 499 void AdvanceLastProcessedMarker(UseInterval* to_start_of, |
| 470 LifetimePosition but_not_past) const; | 500 LifetimePosition but_not_past) const; |
| 471 | 501 |
| 502 LiveRange* GetLastChild(); |
| 503 |
| 472 typedef BitField<bool, 0, 1> SpilledField; | 504 typedef BitField<bool, 0, 1> SpilledField; |
| 473 typedef BitField<bool, 1, 1> HasSlotUseField; | 505 typedef BitField<bool, 1, 1> HasSlotUseField; |
| 474 typedef BitField<bool, 2, 1> IsPhiField; | 506 typedef BitField<bool, 2, 1> IsPhiField; |
| 475 typedef BitField<bool, 3, 1> IsNonLoopPhiField; | 507 typedef BitField<bool, 3, 1> IsNonLoopPhiField; |
| 476 typedef BitField<SpillType, 4, 2> SpillTypeField; | 508 typedef BitField<SpillType, 4, 2> SpillTypeField; |
| 477 typedef BitField<int32_t, 6, 6> AssignedRegisterField; | 509 typedef BitField<int32_t, 6, 6> AssignedRegisterField; |
| 478 typedef BitField<MachineType, 12, 15> MachineTypeField; | 510 typedef BitField<MachineType, 12, 15> MachineTypeField; |
| 479 | 511 |
| 480 int id_; | 512 int id_; |
| 481 int spill_start_index_; | 513 int spill_start_index_; |
| 482 uint32_t bits_; | 514 uint32_t bits_; |
| 483 UseInterval* last_interval_; | 515 UseInterval* last_interval_; |
| 484 UseInterval* first_interval_; | 516 UseInterval* first_interval_; |
| 485 UsePosition* first_pos_; | 517 UsePosition* first_pos_; |
| 486 LiveRange* parent_; | 518 LiveRange* parent_; |
| 487 LiveRange* next_; | 519 LiveRange* next_; |
| 520 LiveRange* splintered_from_; |
| 488 union { | 521 union { |
| 489 // Correct value determined by spill_type() | 522 // Correct value determined by spill_type() |
| 490 InstructionOperand* spill_operand_; | 523 InstructionOperand* spill_operand_; |
| 491 SpillRange* spill_range_; | 524 SpillRange* spill_range_; |
| 492 }; | 525 }; |
| 493 SpillAtDefinitionList* spills_at_definition_; | 526 SpillAtDefinitionList* spills_at_definition_; |
| 494 // This is used as a cache, it doesn't affect correctness. | 527 // This is used as a cache, it doesn't affect correctness. |
| 495 mutable UseInterval* current_interval_; | 528 mutable UseInterval* current_interval_; |
| 496 // This is used as a cache, it doesn't affect correctness. | 529 // This is used as a cache, it doesn't affect correctness. |
| 497 mutable UsePosition* last_processed_use_; | 530 mutable UsePosition* last_processed_use_; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 536 bool TryMerge(SpillRange* other); | 569 bool TryMerge(SpillRange* other); |
| 537 | 570 |
| 538 void set_assigned_slot(int index) { | 571 void set_assigned_slot(int index) { |
| 539 DCHECK_EQ(kUnassignedSlot, assigned_slot_); | 572 DCHECK_EQ(kUnassignedSlot, assigned_slot_); |
| 540 assigned_slot_ = index; | 573 assigned_slot_ = index; |
| 541 } | 574 } |
| 542 int assigned_slot() { | 575 int assigned_slot() { |
| 543 DCHECK_NE(kUnassignedSlot, assigned_slot_); | 576 DCHECK_NE(kUnassignedSlot, assigned_slot_); |
| 544 return assigned_slot_; | 577 return assigned_slot_; |
| 545 } | 578 } |
| 579 const ZoneVector<LiveRange*>& live_ranges() const { return live_ranges_; } |
| 580 ZoneVector<LiveRange*>& live_ranges() { return live_ranges_; } |
| 581 int byte_width() const { return byte_width_; } |
| 582 RegisterKind kind() const { return kind_; } |
| 546 | 583 |
| 547 private: | 584 private: |
| 548 LifetimePosition End() const { return end_position_; } | 585 LifetimePosition End() const { return end_position_; } |
| 549 ZoneVector<LiveRange*>& live_ranges() { return live_ranges_; } | |
| 550 bool IsIntersectingWith(SpillRange* other) const; | 586 bool IsIntersectingWith(SpillRange* other) const; |
| 551 // Merge intervals, making sure the use intervals are sorted | 587 // Merge intervals, making sure the use intervals are sorted |
| 552 void MergeDisjointIntervals(UseInterval* other); | 588 void MergeDisjointIntervals(UseInterval* other); |
| 553 | 589 |
| 554 ZoneVector<LiveRange*> live_ranges_; | 590 ZoneVector<LiveRange*> live_ranges_; |
| 555 UseInterval* use_interval_; | 591 UseInterval* use_interval_; |
| 556 LifetimePosition end_position_; | 592 LifetimePosition end_position_; |
| 557 int assigned_slot_; | 593 int assigned_slot_; |
| 594 int byte_width_; |
| 595 RegisterKind kind_; |
| 558 | 596 |
| 559 DISALLOW_COPY_AND_ASSIGN(SpillRange); | 597 DISALLOW_COPY_AND_ASSIGN(SpillRange); |
| 560 }; | 598 }; |
| 561 | 599 |
| 562 | 600 |
| 563 class RegisterAllocationData final : public ZoneObject { | 601 class RegisterAllocationData final : public ZoneObject { |
| 564 public: | 602 public: |
| 565 class PhiMapValue : public ZoneObject { | 603 class PhiMapValue : public ZoneObject { |
| 566 public: | 604 public: |
| 567 PhiMapValue(PhiInstruction* phi, const InstructionBlock* block, Zone* zone); | 605 PhiMapValue(PhiInstruction* phi, const InstructionBlock* block, Zone* zone); |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 605 return fixed_live_ranges_; | 643 return fixed_live_ranges_; |
| 606 } | 644 } |
| 607 ZoneVector<LiveRange*>& fixed_live_ranges() { return fixed_live_ranges_; } | 645 ZoneVector<LiveRange*>& fixed_live_ranges() { return fixed_live_ranges_; } |
| 608 ZoneVector<LiveRange*>& fixed_double_live_ranges() { | 646 ZoneVector<LiveRange*>& fixed_double_live_ranges() { |
| 609 return fixed_double_live_ranges_; | 647 return fixed_double_live_ranges_; |
| 610 } | 648 } |
| 611 const ZoneVector<LiveRange*>& fixed_double_live_ranges() const { | 649 const ZoneVector<LiveRange*>& fixed_double_live_ranges() const { |
| 612 return fixed_double_live_ranges_; | 650 return fixed_double_live_ranges_; |
| 613 } | 651 } |
| 614 ZoneVector<BitVector*>& live_in_sets() { return live_in_sets_; } | 652 ZoneVector<BitVector*>& live_in_sets() { return live_in_sets_; } |
| 615 ZoneVector<SpillRange*>& spill_ranges() { return spill_ranges_; } | 653 ZoneSet<SpillRange*>& spill_ranges() { return spill_ranges_; } |
| 616 DelayedReferences& delayed_references() { return delayed_references_; } | 654 DelayedReferences& delayed_references() { return delayed_references_; } |
| 617 InstructionSequence* code() const { return code_; } | 655 InstructionSequence* code() const { return code_; } |
| 618 // This zone is for datastructures only needed during register allocation | 656 // This zone is for datastructures only needed during register allocation |
| 619 // phases. | 657 // phases. |
| 620 Zone* allocation_zone() const { return allocation_zone_; } | 658 Zone* allocation_zone() const { return allocation_zone_; } |
| 621 // This zone is for InstructionOperands and moves that live beyond register | 659 // This zone is for InstructionOperands and moves that live beyond register |
| 622 // allocation. | 660 // allocation. |
| 623 Zone* code_zone() const { return code()->zone(); } | 661 Zone* code_zone() const { return code()->zone(); } |
| 624 Frame* frame() const { return frame_; } | 662 Frame* frame() const { return frame_; } |
| 625 const char* debug_name() const { return debug_name_; } | 663 const char* debug_name() const { return debug_name_; } |
| 626 const RegisterConfiguration* config() const { return config_; } | 664 const RegisterConfiguration* config() const { return config_; } |
| 627 | 665 |
| 628 MachineType MachineTypeFor(int virtual_register); | 666 MachineType MachineTypeFor(int virtual_register); |
| 629 | 667 |
| 630 LiveRange* LiveRangeFor(int index); | 668 LiveRange* LiveRangeFor(int index); |
| 631 // Creates a new live range. | 669 // Creates a new live range. |
| 632 LiveRange* NewLiveRange(int index, MachineType machine_type); | 670 LiveRange* NewLiveRange(int index, MachineType machine_type); |
| 671 LiveRange* NextLiveRange(MachineType machine_type); |
| 633 LiveRange* NewChildRangeFor(LiveRange* range); | 672 LiveRange* NewChildRangeFor(LiveRange* range); |
| 634 | 673 |
| 635 SpillRange* AssignSpillRangeToLiveRange(LiveRange* range); | 674 SpillRange* AssignSpillRangeToLiveRange(LiveRange* range); |
| 675 SpillRange* CreateSpillRangeForLiveRange(LiveRange* range); |
| 636 | 676 |
| 637 MoveOperands* AddGapMove(int index, Instruction::GapPosition position, | 677 MoveOperands* AddGapMove(int index, Instruction::GapPosition position, |
| 638 const InstructionOperand& from, | 678 const InstructionOperand& from, |
| 639 const InstructionOperand& to); | 679 const InstructionOperand& to); |
| 640 | 680 |
| 641 bool IsReference(int virtual_register) const { | 681 bool IsReference(int virtual_register) const { |
| 642 return code()->IsReference(virtual_register); | 682 return code()->IsReference(virtual_register); |
| 643 } | 683 } |
| 644 | 684 |
| 645 bool ExistsUseWithoutDefinition(); | 685 bool ExistsUseWithoutDefinition(); |
| 646 | 686 |
| 647 void MarkAllocated(RegisterKind kind, int index); | 687 void MarkAllocated(RegisterKind kind, int index); |
| 648 | 688 |
| 649 PhiMapValue* InitializePhiMap(const InstructionBlock* block, | 689 PhiMapValue* InitializePhiMap(const InstructionBlock* block, |
| 650 PhiInstruction* phi); | 690 PhiInstruction* phi); |
| 651 PhiMapValue* GetPhiMapValueFor(int virtual_register); | 691 PhiMapValue* GetPhiMapValueFor(int virtual_register); |
| 652 bool IsBlockBoundary(LifetimePosition pos) const; | 692 bool IsBlockBoundary(LifetimePosition pos) const; |
| 653 | 693 |
| 654 void Print(const InstructionSequence* instructionSequence); | 694 void Print(const InstructionSequence* instructionSequence); |
| 655 void Print(const Instruction* instruction); | 695 void Print(const Instruction* instruction); |
| 656 void Print(const LiveRange* range, bool with_children = false); | 696 void Print(const LiveRange* range, bool with_children = false); |
| 657 void Print(const InstructionOperand& op); | 697 void Print(const InstructionOperand& op); |
| 658 void Print(const MoveOperands* move); | 698 void Print(const MoveOperands* move); |
| 699 void Print(const SpillRange* spill_range); |
| 659 | 700 |
| 660 private: | 701 private: |
| 661 Zone* const allocation_zone_; | 702 Zone* const allocation_zone_; |
| 662 Frame* const frame_; | 703 Frame* const frame_; |
| 663 InstructionSequence* const code_; | 704 InstructionSequence* const code_; |
| 664 const char* const debug_name_; | 705 const char* const debug_name_; |
| 665 const RegisterConfiguration* const config_; | 706 const RegisterConfiguration* const config_; |
| 666 PhiMap phi_map_; | 707 PhiMap phi_map_; |
| 667 ZoneVector<BitVector*> live_in_sets_; | 708 ZoneVector<BitVector*> live_in_sets_; |
| 668 ZoneVector<LiveRange*> live_ranges_; | 709 ZoneVector<LiveRange*> live_ranges_; |
| 669 ZoneVector<LiveRange*> fixed_live_ranges_; | 710 ZoneVector<LiveRange*> fixed_live_ranges_; |
| 670 ZoneVector<LiveRange*> fixed_double_live_ranges_; | 711 ZoneVector<LiveRange*> fixed_double_live_ranges_; |
| 671 ZoneVector<SpillRange*> spill_ranges_; | 712 ZoneSet<SpillRange*> spill_ranges_; |
| 672 DelayedReferences delayed_references_; | 713 DelayedReferences delayed_references_; |
| 673 BitVector* assigned_registers_; | 714 BitVector* assigned_registers_; |
| 674 BitVector* assigned_double_registers_; | 715 BitVector* assigned_double_registers_; |
| 675 int virtual_register_count_; | 716 int virtual_register_count_; |
| 676 | 717 |
| 677 DISALLOW_COPY_AND_ASSIGN(RegisterAllocationData); | 718 DISALLOW_COPY_AND_ASSIGN(RegisterAllocationData); |
| 678 }; | 719 }; |
| 679 | 720 |
| 680 | 721 |
| 681 class ConstraintBuilder final : public ZoneObject { | 722 class ConstraintBuilder final : public ZoneObject { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 714 DISALLOW_COPY_AND_ASSIGN(ConstraintBuilder); | 755 DISALLOW_COPY_AND_ASSIGN(ConstraintBuilder); |
| 715 }; | 756 }; |
| 716 | 757 |
| 717 | 758 |
| 718 class LiveRangeBuilder final : public ZoneObject { | 759 class LiveRangeBuilder final : public ZoneObject { |
| 719 public: | 760 public: |
| 720 explicit LiveRangeBuilder(RegisterAllocationData* data, Zone* local_zone); | 761 explicit LiveRangeBuilder(RegisterAllocationData* data, Zone* local_zone); |
| 721 | 762 |
| 722 // Phase 3: compute liveness of all virtual register. | 763 // Phase 3: compute liveness of all virtual register. |
| 723 void BuildLiveRanges(); | 764 void BuildLiveRanges(); |
| 765 static BitVector* ComputeLiveOut(const InstructionBlock* block, |
| 766 RegisterAllocationData* data); |
| 724 | 767 |
| 725 private: | 768 private: |
| 726 RegisterAllocationData* data() const { return data_; } | 769 RegisterAllocationData* data() const { return data_; } |
| 727 InstructionSequence* code() const { return data()->code(); } | 770 InstructionSequence* code() const { return data()->code(); } |
| 728 Zone* allocation_zone() const { return data()->allocation_zone(); } | 771 Zone* allocation_zone() const { return data()->allocation_zone(); } |
| 729 Zone* code_zone() const { return code()->zone(); } | 772 Zone* code_zone() const { return code()->zone(); } |
| 730 const RegisterConfiguration* config() const { return data()->config(); } | 773 const RegisterConfiguration* config() const { return data()->config(); } |
| 731 ZoneVector<BitVector*>& live_in_sets() const { | 774 ZoneVector<BitVector*>& live_in_sets() const { |
| 732 return data()->live_in_sets(); | 775 return data()->live_in_sets(); |
| 733 } | 776 } |
| 734 | 777 |
| 735 LiveRange* LiveRangeFor(int index) { return data()->LiveRangeFor(index); } | 778 LiveRange* LiveRangeFor(int index) { return data()->LiveRangeFor(index); } |
| 736 | 779 |
| 737 void Verify() const; | 780 void Verify() const; |
| 738 | 781 |
| 739 // Liveness analysis support. | 782 // Liveness analysis support. |
| 740 BitVector* ComputeLiveOut(const InstructionBlock* block); | |
| 741 void AddInitialIntervals(const InstructionBlock* block, BitVector* live_out); | 783 void AddInitialIntervals(const InstructionBlock* block, BitVector* live_out); |
| 742 void ProcessInstructions(const InstructionBlock* block, BitVector* live); | 784 void ProcessInstructions(const InstructionBlock* block, BitVector* live); |
| 743 void ProcessPhis(const InstructionBlock* block, BitVector* live); | 785 void ProcessPhis(const InstructionBlock* block, BitVector* live); |
| 744 void ProcessLoopHeader(const InstructionBlock* block, BitVector* live); | 786 void ProcessLoopHeader(const InstructionBlock* block, BitVector* live); |
| 745 | 787 |
| 746 static int FixedLiveRangeID(int index) { return -index - 1; } | 788 static int FixedLiveRangeID(int index) { return -index - 1; } |
| 747 int FixedDoubleLiveRangeID(int index); | 789 int FixedDoubleLiveRangeID(int index); |
| 748 LiveRange* FixedLiveRangeFor(int index); | 790 LiveRange* FixedLiveRangeFor(int index); |
| 749 LiveRange* FixedDoubleLiveRangeFor(int index); | 791 LiveRange* FixedDoubleLiveRangeFor(int index); |
| 750 | 792 |
| (...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 978 RegisterAllocationData* const data_; | 1020 RegisterAllocationData* const data_; |
| 979 | 1021 |
| 980 DISALLOW_COPY_AND_ASSIGN(LiveRangeConnector); | 1022 DISALLOW_COPY_AND_ASSIGN(LiveRangeConnector); |
| 981 }; | 1023 }; |
| 982 | 1024 |
| 983 } // namespace compiler | 1025 } // namespace compiler |
| 984 } // namespace internal | 1026 } // namespace internal |
| 985 } // namespace v8 | 1027 } // namespace v8 |
| 986 | 1028 |
| 987 #endif // V8_REGISTER_ALLOCATOR_H_ | 1029 #endif // V8_REGISTER_ALLOCATOR_H_ |
| OLD | NEW |