Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(51)

Side by Side Diff: src/compiler/register-allocator.cc

Issue 1403163003: Revert of [turbofan] Splinter into one range. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/register-allocator.h ('k') | test/unittests/compiler/live-range-unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 680 matching lines...) Expand 10 before | Expand all | Expand 10 after
691 TopLevelLiveRange::TopLevelLiveRange(int vreg, MachineType machine_type) 691 TopLevelLiveRange::TopLevelLiveRange(int vreg, MachineType machine_type)
692 : LiveRange(0, machine_type, this), 692 : LiveRange(0, machine_type, this),
693 vreg_(vreg), 693 vreg_(vreg),
694 last_child_id_(0), 694 last_child_id_(0),
695 splintered_from_(nullptr), 695 splintered_from_(nullptr),
696 spill_operand_(nullptr), 696 spill_operand_(nullptr),
697 spills_at_definition_(nullptr), 697 spills_at_definition_(nullptr),
698 spilled_in_deferred_blocks_(false), 698 spilled_in_deferred_blocks_(false),
699 spill_start_index_(kMaxInt), 699 spill_start_index_(kMaxInt),
700 last_child_(this), 700 last_child_(this),
701 last_pos_(nullptr), 701 last_insertion_point_(this) {
702 splinter_(nullptr) {
703 bits_ |= SpillTypeField::encode(SpillType::kNoSpillType); 702 bits_ |= SpillTypeField::encode(SpillType::kNoSpillType);
704 } 703 }
705 704
706 705
707 void TopLevelLiveRange::SpillAtDefinition(Zone* zone, int gap_index, 706 void TopLevelLiveRange::SpillAtDefinition(Zone* zone, int gap_index,
708 InstructionOperand* operand) { 707 InstructionOperand* operand) {
709 DCHECK(HasNoSpillType()); 708 DCHECK(HasNoSpillType());
710 spills_at_definition_ = new (zone) 709 spills_at_definition_ = new (zone)
711 SpillAtDefinitionList(gap_index, operand, spills_at_definition_); 710 SpillAtDefinitionList(gap_index, operand, spills_at_definition_);
712 } 711 }
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
839 return StackSlotOperand(machine_type(), index); 838 return StackSlotOperand(machine_type(), index);
840 case DOUBLE_REGISTERS: 839 case DOUBLE_REGISTERS:
841 return DoubleStackSlotOperand(machine_type(), index); 840 return DoubleStackSlotOperand(machine_type(), index);
842 } 841 }
843 UNREACHABLE(); 842 UNREACHABLE();
844 return StackSlotOperand(kMachNone, 0); 843 return StackSlotOperand(kMachNone, 0);
845 } 844 }
846 845
847 846
848 void TopLevelLiveRange::Splinter(LifetimePosition start, LifetimePosition end, 847 void TopLevelLiveRange::Splinter(LifetimePosition start, LifetimePosition end,
849 Zone* zone) { 848 TopLevelLiveRange* result, Zone* zone) {
850 DCHECK(start != Start() || end != End()); 849 DCHECK(start != Start() || end != End());
851 DCHECK(start < end); 850 DCHECK(start < end);
852 851
853 TopLevelLiveRange splinter_temp(-1, machine_type()); 852 result->set_spill_type(spill_type());
854 UsePosition* last_in_splinter = nullptr; 853
855 if (start <= Start()) { 854 if (start <= Start()) {
856 // TODO(mtrofin): here, the TopLevel part is in the deferred range, so we 855 // TODO(mtrofin): here, the TopLevel part is in the deferred range, so we
857 // may want to continue processing the splinter. However, if the value is 856 // may want to continue processing the splinter. However, if the value is
858 // defined in a cold block, and then used in a hot block, it follows that 857 // defined in a cold block, and then used in a hot block, it follows that
859 // it should terminate on the RHS of a phi, defined on the hot path. We 858 // it should terminate on the RHS of a phi, defined on the hot path. We
860 // should check this, however, this may not be the place, because we don't 859 // should check this, however, this may not be the place, because we don't
861 // have access to the instruction sequence. 860 // have access to the instruction sequence.
862 DCHECK(end < End()); 861 DCHECK(end < End());
863 DetachAt(end, &splinter_temp, zone); 862 DetachAt(end, result, zone);
864 next_ = nullptr; 863 next_ = nullptr;
865 } else if (end >= End()) { 864 } else if (end >= End()) {
866 DCHECK(start > Start()); 865 DCHECK(start > Start());
867 DetachAt(start, &splinter_temp, zone); 866 DetachAt(start, result, zone);
868 next_ = nullptr; 867 next_ = nullptr;
869 } else { 868 } else {
870 DCHECK(start < End() && Start() < end); 869 DCHECK(start < End() && Start() < end);
871 870
872 const int kInvalidId = std::numeric_limits<int>::max(); 871 const int kInvalidId = std::numeric_limits<int>::max();
873 872
874 UsePosition* last = DetachAt(start, &splinter_temp, zone); 873 UsePosition* last = DetachAt(start, result, zone);
875 874
876 LiveRange end_part(kInvalidId, this->machine_type(), nullptr); 875 LiveRange end_part(kInvalidId, this->machine_type(), nullptr);
877 last_in_splinter = splinter_temp.DetachAt(end, &end_part, zone); 876 result->DetachAt(end, &end_part, zone);
878 877
879 next_ = end_part.next_; 878 next_ = end_part.next_;
880 last_interval_->set_next(end_part.first_interval_); 879 last_interval_->set_next(end_part.first_interval_);
881 // The next splinter will happen either at or after the current interval. 880 // The next splinter will happen either at or after the current interval.
882 // We can optimize DetachAt by setting current_interval_ accordingly, 881 // We can optimize DetachAt by setting current_interval_ accordingly,
883 // which will then be picked up by FirstSearchIntervalForPosition. 882 // which will then be picked up by FirstSearchIntervalForPosition.
884 current_interval_ = last_interval_; 883 current_interval_ = last_interval_;
885 last_interval_ = end_part.last_interval_; 884 last_interval_ = end_part.last_interval_;
886 885
887 if (first_pos_ == nullptr) { 886 if (first_pos_ == nullptr) {
888 first_pos_ = end_part.first_pos_; 887 first_pos_ = end_part.first_pos_;
889 } else { 888 } else {
890 splitting_pointer_ = last; 889 splitting_pointer_ = last;
891 if (last != nullptr) last->set_next(end_part.first_pos_); 890 if (last != nullptr) last->set_next(end_part.first_pos_);
892 } 891 }
893 } 892 }
893 result->next_ = nullptr;
894 result->top_level_ = result;
894 895
895 if (splinter()->IsEmpty()) { 896 result->SetSplinteredFrom(this);
896 splinter()->first_interval_ = splinter_temp.first_interval_; 897 // Ensure the result's relative ID is unique within the IDs used for this
897 splinter()->last_interval_ = splinter_temp.last_interval_; 898 // virtual register's children and splinters.
898 } else { 899 result->relative_id_ = GetNextChildId();
899 splinter()->last_interval_->set_next(splinter_temp.first_interval_);
900 splinter()->last_interval_ = splinter_temp.last_interval_;
901 }
902 if (splinter()->first_pos() == nullptr) {
903 splinter()->first_pos_ = splinter_temp.first_pos_;
904 } else {
905 splinter()->last_pos_->set_next(splinter_temp.first_pos_);
906 }
907 if (last_in_splinter != nullptr) {
908 splinter()->last_pos_ = last_in_splinter;
909 } else {
910 if (splinter()->first_pos() != nullptr &&
911 splinter()->last_pos_ == nullptr) {
912 splinter()->last_pos_ = splinter()->first_pos();
913 for (UsePosition* pos = splinter()->first_pos(); pos != nullptr;
914 pos = pos->next()) {
915 splinter()->last_pos_ = pos;
916 }
917 }
918 }
919 #if DEBUG
920 Verify();
921 splinter()->Verify();
922 #endif
923 } 900 }
924 901
925 902
926 void TopLevelLiveRange::SetSplinteredFrom(TopLevelLiveRange* splinter_parent) { 903 void TopLevelLiveRange::SetSplinteredFrom(TopLevelLiveRange* splinter_parent) {
904 // The splinter parent is always the original "Top".
905 DCHECK(splinter_parent->Start() < Start());
906
927 splintered_from_ = splinter_parent; 907 splintered_from_ = splinter_parent;
928 if (!HasSpillOperand() && splinter_parent->spill_range_ != nullptr) { 908 if (!HasSpillOperand() && splinter_parent->spill_range_ != nullptr) {
929 SetSpillRange(splinter_parent->spill_range_); 909 SetSpillRange(splinter_parent->spill_range_);
930 } 910 }
931 } 911 }
932 912
933 913
934 void TopLevelLiveRange::UpdateSpillRangePostMerge(TopLevelLiveRange* merged) { 914 void TopLevelLiveRange::UpdateSpillRangePostMerge(TopLevelLiveRange* merged) {
935 DCHECK(merged->TopLevel() == this); 915 DCHECK(merged->TopLevel() == this);
936 916
937 if (HasNoSpillType() && merged->HasSpillRange()) { 917 if (HasNoSpillType() && merged->HasSpillRange()) {
938 set_spill_type(merged->spill_type()); 918 set_spill_type(merged->spill_type());
939 DCHECK(GetSpillRange()->live_ranges().size() > 0); 919 DCHECK(GetSpillRange()->live_ranges().size() > 0);
940 merged->spill_range_ = nullptr; 920 merged->spill_range_ = nullptr;
941 merged->bits_ = 921 merged->bits_ =
942 SpillTypeField::update(merged->bits_, SpillType::kNoSpillType); 922 SpillTypeField::update(merged->bits_, SpillType::kNoSpillType);
943 } 923 }
944 } 924 }
945 925
946 926
947 void TopLevelLiveRange::Merge(TopLevelLiveRange* other, Zone* zone) { 927 void TopLevelLiveRange::Merge(TopLevelLiveRange* other, Zone* zone) {
948 DCHECK(Start() < other->Start()); 928 DCHECK(Start() < other->Start());
949 DCHECK(other->splintered_from() == this); 929 DCHECK(other->splintered_from() == this);
950 930
951 LiveRange* first = this; 931 LiveRange* last_other = other->last_child();
952 LiveRange* second = other; 932 LiveRange* last_me = last_child();
953 DCHECK(first->Start() < second->Start());
954 while (first != nullptr && second != nullptr) {
955 DCHECK(first != second);
956 // Make sure the ranges are in order each time we iterate.
957 if (second->Start() < first->Start()) {
958 LiveRange* tmp = second;
959 second = first;
960 first = tmp;
961 continue;
962 }
963 933
964 if (first->End() <= second->Start()) { 934 // Simple case: we just append at the end.
965 if (first->next() == nullptr || 935 if (last_me->End() <= other->Start()) return last_me->AppendAsChild(other);
966 first->next()->Start() > second->Start()) {
967 // First is in order before second.
968 LiveRange* temp = first->next();
969 first->next_ = second;
970 first = temp;
971 } else {
972 // First is in order before its successor (or second), so advance first.
973 first = first->next();
974 }
975 continue;
976 }
977 936
978 DCHECK(first->Start() < second->Start()); 937 DCHECK(last_me->End() > last_other->End());
979 // If first and second intersect, split first.
980 if (first->Start() < second->End() && second->Start() < first->End()) {
981 LiveRange* temp = first->SplitAt(second->Start(), zone);
982 938
983 temp->set_spilled(first->spilled()); 939 // In the more general case, we need to find the ranges between which to
984 if (!temp->spilled()) 940 // insert.
985 temp->set_assigned_register(first->assigned_register()); 941 if (other->Start() < last_insertion_point_->Start()) {
986 942 last_insertion_point_ = this;
987 first->next_ = second;
988 first = temp;
989 continue;
990 }
991 DCHECK(first->End() <= second->Start());
992 } 943 }
993 944
994 TopLevel()->UpdateParentForAllChildren(TopLevel()); 945 for (; last_insertion_point_->next() != nullptr &&
946 last_insertion_point_->next()->Start() <= other->Start();
947 last_insertion_point_ = last_insertion_point_->next()) {
948 }
949
950 // When we splintered the original range, we reconstituted the original range
951 // into one range without children, but with discontinuities. To merge the
952 // splinter back in, we need to split the range - or a child obtained after
953 // register allocation splitting.
954 LiveRange* after = last_insertion_point_->next();
955 if (last_insertion_point_->End() > other->Start()) {
956 LiveRange* new_after = last_insertion_point_->SplitAt(other->Start(), zone);
957 new_after->set_spilled(last_insertion_point_->spilled());
958 if (!new_after->spilled())
959 new_after->set_assigned_register(
960 last_insertion_point_->assigned_register());
961 after = new_after;
962 }
963
964 last_other->next_ = after;
965 last_insertion_point_->next_ = other;
966 other->UpdateParentForAllChildren(TopLevel());
995 TopLevel()->UpdateSpillRangePostMerge(other); 967 TopLevel()->UpdateSpillRangePostMerge(other);
996
997 #if DEBUG
998 Verify();
999 #endif
1000 } 968 }
1001 969
1002 970
1003 void TopLevelLiveRange::ShortenTo(LifetimePosition start) { 971 void TopLevelLiveRange::ShortenTo(LifetimePosition start) {
1004 TRACE("Shorten live range %d to [%d\n", vreg(), start.value()); 972 TRACE("Shorten live range %d to [%d\n", vreg(), start.value());
1005 DCHECK(first_interval_ != nullptr); 973 DCHECK(first_interval_ != nullptr);
1006 DCHECK(first_interval_->start() <= start); 974 DCHECK(first_interval_->start() <= start);
1007 DCHECK(start < first_interval_->end()); 975 DCHECK(start < first_interval_->end());
1008 first_interval_->set_start(start); 976 first_interval_->set_start(start);
1009 } 977 }
(...skipping 2383 matching lines...) Expand 10 before | Expand all | Expand 10 after
3393 auto eliminate = moves->PrepareInsertAfter(move); 3361 auto eliminate = moves->PrepareInsertAfter(move);
3394 to_insert.push_back(move); 3362 to_insert.push_back(move);
3395 if (eliminate != nullptr) to_eliminate.push_back(eliminate); 3363 if (eliminate != nullptr) to_eliminate.push_back(eliminate);
3396 } 3364 }
3397 } 3365 }
3398 3366
3399 3367
3400 } // namespace compiler 3368 } // namespace compiler
3401 } // namespace internal 3369 } // namespace internal
3402 } // namespace v8 3370 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/register-allocator.h ('k') | test/unittests/compiler/live-range-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698