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 #include "src/base/adapters.h" | 5 #include "src/base/adapters.h" |
6 #include "src/compiler/linkage.h" | 6 #include "src/compiler/linkage.h" |
7 #include "src/compiler/register-allocator.h" | 7 #include "src/compiler/register-allocator.h" |
8 #include "src/string-stream.h" | 8 #include "src/string-stream.h" |
9 | 9 |
10 namespace v8 { | 10 namespace v8 { |
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
420 | 420 |
421 | 421 |
422 LiveRange* LiveRange::SplitAt(LifetimePosition position, Zone* zone) { | 422 LiveRange* LiveRange::SplitAt(LifetimePosition position, Zone* zone) { |
423 int new_id = TopLevel()->GetNextChildId(); | 423 int new_id = TopLevel()->GetNextChildId(); |
424 LiveRange* child = new (zone) LiveRange(new_id, machine_type(), TopLevel()); | 424 LiveRange* child = new (zone) LiveRange(new_id, machine_type(), TopLevel()); |
425 DetachAt(position, child, zone); | 425 DetachAt(position, child, zone); |
426 | 426 |
427 child->top_level_ = TopLevel(); | 427 child->top_level_ = TopLevel(); |
428 child->next_ = next_; | 428 child->next_ = next_; |
429 next_ = child; | 429 next_ = child; |
430 | 430 if (child->next() == nullptr) { |
| 431 TopLevel()->set_last_child(child); |
| 432 } |
431 return child; | 433 return child; |
432 } | 434 } |
433 | 435 |
434 | 436 |
435 void LiveRange::DetachAt(LifetimePosition position, LiveRange* result, | 437 void LiveRange::DetachAt(LifetimePosition position, LiveRange* result, |
436 Zone* zone) { | 438 Zone* zone) { |
437 DCHECK(Start() < position); | 439 DCHECK(Start() < position); |
438 DCHECK(result->IsEmpty()); | 440 DCHECK(result->IsEmpty()); |
439 // Find the last interval that ends before the position. If the | 441 // Find the last interval that ends before the position. If the |
440 // position is contained in one of the intervals in the chain, we | 442 // position is contained in one of the intervals in the chain, we |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
517 result->Verify(); | 519 result->Verify(); |
518 #endif | 520 #endif |
519 } | 521 } |
520 | 522 |
521 | 523 |
522 void LiveRange::AppendAsChild(TopLevelLiveRange* other) { | 524 void LiveRange::AppendAsChild(TopLevelLiveRange* other) { |
523 next_ = other; | 525 next_ = other; |
524 | 526 |
525 other->UpdateParentForAllChildren(TopLevel()); | 527 other->UpdateParentForAllChildren(TopLevel()); |
526 TopLevel()->UpdateSpillRangePostMerge(other); | 528 TopLevel()->UpdateSpillRangePostMerge(other); |
| 529 TopLevel()->set_last_child(other->last_child()); |
527 } | 530 } |
528 | 531 |
529 | 532 |
530 void LiveRange::UpdateParentForAllChildren(TopLevelLiveRange* new_top_level) { | 533 void LiveRange::UpdateParentForAllChildren(TopLevelLiveRange* new_top_level) { |
531 LiveRange* child = this; | 534 LiveRange* child = this; |
532 for (; child != nullptr; child = child->next()) { | 535 for (; child != nullptr; child = child->next()) { |
533 child->top_level_ = new_top_level; | 536 child->top_level_ = new_top_level; |
534 } | 537 } |
535 } | 538 } |
536 | 539 |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
659 | 662 |
660 | 663 |
661 TopLevelLiveRange::TopLevelLiveRange(int vreg, MachineType machine_type) | 664 TopLevelLiveRange::TopLevelLiveRange(int vreg, MachineType machine_type) |
662 : LiveRange(0, machine_type, this), | 665 : LiveRange(0, machine_type, this), |
663 vreg_(vreg), | 666 vreg_(vreg), |
664 last_child_id_(0), | 667 last_child_id_(0), |
665 splintered_from_(nullptr), | 668 splintered_from_(nullptr), |
666 spill_operand_(nullptr), | 669 spill_operand_(nullptr), |
667 spills_at_definition_(nullptr), | 670 spills_at_definition_(nullptr), |
668 spilled_in_deferred_blocks_(false), | 671 spilled_in_deferred_blocks_(false), |
669 spill_start_index_(kMaxInt) { | 672 spill_start_index_(kMaxInt), |
| 673 last_child_(this), |
| 674 last_insertion_point_(this) { |
670 bits_ |= SpillTypeField::encode(SpillType::kNoSpillType); | 675 bits_ |= SpillTypeField::encode(SpillType::kNoSpillType); |
671 } | 676 } |
672 | 677 |
673 | 678 |
674 void TopLevelLiveRange::SpillAtDefinition(Zone* zone, int gap_index, | 679 void TopLevelLiveRange::SpillAtDefinition(Zone* zone, int gap_index, |
675 InstructionOperand* operand) { | 680 InstructionOperand* operand) { |
676 DCHECK(HasNoSpillType()); | 681 DCHECK(HasNoSpillType()); |
677 spills_at_definition_ = new (zone) | 682 spills_at_definition_ = new (zone) |
678 SpillAtDefinitionList(gap_index, operand, spills_at_definition_); | 683 SpillAtDefinitionList(gap_index, operand, spills_at_definition_); |
679 } | 684 } |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
875 if (HasNoSpillType() && merged->HasSpillRange()) { | 880 if (HasNoSpillType() && merged->HasSpillRange()) { |
876 set_spill_type(merged->spill_type()); | 881 set_spill_type(merged->spill_type()); |
877 DCHECK(GetSpillRange()->live_ranges().size() > 0); | 882 DCHECK(GetSpillRange()->live_ranges().size() > 0); |
878 merged->spill_range_ = nullptr; | 883 merged->spill_range_ = nullptr; |
879 merged->bits_ = | 884 merged->bits_ = |
880 SpillTypeField::update(merged->bits_, SpillType::kNoSpillType); | 885 SpillTypeField::update(merged->bits_, SpillType::kNoSpillType); |
881 } | 886 } |
882 } | 887 } |
883 | 888 |
884 | 889 |
885 LiveRange* TopLevelLiveRange::GetLastChild() { | |
886 LiveRange* ret = this; | |
887 for (; ret->next() != nullptr; ret = ret->next()) { | |
888 } | |
889 return ret; | |
890 } | |
891 | |
892 | |
893 void TopLevelLiveRange::Merge(TopLevelLiveRange* other, | 890 void TopLevelLiveRange::Merge(TopLevelLiveRange* other, |
894 RegisterAllocationData* data) { | 891 RegisterAllocationData* data) { |
895 DCHECK(Start() < other->Start()); | 892 DCHECK(Start() < other->Start()); |
| 893 DCHECK(other->splintered_from() == this); |
896 | 894 |
897 data->live_ranges()[other->vreg()] = nullptr; | 895 data->live_ranges()[other->vreg()] = nullptr; |
898 | 896 |
899 LiveRange* last_other = other->GetLastChild(); | 897 LiveRange* last_other = other->last_child(); |
900 LiveRange* last_me = GetLastChild(); | 898 LiveRange* last_me = last_child(); |
901 | 899 |
902 // Simple case: we just append at the end. | 900 // Simple case: we just append at the end. |
903 if (last_me->End() <= other->Start()) return last_me->AppendAsChild(other); | 901 if (last_me->End() <= other->Start()) return last_me->AppendAsChild(other); |
904 | 902 |
905 DCHECK(last_me->End() > last_other->End()); | 903 DCHECK(last_me->End() > last_other->End()); |
906 | 904 |
907 // In the more general case, we need to find the ranges between which to | 905 // In the more general case, we need to find the ranges between which to |
908 // insert. | 906 // insert. |
909 LiveRange* insertion_point = this; | 907 if (other->Start() < last_insertion_point_->Start()) { |
910 for (; insertion_point->next() != nullptr && | 908 last_insertion_point_ = this; |
911 insertion_point->next()->Start() <= other->Start(); | 909 } |
912 insertion_point = insertion_point->next()) { | 910 |
| 911 for (; last_insertion_point_->next() != nullptr && |
| 912 last_insertion_point_->next()->Start() <= other->Start(); |
| 913 last_insertion_point_ = last_insertion_point_->next()) { |
913 } | 914 } |
914 | 915 |
915 // When we splintered the original range, we reconstituted the original range | 916 // When we splintered the original range, we reconstituted the original range |
916 // into one range without children, but with discontinuities. To merge the | 917 // into one range without children, but with discontinuities. To merge the |
917 // splinter back in, we need to split the range - or a child obtained after | 918 // splinter back in, we need to split the range - or a child obtained after |
918 // register allocation splitting. | 919 // register allocation splitting. |
919 LiveRange* after = insertion_point->next(); | 920 LiveRange* after = last_insertion_point_->next(); |
920 if (insertion_point->End() > other->Start()) { | 921 if (last_insertion_point_->End() > other->Start()) { |
921 LiveRange* new_after = | 922 LiveRange* new_after = |
922 insertion_point->SplitAt(other->Start(), data->allocation_zone()); | 923 last_insertion_point_->SplitAt(other->Start(), data->allocation_zone()); |
923 new_after->set_spilled(insertion_point->spilled()); | 924 new_after->set_spilled(last_insertion_point_->spilled()); |
924 if (!new_after->spilled()) | 925 if (!new_after->spilled()) |
925 new_after->set_assigned_register(insertion_point->assigned_register()); | 926 new_after->set_assigned_register( |
| 927 last_insertion_point_->assigned_register()); |
926 after = new_after; | 928 after = new_after; |
927 } | 929 } |
928 | 930 |
929 last_other->next_ = after; | 931 last_other->next_ = after; |
930 insertion_point->next_ = other; | 932 last_insertion_point_->next_ = other; |
931 other->UpdateParentForAllChildren(TopLevel()); | 933 other->UpdateParentForAllChildren(TopLevel()); |
932 TopLevel()->UpdateSpillRangePostMerge(other); | 934 TopLevel()->UpdateSpillRangePostMerge(other); |
933 } | 935 } |
934 | 936 |
935 | 937 |
936 void TopLevelLiveRange::ShortenTo(LifetimePosition start) { | 938 void TopLevelLiveRange::ShortenTo(LifetimePosition start) { |
937 TRACE("Shorten live range %d to [%d\n", vreg(), start.value()); | 939 TRACE("Shorten live range %d to [%d\n", vreg(), start.value()); |
938 DCHECK(first_interval_ != nullptr); | 940 DCHECK(first_interval_ != nullptr); |
939 DCHECK(first_interval_->start() <= start); | 941 DCHECK(first_interval_->start() <= start); |
940 DCHECK(start < first_interval_->end()); | 942 DCHECK(start < first_interval_->end()); |
(...skipping 2355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3296 auto eliminate = moves->PrepareInsertAfter(move); | 3298 auto eliminate = moves->PrepareInsertAfter(move); |
3297 to_insert.push_back(move); | 3299 to_insert.push_back(move); |
3298 if (eliminate != nullptr) to_eliminate.push_back(eliminate); | 3300 if (eliminate != nullptr) to_eliminate.push_back(eliminate); |
3299 } | 3301 } |
3300 } | 3302 } |
3301 | 3303 |
3302 | 3304 |
3303 } // namespace compiler | 3305 } // namespace compiler |
3304 } // namespace internal | 3306 } // namespace internal |
3305 } // namespace v8 | 3307 } // namespace v8 |
OLD | NEW |