| 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/register-configuration.h" | 10 #include "src/register-configuration.h" |
| (...skipping 561 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 572 const InstructionOperand& operand, | 572 const InstructionOperand& operand, |
| 573 bool might_be_duplicated); | 573 bool might_be_duplicated); |
| 574 | 574 |
| 575 // If all the children of this range are spilled in deferred blocks, and if | 575 // If all the children of this range are spilled in deferred blocks, and if |
| 576 // for any non-spilled child with a use position requiring a slot, that range | 576 // for any non-spilled child with a use position requiring a slot, that range |
| 577 // is contained in a deferred block, mark the range as | 577 // is contained in a deferred block, mark the range as |
| 578 // IsSpilledOnlyInDeferredBlocks, so that we avoid spilling at definition, | 578 // IsSpilledOnlyInDeferredBlocks, so that we avoid spilling at definition, |
| 579 // and instead let the LiveRangeConnector perform the spills within the | 579 // and instead let the LiveRangeConnector perform the spills within the |
| 580 // deferred blocks. If so, we insert here spills for non-spilled ranges | 580 // deferred blocks. If so, we insert here spills for non-spilled ranges |
| 581 // with slot use positions. | 581 // with slot use positions. |
| 582 void MarkSpilledInDeferredBlock() { | 582 void TreatAsSpilledInDeferredBlock(Zone* zone, int total_block_count) { |
| 583 spill_start_index_ = -1; | 583 spill_start_index_ = -1; |
| 584 spilled_in_deferred_blocks_ = true; | 584 spilled_in_deferred_blocks_ = true; |
| 585 spill_move_insertion_locations_ = nullptr; | 585 spill_move_insertion_locations_ = nullptr; |
| 586 list_of_blocks_requiring_spill_operands_ = |
| 587 new (zone) BitVector(total_block_count, zone); |
| 586 } | 588 } |
| 587 | 589 |
| 588 bool TryCommitSpillInDeferredBlock(InstructionSequence* code, | 590 void CommitSpillInDeferredBlocks(RegisterAllocationData* data, |
| 589 const InstructionOperand& spill_operand); | 591 const InstructionOperand& spill_operand, |
| 592 BitVector* necessary_spill_points); |
| 590 | 593 |
| 591 TopLevelLiveRange* splintered_from() const { return splintered_from_; } | 594 TopLevelLiveRange* splintered_from() const { return splintered_from_; } |
| 592 bool IsSplinter() const { return splintered_from_ != nullptr; } | 595 bool IsSplinter() const { return splintered_from_ != nullptr; } |
| 593 bool MayRequireSpillRange() const { | 596 bool MayRequireSpillRange() const { |
| 594 DCHECK(!IsSplinter()); | 597 DCHECK(!IsSplinter()); |
| 595 return !HasSpillOperand() && spill_range_ == nullptr; | 598 return !HasSpillOperand() && spill_range_ == nullptr; |
| 596 } | 599 } |
| 597 void UpdateSpillRangePostMerge(TopLevelLiveRange* merged); | 600 void UpdateSpillRangePostMerge(TopLevelLiveRange* merged); |
| 598 int vreg() const { return vreg_; } | 601 int vreg() const { return vreg_; } |
| 599 | 602 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 610 } | 613 } |
| 611 | 614 |
| 612 int GetChildCount() const { return last_child_id_ + 1; } | 615 int GetChildCount() const { return last_child_id_ + 1; } |
| 613 | 616 |
| 614 bool IsSpilledOnlyInDeferredBlocks() const { | 617 bool IsSpilledOnlyInDeferredBlocks() const { |
| 615 return spilled_in_deferred_blocks_; | 618 return spilled_in_deferred_blocks_; |
| 616 } | 619 } |
| 617 | 620 |
| 618 struct SpillMoveInsertionList; | 621 struct SpillMoveInsertionList; |
| 619 | 622 |
| 620 SpillMoveInsertionList* spill_move_insertion_locations() const { | 623 SpillMoveInsertionList* GetSpillMoveInsertionLocations() const { |
| 624 DCHECK(!IsSpilledOnlyInDeferredBlocks()); |
| 621 return spill_move_insertion_locations_; | 625 return spill_move_insertion_locations_; |
| 622 } | 626 } |
| 623 TopLevelLiveRange* splinter() const { return splinter_; } | 627 TopLevelLiveRange* splinter() const { return splinter_; } |
| 624 void SetSplinter(TopLevelLiveRange* splinter) { | 628 void SetSplinter(TopLevelLiveRange* splinter) { |
| 625 DCHECK_NULL(splinter_); | 629 DCHECK_NULL(splinter_); |
| 626 DCHECK_NOT_NULL(splinter); | 630 DCHECK_NOT_NULL(splinter); |
| 627 | 631 |
| 628 splinter_ = splinter; | 632 splinter_ = splinter; |
| 629 splinter->relative_id_ = GetNextChildId(); | 633 splinter->relative_id_ = GetNextChildId(); |
| 630 splinter->set_spill_type(spill_type()); | 634 splinter->set_spill_type(spill_type()); |
| 631 splinter->SetSplinteredFrom(this); | 635 splinter->SetSplinteredFrom(this); |
| 632 } | 636 } |
| 633 | 637 |
| 634 void MarkHasPreassignedSlot() { has_preassigned_slot_ = true; } | 638 void MarkHasPreassignedSlot() { has_preassigned_slot_ = true; } |
| 635 bool has_preassigned_slot() const { return has_preassigned_slot_; } | 639 bool has_preassigned_slot() const { return has_preassigned_slot_; } |
| 636 | 640 |
| 641 void AddBlockRequiringSpillOperand(RpoNumber block_id) { |
| 642 DCHECK(IsSpilledOnlyInDeferredBlocks()); |
| 643 GetListOfBlocksRequiringSpillOperands()->Add(block_id.ToInt()); |
| 644 } |
| 645 |
| 646 BitVector* GetListOfBlocksRequiringSpillOperands() const { |
| 647 DCHECK(IsSpilledOnlyInDeferredBlocks()); |
| 648 return list_of_blocks_requiring_spill_operands_; |
| 649 } |
| 650 |
| 637 private: | 651 private: |
| 638 void SetSplinteredFrom(TopLevelLiveRange* splinter_parent); | 652 void SetSplinteredFrom(TopLevelLiveRange* splinter_parent); |
| 639 | 653 |
| 640 typedef BitField<bool, 1, 1> HasSlotUseField; | 654 typedef BitField<bool, 1, 1> HasSlotUseField; |
| 641 typedef BitField<bool, 2, 1> IsPhiField; | 655 typedef BitField<bool, 2, 1> IsPhiField; |
| 642 typedef BitField<bool, 3, 1> IsNonLoopPhiField; | 656 typedef BitField<bool, 3, 1> IsNonLoopPhiField; |
| 643 typedef BitField<SpillType, 4, 2> SpillTypeField; | 657 typedef BitField<SpillType, 4, 2> SpillTypeField; |
| 644 | 658 |
| 645 int vreg_; | 659 int vreg_; |
| 646 int last_child_id_; | 660 int last_child_id_; |
| 647 TopLevelLiveRange* splintered_from_; | 661 TopLevelLiveRange* splintered_from_; |
| 648 union { | 662 union { |
| 649 // Correct value determined by spill_type() | 663 // Correct value determined by spill_type() |
| 650 InstructionOperand* spill_operand_; | 664 InstructionOperand* spill_operand_; |
| 651 SpillRange* spill_range_; | 665 SpillRange* spill_range_; |
| 652 }; | 666 }; |
| 653 SpillMoveInsertionList* spill_move_insertion_locations_; | 667 |
| 668 union { |
| 669 SpillMoveInsertionList* spill_move_insertion_locations_; |
| 670 BitVector* list_of_blocks_requiring_spill_operands_; |
| 671 }; |
| 672 |
| 654 // TODO(mtrofin): generalize spilling after definition, currently specialized | 673 // TODO(mtrofin): generalize spilling after definition, currently specialized |
| 655 // just for spill in a single deferred block. | 674 // just for spill in a single deferred block. |
| 656 bool spilled_in_deferred_blocks_; | 675 bool spilled_in_deferred_blocks_; |
| 657 int spill_start_index_; | 676 int spill_start_index_; |
| 658 UsePosition* last_pos_; | 677 UsePosition* last_pos_; |
| 659 TopLevelLiveRange* splinter_; | 678 TopLevelLiveRange* splinter_; |
| 660 bool has_preassigned_slot_; | 679 bool has_preassigned_slot_; |
| 661 | 680 |
| 662 DISALLOW_COPY_AND_ASSIGN(TopLevelLiveRange); | 681 DISALLOW_COPY_AND_ASSIGN(TopLevelLiveRange); |
| 663 }; | 682 }; |
| (...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1118 RegisterAllocationData* data() const { return data_; } | 1137 RegisterAllocationData* data() const { return data_; } |
| 1119 | 1138 |
| 1120 bool SafePointsAreInOrder() const; | 1139 bool SafePointsAreInOrder() const; |
| 1121 | 1140 |
| 1122 RegisterAllocationData* const data_; | 1141 RegisterAllocationData* const data_; |
| 1123 | 1142 |
| 1124 DISALLOW_COPY_AND_ASSIGN(ReferenceMapPopulator); | 1143 DISALLOW_COPY_AND_ASSIGN(ReferenceMapPopulator); |
| 1125 }; | 1144 }; |
| 1126 | 1145 |
| 1127 | 1146 |
| 1147 class LiveRangeBoundArray; |
| 1128 // Insert moves of the form | 1148 // Insert moves of the form |
| 1129 // | 1149 // |
| 1130 // Operand(child_(k+1)) = Operand(child_k) | 1150 // Operand(child_(k+1)) = Operand(child_k) |
| 1131 // | 1151 // |
| 1132 // where child_k and child_(k+1) are consecutive children of a range (so | 1152 // where child_k and child_(k+1) are consecutive children of a range (so |
| 1133 // child_k->next() == child_(k+1)), and Operand(...) refers to the | 1153 // child_k->next() == child_(k+1)), and Operand(...) refers to the |
| 1134 // assigned operand, be it a register or a slot. | 1154 // assigned operand, be it a register or a slot. |
| 1135 class LiveRangeConnector final : public ZoneObject { | 1155 class LiveRangeConnector final : public ZoneObject { |
| 1136 public: | 1156 public: |
| 1137 explicit LiveRangeConnector(RegisterAllocationData* data); | 1157 explicit LiveRangeConnector(RegisterAllocationData* data); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 1150 InstructionSequence* code() const { return data()->code(); } | 1170 InstructionSequence* code() const { return data()->code(); } |
| 1151 Zone* code_zone() const { return code()->zone(); } | 1171 Zone* code_zone() const { return code()->zone(); } |
| 1152 | 1172 |
| 1153 bool CanEagerlyResolveControlFlow(const InstructionBlock* block) const; | 1173 bool CanEagerlyResolveControlFlow(const InstructionBlock* block) const; |
| 1154 | 1174 |
| 1155 int ResolveControlFlow(const InstructionBlock* block, | 1175 int ResolveControlFlow(const InstructionBlock* block, |
| 1156 const InstructionOperand& cur_op, | 1176 const InstructionOperand& cur_op, |
| 1157 const InstructionBlock* pred, | 1177 const InstructionBlock* pred, |
| 1158 const InstructionOperand& pred_op); | 1178 const InstructionOperand& pred_op); |
| 1159 | 1179 |
| 1180 void CommitSpillsInDeferredBlocks(TopLevelLiveRange* range, |
| 1181 LiveRangeBoundArray* array, |
| 1182 Zone* temp_zone); |
| 1183 |
| 1160 RegisterAllocationData* const data_; | 1184 RegisterAllocationData* const data_; |
| 1161 | 1185 |
| 1162 DISALLOW_COPY_AND_ASSIGN(LiveRangeConnector); | 1186 DISALLOW_COPY_AND_ASSIGN(LiveRangeConnector); |
| 1163 }; | 1187 }; |
| 1164 | 1188 |
| 1165 } // namespace compiler | 1189 } // namespace compiler |
| 1166 } // namespace internal | 1190 } // namespace internal |
| 1167 } // namespace v8 | 1191 } // namespace v8 |
| 1168 | 1192 |
| 1169 #endif // V8_REGISTER_ALLOCATOR_H_ | 1193 #endif // V8_REGISTER_ALLOCATOR_H_ |
| OLD | NEW |