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