| 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 74 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 85     if (output->IsDoubleRegister() && | 85     if (output->IsDoubleRegister() && | 
| 86         LocationOperand::cast(output)->GetDoubleRegister().is(reg)) { | 86         LocationOperand::cast(output)->GetDoubleRegister().is(reg)) { | 
| 87       return true; | 87       return true; | 
| 88     } | 88     } | 
| 89   } | 89   } | 
| 90   return false; | 90   return false; | 
| 91 } | 91 } | 
| 92 | 92 | 
| 93 | 93 | 
| 94 // TODO(dcarney): fix frame to allow frame accesses to half size location. | 94 // TODO(dcarney): fix frame to allow frame accesses to half size location. | 
| 95 int GetByteWidth(MachineType machine_type) { | 95 int GetByteWidth(MachineRepresentation rep) { | 
| 96   DCHECK_EQ(RepresentationOf(machine_type), machine_type); | 96   switch (rep) { | 
| 97   switch (machine_type) { | 97     case MachineRepresentation::kBit: | 
| 98     case kRepBit: | 98     case MachineRepresentation::kWord8: | 
| 99     case kRepWord8: | 99     case MachineRepresentation::kWord16: | 
| 100     case kRepWord16: | 100     case MachineRepresentation::kWord32: | 
| 101     case kRepWord32: | 101     case MachineRepresentation::kTagged: | 
| 102     case kRepTagged: |  | 
| 103       return kPointerSize; | 102       return kPointerSize; | 
| 104     case kRepFloat32: | 103     case MachineRepresentation::kFloat32: | 
| 105     case kRepWord64: | 104     case MachineRepresentation::kWord64: | 
| 106     case kRepFloat64: | 105     case MachineRepresentation::kFloat64: | 
| 107       return 8; | 106       return 8; | 
| 108     default: | 107     default: | 
| 109       UNREACHABLE(); | 108       UNREACHABLE(); | 
| 110       return 0; | 109       return 0; | 
| 111   } | 110   } | 
| 112 } | 111 } | 
| 113 | 112 | 
| 114 }  // namespace | 113 }  // namespace | 
| 115 | 114 | 
| 116 | 115 | 
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 244     os << 'e'; | 243     os << 'e'; | 
| 245   } | 244   } | 
| 246   return os; | 245   return os; | 
| 247 } | 246 } | 
| 248 | 247 | 
| 249 | 248 | 
| 250 const float LiveRange::kInvalidWeight = -1; | 249 const float LiveRange::kInvalidWeight = -1; | 
| 251 const float LiveRange::kMaxWeight = std::numeric_limits<float>::max(); | 250 const float LiveRange::kMaxWeight = std::numeric_limits<float>::max(); | 
| 252 | 251 | 
| 253 | 252 | 
| 254 LiveRange::LiveRange(int relative_id, MachineType machine_type, | 253 LiveRange::LiveRange(int relative_id, MachineRepresentation rep, | 
| 255                      TopLevelLiveRange* top_level) | 254                      TopLevelLiveRange* top_level) | 
| 256     : relative_id_(relative_id), | 255     : relative_id_(relative_id), | 
| 257       bits_(0), | 256       bits_(0), | 
| 258       last_interval_(nullptr), | 257       last_interval_(nullptr), | 
| 259       first_interval_(nullptr), | 258       first_interval_(nullptr), | 
| 260       first_pos_(nullptr), | 259       first_pos_(nullptr), | 
| 261       top_level_(top_level), | 260       top_level_(top_level), | 
| 262       next_(nullptr), | 261       next_(nullptr), | 
| 263       current_interval_(nullptr), | 262       current_interval_(nullptr), | 
| 264       last_processed_use_(nullptr), | 263       last_processed_use_(nullptr), | 
| 265       current_hint_position_(nullptr), | 264       current_hint_position_(nullptr), | 
| 266       splitting_pointer_(nullptr), | 265       splitting_pointer_(nullptr), | 
| 267       size_(kInvalidSize), | 266       size_(kInvalidSize), | 
| 268       weight_(kInvalidWeight), | 267       weight_(kInvalidWeight), | 
| 269       group_(nullptr) { | 268       group_(nullptr) { | 
| 270   DCHECK(AllocatedOperand::IsSupportedMachineType(machine_type)); | 269   DCHECK(AllocatedOperand::IsSupportedRepresentation(rep)); | 
| 271   bits_ = AssignedRegisterField::encode(kUnassignedRegister) | | 270   bits_ = AssignedRegisterField::encode(kUnassignedRegister) | | 
| 272           MachineTypeField::encode(machine_type); | 271           RepresentationField::encode(rep); | 
| 273 } | 272 } | 
| 274 | 273 | 
| 275 | 274 | 
| 276 void LiveRange::Verify() const { | 275 void LiveRange::Verify() const { | 
| 277   // Walk the positions, verifying that each is in an interval. | 276   // Walk the positions, verifying that each is in an interval. | 
| 278   auto interval = first_interval_; | 277   auto interval = first_interval_; | 
| 279   for (auto pos = first_pos_; pos != nullptr; pos = pos->next()) { | 278   for (auto pos = first_pos_; pos != nullptr; pos = pos->next()) { | 
| 280     CHECK(Start() <= pos->pos()); | 279     CHECK(Start() <= pos->pos()); | 
| 281     CHECK(pos->pos() <= End()); | 280     CHECK(pos->pos() <= End()); | 
| 282     CHECK(interval != nullptr); | 281     CHECK(interval != nullptr); | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
| 302 | 301 | 
| 303 void LiveRange::Spill() { | 302 void LiveRange::Spill() { | 
| 304   DCHECK(!spilled()); | 303   DCHECK(!spilled()); | 
| 305   DCHECK(!TopLevel()->HasNoSpillType()); | 304   DCHECK(!TopLevel()->HasNoSpillType()); | 
| 306   set_spilled(true); | 305   set_spilled(true); | 
| 307   bits_ = AssignedRegisterField::update(bits_, kUnassignedRegister); | 306   bits_ = AssignedRegisterField::update(bits_, kUnassignedRegister); | 
| 308 } | 307 } | 
| 309 | 308 | 
| 310 | 309 | 
| 311 RegisterKind LiveRange::kind() const { | 310 RegisterKind LiveRange::kind() const { | 
| 312   switch (RepresentationOf(machine_type())) { | 311   return IsFloatingPoint(representation()) ? DOUBLE_REGISTERS | 
| 313     case kRepFloat32: | 312                                            : GENERAL_REGISTERS; | 
| 314     case kRepFloat64: |  | 
| 315       return DOUBLE_REGISTERS; |  | 
| 316     default: |  | 
| 317       break; |  | 
| 318   } |  | 
| 319   return GENERAL_REGISTERS; |  | 
| 320 } | 313 } | 
| 321 | 314 | 
| 322 | 315 | 
| 323 UsePosition* LiveRange::FirstHintPosition(int* register_index) const { | 316 UsePosition* LiveRange::FirstHintPosition(int* register_index) const { | 
| 324   for (auto pos = first_pos_; pos != nullptr; pos = pos->next()) { | 317   for (auto pos = first_pos_; pos != nullptr; pos = pos->next()) { | 
| 325     if (pos->HintRegister(register_index)) return pos; | 318     if (pos->HintRegister(register_index)) return pos; | 
| 326   } | 319   } | 
| 327   return nullptr; | 320   return nullptr; | 
| 328 } | 321 } | 
| 329 | 322 | 
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 390   return use_pos->pos() > pos.NextStart().End(); | 383   return use_pos->pos() > pos.NextStart().End(); | 
| 391 } | 384 } | 
| 392 | 385 | 
| 393 | 386 | 
| 394 bool LiveRange::IsTopLevel() const { return top_level_ == this; } | 387 bool LiveRange::IsTopLevel() const { return top_level_ == this; } | 
| 395 | 388 | 
| 396 | 389 | 
| 397 InstructionOperand LiveRange::GetAssignedOperand() const { | 390 InstructionOperand LiveRange::GetAssignedOperand() const { | 
| 398   if (HasRegisterAssigned()) { | 391   if (HasRegisterAssigned()) { | 
| 399     DCHECK(!spilled()); | 392     DCHECK(!spilled()); | 
| 400     return AllocatedOperand(LocationOperand::REGISTER, machine_type(), | 393     return AllocatedOperand(LocationOperand::REGISTER, representation(), | 
| 401                             assigned_register()); | 394                             assigned_register()); | 
| 402   } | 395   } | 
| 403   DCHECK(spilled()); | 396   DCHECK(spilled()); | 
| 404   DCHECK(!HasRegisterAssigned()); | 397   DCHECK(!HasRegisterAssigned()); | 
| 405   if (TopLevel()->HasSpillOperand()) { | 398   if (TopLevel()->HasSpillOperand()) { | 
| 406     auto op = TopLevel()->GetSpillOperand(); | 399     auto op = TopLevel()->GetSpillOperand(); | 
| 407     DCHECK(!op->IsUnallocated()); | 400     DCHECK(!op->IsUnallocated()); | 
| 408     return *op; | 401     return *op; | 
| 409   } | 402   } | 
| 410   return TopLevel()->GetSpillRangeOperand(); | 403   return TopLevel()->GetSpillRangeOperand(); | 
| (...skipping 18 matching lines...) Expand all  Loading... | 
| 429   auto start = current_interval_ == nullptr ? LifetimePosition::Invalid() | 422   auto start = current_interval_ == nullptr ? LifetimePosition::Invalid() | 
| 430                                             : current_interval_->start(); | 423                                             : current_interval_->start(); | 
| 431   if (to_start_of->start() > start) { | 424   if (to_start_of->start() > start) { | 
| 432     current_interval_ = to_start_of; | 425     current_interval_ = to_start_of; | 
| 433   } | 426   } | 
| 434 } | 427 } | 
| 435 | 428 | 
| 436 | 429 | 
| 437 LiveRange* LiveRange::SplitAt(LifetimePosition position, Zone* zone) { | 430 LiveRange* LiveRange::SplitAt(LifetimePosition position, Zone* zone) { | 
| 438   int new_id = TopLevel()->GetNextChildId(); | 431   int new_id = TopLevel()->GetNextChildId(); | 
| 439   LiveRange* child = new (zone) LiveRange(new_id, machine_type(), TopLevel()); | 432   LiveRange* child = new (zone) LiveRange(new_id, representation(), TopLevel()); | 
| 440   DetachAt(position, child, zone); | 433   DetachAt(position, child, zone); | 
| 441 | 434 | 
| 442   child->top_level_ = TopLevel(); | 435   child->top_level_ = TopLevel(); | 
| 443   child->next_ = next_; | 436   child->next_ = next_; | 
| 444   next_ = child; | 437   next_ = child; | 
| 445   if (child->next() == nullptr) { | 438   if (child->next() == nullptr) { | 
| 446     TopLevel()->set_last_child(child); | 439     TopLevel()->set_last_child(child); | 
| 447   } | 440   } | 
| 448   return child; | 441   return child; | 
| 449 } | 442 } | 
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 674 struct TopLevelLiveRange::SpillMoveInsertionList : ZoneObject { | 667 struct TopLevelLiveRange::SpillMoveInsertionList : ZoneObject { | 
| 675   SpillMoveInsertionList(int gap_index, InstructionOperand* operand, | 668   SpillMoveInsertionList(int gap_index, InstructionOperand* operand, | 
| 676                          SpillMoveInsertionList* next) | 669                          SpillMoveInsertionList* next) | 
| 677       : gap_index(gap_index), operand(operand), next(next) {} | 670       : gap_index(gap_index), operand(operand), next(next) {} | 
| 678   const int gap_index; | 671   const int gap_index; | 
| 679   InstructionOperand* const operand; | 672   InstructionOperand* const operand; | 
| 680   SpillMoveInsertionList* const next; | 673   SpillMoveInsertionList* const next; | 
| 681 }; | 674 }; | 
| 682 | 675 | 
| 683 | 676 | 
| 684 TopLevelLiveRange::TopLevelLiveRange(int vreg, MachineType machine_type) | 677 TopLevelLiveRange::TopLevelLiveRange(int vreg, MachineRepresentation rep) | 
| 685     : LiveRange(0, machine_type, this), | 678     : LiveRange(0, rep, this), | 
| 686       vreg_(vreg), | 679       vreg_(vreg), | 
| 687       last_child_id_(0), | 680       last_child_id_(0), | 
| 688       splintered_from_(nullptr), | 681       splintered_from_(nullptr), | 
| 689       spill_operand_(nullptr), | 682       spill_operand_(nullptr), | 
| 690       spill_move_insertion_locations_(nullptr), | 683       spill_move_insertion_locations_(nullptr), | 
| 691       spilled_in_deferred_blocks_(false), | 684       spilled_in_deferred_blocks_(false), | 
| 692       spill_start_index_(kMaxInt), | 685       spill_start_index_(kMaxInt), | 
| 693       last_child_(this), | 686       last_child_(this), | 
| 694       last_pos_(nullptr), | 687       last_pos_(nullptr), | 
| 695       splinter_(nullptr), | 688       splinter_(nullptr), | 
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 790 void TopLevelLiveRange::SetSpillRange(SpillRange* spill_range) { | 783 void TopLevelLiveRange::SetSpillRange(SpillRange* spill_range) { | 
| 791   DCHECK(!HasSpillOperand()); | 784   DCHECK(!HasSpillOperand()); | 
| 792   DCHECK(spill_range); | 785   DCHECK(spill_range); | 
| 793   spill_range_ = spill_range; | 786   spill_range_ = spill_range; | 
| 794 } | 787 } | 
| 795 | 788 | 
| 796 | 789 | 
| 797 AllocatedOperand TopLevelLiveRange::GetSpillRangeOperand() const { | 790 AllocatedOperand TopLevelLiveRange::GetSpillRangeOperand() const { | 
| 798   auto spill_range = GetSpillRange(); | 791   auto spill_range = GetSpillRange(); | 
| 799   int index = spill_range->assigned_slot(); | 792   int index = spill_range->assigned_slot(); | 
| 800   return AllocatedOperand(LocationOperand::STACK_SLOT, machine_type(), index); | 793   return AllocatedOperand(LocationOperand::STACK_SLOT, representation(), index); | 
| 801 } | 794 } | 
| 802 | 795 | 
| 803 | 796 | 
| 804 void TopLevelLiveRange::Splinter(LifetimePosition start, LifetimePosition end, | 797 void TopLevelLiveRange::Splinter(LifetimePosition start, LifetimePosition end, | 
| 805                                  Zone* zone) { | 798                                  Zone* zone) { | 
| 806   DCHECK(start != Start() || end != End()); | 799   DCHECK(start != Start() || end != End()); | 
| 807   DCHECK(start < end); | 800   DCHECK(start < end); | 
| 808 | 801 | 
| 809   TopLevelLiveRange splinter_temp(-1, machine_type()); | 802   TopLevelLiveRange splinter_temp(-1, representation()); | 
| 810   UsePosition* last_in_splinter = nullptr; | 803   UsePosition* last_in_splinter = nullptr; | 
| 811   // Live ranges defined in deferred blocks stay in deferred blocks, so we | 804   // Live ranges defined in deferred blocks stay in deferred blocks, so we | 
| 812   // don't need to splinter them. That means that start should always be | 805   // don't need to splinter them. That means that start should always be | 
| 813   // after the beginning of the range. | 806   // after the beginning of the range. | 
| 814   DCHECK(start > Start()); | 807   DCHECK(start > Start()); | 
| 815 | 808 | 
| 816   if (end >= End()) { | 809   if (end >= End()) { | 
| 817     DCHECK(start > Start()); | 810     DCHECK(start > Start()); | 
| 818     DetachAt(start, &splinter_temp, zone); | 811     DetachAt(start, &splinter_temp, zone); | 
| 819     next_ = nullptr; | 812     next_ = nullptr; | 
| 820   } else { | 813   } else { | 
| 821     DCHECK(start < End() && Start() < end); | 814     DCHECK(start < End() && Start() < end); | 
| 822 | 815 | 
| 823     const int kInvalidId = std::numeric_limits<int>::max(); | 816     const int kInvalidId = std::numeric_limits<int>::max(); | 
| 824 | 817 | 
| 825     UsePosition* last = DetachAt(start, &splinter_temp, zone); | 818     UsePosition* last = DetachAt(start, &splinter_temp, zone); | 
| 826 | 819 | 
| 827     LiveRange end_part(kInvalidId, this->machine_type(), nullptr); | 820     LiveRange end_part(kInvalidId, this->representation(), nullptr); | 
| 828     last_in_splinter = splinter_temp.DetachAt(end, &end_part, zone); | 821     last_in_splinter = splinter_temp.DetachAt(end, &end_part, zone); | 
| 829 | 822 | 
| 830     next_ = end_part.next_; | 823     next_ = end_part.next_; | 
| 831     last_interval_->set_next(end_part.first_interval_); | 824     last_interval_->set_next(end_part.first_interval_); | 
| 832     // The next splinter will happen either at or after the current interval. | 825     // The next splinter will happen either at or after the current interval. | 
| 833     // We can optimize DetachAt by setting current_interval_ accordingly, | 826     // We can optimize DetachAt by setting current_interval_ accordingly, | 
| 834     // which will then be picked up by FirstSearchIntervalForPosition. | 827     // which will then be picked up by FirstSearchIntervalForPosition. | 
| 835     current_interval_ = last_interval_; | 828     current_interval_ = last_interval_; | 
| 836     last_interval_ = end_part.last_interval_; | 829     last_interval_ = end_part.last_interval_; | 
| 837 | 830 | 
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1081     interval = interval->next(); | 1074     interval = interval->next(); | 
| 1082   } | 1075   } | 
| 1083   os << "}"; | 1076   os << "}"; | 
| 1084   return os; | 1077   return os; | 
| 1085 } | 1078 } | 
| 1086 | 1079 | 
| 1087 | 1080 | 
| 1088 SpillRange::SpillRange(TopLevelLiveRange* parent, Zone* zone) | 1081 SpillRange::SpillRange(TopLevelLiveRange* parent, Zone* zone) | 
| 1089     : live_ranges_(zone), | 1082     : live_ranges_(zone), | 
| 1090       assigned_slot_(kUnassignedSlot), | 1083       assigned_slot_(kUnassignedSlot), | 
| 1091       byte_width_(GetByteWidth(parent->machine_type())), | 1084       byte_width_(GetByteWidth(parent->representation())), | 
| 1092       kind_(parent->kind()) { | 1085       kind_(parent->kind()) { | 
| 1093   // Spill ranges are created for top level, non-splintered ranges. This is so | 1086   // Spill ranges are created for top level, non-splintered ranges. This is so | 
| 1094   // that, when merging decisions are made, we consider the full extent of the | 1087   // that, when merging decisions are made, we consider the full extent of the | 
| 1095   // virtual register, and avoid clobbering it. | 1088   // virtual register, and avoid clobbering it. | 
| 1096   DCHECK(!parent->IsSplinter()); | 1089   DCHECK(!parent->IsSplinter()); | 
| 1097   UseInterval* result = nullptr; | 1090   UseInterval* result = nullptr; | 
| 1098   UseInterval* node = nullptr; | 1091   UseInterval* node = nullptr; | 
| 1099   // Copy the intervals for all ranges. | 1092   // Copy the intervals for all ranges. | 
| 1100   for (LiveRange* range = parent; range != nullptr; range = range->next()) { | 1093   for (LiveRange* range = parent; range != nullptr; range = range->next()) { | 
| 1101     auto src = range->first_interval(); | 1094     auto src = range->first_interval(); | 
| 1102     while (src != nullptr) { | 1095     while (src != nullptr) { | 
| 1103       auto new_node = new (zone) UseInterval(src->start(), src->end()); | 1096       auto new_node = new (zone) UseInterval(src->start(), src->end()); | 
| 1104       if (result == nullptr) { | 1097       if (result == nullptr) { | 
| 1105         result = new_node; | 1098         result = new_node; | 
| 1106       } else { | 1099       } else { | 
| 1107         node->set_next(new_node); | 1100         node->set_next(new_node); | 
| 1108       } | 1101       } | 
| 1109       node = new_node; | 1102       node = new_node; | 
| 1110       src = src->next(); | 1103       src = src->next(); | 
| 1111     } | 1104     } | 
| 1112   } | 1105   } | 
| 1113   use_interval_ = result; | 1106   use_interval_ = result; | 
| 1114   live_ranges().push_back(parent); | 1107   live_ranges().push_back(parent); | 
| 1115   end_position_ = node->end(); | 1108   end_position_ = node->end(); | 
| 1116   parent->SetSpillRange(this); | 1109   parent->SetSpillRange(this); | 
| 1117 } | 1110 } | 
| 1118 | 1111 | 
| 1119 | 1112 | 
| 1120 int SpillRange::ByteWidth() const { | 1113 int SpillRange::ByteWidth() const { | 
| 1121   return GetByteWidth(live_ranges_[0]->machine_type()); | 1114   return GetByteWidth(live_ranges_[0]->representation()); | 
| 1122 } | 1115 } | 
| 1123 | 1116 | 
| 1124 | 1117 | 
| 1125 bool SpillRange::IsIntersectingWith(SpillRange* other) const { | 1118 bool SpillRange::IsIntersectingWith(SpillRange* other) const { | 
| 1126   if (this->use_interval_ == nullptr || other->use_interval_ == nullptr || | 1119   if (this->use_interval_ == nullptr || other->use_interval_ == nullptr || | 
| 1127       this->End() <= other->use_interval_->start() || | 1120       this->End() <= other->use_interval_->start() || | 
| 1128       other->End() <= this->use_interval_->start()) { | 1121       other->End() <= this->use_interval_->start()) { | 
| 1129     return false; | 1122     return false; | 
| 1130   } | 1123   } | 
| 1131   return AreUseIntervalsIntersecting(use_interval_, other->use_interval_); | 1124   return AreUseIntervalsIntersecting(use_interval_, other->use_interval_); | 
| (...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1250 | 1243 | 
| 1251 MoveOperands* RegisterAllocationData::AddGapMove( | 1244 MoveOperands* RegisterAllocationData::AddGapMove( | 
| 1252     int index, Instruction::GapPosition position, | 1245     int index, Instruction::GapPosition position, | 
| 1253     const InstructionOperand& from, const InstructionOperand& to) { | 1246     const InstructionOperand& from, const InstructionOperand& to) { | 
| 1254   auto instr = code()->InstructionAt(index); | 1247   auto instr = code()->InstructionAt(index); | 
| 1255   auto moves = instr->GetOrCreateParallelMove(position, code_zone()); | 1248   auto moves = instr->GetOrCreateParallelMove(position, code_zone()); | 
| 1256   return moves->AddMove(from, to); | 1249   return moves->AddMove(from, to); | 
| 1257 } | 1250 } | 
| 1258 | 1251 | 
| 1259 | 1252 | 
| 1260 MachineType RegisterAllocationData::MachineTypeFor(int virtual_register) { | 1253 MachineRepresentation RegisterAllocationData::RepresentationFor( | 
|  | 1254     int virtual_register) { | 
| 1261   DCHECK_LT(virtual_register, code()->VirtualRegisterCount()); | 1255   DCHECK_LT(virtual_register, code()->VirtualRegisterCount()); | 
| 1262   return code()->GetRepresentation(virtual_register); | 1256   return code()->GetRepresentation(virtual_register); | 
| 1263 } | 1257 } | 
| 1264 | 1258 | 
| 1265 | 1259 | 
| 1266 TopLevelLiveRange* RegisterAllocationData::GetOrCreateLiveRangeFor(int index) { | 1260 TopLevelLiveRange* RegisterAllocationData::GetOrCreateLiveRangeFor(int index) { | 
| 1267   if (index >= static_cast<int>(live_ranges().size())) { | 1261   if (index >= static_cast<int>(live_ranges().size())) { | 
| 1268     live_ranges().resize(index + 1, nullptr); | 1262     live_ranges().resize(index + 1, nullptr); | 
| 1269   } | 1263   } | 
| 1270   auto result = live_ranges()[index]; | 1264   auto result = live_ranges()[index]; | 
| 1271   if (result == nullptr) { | 1265   if (result == nullptr) { | 
| 1272     result = NewLiveRange(index, MachineTypeFor(index)); | 1266     result = NewLiveRange(index, RepresentationFor(index)); | 
| 1273     live_ranges()[index] = result; | 1267     live_ranges()[index] = result; | 
| 1274   } | 1268   } | 
| 1275   return result; | 1269   return result; | 
| 1276 } | 1270 } | 
| 1277 | 1271 | 
| 1278 | 1272 | 
| 1279 TopLevelLiveRange* RegisterAllocationData::NewLiveRange( | 1273 TopLevelLiveRange* RegisterAllocationData::NewLiveRange( | 
| 1280     int index, MachineType machine_type) { | 1274     int index, MachineRepresentation rep) { | 
| 1281   return new (allocation_zone()) TopLevelLiveRange(index, machine_type); | 1275   return new (allocation_zone()) TopLevelLiveRange(index, rep); | 
| 1282 } | 1276 } | 
| 1283 | 1277 | 
| 1284 | 1278 | 
| 1285 int RegisterAllocationData::GetNextLiveRangeId() { | 1279 int RegisterAllocationData::GetNextLiveRangeId() { | 
| 1286   int vreg = virtual_register_count_++; | 1280   int vreg = virtual_register_count_++; | 
| 1287   if (vreg >= static_cast<int>(live_ranges().size())) { | 1281   if (vreg >= static_cast<int>(live_ranges().size())) { | 
| 1288     live_ranges().resize(vreg + 1, nullptr); | 1282     live_ranges().resize(vreg + 1, nullptr); | 
| 1289   } | 1283   } | 
| 1290   return vreg; | 1284   return vreg; | 
| 1291 } | 1285 } | 
| 1292 | 1286 | 
| 1293 | 1287 | 
| 1294 TopLevelLiveRange* RegisterAllocationData::NextLiveRange( | 1288 TopLevelLiveRange* RegisterAllocationData::NextLiveRange( | 
| 1295     MachineType machine_type) { | 1289     MachineRepresentation rep) { | 
| 1296   int vreg = GetNextLiveRangeId(); | 1290   int vreg = GetNextLiveRangeId(); | 
| 1297   TopLevelLiveRange* ret = NewLiveRange(vreg, machine_type); | 1291   TopLevelLiveRange* ret = NewLiveRange(vreg, rep); | 
| 1298   return ret; | 1292   return ret; | 
| 1299 } | 1293 } | 
| 1300 | 1294 | 
| 1301 | 1295 | 
| 1302 RegisterAllocationData::PhiMapValue* RegisterAllocationData::InitializePhiMap( | 1296 RegisterAllocationData::PhiMapValue* RegisterAllocationData::InitializePhiMap( | 
| 1303     const InstructionBlock* block, PhiInstruction* phi) { | 1297     const InstructionBlock* block, PhiInstruction* phi) { | 
| 1304   auto map_value = new (allocation_zone()) | 1298   auto map_value = new (allocation_zone()) | 
| 1305       RegisterAllocationData::PhiMapValue(phi, block, allocation_zone()); | 1299       RegisterAllocationData::PhiMapValue(phi, block, allocation_zone()); | 
| 1306   auto res = | 1300   auto res = | 
| 1307       phi_map_.insert(std::make_pair(phi->virtual_register(), map_value)); | 1301       phi_map_.insert(std::make_pair(phi->virtual_register(), map_value)); | 
| (...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1494 | 1488 | 
| 1495 ConstraintBuilder::ConstraintBuilder(RegisterAllocationData* data) | 1489 ConstraintBuilder::ConstraintBuilder(RegisterAllocationData* data) | 
| 1496     : data_(data) {} | 1490     : data_(data) {} | 
| 1497 | 1491 | 
| 1498 | 1492 | 
| 1499 InstructionOperand* ConstraintBuilder::AllocateFixed( | 1493 InstructionOperand* ConstraintBuilder::AllocateFixed( | 
| 1500     UnallocatedOperand* operand, int pos, bool is_tagged) { | 1494     UnallocatedOperand* operand, int pos, bool is_tagged) { | 
| 1501   TRACE("Allocating fixed reg for op %d\n", operand->virtual_register()); | 1495   TRACE("Allocating fixed reg for op %d\n", operand->virtual_register()); | 
| 1502   DCHECK(operand->HasFixedPolicy()); | 1496   DCHECK(operand->HasFixedPolicy()); | 
| 1503   InstructionOperand allocated; | 1497   InstructionOperand allocated; | 
| 1504   MachineType machine_type = InstructionSequence::DefaultRepresentation(); | 1498   MachineRepresentation rep = InstructionSequence::DefaultRepresentation(); | 
| 1505   int virtual_register = operand->virtual_register(); | 1499   int virtual_register = operand->virtual_register(); | 
| 1506   if (virtual_register != InstructionOperand::kInvalidVirtualRegister) { | 1500   if (virtual_register != InstructionOperand::kInvalidVirtualRegister) { | 
| 1507     machine_type = data()->MachineTypeFor(virtual_register); | 1501     rep = data()->RepresentationFor(virtual_register); | 
| 1508   } | 1502   } | 
| 1509   if (operand->HasFixedSlotPolicy()) { | 1503   if (operand->HasFixedSlotPolicy()) { | 
| 1510     allocated = AllocatedOperand(AllocatedOperand::STACK_SLOT, machine_type, | 1504     allocated = AllocatedOperand(AllocatedOperand::STACK_SLOT, rep, | 
| 1511                                  operand->fixed_slot_index()); | 1505                                  operand->fixed_slot_index()); | 
| 1512   } else if (operand->HasFixedRegisterPolicy()) { | 1506   } else if (operand->HasFixedRegisterPolicy()) { | 
| 1513     DCHECK(!IsFloatingPoint(machine_type)); | 1507     DCHECK(!IsFloatingPoint(rep)); | 
| 1514     allocated = AllocatedOperand(AllocatedOperand::REGISTER, machine_type, | 1508     allocated = AllocatedOperand(AllocatedOperand::REGISTER, rep, | 
| 1515                                  operand->fixed_register_index()); | 1509                                  operand->fixed_register_index()); | 
| 1516   } else if (operand->HasFixedDoubleRegisterPolicy()) { | 1510   } else if (operand->HasFixedDoubleRegisterPolicy()) { | 
| 1517     DCHECK(IsFloatingPoint(machine_type)); | 1511     DCHECK(IsFloatingPoint(rep)); | 
| 1518     DCHECK_NE(InstructionOperand::kInvalidVirtualRegister, virtual_register); | 1512     DCHECK_NE(InstructionOperand::kInvalidVirtualRegister, virtual_register); | 
| 1519     allocated = AllocatedOperand(AllocatedOperand::REGISTER, machine_type, | 1513     allocated = AllocatedOperand(AllocatedOperand::REGISTER, rep, | 
| 1520                                  operand->fixed_register_index()); | 1514                                  operand->fixed_register_index()); | 
| 1521   } else { | 1515   } else { | 
| 1522     UNREACHABLE(); | 1516     UNREACHABLE(); | 
| 1523   } | 1517   } | 
| 1524   InstructionOperand::ReplaceWith(operand, &allocated); | 1518   InstructionOperand::ReplaceWith(operand, &allocated); | 
| 1525   if (is_tagged) { | 1519   if (is_tagged) { | 
| 1526     TRACE("Fixed reg is tagged at %d\n", pos); | 1520     TRACE("Fixed reg is tagged at %d\n", pos); | 
| 1527     auto instr = code()->InstructionAt(pos); | 1521     auto instr = code()->InstructionAt(pos); | 
| 1528     if (instr->HasReferenceMap()) { | 1522     if (instr->HasReferenceMap()) { | 
| 1529       instr->reference_map()->RecordReference(*AllocatedOperand::cast(operand)); | 1523       instr->reference_map()->RecordReference(*AllocatedOperand::cast(operand)); | 
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1621         data()->GetOrCreateLiveRangeFor(first_output->virtual_register()); | 1615         data()->GetOrCreateLiveRangeFor(first_output->virtual_register()); | 
| 1622     bool assigned = false; | 1616     bool assigned = false; | 
| 1623     if (first_output->HasFixedPolicy()) { | 1617     if (first_output->HasFixedPolicy()) { | 
| 1624       int output_vreg = first_output->virtual_register(); | 1618       int output_vreg = first_output->virtual_register(); | 
| 1625       UnallocatedOperand output_copy(UnallocatedOperand::ANY, output_vreg); | 1619       UnallocatedOperand output_copy(UnallocatedOperand::ANY, output_vreg); | 
| 1626       bool is_tagged = code()->IsReference(output_vreg); | 1620       bool is_tagged = code()->IsReference(output_vreg); | 
| 1627       if (first_output->HasSecondaryStorage()) { | 1621       if (first_output->HasSecondaryStorage()) { | 
| 1628         range->MarkHasPreassignedSlot(); | 1622         range->MarkHasPreassignedSlot(); | 
| 1629         InstructionOperand* spill_op = AllocatedOperand::New( | 1623         InstructionOperand* spill_op = AllocatedOperand::New( | 
| 1630             data()->code_zone(), LocationOperand::LocationKind::STACK_SLOT, | 1624             data()->code_zone(), LocationOperand::LocationKind::STACK_SLOT, | 
| 1631             range->machine_type(), first_output->GetSecondaryStorage()); | 1625             range->representation(), first_output->GetSecondaryStorage()); | 
| 1632         range->RecordSpillLocation(allocation_zone(), instr_index + 1, | 1626         range->RecordSpillLocation(allocation_zone(), instr_index + 1, | 
| 1633                                    first_output); | 1627                                    first_output); | 
| 1634         range->SetSpillOperand(spill_op); | 1628         range->SetSpillOperand(spill_op); | 
| 1635         range->SetSpillStartIndex(instr_index + 1); | 1629         range->SetSpillStartIndex(instr_index + 1); | 
| 1636         assigned = true; | 1630         assigned = true; | 
| 1637       } | 1631       } | 
| 1638       AllocateFixed(first_output, instr_index, is_tagged); | 1632       AllocateFixed(first_output, instr_index, is_tagged); | 
| 1639 | 1633 | 
| 1640       // This value is produced on the stack, we never need to spill it. | 1634       // This value is produced on the stack, we never need to spill it. | 
| 1641       if (first_output->IsStackSlot()) { | 1635       if (first_output->IsStackSlot()) { | 
| (...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 1820     data()->fixed_live_ranges()[index] = result; | 1814     data()->fixed_live_ranges()[index] = result; | 
| 1821   } | 1815   } | 
| 1822   return result; | 1816   return result; | 
| 1823 } | 1817 } | 
| 1824 | 1818 | 
| 1825 | 1819 | 
| 1826 TopLevelLiveRange* LiveRangeBuilder::FixedDoubleLiveRangeFor(int index) { | 1820 TopLevelLiveRange* LiveRangeBuilder::FixedDoubleLiveRangeFor(int index) { | 
| 1827   DCHECK(index < config()->num_double_registers()); | 1821   DCHECK(index < config()->num_double_registers()); | 
| 1828   auto result = data()->fixed_double_live_ranges()[index]; | 1822   auto result = data()->fixed_double_live_ranges()[index]; | 
| 1829   if (result == nullptr) { | 1823   if (result == nullptr) { | 
| 1830     result = data()->NewLiveRange(FixedDoubleLiveRangeID(index), kRepFloat64); | 1824     result = data()->NewLiveRange(FixedDoubleLiveRangeID(index), | 
|  | 1825                                   MachineRepresentation::kFloat64); | 
| 1831     DCHECK(result->IsFixed()); | 1826     DCHECK(result->IsFixed()); | 
| 1832     result->set_assigned_register(index); | 1827     result->set_assigned_register(index); | 
| 1833     data()->MarkAllocated(DOUBLE_REGISTERS, index); | 1828     data()->MarkAllocated(DOUBLE_REGISTERS, index); | 
| 1834     data()->fixed_double_live_ranges()[index] = result; | 1829     data()->fixed_double_live_ranges()[index] = result; | 
| 1835   } | 1830   } | 
| 1836   return result; | 1831   return result; | 
| 1837 } | 1832 } | 
| 1838 | 1833 | 
| 1839 | 1834 | 
| 1840 TopLevelLiveRange* LiveRangeBuilder::LiveRangeFor(InstructionOperand* operand) { | 1835 TopLevelLiveRange* LiveRangeBuilder::LiveRangeFor(InstructionOperand* operand) { | 
| (...skipping 1252 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3093     InstructionOperand spill_operand; | 3088     InstructionOperand spill_operand; | 
| 3094     if (((range->HasSpillOperand() && | 3089     if (((range->HasSpillOperand() && | 
| 3095           !range->GetSpillOperand()->IsConstant()) || | 3090           !range->GetSpillOperand()->IsConstant()) || | 
| 3096          range->HasSpillRange())) { | 3091          range->HasSpillRange())) { | 
| 3097       if (range->HasSpillOperand()) { | 3092       if (range->HasSpillOperand()) { | 
| 3098         spill_operand = *range->GetSpillOperand(); | 3093         spill_operand = *range->GetSpillOperand(); | 
| 3099       } else { | 3094       } else { | 
| 3100         spill_operand = range->GetSpillRangeOperand(); | 3095         spill_operand = range->GetSpillRangeOperand(); | 
| 3101       } | 3096       } | 
| 3102       DCHECK(spill_operand.IsStackSlot()); | 3097       DCHECK(spill_operand.IsStackSlot()); | 
| 3103       DCHECK_EQ(kRepTagged, | 3098       DCHECK_EQ(MachineRepresentation::kTagged, | 
| 3104                 AllocatedOperand::cast(spill_operand).machine_type()); | 3099                 AllocatedOperand::cast(spill_operand).representation()); | 
| 3105     } | 3100     } | 
| 3106 | 3101 | 
| 3107     // Step through the safe points to see whether they are in the range. | 3102     // Step through the safe points to see whether they are in the range. | 
| 3108     for (auto it = first_it; it != reference_maps->end(); ++it) { | 3103     for (auto it = first_it; it != reference_maps->end(); ++it) { | 
| 3109       auto map = *it; | 3104       auto map = *it; | 
| 3110       int safe_point = map->instruction_position(); | 3105       int safe_point = map->instruction_position(); | 
| 3111 | 3106 | 
| 3112       // The safe points are sorted so we can stop searching here. | 3107       // The safe points are sorted so we can stop searching here. | 
| 3113       if (safe_point - 1 > end) break; | 3108       if (safe_point - 1 > end) break; | 
| 3114 | 3109 | 
| (...skipping 20 matching lines...) Expand all  Loading... | 
| 3135       } | 3130       } | 
| 3136 | 3131 | 
| 3137       if (!cur->spilled()) { | 3132       if (!cur->spilled()) { | 
| 3138         TRACE( | 3133         TRACE( | 
| 3139             "Pointer in register for range %d:%d (start at %d) " | 3134             "Pointer in register for range %d:%d (start at %d) " | 
| 3140             "at safe point %d\n", | 3135             "at safe point %d\n", | 
| 3141             range->vreg(), cur->relative_id(), cur->Start().value(), | 3136             range->vreg(), cur->relative_id(), cur->Start().value(), | 
| 3142             safe_point); | 3137             safe_point); | 
| 3143         auto operand = cur->GetAssignedOperand(); | 3138         auto operand = cur->GetAssignedOperand(); | 
| 3144         DCHECK(!operand.IsStackSlot()); | 3139         DCHECK(!operand.IsStackSlot()); | 
| 3145         DCHECK_EQ(kRepTagged, AllocatedOperand::cast(operand).machine_type()); | 3140         DCHECK_EQ(MachineRepresentation::kTagged, | 
|  | 3141                   AllocatedOperand::cast(operand).representation()); | 
| 3146         map->RecordReference(AllocatedOperand::cast(operand)); | 3142         map->RecordReference(AllocatedOperand::cast(operand)); | 
| 3147       } | 3143       } | 
| 3148     } | 3144     } | 
| 3149   } | 3145   } | 
| 3150 } | 3146 } | 
| 3151 | 3147 | 
| 3152 | 3148 | 
| 3153 namespace { | 3149 namespace { | 
| 3154 | 3150 | 
| 3155 class LiveRangeBound { | 3151 class LiveRangeBound { | 
| (...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3445     auto eliminate = moves->PrepareInsertAfter(move); | 3441     auto eliminate = moves->PrepareInsertAfter(move); | 
| 3446     to_insert.push_back(move); | 3442     to_insert.push_back(move); | 
| 3447     if (eliminate != nullptr) to_eliminate.push_back(eliminate); | 3443     if (eliminate != nullptr) to_eliminate.push_back(eliminate); | 
| 3448   } | 3444   } | 
| 3449 } | 3445 } | 
| 3450 | 3446 | 
| 3451 | 3447 | 
| 3452 }  // namespace compiler | 3448 }  // namespace compiler | 
| 3453 }  // namespace internal | 3449 }  // namespace internal | 
| 3454 }  // namespace v8 | 3450 }  // namespace v8 | 
| OLD | NEW | 
|---|