Home | History | Annotate | Download | only in compiler
      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
      3 // found in the LICENSE file.
      4 
      5 #include "src/base/adapters.h"
      6 #include "src/compiler/linkage.h"
      7 #include "src/compiler/register-allocator.h"
      8 #include "src/string-stream.h"
      9 
     10 namespace v8 {
     11 namespace internal {
     12 namespace compiler {
     13 
     14 #define TRACE(...)                             \
     15   do {                                         \
     16     if (FLAG_trace_alloc) PrintF(__VA_ARGS__); \
     17   } while (false)
     18 
     19 
     20 namespace {
     21 
     22 static const int kFloatRepBit =
     23     1 << static_cast<int>(MachineRepresentation::kFloat32);
     24 static const int kSimd128RepBit =
     25     1 << static_cast<int>(MachineRepresentation::kSimd128);
     26 
     27 void RemoveElement(ZoneVector<LiveRange*>* v, LiveRange* range) {
     28   auto it = std::find(v->begin(), v->end(), range);
     29   DCHECK(it != v->end());
     30   v->erase(it);
     31 }
     32 
     33 int GetRegisterCount(const RegisterConfiguration* cfg, RegisterKind kind) {
     34   return kind == FP_REGISTERS ? cfg->num_double_registers()
     35                               : cfg->num_general_registers();
     36 }
     37 
     38 
     39 int GetAllocatableRegisterCount(const RegisterConfiguration* cfg,
     40                                 RegisterKind kind) {
     41   return kind == FP_REGISTERS ? cfg->num_allocatable_double_registers()
     42                               : cfg->num_allocatable_general_registers();
     43 }
     44 
     45 
     46 const int* GetAllocatableRegisterCodes(const RegisterConfiguration* cfg,
     47                                        RegisterKind kind) {
     48   return kind == FP_REGISTERS ? cfg->allocatable_double_codes()
     49                               : cfg->allocatable_general_codes();
     50 }
     51 
     52 
     53 const InstructionBlock* GetContainingLoop(const InstructionSequence* sequence,
     54                                           const InstructionBlock* block) {
     55   RpoNumber index = block->loop_header();
     56   if (!index.IsValid()) return nullptr;
     57   return sequence->InstructionBlockAt(index);
     58 }
     59 
     60 
     61 const InstructionBlock* GetInstructionBlock(const InstructionSequence* code,
     62                                             LifetimePosition pos) {
     63   return code->GetInstructionBlock(pos.ToInstructionIndex());
     64 }
     65 
     66 
     67 Instruction* GetLastInstruction(InstructionSequence* code,
     68                                 const InstructionBlock* block) {
     69   return code->InstructionAt(block->last_instruction_index());
     70 }
     71 
     72 // TODO(dcarney): fix frame to allow frame accesses to half size location.
     73 int GetByteWidth(MachineRepresentation rep) {
     74   switch (rep) {
     75     case MachineRepresentation::kBit:
     76     case MachineRepresentation::kWord8:
     77     case MachineRepresentation::kWord16:
     78     case MachineRepresentation::kWord32:
     79     case MachineRepresentation::kTaggedSigned:
     80     case MachineRepresentation::kTaggedPointer:
     81     case MachineRepresentation::kTagged:
     82     case MachineRepresentation::kFloat32:
     83       return kPointerSize;
     84     case MachineRepresentation::kWord64:
     85     case MachineRepresentation::kFloat64:
     86       return kDoubleSize;
     87     case MachineRepresentation::kSimd128:
     88       return kSimd128Size;
     89     case MachineRepresentation::kNone:
     90       break;
     91   }
     92   UNREACHABLE();
     93   return 0;
     94 }
     95 
     96 }  // namespace
     97 
     98 class LiveRangeBound {
     99  public:
    100   explicit LiveRangeBound(LiveRange* range, bool skip)
    101       : range_(range), start_(range->Start()), end_(range->End()), skip_(skip) {
    102     DCHECK(!range->IsEmpty());
    103   }
    104 
    105   bool CanCover(LifetimePosition position) {
    106     return start_ <= position && position < end_;
    107   }
    108 
    109   LiveRange* const range_;
    110   const LifetimePosition start_;
    111   const LifetimePosition end_;
    112   const bool skip_;
    113 
    114  private:
    115   DISALLOW_COPY_AND_ASSIGN(LiveRangeBound);
    116 };
    117 
    118 
    119 struct FindResult {
    120   LiveRange* cur_cover_;
    121   LiveRange* pred_cover_;
    122 };
    123 
    124 
    125 class LiveRangeBoundArray {
    126  public:
    127   LiveRangeBoundArray() : length_(0), start_(nullptr) {}
    128 
    129   bool ShouldInitialize() { return start_ == nullptr; }
    130 
    131   void Initialize(Zone* zone, TopLevelLiveRange* range) {
    132     length_ = range->GetChildCount();
    133 
    134     start_ = zone->NewArray<LiveRangeBound>(length_);
    135     LiveRangeBound* curr = start_;
    136     // Normally, spilled ranges do not need connecting moves, because the spill
    137     // location has been assigned at definition. For ranges spilled in deferred
    138     // blocks, that is not the case, so we need to connect the spilled children.
    139     for (LiveRange *i = range; i != nullptr; i = i->next(), ++curr) {
    140       new (curr) LiveRangeBound(i, i->spilled());
    141     }
    142   }
    143 
    144   LiveRangeBound* Find(const LifetimePosition position) const {
    145     size_t left_index = 0;
    146     size_t right_index = length_;
    147     while (true) {
    148       size_t current_index = left_index + (right_index - left_index) / 2;
    149       DCHECK(right_index > current_index);
    150       LiveRangeBound* bound = &start_[current_index];
    151       if (bound->start_ <= position) {
    152         if (position < bound->end_) return bound;
    153         DCHECK(left_index < current_index);
    154         left_index = current_index;
    155       } else {
    156         right_index = current_index;
    157       }
    158     }
    159   }
    160 
    161   LiveRangeBound* FindPred(const InstructionBlock* pred) {
    162     LifetimePosition pred_end =
    163         LifetimePosition::InstructionFromInstructionIndex(
    164             pred->last_instruction_index());
    165     return Find(pred_end);
    166   }
    167 
    168   LiveRangeBound* FindSucc(const InstructionBlock* succ) {
    169     LifetimePosition succ_start = LifetimePosition::GapFromInstructionIndex(
    170         succ->first_instruction_index());
    171     return Find(succ_start);
    172   }
    173 
    174   bool FindConnectableSubranges(const InstructionBlock* block,
    175                                 const InstructionBlock* pred,
    176                                 FindResult* result) const {
    177     LifetimePosition pred_end =
    178         LifetimePosition::InstructionFromInstructionIndex(
    179             pred->last_instruction_index());
    180     LiveRangeBound* bound = Find(pred_end);
    181     result->pred_cover_ = bound->range_;
    182     LifetimePosition cur_start = LifetimePosition::GapFromInstructionIndex(
    183         block->first_instruction_index());
    184 
    185     if (bound->CanCover(cur_start)) {
    186       // Both blocks are covered by the same range, so there is nothing to
    187       // connect.
    188       return false;
    189     }
    190     bound = Find(cur_start);
    191     if (bound->skip_) {
    192       return false;
    193     }
    194     result->cur_cover_ = bound->range_;
    195     DCHECK(result->pred_cover_ != nullptr && result->cur_cover_ != nullptr);
    196     return (result->cur_cover_ != result->pred_cover_);
    197   }
    198 
    199  private:
    200   size_t length_;
    201   LiveRangeBound* start_;
    202 
    203   DISALLOW_COPY_AND_ASSIGN(LiveRangeBoundArray);
    204 };
    205 
    206 
    207 class LiveRangeFinder {
    208  public:
    209   explicit LiveRangeFinder(const RegisterAllocationData* data, Zone* zone)
    210       : data_(data),
    211         bounds_length_(static_cast<int>(data_->live_ranges().size())),
    212         bounds_(zone->NewArray<LiveRangeBoundArray>(bounds_length_)),
    213         zone_(zone) {
    214     for (int i = 0; i < bounds_length_; ++i) {
    215       new (&bounds_[i]) LiveRangeBoundArray();
    216     }
    217   }
    218 
    219   LiveRangeBoundArray* ArrayFor(int operand_index) {
    220     DCHECK(operand_index < bounds_length_);
    221     TopLevelLiveRange* range = data_->live_ranges()[operand_index];
    222     DCHECK(range != nullptr && !range->IsEmpty());
    223     LiveRangeBoundArray* array = &bounds_[operand_index];
    224     if (array->ShouldInitialize()) {
    225       array->Initialize(zone_, range);
    226     }
    227     return array;
    228   }
    229 
    230  private:
    231   const RegisterAllocationData* const data_;
    232   const int bounds_length_;
    233   LiveRangeBoundArray* const bounds_;
    234   Zone* const zone_;
    235 
    236   DISALLOW_COPY_AND_ASSIGN(LiveRangeFinder);
    237 };
    238 
    239 
    240 typedef std::pair<ParallelMove*, InstructionOperand> DelayedInsertionMapKey;
    241 
    242 
    243 struct DelayedInsertionMapCompare {
    244   bool operator()(const DelayedInsertionMapKey& a,
    245                   const DelayedInsertionMapKey& b) const {
    246     if (a.first == b.first) {
    247       return a.second.Compare(b.second);
    248     }
    249     return a.first < b.first;
    250   }
    251 };
    252 
    253 
    254 typedef ZoneMap<DelayedInsertionMapKey, InstructionOperand,
    255                 DelayedInsertionMapCompare> DelayedInsertionMap;
    256 
    257 
    258 UsePosition::UsePosition(LifetimePosition pos, InstructionOperand* operand,
    259                          void* hint, UsePositionHintType hint_type)
    260     : operand_(operand), hint_(hint), next_(nullptr), pos_(pos), flags_(0) {
    261   DCHECK_IMPLIES(hint == nullptr, hint_type == UsePositionHintType::kNone);
    262   bool register_beneficial = true;
    263   UsePositionType type = UsePositionType::kAny;
    264   if (operand_ != nullptr && operand_->IsUnallocated()) {
    265     const UnallocatedOperand* unalloc = UnallocatedOperand::cast(operand_);
    266     if (unalloc->HasRegisterPolicy()) {
    267       type = UsePositionType::kRequiresRegister;
    268     } else if (unalloc->HasSlotPolicy()) {
    269       type = UsePositionType::kRequiresSlot;
    270       register_beneficial = false;
    271     } else {
    272       register_beneficial = !unalloc->HasAnyPolicy();
    273     }
    274   }
    275   flags_ = TypeField::encode(type) | HintTypeField::encode(hint_type) |
    276            RegisterBeneficialField::encode(register_beneficial) |
    277            AssignedRegisterField::encode(kUnassignedRegister);
    278   DCHECK(pos_.IsValid());
    279 }
    280 
    281 
    282 bool UsePosition::HasHint() const {
    283   int hint_register;
    284   return HintRegister(&hint_register);
    285 }
    286 
    287 
    288 bool UsePosition::HintRegister(int* register_code) const {
    289   if (hint_ == nullptr) return false;
    290   switch (HintTypeField::decode(flags_)) {
    291     case UsePositionHintType::kNone:
    292     case UsePositionHintType::kUnresolved:
    293       return false;
    294     case UsePositionHintType::kUsePos: {
    295       UsePosition* use_pos = reinterpret_cast<UsePosition*>(hint_);
    296       int assigned_register = AssignedRegisterField::decode(use_pos->flags_);
    297       if (assigned_register == kUnassignedRegister) return false;
    298       *register_code = assigned_register;
    299       return true;
    300     }
    301     case UsePositionHintType::kOperand: {
    302       InstructionOperand* operand =
    303           reinterpret_cast<InstructionOperand*>(hint_);
    304       *register_code = LocationOperand::cast(operand)->register_code();
    305       return true;
    306     }
    307     case UsePositionHintType::kPhi: {
    308       RegisterAllocationData::PhiMapValue* phi =
    309           reinterpret_cast<RegisterAllocationData::PhiMapValue*>(hint_);
    310       int assigned_register = phi->assigned_register();
    311       if (assigned_register == kUnassignedRegister) return false;
    312       *register_code = assigned_register;
    313       return true;
    314     }
    315   }
    316   UNREACHABLE();
    317   return false;
    318 }
    319 
    320 
    321 UsePositionHintType UsePosition::HintTypeForOperand(
    322     const InstructionOperand& op) {
    323   switch (op.kind()) {
    324     case InstructionOperand::CONSTANT:
    325     case InstructionOperand::IMMEDIATE:
    326     case InstructionOperand::EXPLICIT:
    327       return UsePositionHintType::kNone;
    328     case InstructionOperand::UNALLOCATED:
    329       return UsePositionHintType::kUnresolved;
    330     case InstructionOperand::ALLOCATED:
    331       if (op.IsRegister() || op.IsFPRegister()) {
    332         return UsePositionHintType::kOperand;
    333       } else {
    334         DCHECK(op.IsStackSlot() || op.IsFPStackSlot());
    335         return UsePositionHintType::kNone;
    336       }
    337     case InstructionOperand::INVALID:
    338       break;
    339   }
    340   UNREACHABLE();
    341   return UsePositionHintType::kNone;
    342 }
    343 
    344 void UsePosition::SetHint(UsePosition* use_pos) {
    345   DCHECK_NOT_NULL(use_pos);
    346   hint_ = use_pos;
    347   flags_ = HintTypeField::update(flags_, UsePositionHintType::kUsePos);
    348 }
    349 
    350 void UsePosition::ResolveHint(UsePosition* use_pos) {
    351   DCHECK_NOT_NULL(use_pos);
    352   if (HintTypeField::decode(flags_) != UsePositionHintType::kUnresolved) return;
    353   hint_ = use_pos;
    354   flags_ = HintTypeField::update(flags_, UsePositionHintType::kUsePos);
    355 }
    356 
    357 
    358 void UsePosition::set_type(UsePositionType type, bool register_beneficial) {
    359   DCHECK_IMPLIES(type == UsePositionType::kRequiresSlot, !register_beneficial);
    360   DCHECK_EQ(kUnassignedRegister, AssignedRegisterField::decode(flags_));
    361   flags_ = TypeField::encode(type) |
    362            RegisterBeneficialField::encode(register_beneficial) |
    363            HintTypeField::encode(HintTypeField::decode(flags_)) |
    364            AssignedRegisterField::encode(kUnassignedRegister);
    365 }
    366 
    367 
    368 UseInterval* UseInterval::SplitAt(LifetimePosition pos, Zone* zone) {
    369   DCHECK(Contains(pos) && pos != start());
    370   UseInterval* after = new (zone) UseInterval(pos, end_);
    371   after->next_ = next_;
    372   next_ = nullptr;
    373   end_ = pos;
    374   return after;
    375 }
    376 
    377 
    378 void LifetimePosition::Print() const {
    379   OFStream os(stdout);
    380   os << *this << std::endl;
    381 }
    382 
    383 
    384 std::ostream& operator<<(std::ostream& os, const LifetimePosition pos) {
    385   os << '@' << pos.ToInstructionIndex();
    386   if (pos.IsGapPosition()) {
    387     os << 'g';
    388   } else {
    389     os << 'i';
    390   }
    391   if (pos.IsStart()) {
    392     os << 's';
    393   } else {
    394     os << 'e';
    395   }
    396   return os;
    397 }
    398 
    399 LiveRange::LiveRange(int relative_id, MachineRepresentation rep,
    400                      TopLevelLiveRange* top_level)
    401     : relative_id_(relative_id),
    402       bits_(0),
    403       last_interval_(nullptr),
    404       first_interval_(nullptr),
    405       first_pos_(nullptr),
    406       top_level_(top_level),
    407       next_(nullptr),
    408       current_interval_(nullptr),
    409       last_processed_use_(nullptr),
    410       current_hint_position_(nullptr),
    411       splitting_pointer_(nullptr) {
    412   DCHECK(AllocatedOperand::IsSupportedRepresentation(rep));
    413   bits_ = AssignedRegisterField::encode(kUnassignedRegister) |
    414           RepresentationField::encode(rep);
    415 }
    416 
    417 
    418 void LiveRange::VerifyPositions() const {
    419   // Walk the positions, verifying that each is in an interval.
    420   UseInterval* interval = first_interval_;
    421   for (UsePosition* pos = first_pos_; pos != nullptr; pos = pos->next()) {
    422     CHECK(Start() <= pos->pos());
    423     CHECK(pos->pos() <= End());
    424     CHECK_NOT_NULL(interval);
    425     while (!interval->Contains(pos->pos()) && interval->end() != pos->pos()) {
    426       interval = interval->next();
    427       CHECK_NOT_NULL(interval);
    428     }
    429   }
    430 }
    431 
    432 
    433 void LiveRange::VerifyIntervals() const {
    434   DCHECK(first_interval()->start() == Start());
    435   LifetimePosition last_end = first_interval()->end();
    436   for (UseInterval* interval = first_interval()->next(); interval != nullptr;
    437        interval = interval->next()) {
    438     DCHECK(last_end <= interval->start());
    439     last_end = interval->end();
    440   }
    441   DCHECK(last_end == End());
    442 }
    443 
    444 
    445 void LiveRange::set_assigned_register(int reg) {
    446   DCHECK(!HasRegisterAssigned() && !spilled());
    447   bits_ = AssignedRegisterField::update(bits_, reg);
    448 }
    449 
    450 
    451 void LiveRange::UnsetAssignedRegister() {
    452   DCHECK(HasRegisterAssigned() && !spilled());
    453   bits_ = AssignedRegisterField::update(bits_, kUnassignedRegister);
    454 }
    455 
    456 
    457 void LiveRange::Spill() {
    458   DCHECK(!spilled());
    459   DCHECK(!TopLevel()->HasNoSpillType());
    460   set_spilled(true);
    461   bits_ = AssignedRegisterField::update(bits_, kUnassignedRegister);
    462 }
    463 
    464 
    465 RegisterKind LiveRange::kind() const {
    466   return IsFloatingPoint(representation()) ? FP_REGISTERS : GENERAL_REGISTERS;
    467 }
    468 
    469 
    470 UsePosition* LiveRange::FirstHintPosition(int* register_index) const {
    471   for (UsePosition* pos = first_pos_; pos != nullptr; pos = pos->next()) {
    472     if (pos->HintRegister(register_index)) return pos;
    473   }
    474   return nullptr;
    475 }
    476 
    477 
    478 UsePosition* LiveRange::NextUsePosition(LifetimePosition start) const {
    479   UsePosition* use_pos = last_processed_use_;
    480   if (use_pos == nullptr || use_pos->pos() > start) {
    481     use_pos = first_pos();
    482   }
    483   while (use_pos != nullptr && use_pos->pos() < start) {
    484     use_pos = use_pos->next();
    485   }
    486   last_processed_use_ = use_pos;
    487   return use_pos;
    488 }
    489 
    490 
    491 UsePosition* LiveRange::NextUsePositionRegisterIsBeneficial(
    492     LifetimePosition start) const {
    493   UsePosition* pos = NextUsePosition(start);
    494   while (pos != nullptr && !pos->RegisterIsBeneficial()) {
    495     pos = pos->next();
    496   }
    497   return pos;
    498 }
    499 
    500 LifetimePosition LiveRange::NextLifetimePositionRegisterIsBeneficial(
    501     const LifetimePosition& start) const {
    502   UsePosition* next_use = NextUsePositionRegisterIsBeneficial(start);
    503   if (next_use == nullptr) return End();
    504   return next_use->pos();
    505 }
    506 
    507 UsePosition* LiveRange::PreviousUsePositionRegisterIsBeneficial(
    508     LifetimePosition start) const {
    509   UsePosition* pos = first_pos();
    510   UsePosition* prev = nullptr;
    511   while (pos != nullptr && pos->pos() < start) {
    512     if (pos->RegisterIsBeneficial()) prev = pos;
    513     pos = pos->next();
    514   }
    515   return prev;
    516 }
    517 
    518 
    519 UsePosition* LiveRange::NextRegisterPosition(LifetimePosition start) const {
    520   UsePosition* pos = NextUsePosition(start);
    521   while (pos != nullptr && pos->type() != UsePositionType::kRequiresRegister) {
    522     pos = pos->next();
    523   }
    524   return pos;
    525 }
    526 
    527 
    528 UsePosition* LiveRange::NextSlotPosition(LifetimePosition start) const {
    529   for (UsePosition* pos = NextUsePosition(start); pos != nullptr;
    530        pos = pos->next()) {
    531     if (pos->type() != UsePositionType::kRequiresSlot) continue;
    532     return pos;
    533   }
    534   return nullptr;
    535 }
    536 
    537 
    538 bool LiveRange::CanBeSpilled(LifetimePosition pos) const {
    539   // We cannot spill a live range that has a use requiring a register
    540   // at the current or the immediate next position.
    541   UsePosition* use_pos = NextRegisterPosition(pos);
    542   if (use_pos == nullptr) return true;
    543   return use_pos->pos() > pos.NextStart().End();
    544 }
    545 
    546 
    547 bool LiveRange::IsTopLevel() const { return top_level_ == this; }
    548 
    549 
    550 InstructionOperand LiveRange::GetAssignedOperand() const {
    551   if (HasRegisterAssigned()) {
    552     DCHECK(!spilled());
    553     return AllocatedOperand(LocationOperand::REGISTER, representation(),
    554                             assigned_register());
    555   }
    556   DCHECK(spilled());
    557   DCHECK(!HasRegisterAssigned());
    558   if (TopLevel()->HasSpillOperand()) {
    559     InstructionOperand* op = TopLevel()->GetSpillOperand();
    560     DCHECK(!op->IsUnallocated());
    561     return *op;
    562   }
    563   return TopLevel()->GetSpillRangeOperand();
    564 }
    565 
    566 
    567 UseInterval* LiveRange::FirstSearchIntervalForPosition(
    568     LifetimePosition position) const {
    569   if (current_interval_ == nullptr) return first_interval_;
    570   if (current_interval_->start() > position) {
    571     current_interval_ = nullptr;
    572     return first_interval_;
    573   }
    574   return current_interval_;
    575 }
    576 
    577 
    578 void LiveRange::AdvanceLastProcessedMarker(
    579     UseInterval* to_start_of, LifetimePosition but_not_past) const {
    580   if (to_start_of == nullptr) return;
    581   if (to_start_of->start() > but_not_past) return;
    582   LifetimePosition start = current_interval_ == nullptr
    583                                ? LifetimePosition::Invalid()
    584                                : current_interval_->start();
    585   if (to_start_of->start() > start) {
    586     current_interval_ = to_start_of;
    587   }
    588 }
    589 
    590 
    591 LiveRange* LiveRange::SplitAt(LifetimePosition position, Zone* zone) {
    592   int new_id = TopLevel()->GetNextChildId();
    593   LiveRange* child = new (zone) LiveRange(new_id, representation(), TopLevel());
    594   // If we split, we do so because we're about to switch registers or move
    595   // to/from a slot, so there's no value in connecting hints.
    596   DetachAt(position, child, zone, DoNotConnectHints);
    597 
    598   child->top_level_ = TopLevel();
    599   child->next_ = next_;
    600   next_ = child;
    601   return child;
    602 }
    603 
    604 UsePosition* LiveRange::DetachAt(LifetimePosition position, LiveRange* result,
    605                                  Zone* zone,
    606                                  HintConnectionOption connect_hints) {
    607   DCHECK(Start() < position);
    608   DCHECK(End() > position);
    609   DCHECK(result->IsEmpty());
    610   // Find the last interval that ends before the position. If the
    611   // position is contained in one of the intervals in the chain, we
    612   // split that interval and use the first part.
    613   UseInterval* current = FirstSearchIntervalForPosition(position);
    614 
    615   // If the split position coincides with the beginning of a use interval
    616   // we need to split use positons in a special way.
    617   bool split_at_start = false;
    618 
    619   if (current->start() == position) {
    620     // When splitting at start we need to locate the previous use interval.
    621     current = first_interval_;
    622   }
    623 
    624   UseInterval* after = nullptr;
    625   while (current != nullptr) {
    626     if (current->Contains(position)) {
    627       after = current->SplitAt(position, zone);
    628       break;
    629     }
    630     UseInterval* next = current->next();
    631     if (next->start() >= position) {
    632       split_at_start = (next->start() == position);
    633       after = next;
    634       current->set_next(nullptr);
    635       break;
    636     }
    637     current = next;
    638   }
    639   DCHECK(nullptr != after);
    640 
    641   // Partition original use intervals to the two live ranges.
    642   UseInterval* before = current;
    643   result->last_interval_ =
    644       (last_interval_ == before)
    645           ? after            // Only interval in the range after split.
    646           : last_interval_;  // Last interval of the original range.
    647   result->first_interval_ = after;
    648   last_interval_ = before;
    649 
    650   // Find the last use position before the split and the first use
    651   // position after it.
    652   UsePosition* use_after =
    653       splitting_pointer_ == nullptr || splitting_pointer_->pos() > position
    654           ? first_pos()
    655           : splitting_pointer_;
    656   UsePosition* use_before = nullptr;
    657   if (split_at_start) {
    658     // The split position coincides with the beginning of a use interval (the
    659     // end of a lifetime hole). Use at this position should be attributed to
    660     // the split child because split child owns use interval covering it.
    661     while (use_after != nullptr && use_after->pos() < position) {
    662       use_before = use_after;
    663       use_after = use_after->next();
    664     }
    665   } else {
    666     while (use_after != nullptr && use_after->pos() <= position) {
    667       use_before = use_after;
    668       use_after = use_after->next();
    669     }
    670   }
    671 
    672   // Partition original use positions to the two live ranges.
    673   if (use_before != nullptr) {
    674     use_before->set_next(nullptr);
    675   } else {
    676     first_pos_ = nullptr;
    677   }
    678   result->first_pos_ = use_after;
    679 
    680   // Discard cached iteration state. It might be pointing
    681   // to the use that no longer belongs to this live range.
    682   last_processed_use_ = nullptr;
    683   current_interval_ = nullptr;
    684 
    685   if (connect_hints == ConnectHints && use_before != nullptr &&
    686       use_after != nullptr) {
    687     use_after->SetHint(use_before);
    688   }
    689 #ifdef DEBUG
    690   VerifyChildStructure();
    691   result->VerifyChildStructure();
    692 #endif
    693   return use_before;
    694 }
    695 
    696 
    697 void LiveRange::UpdateParentForAllChildren(TopLevelLiveRange* new_top_level) {
    698   LiveRange* child = this;
    699   for (; child != nullptr; child = child->next()) {
    700     child->top_level_ = new_top_level;
    701   }
    702 }
    703 
    704 
    705 void LiveRange::ConvertUsesToOperand(const InstructionOperand& op,
    706                                      const InstructionOperand& spill_op) {
    707   for (UsePosition* pos = first_pos(); pos != nullptr; pos = pos->next()) {
    708     DCHECK(Start() <= pos->pos() && pos->pos() <= End());
    709     if (!pos->HasOperand()) continue;
    710     switch (pos->type()) {
    711       case UsePositionType::kRequiresSlot:
    712         DCHECK(spill_op.IsStackSlot() || spill_op.IsFPStackSlot());
    713         InstructionOperand::ReplaceWith(pos->operand(), &spill_op);
    714         break;
    715       case UsePositionType::kRequiresRegister:
    716         DCHECK(op.IsRegister() || op.IsFPRegister());
    717       // Fall through.
    718       case UsePositionType::kAny:
    719         InstructionOperand::ReplaceWith(pos->operand(), &op);
    720         break;
    721     }
    722   }
    723 }
    724 
    725 
    726 // This implements an ordering on live ranges so that they are ordered by their
    727 // start positions.  This is needed for the correctness of the register
    728 // allocation algorithm.  If two live ranges start at the same offset then there
    729 // is a tie breaker based on where the value is first used.  This part of the
    730 // ordering is merely a heuristic.
    731 bool LiveRange::ShouldBeAllocatedBefore(const LiveRange* other) const {
    732   LifetimePosition start = Start();
    733   LifetimePosition other_start = other->Start();
    734   if (start == other_start) {
    735     UsePosition* pos = first_pos();
    736     if (pos == nullptr) return false;
    737     UsePosition* other_pos = other->first_pos();
    738     if (other_pos == nullptr) return true;
    739     return pos->pos() < other_pos->pos();
    740   }
    741   return start < other_start;
    742 }
    743 
    744 
    745 void LiveRange::SetUseHints(int register_index) {
    746   for (UsePosition* pos = first_pos(); pos != nullptr; pos = pos->next()) {
    747     if (!pos->HasOperand()) continue;
    748     switch (pos->type()) {
    749       case UsePositionType::kRequiresSlot:
    750         break;
    751       case UsePositionType::kRequiresRegister:
    752       case UsePositionType::kAny:
    753         pos->set_assigned_register(register_index);
    754         break;
    755     }
    756   }
    757 }
    758 
    759 
    760 bool LiveRange::CanCover(LifetimePosition position) const {
    761   if (IsEmpty()) return false;
    762   return Start() <= position && position < End();
    763 }
    764 
    765 
    766 bool LiveRange::Covers(LifetimePosition position) const {
    767   if (!CanCover(position)) return false;
    768   UseInterval* start_search = FirstSearchIntervalForPosition(position);
    769   for (UseInterval* interval = start_search; interval != nullptr;
    770        interval = interval->next()) {
    771     DCHECK(interval->next() == nullptr ||
    772            interval->next()->start() >= interval->start());
    773     AdvanceLastProcessedMarker(interval, position);
    774     if (interval->Contains(position)) return true;
    775     if (interval->start() > position) return false;
    776   }
    777   return false;
    778 }
    779 
    780 
    781 LifetimePosition LiveRange::FirstIntersection(LiveRange* other) const {
    782   UseInterval* b = other->first_interval();
    783   if (b == nullptr) return LifetimePosition::Invalid();
    784   LifetimePosition advance_last_processed_up_to = b->start();
    785   UseInterval* a = FirstSearchIntervalForPosition(b->start());
    786   while (a != nullptr && b != nullptr) {
    787     if (a->start() > other->End()) break;
    788     if (b->start() > End()) break;
    789     LifetimePosition cur_intersection = a->Intersect(b);
    790     if (cur_intersection.IsValid()) {
    791       return cur_intersection;
    792     }
    793     if (a->start() < b->start()) {
    794       a = a->next();
    795       if (a == nullptr || a->start() > other->End()) break;
    796       AdvanceLastProcessedMarker(a, advance_last_processed_up_to);
    797     } else {
    798       b = b->next();
    799     }
    800   }
    801   return LifetimePosition::Invalid();
    802 }
    803 
    804 void LiveRange::Print(const RegisterConfiguration* config,
    805                       bool with_children) const {
    806   OFStream os(stdout);
    807   PrintableLiveRange wrapper;
    808   wrapper.register_configuration_ = config;
    809   for (const LiveRange* i = this; i != nullptr; i = i->next()) {
    810     wrapper.range_ = i;
    811     os << wrapper << std::endl;
    812     if (!with_children) break;
    813   }
    814 }
    815 
    816 
    817 void LiveRange::Print(bool with_children) const {
    818   Print(RegisterConfiguration::Turbofan(), with_children);
    819 }
    820 
    821 
    822 struct TopLevelLiveRange::SpillMoveInsertionList : ZoneObject {
    823   SpillMoveInsertionList(int gap_index, InstructionOperand* operand,
    824                          SpillMoveInsertionList* next)
    825       : gap_index(gap_index), operand(operand), next(next) {}
    826   const int gap_index;
    827   InstructionOperand* const operand;
    828   SpillMoveInsertionList* const next;
    829 };
    830 
    831 
    832 TopLevelLiveRange::TopLevelLiveRange(int vreg, MachineRepresentation rep)
    833     : LiveRange(0, rep, this),
    834       vreg_(vreg),
    835       last_child_id_(0),
    836       splintered_from_(nullptr),
    837       spill_operand_(nullptr),
    838       spill_move_insertion_locations_(nullptr),
    839       spilled_in_deferred_blocks_(false),
    840       spill_start_index_(kMaxInt),
    841       last_pos_(nullptr),
    842       splinter_(nullptr),
    843       has_preassigned_slot_(false) {
    844   bits_ |= SpillTypeField::encode(SpillType::kNoSpillType);
    845 }
    846 
    847 
    848 #if DEBUG
    849 int TopLevelLiveRange::debug_virt_reg() const {
    850   return IsSplinter() ? splintered_from()->vreg() : vreg();
    851 }
    852 #endif
    853 
    854 
    855 void TopLevelLiveRange::RecordSpillLocation(Zone* zone, int gap_index,
    856                                             InstructionOperand* operand) {
    857   DCHECK(HasNoSpillType());
    858   spill_move_insertion_locations_ = new (zone) SpillMoveInsertionList(
    859       gap_index, operand, spill_move_insertion_locations_);
    860 }
    861 
    862 void TopLevelLiveRange::CommitSpillMoves(InstructionSequence* sequence,
    863                                          const InstructionOperand& op,
    864                                          bool might_be_duplicated) {
    865   DCHECK_IMPLIES(op.IsConstant(), GetSpillMoveInsertionLocations() == nullptr);
    866   Zone* zone = sequence->zone();
    867 
    868   for (SpillMoveInsertionList* to_spill = GetSpillMoveInsertionLocations();
    869        to_spill != nullptr; to_spill = to_spill->next) {
    870     Instruction* instr = sequence->InstructionAt(to_spill->gap_index);
    871     ParallelMove* move =
    872         instr->GetOrCreateParallelMove(Instruction::START, zone);
    873     // Skip insertion if it's possible that the move exists already as a
    874     // constraint move from a fixed output register to a slot.
    875     if (might_be_duplicated || has_preassigned_slot()) {
    876       bool found = false;
    877       for (MoveOperands* move_op : *move) {
    878         if (move_op->IsEliminated()) continue;
    879         if (move_op->source().Equals(*to_spill->operand) &&
    880             move_op->destination().Equals(op)) {
    881           found = true;
    882           if (has_preassigned_slot()) move_op->Eliminate();
    883           break;
    884         }
    885       }
    886       if (found) continue;
    887     }
    888     if (!has_preassigned_slot()) {
    889       move->AddMove(*to_spill->operand, op);
    890     }
    891   }
    892 }
    893 
    894 
    895 void TopLevelLiveRange::SetSpillOperand(InstructionOperand* operand) {
    896   DCHECK(HasNoSpillType());
    897   DCHECK(!operand->IsUnallocated() && !operand->IsImmediate());
    898   set_spill_type(SpillType::kSpillOperand);
    899   spill_operand_ = operand;
    900 }
    901 
    902 
    903 void TopLevelLiveRange::SetSpillRange(SpillRange* spill_range) {
    904   DCHECK(!HasSpillOperand());
    905   DCHECK(spill_range);
    906   spill_range_ = spill_range;
    907 }
    908 
    909 
    910 AllocatedOperand TopLevelLiveRange::GetSpillRangeOperand() const {
    911   SpillRange* spill_range = GetSpillRange();
    912   int index = spill_range->assigned_slot();
    913   return AllocatedOperand(LocationOperand::STACK_SLOT, representation(), index);
    914 }
    915 
    916 
    917 void TopLevelLiveRange::Splinter(LifetimePosition start, LifetimePosition end,
    918                                  Zone* zone) {
    919   DCHECK(start != Start() || end != End());
    920   DCHECK(start < end);
    921 
    922   TopLevelLiveRange splinter_temp(-1, representation());
    923   UsePosition* last_in_splinter = nullptr;
    924   // Live ranges defined in deferred blocks stay in deferred blocks, so we
    925   // don't need to splinter them. That means that start should always be
    926   // after the beginning of the range.
    927   DCHECK(start > Start());
    928 
    929   if (end >= End()) {
    930     DCHECK(start > Start());
    931     DetachAt(start, &splinter_temp, zone, ConnectHints);
    932     next_ = nullptr;
    933   } else {
    934     DCHECK(start < End() && Start() < end);
    935 
    936     const int kInvalidId = std::numeric_limits<int>::max();
    937 
    938     UsePosition* last = DetachAt(start, &splinter_temp, zone, ConnectHints);
    939 
    940     LiveRange end_part(kInvalidId, this->representation(), nullptr);
    941     // The last chunk exits the deferred region, and we don't want to connect
    942     // hints here, because the non-deferred region shouldn't be affected
    943     // by allocation decisions on the deferred path.
    944     last_in_splinter =
    945         splinter_temp.DetachAt(end, &end_part, zone, DoNotConnectHints);
    946 
    947     next_ = end_part.next_;
    948     last_interval_->set_next(end_part.first_interval_);
    949     // The next splinter will happen either at or after the current interval.
    950     // We can optimize DetachAt by setting current_interval_ accordingly,
    951     // which will then be picked up by FirstSearchIntervalForPosition.
    952     current_interval_ = last_interval_;
    953     last_interval_ = end_part.last_interval_;
    954 
    955     if (first_pos_ == nullptr) {
    956       first_pos_ = end_part.first_pos_;
    957     } else {
    958       splitting_pointer_ = last;
    959       if (last != nullptr) last->set_next(end_part.first_pos_);
    960     }
    961   }
    962 
    963   if (splinter()->IsEmpty()) {
    964     splinter()->first_interval_ = splinter_temp.first_interval_;
    965     splinter()->last_interval_ = splinter_temp.last_interval_;
    966   } else {
    967     splinter()->last_interval_->set_next(splinter_temp.first_interval_);
    968     splinter()->last_interval_ = splinter_temp.last_interval_;
    969   }
    970   if (splinter()->first_pos() == nullptr) {
    971     splinter()->first_pos_ = splinter_temp.first_pos_;
    972   } else {
    973     splinter()->last_pos_->set_next(splinter_temp.first_pos_);
    974   }
    975   if (last_in_splinter != nullptr) {
    976     splinter()->last_pos_ = last_in_splinter;
    977   } else {
    978     if (splinter()->first_pos() != nullptr &&
    979         splinter()->last_pos_ == nullptr) {
    980       splinter()->last_pos_ = splinter()->first_pos();
    981       for (UsePosition* pos = splinter()->first_pos(); pos != nullptr;
    982            pos = pos->next()) {
    983         splinter()->last_pos_ = pos;
    984       }
    985     }
    986   }
    987 #if DEBUG
    988   Verify();
    989   splinter()->Verify();
    990 #endif
    991 }
    992 
    993 
    994 void TopLevelLiveRange::SetSplinteredFrom(TopLevelLiveRange* splinter_parent) {
    995   splintered_from_ = splinter_parent;
    996   if (!HasSpillOperand() && splinter_parent->spill_range_ != nullptr) {
    997     SetSpillRange(splinter_parent->spill_range_);
    998   }
    999 }
   1000 
   1001 
   1002 void TopLevelLiveRange::UpdateSpillRangePostMerge(TopLevelLiveRange* merged) {
   1003   DCHECK(merged->TopLevel() == this);
   1004 
   1005   if (HasNoSpillType() && merged->HasSpillRange()) {
   1006     set_spill_type(merged->spill_type());
   1007     DCHECK(GetSpillRange()->live_ranges().size() > 0);
   1008     merged->spill_range_ = nullptr;
   1009     merged->bits_ =
   1010         SpillTypeField::update(merged->bits_, SpillType::kNoSpillType);
   1011   }
   1012 }
   1013 
   1014 
   1015 void TopLevelLiveRange::Merge(TopLevelLiveRange* other, Zone* zone) {
   1016   DCHECK(Start() < other->Start());
   1017   DCHECK(other->splintered_from() == this);
   1018 
   1019   LiveRange* first = this;
   1020   LiveRange* second = other;
   1021   DCHECK(first->Start() < second->Start());
   1022   while (first != nullptr && second != nullptr) {
   1023     DCHECK(first != second);
   1024     // Make sure the ranges are in order each time we iterate.
   1025     if (second->Start() < first->Start()) {
   1026       LiveRange* tmp = second;
   1027       second = first;
   1028       first = tmp;
   1029       continue;
   1030     }
   1031 
   1032     if (first->End() <= second->Start()) {
   1033       if (first->next() == nullptr ||
   1034           first->next()->Start() > second->Start()) {
   1035         // First is in order before second.
   1036         LiveRange* temp = first->next();
   1037         first->next_ = second;
   1038         first = temp;
   1039       } else {
   1040         // First is in order before its successor (or second), so advance first.
   1041         first = first->next();
   1042       }
   1043       continue;
   1044     }
   1045 
   1046     DCHECK(first->Start() < second->Start());
   1047     // If first and second intersect, split first.
   1048     if (first->Start() < second->End() && second->Start() < first->End()) {
   1049       LiveRange* temp = first->SplitAt(second->Start(), zone);
   1050       CHECK(temp != first);
   1051       temp->set_spilled(first->spilled());
   1052       if (!temp->spilled())
   1053         temp->set_assigned_register(first->assigned_register());
   1054 
   1055       first->next_ = second;
   1056       first = temp;
   1057       continue;
   1058     }
   1059     DCHECK(first->End() <= second->Start());
   1060   }
   1061 
   1062   TopLevel()->UpdateParentForAllChildren(TopLevel());
   1063   TopLevel()->UpdateSpillRangePostMerge(other);
   1064   TopLevel()->set_has_slot_use(TopLevel()->has_slot_use() ||
   1065                                other->has_slot_use());
   1066 
   1067 #if DEBUG
   1068   Verify();
   1069 #endif
   1070 }
   1071 
   1072 
   1073 void TopLevelLiveRange::VerifyChildrenInOrder() const {
   1074   LifetimePosition last_end = End();
   1075   for (const LiveRange* child = this->next(); child != nullptr;
   1076        child = child->next()) {
   1077     DCHECK(last_end <= child->Start());
   1078     last_end = child->End();
   1079   }
   1080 }
   1081 
   1082 
   1083 void TopLevelLiveRange::Verify() const {
   1084   VerifyChildrenInOrder();
   1085   for (const LiveRange* child = this; child != nullptr; child = child->next()) {
   1086     VerifyChildStructure();
   1087   }
   1088 }
   1089 
   1090 
   1091 void TopLevelLiveRange::ShortenTo(LifetimePosition start) {
   1092   TRACE("Shorten live range %d to [%d\n", vreg(), start.value());
   1093   DCHECK(first_interval_ != nullptr);
   1094   DCHECK(first_interval_->start() <= start);
   1095   DCHECK(start < first_interval_->end());
   1096   first_interval_->set_start(start);
   1097 }
   1098 
   1099 
   1100 void TopLevelLiveRange::EnsureInterval(LifetimePosition start,
   1101                                        LifetimePosition end, Zone* zone) {
   1102   TRACE("Ensure live range %d in interval [%d %d[\n", vreg(), start.value(),
   1103         end.value());
   1104   LifetimePosition new_end = end;
   1105   while (first_interval_ != nullptr && first_interval_->start() <= end) {
   1106     if (first_interval_->end() > end) {
   1107       new_end = first_interval_->end();
   1108     }
   1109     first_interval_ = first_interval_->next();
   1110   }
   1111 
   1112   UseInterval* new_interval = new (zone) UseInterval(start, new_end);
   1113   new_interval->set_next(first_interval_);
   1114   first_interval_ = new_interval;
   1115   if (new_interval->next() == nullptr) {
   1116     last_interval_ = new_interval;
   1117   }
   1118 }
   1119 
   1120 
   1121 void TopLevelLiveRange::AddUseInterval(LifetimePosition start,
   1122                                        LifetimePosition end, Zone* zone) {
   1123   TRACE("Add to live range %d interval [%d %d[\n", vreg(), start.value(),
   1124         end.value());
   1125   if (first_interval_ == nullptr) {
   1126     UseInterval* interval = new (zone) UseInterval(start, end);
   1127     first_interval_ = interval;
   1128     last_interval_ = interval;
   1129   } else {
   1130     if (end == first_interval_->start()) {
   1131       first_interval_->set_start(start);
   1132     } else if (end < first_interval_->start()) {
   1133       UseInterval* interval = new (zone) UseInterval(start, end);
   1134       interval->set_next(first_interval_);
   1135       first_interval_ = interval;
   1136     } else {
   1137       // Order of instruction's processing (see ProcessInstructions) guarantees
   1138       // that each new use interval either precedes, intersects with or touches
   1139       // the last added interval.
   1140       DCHECK(start <= first_interval_->end());
   1141       first_interval_->set_start(Min(start, first_interval_->start()));
   1142       first_interval_->set_end(Max(end, first_interval_->end()));
   1143     }
   1144   }
   1145 }
   1146 
   1147 
   1148 void TopLevelLiveRange::AddUsePosition(UsePosition* use_pos) {
   1149   LifetimePosition pos = use_pos->pos();
   1150   TRACE("Add to live range %d use position %d\n", vreg(), pos.value());
   1151   UsePosition* prev_hint = nullptr;
   1152   UsePosition* prev = nullptr;
   1153   UsePosition* current = first_pos_;
   1154   while (current != nullptr && current->pos() < pos) {
   1155     prev_hint = current->HasHint() ? current : prev_hint;
   1156     prev = current;
   1157     current = current->next();
   1158   }
   1159 
   1160   if (prev == nullptr) {
   1161     use_pos->set_next(first_pos_);
   1162     first_pos_ = use_pos;
   1163   } else {
   1164     use_pos->set_next(prev->next());
   1165     prev->set_next(use_pos);
   1166   }
   1167 
   1168   if (prev_hint == nullptr && use_pos->HasHint()) {
   1169     current_hint_position_ = use_pos;
   1170   }
   1171 }
   1172 
   1173 
   1174 static bool AreUseIntervalsIntersecting(UseInterval* interval1,
   1175                                         UseInterval* interval2) {
   1176   while (interval1 != nullptr && interval2 != nullptr) {
   1177     if (interval1->start() < interval2->start()) {
   1178       if (interval1->end() > interval2->start()) {
   1179         return true;
   1180       }
   1181       interval1 = interval1->next();
   1182     } else {
   1183       if (interval2->end() > interval1->start()) {
   1184         return true;
   1185       }
   1186       interval2 = interval2->next();
   1187     }
   1188   }
   1189   return false;
   1190 }
   1191 
   1192 
   1193 std::ostream& operator<<(std::ostream& os,
   1194                          const PrintableLiveRange& printable_range) {
   1195   const LiveRange* range = printable_range.range_;
   1196   os << "Range: " << range->TopLevel()->vreg() << ":" << range->relative_id()
   1197      << " ";
   1198   if (range->TopLevel()->is_phi()) os << "phi ";
   1199   if (range->TopLevel()->is_non_loop_phi()) os << "nlphi ";
   1200 
   1201   os << "{" << std::endl;
   1202   UseInterval* interval = range->first_interval();
   1203   UsePosition* use_pos = range->first_pos();
   1204   PrintableInstructionOperand pio;
   1205   pio.register_configuration_ = printable_range.register_configuration_;
   1206   while (use_pos != nullptr) {
   1207     if (use_pos->HasOperand()) {
   1208       pio.op_ = *use_pos->operand();
   1209       os << pio << use_pos->pos() << " ";
   1210     }
   1211     use_pos = use_pos->next();
   1212   }
   1213   os << std::endl;
   1214 
   1215   while (interval != nullptr) {
   1216     os << '[' << interval->start() << ", " << interval->end() << ')'
   1217        << std::endl;
   1218     interval = interval->next();
   1219   }
   1220   os << "}";
   1221   return os;
   1222 }
   1223 
   1224 SpillRange::SpillRange(TopLevelLiveRange* parent, Zone* zone)
   1225     : live_ranges_(zone),
   1226       assigned_slot_(kUnassignedSlot),
   1227       byte_width_(GetByteWidth(parent->representation())) {
   1228   // Spill ranges are created for top level, non-splintered ranges. This is so
   1229   // that, when merging decisions are made, we consider the full extent of the
   1230   // virtual register, and avoid clobbering it.
   1231   DCHECK(!parent->IsSplinter());
   1232   UseInterval* result = nullptr;
   1233   UseInterval* node = nullptr;
   1234   // Copy the intervals for all ranges.
   1235   for (LiveRange* range = parent; range != nullptr; range = range->next()) {
   1236     UseInterval* src = range->first_interval();
   1237     while (src != nullptr) {
   1238       UseInterval* new_node = new (zone) UseInterval(src->start(), src->end());
   1239       if (result == nullptr) {
   1240         result = new_node;
   1241       } else {
   1242         node->set_next(new_node);
   1243       }
   1244       node = new_node;
   1245       src = src->next();
   1246     }
   1247   }
   1248   use_interval_ = result;
   1249   live_ranges().push_back(parent);
   1250   end_position_ = node->end();
   1251   parent->SetSpillRange(this);
   1252 }
   1253 
   1254 bool SpillRange::IsIntersectingWith(SpillRange* other) const {
   1255   if (this->use_interval_ == nullptr || other->use_interval_ == nullptr ||
   1256       this->End() <= other->use_interval_->start() ||
   1257       other->End() <= this->use_interval_->start()) {
   1258     return false;
   1259   }
   1260   return AreUseIntervalsIntersecting(use_interval_, other->use_interval_);
   1261 }
   1262 
   1263 
   1264 bool SpillRange::TryMerge(SpillRange* other) {
   1265   if (HasSlot() || other->HasSlot()) return false;
   1266   if (byte_width() != other->byte_width() || IsIntersectingWith(other))
   1267     return false;
   1268 
   1269   LifetimePosition max = LifetimePosition::MaxPosition();
   1270   if (End() < other->End() && other->End() != max) {
   1271     end_position_ = other->End();
   1272   }
   1273   other->end_position_ = max;
   1274 
   1275   MergeDisjointIntervals(other->use_interval_);
   1276   other->use_interval_ = nullptr;
   1277 
   1278   for (TopLevelLiveRange* range : other->live_ranges()) {
   1279     DCHECK(range->GetSpillRange() == other);
   1280     range->SetSpillRange(this);
   1281   }
   1282 
   1283   live_ranges().insert(live_ranges().end(), other->live_ranges().begin(),
   1284                        other->live_ranges().end());
   1285   other->live_ranges().clear();
   1286 
   1287   return true;
   1288 }
   1289 
   1290 
   1291 void SpillRange::MergeDisjointIntervals(UseInterval* other) {
   1292   UseInterval* tail = nullptr;
   1293   UseInterval* current = use_interval_;
   1294   while (other != nullptr) {
   1295     // Make sure the 'current' list starts first
   1296     if (current == nullptr || current->start() > other->start()) {
   1297       std::swap(current, other);
   1298     }
   1299     // Check disjointness
   1300     DCHECK(other == nullptr || current->end() <= other->start());
   1301     // Append the 'current' node to the result accumulator and move forward
   1302     if (tail == nullptr) {
   1303       use_interval_ = current;
   1304     } else {
   1305       tail->set_next(current);
   1306     }
   1307     tail = current;
   1308     current = current->next();
   1309   }
   1310   // Other list is empty => we are done
   1311 }
   1312 
   1313 
   1314 void SpillRange::Print() const {
   1315   OFStream os(stdout);
   1316   os << "{" << std::endl;
   1317   for (TopLevelLiveRange* range : live_ranges()) {
   1318     os << range->vreg() << " ";
   1319   }
   1320   os << std::endl;
   1321 
   1322   for (UseInterval* i = interval(); i != nullptr; i = i->next()) {
   1323     os << '[' << i->start() << ", " << i->end() << ')' << std::endl;
   1324   }
   1325   os << "}" << std::endl;
   1326 }
   1327 
   1328 
   1329 RegisterAllocationData::PhiMapValue::PhiMapValue(PhiInstruction* phi,
   1330                                                  const InstructionBlock* block,
   1331                                                  Zone* zone)
   1332     : phi_(phi),
   1333       block_(block),
   1334       incoming_operands_(zone),
   1335       assigned_register_(kUnassignedRegister) {
   1336   incoming_operands_.reserve(phi->operands().size());
   1337 }
   1338 
   1339 
   1340 void RegisterAllocationData::PhiMapValue::AddOperand(
   1341     InstructionOperand* operand) {
   1342   incoming_operands_.push_back(operand);
   1343 }
   1344 
   1345 
   1346 void RegisterAllocationData::PhiMapValue::CommitAssignment(
   1347     const InstructionOperand& assigned) {
   1348   for (InstructionOperand* operand : incoming_operands_) {
   1349     InstructionOperand::ReplaceWith(operand, &assigned);
   1350   }
   1351 }
   1352 
   1353 RegisterAllocationData::RegisterAllocationData(
   1354     const RegisterConfiguration* config, Zone* zone, Frame* frame,
   1355     InstructionSequence* code, const char* debug_name)
   1356     : allocation_zone_(zone),
   1357       frame_(frame),
   1358       code_(code),
   1359       debug_name_(debug_name),
   1360       config_(config),
   1361       phi_map_(allocation_zone()),
   1362       live_in_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()),
   1363       live_out_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()),
   1364       live_ranges_(code->VirtualRegisterCount() * 2, nullptr,
   1365                    allocation_zone()),
   1366       fixed_live_ranges_(this->config()->num_general_registers(), nullptr,
   1367                          allocation_zone()),
   1368       fixed_float_live_ranges_(allocation_zone()),
   1369       fixed_double_live_ranges_(this->config()->num_double_registers(), nullptr,
   1370                                 allocation_zone()),
   1371       fixed_simd128_live_ranges_(allocation_zone()),
   1372       spill_ranges_(code->VirtualRegisterCount(), nullptr, allocation_zone()),
   1373       delayed_references_(allocation_zone()),
   1374       assigned_registers_(nullptr),
   1375       assigned_double_registers_(nullptr),
   1376       virtual_register_count_(code->VirtualRegisterCount()),
   1377       preassigned_slot_ranges_(zone) {
   1378   if (!kSimpleFPAliasing) {
   1379     fixed_float_live_ranges_.resize(this->config()->num_float_registers(),
   1380                                     nullptr);
   1381     fixed_simd128_live_ranges_.resize(this->config()->num_simd128_registers(),
   1382                                       nullptr);
   1383   }
   1384 
   1385   assigned_registers_ = new (code_zone())
   1386       BitVector(this->config()->num_general_registers(), code_zone());
   1387   assigned_double_registers_ = new (code_zone())
   1388       BitVector(this->config()->num_double_registers(), code_zone());
   1389   this->frame()->SetAllocatedRegisters(assigned_registers_);
   1390   this->frame()->SetAllocatedDoubleRegisters(assigned_double_registers_);
   1391 }
   1392 
   1393 
   1394 MoveOperands* RegisterAllocationData::AddGapMove(
   1395     int index, Instruction::GapPosition position,
   1396     const InstructionOperand& from, const InstructionOperand& to) {
   1397   Instruction* instr = code()->InstructionAt(index);
   1398   ParallelMove* moves = instr->GetOrCreateParallelMove(position, code_zone());
   1399   return moves->AddMove(from, to);
   1400 }
   1401 
   1402 
   1403 MachineRepresentation RegisterAllocationData::RepresentationFor(
   1404     int virtual_register) {
   1405   DCHECK_LT(virtual_register, code()->VirtualRegisterCount());
   1406   return code()->GetRepresentation(virtual_register);
   1407 }
   1408 
   1409 
   1410 TopLevelLiveRange* RegisterAllocationData::GetOrCreateLiveRangeFor(int index) {
   1411   if (index >= static_cast<int>(live_ranges().size())) {
   1412     live_ranges().resize(index + 1, nullptr);
   1413   }
   1414   TopLevelLiveRange* result = live_ranges()[index];
   1415   if (result == nullptr) {
   1416     result = NewLiveRange(index, RepresentationFor(index));
   1417     live_ranges()[index] = result;
   1418   }
   1419   return result;
   1420 }
   1421 
   1422 
   1423 TopLevelLiveRange* RegisterAllocationData::NewLiveRange(
   1424     int index, MachineRepresentation rep) {
   1425   return new (allocation_zone()) TopLevelLiveRange(index, rep);
   1426 }
   1427 
   1428 
   1429 int RegisterAllocationData::GetNextLiveRangeId() {
   1430   int vreg = virtual_register_count_++;
   1431   if (vreg >= static_cast<int>(live_ranges().size())) {
   1432     live_ranges().resize(vreg + 1, nullptr);
   1433   }
   1434   return vreg;
   1435 }
   1436 
   1437 
   1438 TopLevelLiveRange* RegisterAllocationData::NextLiveRange(
   1439     MachineRepresentation rep) {
   1440   int vreg = GetNextLiveRangeId();
   1441   TopLevelLiveRange* ret = NewLiveRange(vreg, rep);
   1442   return ret;
   1443 }
   1444 
   1445 
   1446 RegisterAllocationData::PhiMapValue* RegisterAllocationData::InitializePhiMap(
   1447     const InstructionBlock* block, PhiInstruction* phi) {
   1448   RegisterAllocationData::PhiMapValue* map_value = new (allocation_zone())
   1449       RegisterAllocationData::PhiMapValue(phi, block, allocation_zone());
   1450   auto res =
   1451       phi_map_.insert(std::make_pair(phi->virtual_register(), map_value));
   1452   DCHECK(res.second);
   1453   USE(res);
   1454   return map_value;
   1455 }
   1456 
   1457 
   1458 RegisterAllocationData::PhiMapValue* RegisterAllocationData::GetPhiMapValueFor(
   1459     int virtual_register) {
   1460   auto it = phi_map_.find(virtual_register);
   1461   DCHECK(it != phi_map_.end());
   1462   return it->second;
   1463 }
   1464 
   1465 
   1466 RegisterAllocationData::PhiMapValue* RegisterAllocationData::GetPhiMapValueFor(
   1467     TopLevelLiveRange* top_range) {
   1468   return GetPhiMapValueFor(top_range->vreg());
   1469 }
   1470 
   1471 
   1472 bool RegisterAllocationData::ExistsUseWithoutDefinition() {
   1473   bool found = false;
   1474   BitVector::Iterator iterator(live_in_sets()[0]);
   1475   while (!iterator.Done()) {
   1476     found = true;
   1477     int operand_index = iterator.Current();
   1478     PrintF("Register allocator error: live v%d reached first block.\n",
   1479            operand_index);
   1480     LiveRange* range = GetOrCreateLiveRangeFor(operand_index);
   1481     PrintF("  (first use is at %d)\n", range->first_pos()->pos().value());
   1482     if (debug_name() == nullptr) {
   1483       PrintF("\n");
   1484     } else {
   1485       PrintF("  (function: %s)\n", debug_name());
   1486     }
   1487     iterator.Advance();
   1488   }
   1489   return found;
   1490 }
   1491 
   1492 
   1493 // If a range is defined in a deferred block, we can expect all the range
   1494 // to only cover positions in deferred blocks. Otherwise, a block on the
   1495 // hot path would be dominated by a deferred block, meaning it is unreachable
   1496 // without passing through the deferred block, which is contradictory.
   1497 // In particular, when such a range contributes a result back on the hot
   1498 // path, it will be as one of the inputs of a phi. In that case, the value
   1499 // will be transferred via a move in the Gap::END's of the last instruction
   1500 // of a deferred block.
   1501 bool RegisterAllocationData::RangesDefinedInDeferredStayInDeferred() {
   1502   for (const TopLevelLiveRange* range : live_ranges()) {
   1503     if (range == nullptr || range->IsEmpty() ||
   1504         !code()
   1505              ->GetInstructionBlock(range->Start().ToInstructionIndex())
   1506              ->IsDeferred()) {
   1507       continue;
   1508     }
   1509     for (const UseInterval* i = range->first_interval(); i != nullptr;
   1510          i = i->next()) {
   1511       int first = i->FirstGapIndex();
   1512       int last = i->LastGapIndex();
   1513       for (int instr = first; instr <= last;) {
   1514         const InstructionBlock* block = code()->GetInstructionBlock(instr);
   1515         if (!block->IsDeferred()) return false;
   1516         instr = block->last_instruction_index() + 1;
   1517       }
   1518     }
   1519   }
   1520   return true;
   1521 }
   1522 
   1523 SpillRange* RegisterAllocationData::AssignSpillRangeToLiveRange(
   1524     TopLevelLiveRange* range) {
   1525   DCHECK(!range->HasSpillOperand());
   1526 
   1527   SpillRange* spill_range = range->GetAllocatedSpillRange();
   1528   if (spill_range == nullptr) {
   1529     DCHECK(!range->IsSplinter());
   1530     spill_range = new (allocation_zone()) SpillRange(range, allocation_zone());
   1531   }
   1532   range->set_spill_type(TopLevelLiveRange::SpillType::kSpillRange);
   1533 
   1534   int spill_range_index =
   1535       range->IsSplinter() ? range->splintered_from()->vreg() : range->vreg();
   1536 
   1537   spill_ranges()[spill_range_index] = spill_range;
   1538 
   1539   return spill_range;
   1540 }
   1541 
   1542 
   1543 SpillRange* RegisterAllocationData::CreateSpillRangeForLiveRange(
   1544     TopLevelLiveRange* range) {
   1545   DCHECK(!range->HasSpillOperand());
   1546   DCHECK(!range->IsSplinter());
   1547   SpillRange* spill_range =
   1548       new (allocation_zone()) SpillRange(range, allocation_zone());
   1549   return spill_range;
   1550 }
   1551 
   1552 void RegisterAllocationData::MarkAllocated(MachineRepresentation rep,
   1553                                            int index) {
   1554   switch (rep) {
   1555     case MachineRepresentation::kFloat32:
   1556     case MachineRepresentation::kSimd128:
   1557       if (kSimpleFPAliasing) {
   1558         assigned_double_registers_->Add(index);
   1559       } else {
   1560         int alias_base_index = -1;
   1561         int aliases = config()->GetAliases(
   1562             rep, index, MachineRepresentation::kFloat64, &alias_base_index);
   1563         DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1));
   1564         while (aliases--) {
   1565           int aliased_reg = alias_base_index + aliases;
   1566           assigned_double_registers_->Add(aliased_reg);
   1567         }
   1568       }
   1569       break;
   1570     case MachineRepresentation::kFloat64:
   1571       assigned_double_registers_->Add(index);
   1572       break;
   1573     default:
   1574       DCHECK(!IsFloatingPoint(rep));
   1575       assigned_registers_->Add(index);
   1576       break;
   1577   }
   1578 }
   1579 
   1580 bool RegisterAllocationData::IsBlockBoundary(LifetimePosition pos) const {
   1581   return pos.IsFullStart() &&
   1582          code()->GetInstructionBlock(pos.ToInstructionIndex())->code_start() ==
   1583              pos.ToInstructionIndex();
   1584 }
   1585 
   1586 
   1587 ConstraintBuilder::ConstraintBuilder(RegisterAllocationData* data)
   1588     : data_(data) {}
   1589 
   1590 
   1591 InstructionOperand* ConstraintBuilder::AllocateFixed(
   1592     UnallocatedOperand* operand, int pos, bool is_tagged) {
   1593   TRACE("Allocating fixed reg for op %d\n", operand->virtual_register());
   1594   DCHECK(operand->HasFixedPolicy());
   1595   InstructionOperand allocated;
   1596   MachineRepresentation rep = InstructionSequence::DefaultRepresentation();
   1597   int virtual_register = operand->virtual_register();
   1598   if (virtual_register != InstructionOperand::kInvalidVirtualRegister) {
   1599     rep = data()->RepresentationFor(virtual_register);
   1600   }
   1601   if (operand->HasFixedSlotPolicy()) {
   1602     allocated = AllocatedOperand(AllocatedOperand::STACK_SLOT, rep,
   1603                                  operand->fixed_slot_index());
   1604   } else if (operand->HasFixedRegisterPolicy()) {
   1605     DCHECK(!IsFloatingPoint(rep));
   1606     allocated = AllocatedOperand(AllocatedOperand::REGISTER, rep,
   1607                                  operand->fixed_register_index());
   1608   } else if (operand->HasFixedFPRegisterPolicy()) {
   1609     DCHECK(IsFloatingPoint(rep));
   1610     DCHECK_NE(InstructionOperand::kInvalidVirtualRegister, virtual_register);
   1611     allocated = AllocatedOperand(AllocatedOperand::REGISTER, rep,
   1612                                  operand->fixed_register_index());
   1613   } else {
   1614     UNREACHABLE();
   1615   }
   1616   InstructionOperand::ReplaceWith(operand, &allocated);
   1617   if (is_tagged) {
   1618     TRACE("Fixed reg is tagged at %d\n", pos);
   1619     Instruction* instr = code()->InstructionAt(pos);
   1620     if (instr->HasReferenceMap()) {
   1621       instr->reference_map()->RecordReference(*AllocatedOperand::cast(operand));
   1622     }
   1623   }
   1624   return operand;
   1625 }
   1626 
   1627 
   1628 void ConstraintBuilder::MeetRegisterConstraints() {
   1629   for (InstructionBlock* block : code()->instruction_blocks()) {
   1630     MeetRegisterConstraints(block);
   1631   }
   1632 }
   1633 
   1634 
   1635 void ConstraintBuilder::MeetRegisterConstraints(const InstructionBlock* block) {
   1636   int start = block->first_instruction_index();
   1637   int end = block->last_instruction_index();
   1638   DCHECK_NE(-1, start);
   1639   for (int i = start; i <= end; ++i) {
   1640     MeetConstraintsBefore(i);
   1641     if (i != end) MeetConstraintsAfter(i);
   1642   }
   1643   // Meet register constraints for the instruction in the end.
   1644   MeetRegisterConstraintsForLastInstructionInBlock(block);
   1645 }
   1646 
   1647 
   1648 void ConstraintBuilder::MeetRegisterConstraintsForLastInstructionInBlock(
   1649     const InstructionBlock* block) {
   1650   int end = block->last_instruction_index();
   1651   Instruction* last_instruction = code()->InstructionAt(end);
   1652   for (size_t i = 0; i < last_instruction->OutputCount(); i++) {
   1653     InstructionOperand* output_operand = last_instruction->OutputAt(i);
   1654     DCHECK(!output_operand->IsConstant());
   1655     UnallocatedOperand* output = UnallocatedOperand::cast(output_operand);
   1656     int output_vreg = output->virtual_register();
   1657     TopLevelLiveRange* range = data()->GetOrCreateLiveRangeFor(output_vreg);
   1658     bool assigned = false;
   1659     if (output->HasFixedPolicy()) {
   1660       AllocateFixed(output, -1, false);
   1661       // This value is produced on the stack, we never need to spill it.
   1662       if (output->IsStackSlot()) {
   1663         DCHECK(LocationOperand::cast(output)->index() <
   1664                data()->frame()->GetSpillSlotCount());
   1665         range->SetSpillOperand(LocationOperand::cast(output));
   1666         range->SetSpillStartIndex(end);
   1667         assigned = true;
   1668       }
   1669 
   1670       for (const RpoNumber& succ : block->successors()) {
   1671         const InstructionBlock* successor = code()->InstructionBlockAt(succ);
   1672         DCHECK(successor->PredecessorCount() == 1);
   1673         int gap_index = successor->first_instruction_index();
   1674         // Create an unconstrained operand for the same virtual register
   1675         // and insert a gap move from the fixed output to the operand.
   1676         UnallocatedOperand output_copy(UnallocatedOperand::ANY, output_vreg);
   1677         data()->AddGapMove(gap_index, Instruction::START, *output, output_copy);
   1678       }
   1679     }
   1680 
   1681     if (!assigned) {
   1682       for (const RpoNumber& succ : block->successors()) {
   1683         const InstructionBlock* successor = code()->InstructionBlockAt(succ);
   1684         DCHECK(successor->PredecessorCount() == 1);
   1685         int gap_index = successor->first_instruction_index();
   1686         range->RecordSpillLocation(allocation_zone(), gap_index, output);
   1687         range->SetSpillStartIndex(gap_index);
   1688       }
   1689     }
   1690   }
   1691 }
   1692 
   1693 
   1694 void ConstraintBuilder::MeetConstraintsAfter(int instr_index) {
   1695   Instruction* first = code()->InstructionAt(instr_index);
   1696   // Handle fixed temporaries.
   1697   for (size_t i = 0; i < first->TempCount(); i++) {
   1698     UnallocatedOperand* temp = UnallocatedOperand::cast(first->TempAt(i));
   1699     if (temp->HasFixedPolicy()) AllocateFixed(temp, instr_index, false);
   1700   }
   1701   // Handle constant/fixed output operands.
   1702   for (size_t i = 0; i < first->OutputCount(); i++) {
   1703     InstructionOperand* output = first->OutputAt(i);
   1704     if (output->IsConstant()) {
   1705       int output_vreg = ConstantOperand::cast(output)->virtual_register();
   1706       TopLevelLiveRange* range = data()->GetOrCreateLiveRangeFor(output_vreg);
   1707       range->SetSpillStartIndex(instr_index + 1);
   1708       range->SetSpillOperand(output);
   1709       continue;
   1710     }
   1711     UnallocatedOperand* first_output = UnallocatedOperand::cast(output);
   1712     TopLevelLiveRange* range =
   1713         data()->GetOrCreateLiveRangeFor(first_output->virtual_register());
   1714     bool assigned = false;
   1715     if (first_output->HasFixedPolicy()) {
   1716       int output_vreg = first_output->virtual_register();
   1717       UnallocatedOperand output_copy(UnallocatedOperand::ANY, output_vreg);
   1718       bool is_tagged = code()->IsReference(output_vreg);
   1719       if (first_output->HasSecondaryStorage()) {
   1720         range->MarkHasPreassignedSlot();
   1721         data()->preassigned_slot_ranges().push_back(
   1722             std::make_pair(range, first_output->GetSecondaryStorage()));
   1723       }
   1724       AllocateFixed(first_output, instr_index, is_tagged);
   1725 
   1726       // This value is produced on the stack, we never need to spill it.
   1727       if (first_output->IsStackSlot()) {
   1728         DCHECK(LocationOperand::cast(first_output)->index() <
   1729                data()->frame()->GetTotalFrameSlotCount());
   1730         range->SetSpillOperand(LocationOperand::cast(first_output));
   1731         range->SetSpillStartIndex(instr_index + 1);
   1732         assigned = true;
   1733       }
   1734       data()->AddGapMove(instr_index + 1, Instruction::START, *first_output,
   1735                          output_copy);
   1736     }
   1737     // Make sure we add a gap move for spilling (if we have not done
   1738     // so already).
   1739     if (!assigned) {
   1740       range->RecordSpillLocation(allocation_zone(), instr_index + 1,
   1741                                  first_output);
   1742       range->SetSpillStartIndex(instr_index + 1);
   1743     }
   1744   }
   1745 }
   1746 
   1747 
   1748 void ConstraintBuilder::MeetConstraintsBefore(int instr_index) {
   1749   Instruction* second = code()->InstructionAt(instr_index);
   1750   // Handle fixed input operands of second instruction.
   1751   for (size_t i = 0; i < second->InputCount(); i++) {
   1752     InstructionOperand* input = second->InputAt(i);
   1753     if (input->IsImmediate() || input->IsExplicit()) {
   1754       continue;  // Ignore immediates and explicitly reserved registers.
   1755     }
   1756     UnallocatedOperand* cur_input = UnallocatedOperand::cast(input);
   1757     if (cur_input->HasFixedPolicy()) {
   1758       int input_vreg = cur_input->virtual_register();
   1759       UnallocatedOperand input_copy(UnallocatedOperand::ANY, input_vreg);
   1760       bool is_tagged = code()->IsReference(input_vreg);
   1761       AllocateFixed(cur_input, instr_index, is_tagged);
   1762       data()->AddGapMove(instr_index, Instruction::END, input_copy, *cur_input);
   1763     }
   1764   }
   1765   // Handle "output same as input" for second instruction.
   1766   for (size_t i = 0; i < second->OutputCount(); i++) {
   1767     InstructionOperand* output = second->OutputAt(i);
   1768     if (!output->IsUnallocated()) continue;
   1769     UnallocatedOperand* second_output = UnallocatedOperand::cast(output);
   1770     if (!second_output->HasSameAsInputPolicy()) continue;
   1771     DCHECK(i == 0);  // Only valid for first output.
   1772     UnallocatedOperand* cur_input =
   1773         UnallocatedOperand::cast(second->InputAt(0));
   1774     int output_vreg = second_output->virtual_register();
   1775     int input_vreg = cur_input->virtual_register();
   1776     UnallocatedOperand input_copy(UnallocatedOperand::ANY, input_vreg);
   1777     cur_input->set_virtual_register(second_output->virtual_register());
   1778     MoveOperands* gap_move = data()->AddGapMove(instr_index, Instruction::END,
   1779                                                 input_copy, *cur_input);
   1780     if (code()->IsReference(input_vreg) && !code()->IsReference(output_vreg)) {
   1781       if (second->HasReferenceMap()) {
   1782         RegisterAllocationData::DelayedReference delayed_reference = {
   1783             second->reference_map(), &gap_move->source()};
   1784         data()->delayed_references().push_back(delayed_reference);
   1785       }
   1786     } else if (!code()->IsReference(input_vreg) &&
   1787                code()->IsReference(output_vreg)) {
   1788       // The input is assumed to immediately have a tagged representation,
   1789       // before the pointer map can be used. I.e. the pointer map at the
   1790       // instruction will include the output operand (whose value at the
   1791       // beginning of the instruction is equal to the input operand). If
   1792       // this is not desired, then the pointer map at this instruction needs
   1793       // to be adjusted manually.
   1794     }
   1795   }
   1796 }
   1797 
   1798 
   1799 void ConstraintBuilder::ResolvePhis() {
   1800   // Process the blocks in reverse order.
   1801   for (InstructionBlock* block : base::Reversed(code()->instruction_blocks())) {
   1802     ResolvePhis(block);
   1803   }
   1804 }
   1805 
   1806 
   1807 void ConstraintBuilder::ResolvePhis(const InstructionBlock* block) {
   1808   for (PhiInstruction* phi : block->phis()) {
   1809     int phi_vreg = phi->virtual_register();
   1810     RegisterAllocationData::PhiMapValue* map_value =
   1811         data()->InitializePhiMap(block, phi);
   1812     InstructionOperand& output = phi->output();
   1813     // Map the destination operands, so the commitment phase can find them.
   1814     for (size_t i = 0; i < phi->operands().size(); ++i) {
   1815       InstructionBlock* cur_block =
   1816           code()->InstructionBlockAt(block->predecessors()[i]);
   1817       UnallocatedOperand input(UnallocatedOperand::ANY, phi->operands()[i]);
   1818       MoveOperands* move = data()->AddGapMove(
   1819           cur_block->last_instruction_index(), Instruction::END, input, output);
   1820       map_value->AddOperand(&move->destination());
   1821       DCHECK(!code()
   1822                   ->InstructionAt(cur_block->last_instruction_index())
   1823                   ->HasReferenceMap());
   1824     }
   1825     TopLevelLiveRange* live_range = data()->GetOrCreateLiveRangeFor(phi_vreg);
   1826     int gap_index = block->first_instruction_index();
   1827     live_range->RecordSpillLocation(allocation_zone(), gap_index, &output);
   1828     live_range->SetSpillStartIndex(gap_index);
   1829     // We use the phi-ness of some nodes in some later heuristics.
   1830     live_range->set_is_phi(true);
   1831     live_range->set_is_non_loop_phi(!block->IsLoopHeader());
   1832   }
   1833 }
   1834 
   1835 
   1836 LiveRangeBuilder::LiveRangeBuilder(RegisterAllocationData* data,
   1837                                    Zone* local_zone)
   1838     : data_(data), phi_hints_(local_zone) {}
   1839 
   1840 
   1841 BitVector* LiveRangeBuilder::ComputeLiveOut(const InstructionBlock* block,
   1842                                             RegisterAllocationData* data) {
   1843   size_t block_index = block->rpo_number().ToSize();
   1844   BitVector* live_out = data->live_out_sets()[block_index];
   1845   if (live_out == nullptr) {
   1846     // Compute live out for the given block, except not including backward
   1847     // successor edges.
   1848     Zone* zone = data->allocation_zone();
   1849     const InstructionSequence* code = data->code();
   1850 
   1851     live_out = new (zone) BitVector(code->VirtualRegisterCount(), zone);
   1852 
   1853     // Process all successor blocks.
   1854     for (const RpoNumber& succ : block->successors()) {
   1855       // Add values live on entry to the successor.
   1856       if (succ <= block->rpo_number()) continue;
   1857       BitVector* live_in = data->live_in_sets()[succ.ToSize()];
   1858       if (live_in != nullptr) live_out->Union(*live_in);
   1859 
   1860       // All phi input operands corresponding to this successor edge are live
   1861       // out from this block.
   1862       const InstructionBlock* successor = code->InstructionBlockAt(succ);
   1863       size_t index = successor->PredecessorIndexOf(block->rpo_number());
   1864       DCHECK(index < successor->PredecessorCount());
   1865       for (PhiInstruction* phi : successor->phis()) {
   1866         live_out->Add(phi->operands()[index]);
   1867       }
   1868     }
   1869     data->live_out_sets()[block_index] = live_out;
   1870   }
   1871   return live_out;
   1872 }
   1873 
   1874 
   1875 void LiveRangeBuilder::AddInitialIntervals(const InstructionBlock* block,
   1876                                            BitVector* live_out) {
   1877   // Add an interval that includes the entire block to the live range for
   1878   // each live_out value.
   1879   LifetimePosition start = LifetimePosition::GapFromInstructionIndex(
   1880       block->first_instruction_index());
   1881   LifetimePosition end = LifetimePosition::InstructionFromInstructionIndex(
   1882                              block->last_instruction_index())
   1883                              .NextStart();
   1884   BitVector::Iterator iterator(live_out);
   1885   while (!iterator.Done()) {
   1886     int operand_index = iterator.Current();
   1887     TopLevelLiveRange* range = data()->GetOrCreateLiveRangeFor(operand_index);
   1888     range->AddUseInterval(start, end, allocation_zone());
   1889     iterator.Advance();
   1890   }
   1891 }
   1892 
   1893 int LiveRangeBuilder::FixedFPLiveRangeID(int index, MachineRepresentation rep) {
   1894   int result = -index - 1;
   1895   switch (rep) {
   1896     case MachineRepresentation::kSimd128:
   1897       result -= config()->num_float_registers();
   1898     // Fall through.
   1899     case MachineRepresentation::kFloat32:
   1900       result -= config()->num_double_registers();
   1901     // Fall through.
   1902     case MachineRepresentation::kFloat64:
   1903       result -= config()->num_general_registers();
   1904       break;
   1905     default:
   1906       UNREACHABLE();
   1907       break;
   1908   }
   1909   return result;
   1910 }
   1911 
   1912 TopLevelLiveRange* LiveRangeBuilder::FixedLiveRangeFor(int index) {
   1913   DCHECK(index < config()->num_general_registers());
   1914   TopLevelLiveRange* result = data()->fixed_live_ranges()[index];
   1915   if (result == nullptr) {
   1916     MachineRepresentation rep = InstructionSequence::DefaultRepresentation();
   1917     result = data()->NewLiveRange(FixedLiveRangeID(index), rep);
   1918     DCHECK(result->IsFixed());
   1919     result->set_assigned_register(index);
   1920     data()->MarkAllocated(rep, index);
   1921     data()->fixed_live_ranges()[index] = result;
   1922   }
   1923   return result;
   1924 }
   1925 
   1926 TopLevelLiveRange* LiveRangeBuilder::FixedFPLiveRangeFor(
   1927     int index, MachineRepresentation rep) {
   1928   int num_regs = config()->num_double_registers();
   1929   ZoneVector<TopLevelLiveRange*>* live_ranges =
   1930       &data()->fixed_double_live_ranges();
   1931   if (!kSimpleFPAliasing) {
   1932     switch (rep) {
   1933       case MachineRepresentation::kFloat32:
   1934         num_regs = config()->num_float_registers();
   1935         live_ranges = &data()->fixed_float_live_ranges();
   1936         break;
   1937       case MachineRepresentation::kSimd128:
   1938         num_regs = config()->num_simd128_registers();
   1939         live_ranges = &data()->fixed_simd128_live_ranges();
   1940         break;
   1941       default:
   1942         break;
   1943     }
   1944   }
   1945 
   1946   DCHECK(index < num_regs);
   1947   USE(num_regs);
   1948   TopLevelLiveRange* result = (*live_ranges)[index];
   1949   if (result == nullptr) {
   1950     result = data()->NewLiveRange(FixedFPLiveRangeID(index, rep), rep);
   1951     DCHECK(result->IsFixed());
   1952     result->set_assigned_register(index);
   1953     data()->MarkAllocated(rep, index);
   1954     (*live_ranges)[index] = result;
   1955   }
   1956   return result;
   1957 }
   1958 
   1959 TopLevelLiveRange* LiveRangeBuilder::LiveRangeFor(InstructionOperand* operand) {
   1960   if (operand->IsUnallocated()) {
   1961     return data()->GetOrCreateLiveRangeFor(
   1962         UnallocatedOperand::cast(operand)->virtual_register());
   1963   } else if (operand->IsConstant()) {
   1964     return data()->GetOrCreateLiveRangeFor(
   1965         ConstantOperand::cast(operand)->virtual_register());
   1966   } else if (operand->IsRegister()) {
   1967     return FixedLiveRangeFor(
   1968         LocationOperand::cast(operand)->GetRegister().code());
   1969   } else if (operand->IsFPRegister()) {
   1970     LocationOperand* op = LocationOperand::cast(operand);
   1971     return FixedFPLiveRangeFor(op->register_code(), op->representation());
   1972   } else {
   1973     return nullptr;
   1974   }
   1975 }
   1976 
   1977 
   1978 UsePosition* LiveRangeBuilder::NewUsePosition(LifetimePosition pos,
   1979                                               InstructionOperand* operand,
   1980                                               void* hint,
   1981                                               UsePositionHintType hint_type) {
   1982   return new (allocation_zone()) UsePosition(pos, operand, hint, hint_type);
   1983 }
   1984 
   1985 
   1986 UsePosition* LiveRangeBuilder::Define(LifetimePosition position,
   1987                                       InstructionOperand* operand, void* hint,
   1988                                       UsePositionHintType hint_type) {
   1989   TopLevelLiveRange* range = LiveRangeFor(operand);
   1990   if (range == nullptr) return nullptr;
   1991 
   1992   if (range->IsEmpty() || range->Start() > position) {
   1993     // Can happen if there is a definition without use.
   1994     range->AddUseInterval(position, position.NextStart(), allocation_zone());
   1995     range->AddUsePosition(NewUsePosition(position.NextStart()));
   1996   } else {
   1997     range->ShortenTo(position);
   1998   }
   1999   if (!operand->IsUnallocated()) return nullptr;
   2000   UnallocatedOperand* unalloc_operand = UnallocatedOperand::cast(operand);
   2001   UsePosition* use_pos =
   2002       NewUsePosition(position, unalloc_operand, hint, hint_type);
   2003   range->AddUsePosition(use_pos);
   2004   return use_pos;
   2005 }
   2006 
   2007 
   2008 UsePosition* LiveRangeBuilder::Use(LifetimePosition block_start,
   2009                                    LifetimePosition position,
   2010                                    InstructionOperand* operand, void* hint,
   2011                                    UsePositionHintType hint_type) {
   2012   TopLevelLiveRange* range = LiveRangeFor(operand);
   2013   if (range == nullptr) return nullptr;
   2014   UsePosition* use_pos = nullptr;
   2015   if (operand->IsUnallocated()) {
   2016     UnallocatedOperand* unalloc_operand = UnallocatedOperand::cast(operand);
   2017     use_pos = NewUsePosition(position, unalloc_operand, hint, hint_type);
   2018     range->AddUsePosition(use_pos);
   2019   }
   2020   range->AddUseInterval(block_start, position, allocation_zone());
   2021   return use_pos;
   2022 }
   2023 
   2024 
   2025 void LiveRangeBuilder::ProcessInstructions(const InstructionBlock* block,
   2026                                            BitVector* live) {
   2027   int block_start = block->first_instruction_index();
   2028   LifetimePosition block_start_position =
   2029       LifetimePosition::GapFromInstructionIndex(block_start);
   2030   bool fixed_float_live_ranges = false;
   2031   bool fixed_simd128_live_ranges = false;
   2032   if (!kSimpleFPAliasing) {
   2033     int mask = data()->code()->representation_mask();
   2034     fixed_float_live_ranges = (mask & kFloatRepBit) != 0;
   2035     fixed_simd128_live_ranges = (mask & kSimd128RepBit) != 0;
   2036   }
   2037 
   2038   for (int index = block->last_instruction_index(); index >= block_start;
   2039        index--) {
   2040     LifetimePosition curr_position =
   2041         LifetimePosition::InstructionFromInstructionIndex(index);
   2042     Instruction* instr = code()->InstructionAt(index);
   2043     DCHECK(instr != nullptr);
   2044     DCHECK(curr_position.IsInstructionPosition());
   2045     // Process output, inputs, and temps of this instruction.
   2046     for (size_t i = 0; i < instr->OutputCount(); i++) {
   2047       InstructionOperand* output = instr->OutputAt(i);
   2048       if (output->IsUnallocated()) {
   2049         // Unsupported.
   2050         DCHECK(!UnallocatedOperand::cast(output)->HasSlotPolicy());
   2051         int out_vreg = UnallocatedOperand::cast(output)->virtual_register();
   2052         live->Remove(out_vreg);
   2053       } else if (output->IsConstant()) {
   2054         int out_vreg = ConstantOperand::cast(output)->virtual_register();
   2055         live->Remove(out_vreg);
   2056       }
   2057       if (block->IsHandler() && index == block_start && output->IsAllocated() &&
   2058           output->IsRegister() &&
   2059           AllocatedOperand::cast(output)->GetRegister().is(
   2060               v8::internal::kReturnRegister0)) {
   2061         // The register defined here is blocked from gap start - it is the
   2062         // exception value.
   2063         // TODO(mtrofin): should we explore an explicit opcode for
   2064         // the first instruction in the handler?
   2065         Define(LifetimePosition::GapFromInstructionIndex(index), output);
   2066       } else {
   2067         Define(curr_position, output);
   2068       }
   2069     }
   2070 
   2071     if (instr->ClobbersRegisters()) {
   2072       for (int i = 0; i < config()->num_allocatable_general_registers(); ++i) {
   2073         // Create a UseInterval at this instruction for all fixed registers,
   2074         // (including the instruction outputs). Adding another UseInterval here
   2075         // is OK because AddUseInterval will just merge it with the existing
   2076         // one at the end of the range.
   2077         int code = config()->GetAllocatableGeneralCode(i);
   2078         TopLevelLiveRange* range = FixedLiveRangeFor(code);
   2079         range->AddUseInterval(curr_position, curr_position.End(),
   2080                               allocation_zone());
   2081       }
   2082     }
   2083 
   2084     if (instr->ClobbersDoubleRegisters()) {
   2085       for (int i = 0; i < config()->num_allocatable_double_registers(); ++i) {
   2086         // Add a UseInterval for all DoubleRegisters. See comment above for
   2087         // general registers.
   2088         int code = config()->GetAllocatableDoubleCode(i);
   2089         TopLevelLiveRange* range =
   2090             FixedFPLiveRangeFor(code, MachineRepresentation::kFloat64);
   2091         range->AddUseInterval(curr_position, curr_position.End(),
   2092                               allocation_zone());
   2093       }
   2094       // Clobber fixed float registers on archs with non-simple aliasing.
   2095       if (!kSimpleFPAliasing) {
   2096         if (fixed_float_live_ranges) {
   2097           for (int i = 0; i < config()->num_allocatable_float_registers();
   2098                ++i) {
   2099             // Add a UseInterval for all FloatRegisters. See comment above for
   2100             // general registers.
   2101             int code = config()->GetAllocatableFloatCode(i);
   2102             TopLevelLiveRange* range =
   2103                 FixedFPLiveRangeFor(code, MachineRepresentation::kFloat32);
   2104             range->AddUseInterval(curr_position, curr_position.End(),
   2105                                   allocation_zone());
   2106           }
   2107         }
   2108         if (fixed_simd128_live_ranges) {
   2109           for (int i = 0; i < config()->num_allocatable_simd128_registers();
   2110                ++i) {
   2111             int code = config()->GetAllocatableSimd128Code(i);
   2112             TopLevelLiveRange* range =
   2113                 FixedFPLiveRangeFor(code, MachineRepresentation::kSimd128);
   2114             range->AddUseInterval(curr_position, curr_position.End(),
   2115                                   allocation_zone());
   2116           }
   2117         }
   2118       }
   2119     }
   2120 
   2121     for (size_t i = 0; i < instr->InputCount(); i++) {
   2122       InstructionOperand* input = instr->InputAt(i);
   2123       if (input->IsImmediate() || input->IsExplicit()) {
   2124         continue;  // Ignore immediates and explicitly reserved registers.
   2125       }
   2126       LifetimePosition use_pos;
   2127       if (input->IsUnallocated() &&
   2128           UnallocatedOperand::cast(input)->IsUsedAtStart()) {
   2129         use_pos = curr_position;
   2130       } else {
   2131         use_pos = curr_position.End();
   2132       }
   2133 
   2134       if (input->IsUnallocated()) {
   2135         UnallocatedOperand* unalloc = UnallocatedOperand::cast(input);
   2136         int vreg = unalloc->virtual_register();
   2137         live->Add(vreg);
   2138         if (unalloc->HasSlotPolicy()) {
   2139           data()->GetOrCreateLiveRangeFor(vreg)->set_has_slot_use(true);
   2140         }
   2141       }
   2142       Use(block_start_position, use_pos, input);
   2143     }
   2144 
   2145     for (size_t i = 0; i < instr->TempCount(); i++) {
   2146       InstructionOperand* temp = instr->TempAt(i);
   2147       // Unsupported.
   2148       DCHECK_IMPLIES(temp->IsUnallocated(),
   2149                      !UnallocatedOperand::cast(temp)->HasSlotPolicy());
   2150       if (instr->ClobbersTemps()) {
   2151         if (temp->IsRegister()) continue;
   2152         if (temp->IsUnallocated()) {
   2153           UnallocatedOperand* temp_unalloc = UnallocatedOperand::cast(temp);
   2154           if (temp_unalloc->HasFixedPolicy()) {
   2155             continue;
   2156           }
   2157         }
   2158       }
   2159       Use(block_start_position, curr_position.End(), temp);
   2160       Define(curr_position, temp);
   2161     }
   2162 
   2163     // Process the moves of the instruction's gaps, making their sources live.
   2164     const Instruction::GapPosition kPositions[] = {Instruction::END,
   2165                                                    Instruction::START};
   2166     curr_position = curr_position.PrevStart();
   2167     DCHECK(curr_position.IsGapPosition());
   2168     for (const Instruction::GapPosition& position : kPositions) {
   2169       ParallelMove* move = instr->GetParallelMove(position);
   2170       if (move == nullptr) continue;
   2171       if (position == Instruction::END) {
   2172         curr_position = curr_position.End();
   2173       } else {
   2174         curr_position = curr_position.Start();
   2175       }
   2176       for (MoveOperands* cur : *move) {
   2177         InstructionOperand& from = cur->source();
   2178         InstructionOperand& to = cur->destination();
   2179         void* hint = &to;
   2180         UsePositionHintType hint_type = UsePosition::HintTypeForOperand(to);
   2181         UsePosition* to_use = nullptr;
   2182         int phi_vreg = -1;
   2183         if (to.IsUnallocated()) {
   2184           int to_vreg = UnallocatedOperand::cast(to).virtual_register();
   2185           TopLevelLiveRange* to_range =
   2186               data()->GetOrCreateLiveRangeFor(to_vreg);
   2187           if (to_range->is_phi()) {
   2188             phi_vreg = to_vreg;
   2189             if (to_range->is_non_loop_phi()) {
   2190               hint = to_range->current_hint_position();
   2191               hint_type = hint == nullptr ? UsePositionHintType::kNone
   2192                                           : UsePositionHintType::kUsePos;
   2193             } else {
   2194               hint_type = UsePositionHintType::kPhi;
   2195               hint = data()->GetPhiMapValueFor(to_vreg);
   2196             }
   2197           } else {
   2198             if (live->Contains(to_vreg)) {
   2199               to_use = Define(curr_position, &to, &from,
   2200                               UsePosition::HintTypeForOperand(from));
   2201               live->Remove(to_vreg);
   2202             } else {
   2203               cur->Eliminate();
   2204               continue;
   2205             }
   2206           }
   2207         } else {
   2208           Define(curr_position, &to);
   2209         }
   2210         UsePosition* from_use =
   2211             Use(block_start_position, curr_position, &from, hint, hint_type);
   2212         // Mark range live.
   2213         if (from.IsUnallocated()) {
   2214           live->Add(UnallocatedOperand::cast(from).virtual_register());
   2215         }
   2216         // Resolve use position hints just created.
   2217         if (to_use != nullptr && from_use != nullptr) {
   2218           to_use->ResolveHint(from_use);
   2219           from_use->ResolveHint(to_use);
   2220         }
   2221         DCHECK_IMPLIES(to_use != nullptr, to_use->IsResolved());
   2222         DCHECK_IMPLIES(from_use != nullptr, from_use->IsResolved());
   2223         // Potentially resolve phi hint.
   2224         if (phi_vreg != -1) ResolvePhiHint(&from, from_use);
   2225       }
   2226     }
   2227   }
   2228 }
   2229 
   2230 void LiveRangeBuilder::ProcessPhis(const InstructionBlock* block,
   2231                                    BitVector* live) {
   2232   for (PhiInstruction* phi : block->phis()) {
   2233     // The live range interval already ends at the first instruction of the
   2234     // block.
   2235     int phi_vreg = phi->virtual_register();
   2236     live->Remove(phi_vreg);
   2237     // Select a hint from a predecessor block that preceeds this block in the
   2238     // rpo order. In order of priority:
   2239     // - Avoid hints from deferred blocks.
   2240     // - Prefer hints from allocated (or explicit) operands.
   2241     // - Prefer hints from empty blocks (containing just parallel moves and a
   2242     //   jump). In these cases, if we can elide the moves, the jump threader
   2243     //   is likely to be able to elide the jump.
   2244     // The enforcement of hinting in rpo order is required because hint
   2245     // resolution that happens later in the compiler pipeline visits
   2246     // instructions in reverse rpo order, relying on the fact that phis are
   2247     // encountered before their hints.
   2248     InstructionOperand* hint = nullptr;
   2249     int hint_preference = 0;
   2250 
   2251     // The cost of hinting increases with the number of predecessors. At the
   2252     // same time, the typical benefit decreases, since this hinting only
   2253     // optimises the execution path through one predecessor. A limit of 2 is
   2254     // sufficient to hit the common if/else pattern.
   2255     int predecessor_limit = 2;
   2256 
   2257     for (RpoNumber predecessor : block->predecessors()) {
   2258       const InstructionBlock* predecessor_block =
   2259           code()->InstructionBlockAt(predecessor);
   2260       DCHECK_EQ(predecessor_block->rpo_number(), predecessor);
   2261 
   2262       // Only take hints from earlier rpo numbers.
   2263       if (predecessor >= block->rpo_number()) continue;
   2264 
   2265       // Look up the predecessor instruction.
   2266       const Instruction* predecessor_instr =
   2267           GetLastInstruction(code(), predecessor_block);
   2268       InstructionOperand* predecessor_hint = nullptr;
   2269       // Phis are assigned in the END position of the last instruction in each
   2270       // predecessor block.
   2271       for (MoveOperands* move :
   2272            *predecessor_instr->GetParallelMove(Instruction::END)) {
   2273         InstructionOperand& to = move->destination();
   2274         if (to.IsUnallocated() &&
   2275             UnallocatedOperand::cast(to).virtual_register() == phi_vreg) {
   2276           predecessor_hint = &move->source();
   2277           break;
   2278         }
   2279       }
   2280       DCHECK_NOT_NULL(predecessor_hint);
   2281 
   2282       // For each predecessor, generate a score according to the priorities
   2283       // described above, and pick the best one. Flags in higher-order bits have
   2284       // a higher priority than those in lower-order bits.
   2285       int predecessor_hint_preference = 0;
   2286       const int kNotDeferredBlockPreference = (1 << 2);
   2287       const int kMoveIsAllocatedPreference = (1 << 1);
   2288       const int kBlockIsEmptyPreference = (1 << 0);
   2289 
   2290       // - Avoid hints from deferred blocks.
   2291       if (!predecessor_block->IsDeferred()) {
   2292         predecessor_hint_preference |= kNotDeferredBlockPreference;
   2293       }
   2294 
   2295       // - Prefer hints from allocated (or explicit) operands.
   2296       //
   2297       // Already-allocated or explicit operands are typically assigned using
   2298       // the parallel moves on the last instruction. For example:
   2299       //
   2300       //      gap (v101 = [x0|R|w32]) (v100 = v101)
   2301       //      ArchJmp
   2302       //    ...
   2303       //    phi: v100 = v101 v102
   2304       //
   2305       // We have already found the END move, so look for a matching START move
   2306       // from an allocated (or explicit) operand.
   2307       //
   2308       // Note that we cannot simply look up data()->live_ranges()[vreg] here
   2309       // because the live ranges are still being built when this function is
   2310       // called.
   2311       // TODO(v8): Find a way to separate hinting from live range analysis in
   2312       // BuildLiveRanges so that we can use the O(1) live-range look-up.
   2313       auto moves = predecessor_instr->GetParallelMove(Instruction::START);
   2314       if (moves != nullptr) {
   2315         for (MoveOperands* move : *moves) {
   2316           InstructionOperand& to = move->destination();
   2317           if (predecessor_hint->Equals(to)) {
   2318             if (move->source().IsAllocated() || move->source().IsExplicit()) {
   2319               predecessor_hint_preference |= kMoveIsAllocatedPreference;
   2320             }
   2321             break;
   2322           }
   2323         }
   2324       }
   2325 
   2326       // - Prefer hints from empty blocks.
   2327       if (predecessor_block->last_instruction_index() ==
   2328           predecessor_block->first_instruction_index()) {
   2329         predecessor_hint_preference |= kBlockIsEmptyPreference;
   2330       }
   2331 
   2332       if ((hint == nullptr) ||
   2333           (predecessor_hint_preference > hint_preference)) {
   2334         // Take the hint from this predecessor.
   2335         hint = predecessor_hint;
   2336         hint_preference = predecessor_hint_preference;
   2337       }
   2338 
   2339       if (--predecessor_limit <= 0) break;
   2340     }
   2341     DCHECK_NOT_NULL(hint);
   2342 
   2343     LifetimePosition block_start = LifetimePosition::GapFromInstructionIndex(
   2344         block->first_instruction_index());
   2345     UsePosition* use_pos = Define(block_start, &phi->output(), hint,
   2346                                   UsePosition::HintTypeForOperand(*hint));
   2347     MapPhiHint(hint, use_pos);
   2348   }
   2349 }
   2350 
   2351 
   2352 void LiveRangeBuilder::ProcessLoopHeader(const InstructionBlock* block,
   2353                                          BitVector* live) {
   2354   DCHECK(block->IsLoopHeader());
   2355   // Add a live range stretching from the first loop instruction to the last
   2356   // for each value live on entry to the header.
   2357   BitVector::Iterator iterator(live);
   2358   LifetimePosition start = LifetimePosition::GapFromInstructionIndex(
   2359       block->first_instruction_index());
   2360   LifetimePosition end = LifetimePosition::GapFromInstructionIndex(
   2361                              code()->LastLoopInstructionIndex(block))
   2362                              .NextFullStart();
   2363   while (!iterator.Done()) {
   2364     int operand_index = iterator.Current();
   2365     TopLevelLiveRange* range = data()->GetOrCreateLiveRangeFor(operand_index);
   2366     range->EnsureInterval(start, end, allocation_zone());
   2367     iterator.Advance();
   2368   }
   2369   // Insert all values into the live in sets of all blocks in the loop.
   2370   for (int i = block->rpo_number().ToInt() + 1; i < block->loop_end().ToInt();
   2371        ++i) {
   2372     live_in_sets()[i]->Union(*live);
   2373   }
   2374 }
   2375 
   2376 
   2377 void LiveRangeBuilder::BuildLiveRanges() {
   2378   // Process the blocks in reverse order.
   2379   for (int block_id = code()->InstructionBlockCount() - 1; block_id >= 0;
   2380        --block_id) {
   2381     InstructionBlock* block =
   2382         code()->InstructionBlockAt(RpoNumber::FromInt(block_id));
   2383     BitVector* live = ComputeLiveOut(block, data());
   2384     // Initially consider all live_out values live for the entire block. We
   2385     // will shorten these intervals if necessary.
   2386     AddInitialIntervals(block, live);
   2387     // Process the instructions in reverse order, generating and killing
   2388     // live values.
   2389     ProcessInstructions(block, live);
   2390     // All phi output operands are killed by this block.
   2391     ProcessPhis(block, live);
   2392     // Now live is live_in for this block except not including values live
   2393     // out on backward successor edges.
   2394     if (block->IsLoopHeader()) ProcessLoopHeader(block, live);
   2395     live_in_sets()[block_id] = live;
   2396   }
   2397   // Postprocess the ranges.
   2398   for (TopLevelLiveRange* range : data()->live_ranges()) {
   2399     if (range == nullptr) continue;
   2400     // Give slots to all ranges with a non fixed slot use.
   2401     if (range->has_slot_use() && range->HasNoSpillType()) {
   2402       data()->AssignSpillRangeToLiveRange(range);
   2403     }
   2404     // TODO(bmeurer): This is a horrible hack to make sure that for constant
   2405     // live ranges, every use requires the constant to be in a register.
   2406     // Without this hack, all uses with "any" policy would get the constant
   2407     // operand assigned.
   2408     if (range->HasSpillOperand() && range->GetSpillOperand()->IsConstant()) {
   2409       for (UsePosition* pos = range->first_pos(); pos != nullptr;
   2410            pos = pos->next()) {
   2411         if (pos->type() == UsePositionType::kRequiresSlot) continue;
   2412         UsePositionType new_type = UsePositionType::kAny;
   2413         // Can't mark phis as needing a register.
   2414         if (!pos->pos().IsGapPosition()) {
   2415           new_type = UsePositionType::kRequiresRegister;
   2416         }
   2417         pos->set_type(new_type, true);
   2418       }
   2419     }
   2420   }
   2421   for (auto preassigned : data()->preassigned_slot_ranges()) {
   2422     TopLevelLiveRange* range = preassigned.first;
   2423     int slot_id = preassigned.second;
   2424     SpillRange* spill = range->HasSpillRange()
   2425                             ? range->GetSpillRange()
   2426                             : data()->AssignSpillRangeToLiveRange(range);
   2427     spill->set_assigned_slot(slot_id);
   2428   }
   2429 #ifdef DEBUG
   2430   Verify();
   2431 #endif
   2432 }
   2433 
   2434 
   2435 void LiveRangeBuilder::MapPhiHint(InstructionOperand* operand,
   2436                                   UsePosition* use_pos) {
   2437   DCHECK(!use_pos->IsResolved());
   2438   auto res = phi_hints_.insert(std::make_pair(operand, use_pos));
   2439   DCHECK(res.second);
   2440   USE(res);
   2441 }
   2442 
   2443 
   2444 void LiveRangeBuilder::ResolvePhiHint(InstructionOperand* operand,
   2445                                       UsePosition* use_pos) {
   2446   auto it = phi_hints_.find(operand);
   2447   if (it == phi_hints_.end()) return;
   2448   DCHECK(!it->second->IsResolved());
   2449   it->second->ResolveHint(use_pos);
   2450 }
   2451 
   2452 
   2453 void LiveRangeBuilder::Verify() const {
   2454   for (auto& hint : phi_hints_) {
   2455     CHECK(hint.second->IsResolved());
   2456   }
   2457   for (const TopLevelLiveRange* current : data()->live_ranges()) {
   2458     if (current != nullptr && !current->IsEmpty()) {
   2459       // New LiveRanges should not be split.
   2460       CHECK_NULL(current->next());
   2461       // General integrity check.
   2462       current->Verify();
   2463       const UseInterval* first = current->first_interval();
   2464       if (first->next() == nullptr) continue;
   2465 
   2466       // Consecutive intervals should not end and start in the same block,
   2467       // otherwise the intervals should have been joined, because the
   2468       // variable is live throughout that block.
   2469       CHECK(NextIntervalStartsInDifferentBlocks(first));
   2470 
   2471       for (const UseInterval* i = first->next(); i != nullptr; i = i->next()) {
   2472         // Except for the first interval, the other intevals must start at
   2473         // a block boundary, otherwise data wouldn't flow to them.
   2474         CHECK(IntervalStartsAtBlockBoundary(i));
   2475         // The last instruction of the predecessors of the block the interval
   2476         // starts must be covered by the range.
   2477         CHECK(IntervalPredecessorsCoveredByRange(i, current));
   2478         if (i->next() != nullptr) {
   2479           // Check the consecutive intervals property, except for the last
   2480           // interval, where it doesn't apply.
   2481           CHECK(NextIntervalStartsInDifferentBlocks(i));
   2482         }
   2483       }
   2484     }
   2485   }
   2486 }
   2487 
   2488 bool LiveRangeBuilder::IntervalStartsAtBlockBoundary(
   2489     const UseInterval* interval) const {
   2490   LifetimePosition start = interval->start();
   2491   if (!start.IsFullStart()) return false;
   2492   int instruction_index = start.ToInstructionIndex();
   2493   const InstructionBlock* block =
   2494       data()->code()->GetInstructionBlock(instruction_index);
   2495   return block->first_instruction_index() == instruction_index;
   2496 }
   2497 
   2498 bool LiveRangeBuilder::IntervalPredecessorsCoveredByRange(
   2499     const UseInterval* interval, const TopLevelLiveRange* range) const {
   2500   LifetimePosition start = interval->start();
   2501   int instruction_index = start.ToInstructionIndex();
   2502   const InstructionBlock* block =
   2503       data()->code()->GetInstructionBlock(instruction_index);
   2504   for (RpoNumber pred_index : block->predecessors()) {
   2505     const InstructionBlock* predecessor =
   2506         data()->code()->InstructionBlockAt(pred_index);
   2507     LifetimePosition last_pos = LifetimePosition::GapFromInstructionIndex(
   2508         predecessor->last_instruction_index());
   2509     last_pos = last_pos.NextStart().End();
   2510     if (!range->Covers(last_pos)) return false;
   2511   }
   2512   return true;
   2513 }
   2514 
   2515 bool LiveRangeBuilder::NextIntervalStartsInDifferentBlocks(
   2516     const UseInterval* interval) const {
   2517   DCHECK_NOT_NULL(interval->next());
   2518   LifetimePosition end = interval->end();
   2519   LifetimePosition next_start = interval->next()->start();
   2520   // Since end is not covered, but the previous position is, move back a
   2521   // position
   2522   end = end.IsStart() ? end.PrevStart().End() : end.Start();
   2523   int last_covered_index = end.ToInstructionIndex();
   2524   const InstructionBlock* block =
   2525       data()->code()->GetInstructionBlock(last_covered_index);
   2526   const InstructionBlock* next_block =
   2527       data()->code()->GetInstructionBlock(next_start.ToInstructionIndex());
   2528   return block->rpo_number() < next_block->rpo_number();
   2529 }
   2530 
   2531 RegisterAllocator::RegisterAllocator(RegisterAllocationData* data,
   2532                                      RegisterKind kind)
   2533     : data_(data),
   2534       mode_(kind),
   2535       num_registers_(GetRegisterCount(data->config(), kind)),
   2536       num_allocatable_registers_(
   2537           GetAllocatableRegisterCount(data->config(), kind)),
   2538       allocatable_register_codes_(
   2539           GetAllocatableRegisterCodes(data->config(), kind)),
   2540       check_fp_aliasing_(false) {
   2541   if (!kSimpleFPAliasing && kind == FP_REGISTERS) {
   2542     check_fp_aliasing_ = (data->code()->representation_mask() &
   2543                           (kFloatRepBit | kSimd128RepBit)) != 0;
   2544   }
   2545 }
   2546 
   2547 LifetimePosition RegisterAllocator::GetSplitPositionForInstruction(
   2548     const LiveRange* range, int instruction_index) {
   2549   LifetimePosition ret = LifetimePosition::Invalid();
   2550 
   2551   ret = LifetimePosition::GapFromInstructionIndex(instruction_index);
   2552   if (range->Start() >= ret || ret >= range->End()) {
   2553     return LifetimePosition::Invalid();
   2554   }
   2555   return ret;
   2556 }
   2557 
   2558 void RegisterAllocator::SplitAndSpillRangesDefinedByMemoryOperand() {
   2559   size_t initial_range_count = data()->live_ranges().size();
   2560   for (size_t i = 0; i < initial_range_count; ++i) {
   2561     TopLevelLiveRange* range = data()->live_ranges()[i];
   2562     if (!CanProcessRange(range)) continue;
   2563     if (range->HasNoSpillType() ||
   2564         (range->HasSpillRange() && !range->has_slot_use())) {
   2565       continue;
   2566     }
   2567     LifetimePosition start = range->Start();
   2568     TRACE("Live range %d:%d is defined by a spill operand.\n",
   2569           range->TopLevel()->vreg(), range->relative_id());
   2570     LifetimePosition next_pos = start;
   2571     if (next_pos.IsGapPosition()) {
   2572       next_pos = next_pos.NextStart();
   2573     }
   2574 
   2575     // With splinters, we can be more strict and skip over positions
   2576     // not strictly needing registers.
   2577     UsePosition* pos =
   2578         range->IsSplinter()
   2579             ? range->NextRegisterPosition(next_pos)
   2580             : range->NextUsePositionRegisterIsBeneficial(next_pos);
   2581     // If the range already has a spill operand and it doesn't need a
   2582     // register immediately, split it and spill the first part of the range.
   2583     if (pos == nullptr) {
   2584       Spill(range);
   2585     } else if (pos->pos() > range->Start().NextStart()) {
   2586       // Do not spill live range eagerly if use position that can benefit from
   2587       // the register is too close to the start of live range.
   2588       LifetimePosition split_pos = GetSplitPositionForInstruction(
   2589           range, pos->pos().ToInstructionIndex());
   2590       // There is no place to split, so we can't split and spill.
   2591       if (!split_pos.IsValid()) continue;
   2592 
   2593       split_pos =
   2594           FindOptimalSplitPos(range->Start().NextFullStart(), split_pos);
   2595 
   2596       SplitRangeAt(range, split_pos);
   2597       Spill(range);
   2598     }
   2599   }
   2600 }
   2601 
   2602 
   2603 LiveRange* RegisterAllocator::SplitRangeAt(LiveRange* range,
   2604                                            LifetimePosition pos) {
   2605   DCHECK(!range->TopLevel()->IsFixed());
   2606   TRACE("Splitting live range %d:%d at %d\n", range->TopLevel()->vreg(),
   2607         range->relative_id(), pos.value());
   2608 
   2609   if (pos <= range->Start()) return range;
   2610 
   2611   // We can't properly connect liveranges if splitting occurred at the end
   2612   // a block.
   2613   DCHECK(pos.IsStart() || pos.IsGapPosition() ||
   2614          (GetInstructionBlock(code(), pos)->last_instruction_index() !=
   2615           pos.ToInstructionIndex()));
   2616 
   2617   LiveRange* result = range->SplitAt(pos, allocation_zone());
   2618   return result;
   2619 }
   2620 
   2621 
   2622 LiveRange* RegisterAllocator::SplitBetween(LiveRange* range,
   2623                                            LifetimePosition start,
   2624                                            LifetimePosition end) {
   2625   DCHECK(!range->TopLevel()->IsFixed());
   2626   TRACE("Splitting live range %d:%d in position between [%d, %d]\n",
   2627         range->TopLevel()->vreg(), range->relative_id(), start.value(),
   2628         end.value());
   2629 
   2630   LifetimePosition split_pos = FindOptimalSplitPos(start, end);
   2631   DCHECK(split_pos >= start);
   2632   return SplitRangeAt(range, split_pos);
   2633 }
   2634 
   2635 
   2636 LifetimePosition RegisterAllocator::FindOptimalSplitPos(LifetimePosition start,
   2637                                                         LifetimePosition end) {
   2638   int start_instr = start.ToInstructionIndex();
   2639   int end_instr = end.ToInstructionIndex();
   2640   DCHECK(start_instr <= end_instr);
   2641 
   2642   // We have no choice
   2643   if (start_instr == end_instr) return end;
   2644 
   2645   const InstructionBlock* start_block = GetInstructionBlock(code(), start);
   2646   const InstructionBlock* end_block = GetInstructionBlock(code(), end);
   2647 
   2648   if (end_block == start_block) {
   2649     // The interval is split in the same basic block. Split at the latest
   2650     // possible position.
   2651     return end;
   2652   }
   2653 
   2654   const InstructionBlock* block = end_block;
   2655   // Find header of outermost loop.
   2656   do {
   2657     const InstructionBlock* loop = GetContainingLoop(code(), block);
   2658     if (loop == nullptr ||
   2659         loop->rpo_number().ToInt() <= start_block->rpo_number().ToInt()) {
   2660       // No more loops or loop starts before the lifetime start.
   2661       break;
   2662     }
   2663     block = loop;
   2664   } while (true);
   2665 
   2666   // We did not find any suitable outer loop. Split at the latest possible
   2667   // position unless end_block is a loop header itself.
   2668   if (block == end_block && !end_block->IsLoopHeader()) return end;
   2669 
   2670   return LifetimePosition::GapFromInstructionIndex(
   2671       block->first_instruction_index());
   2672 }
   2673 
   2674 
   2675 LifetimePosition RegisterAllocator::FindOptimalSpillingPos(
   2676     LiveRange* range, LifetimePosition pos) {
   2677   const InstructionBlock* block = GetInstructionBlock(code(), pos.Start());
   2678   const InstructionBlock* loop_header =
   2679       block->IsLoopHeader() ? block : GetContainingLoop(code(), block);
   2680 
   2681   if (loop_header == nullptr) return pos;
   2682 
   2683   const UsePosition* prev_use =
   2684       range->PreviousUsePositionRegisterIsBeneficial(pos);
   2685 
   2686   while (loop_header != nullptr) {
   2687     // We are going to spill live range inside the loop.
   2688     // If possible try to move spilling position backwards to loop header.
   2689     // This will reduce number of memory moves on the back edge.
   2690     LifetimePosition loop_start = LifetimePosition::GapFromInstructionIndex(
   2691         loop_header->first_instruction_index());
   2692 
   2693     if (range->Covers(loop_start)) {
   2694       if (prev_use == nullptr || prev_use->pos() < loop_start) {
   2695         // No register beneficial use inside the loop before the pos.
   2696         pos = loop_start;
   2697       }
   2698     }
   2699 
   2700     // Try hoisting out to an outer loop.
   2701     loop_header = GetContainingLoop(code(), loop_header);
   2702   }
   2703 
   2704   return pos;
   2705 }
   2706 
   2707 
   2708 void RegisterAllocator::Spill(LiveRange* range) {
   2709   DCHECK(!range->spilled());
   2710   TopLevelLiveRange* first = range->TopLevel();
   2711   TRACE("Spilling live range %d:%d\n", first->vreg(), range->relative_id());
   2712 
   2713   if (first->HasNoSpillType()) {
   2714     data()->AssignSpillRangeToLiveRange(first);
   2715   }
   2716   range->Spill();
   2717 }
   2718 
   2719 const char* RegisterAllocator::RegisterName(int register_code) const {
   2720   if (mode() == GENERAL_REGISTERS) {
   2721     return data()->config()->GetGeneralRegisterName(register_code);
   2722   } else {
   2723     return data()->config()->GetDoubleRegisterName(register_code);
   2724   }
   2725 }
   2726 
   2727 
   2728 LinearScanAllocator::LinearScanAllocator(RegisterAllocationData* data,
   2729                                          RegisterKind kind, Zone* local_zone)
   2730     : RegisterAllocator(data, kind),
   2731       unhandled_live_ranges_(local_zone),
   2732       active_live_ranges_(local_zone),
   2733       inactive_live_ranges_(local_zone) {
   2734   unhandled_live_ranges().reserve(
   2735       static_cast<size_t>(code()->VirtualRegisterCount() * 2));
   2736   active_live_ranges().reserve(8);
   2737   inactive_live_ranges().reserve(8);
   2738   // TryAllocateFreeReg and AllocateBlockedReg assume this
   2739   // when allocating local arrays.
   2740   DCHECK(RegisterConfiguration::kMaxFPRegisters >=
   2741          this->data()->config()->num_general_registers());
   2742 }
   2743 
   2744 
   2745 void LinearScanAllocator::AllocateRegisters() {
   2746   DCHECK(unhandled_live_ranges().empty());
   2747   DCHECK(active_live_ranges().empty());
   2748   DCHECK(inactive_live_ranges().empty());
   2749 
   2750   SplitAndSpillRangesDefinedByMemoryOperand();
   2751 
   2752   for (TopLevelLiveRange* range : data()->live_ranges()) {
   2753     if (!CanProcessRange(range)) continue;
   2754     for (LiveRange* to_add = range; to_add != nullptr;
   2755          to_add = to_add->next()) {
   2756       if (!to_add->spilled()) {
   2757         AddToUnhandledUnsorted(to_add);
   2758       }
   2759     }
   2760   }
   2761   SortUnhandled();
   2762   DCHECK(UnhandledIsSorted());
   2763 
   2764   if (mode() == GENERAL_REGISTERS) {
   2765     for (TopLevelLiveRange* current : data()->fixed_live_ranges()) {
   2766       if (current != nullptr) AddToInactive(current);
   2767     }
   2768   } else {
   2769     for (TopLevelLiveRange* current : data()->fixed_double_live_ranges()) {
   2770       if (current != nullptr) AddToInactive(current);
   2771     }
   2772     if (!kSimpleFPAliasing && check_fp_aliasing()) {
   2773       for (TopLevelLiveRange* current : data()->fixed_float_live_ranges()) {
   2774         if (current != nullptr) AddToInactive(current);
   2775       }
   2776       for (TopLevelLiveRange* current : data()->fixed_simd128_live_ranges()) {
   2777         if (current != nullptr) AddToInactive(current);
   2778       }
   2779     }
   2780   }
   2781 
   2782   while (!unhandled_live_ranges().empty()) {
   2783     DCHECK(UnhandledIsSorted());
   2784     LiveRange* current = unhandled_live_ranges().back();
   2785     unhandled_live_ranges().pop_back();
   2786     DCHECK(UnhandledIsSorted());
   2787     LifetimePosition position = current->Start();
   2788 #ifdef DEBUG
   2789     allocation_finger_ = position;
   2790 #endif
   2791     TRACE("Processing interval %d:%d start=%d\n", current->TopLevel()->vreg(),
   2792           current->relative_id(), position.value());
   2793 
   2794     if (current->IsTopLevel() && TryReuseSpillForPhi(current->TopLevel()))
   2795       continue;
   2796 
   2797     for (size_t i = 0; i < active_live_ranges().size(); ++i) {
   2798       LiveRange* cur_active = active_live_ranges()[i];
   2799       if (cur_active->End() <= position) {
   2800         ActiveToHandled(cur_active);
   2801         --i;  // The live range was removed from the list of active live ranges.
   2802       } else if (!cur_active->Covers(position)) {
   2803         ActiveToInactive(cur_active);
   2804         --i;  // The live range was removed from the list of active live ranges.
   2805       }
   2806     }
   2807 
   2808     for (size_t i = 0; i < inactive_live_ranges().size(); ++i) {
   2809       LiveRange* cur_inactive = inactive_live_ranges()[i];
   2810       if (cur_inactive->End() <= position) {
   2811         InactiveToHandled(cur_inactive);
   2812         --i;  // Live range was removed from the list of inactive live ranges.
   2813       } else if (cur_inactive->Covers(position)) {
   2814         InactiveToActive(cur_inactive);
   2815         --i;  // Live range was removed from the list of inactive live ranges.
   2816       }
   2817     }
   2818 
   2819     DCHECK(!current->HasRegisterAssigned() && !current->spilled());
   2820 
   2821     ProcessCurrentRange(current);
   2822   }
   2823 }
   2824 
   2825 bool LinearScanAllocator::TrySplitAndSpillSplinter(LiveRange* range) {
   2826   DCHECK(range->TopLevel()->IsSplinter());
   2827   // If we can spill the whole range, great. Otherwise, split above the
   2828   // first use needing a register and spill the top part.
   2829   const UsePosition* next_reg = range->NextRegisterPosition(range->Start());
   2830   if (next_reg == nullptr) {
   2831     Spill(range);
   2832     return true;
   2833   } else if (range->FirstHintPosition() == nullptr) {
   2834     // If there was no hint, but we have a use position requiring a
   2835     // register, apply the hot path heuristics.
   2836     return false;
   2837   } else if (next_reg->pos().PrevStart() > range->Start()) {
   2838     LiveRange* tail = SplitRangeAt(range, next_reg->pos().PrevStart());
   2839     AddToUnhandledSorted(tail);
   2840     Spill(range);
   2841     return true;
   2842   }
   2843   return false;
   2844 }
   2845 
   2846 void LinearScanAllocator::SetLiveRangeAssignedRegister(LiveRange* range,
   2847                                                        int reg) {
   2848   data()->MarkAllocated(range->representation(), reg);
   2849   range->set_assigned_register(reg);
   2850   range->SetUseHints(reg);
   2851   if (range->IsTopLevel() && range->TopLevel()->is_phi()) {
   2852     data()->GetPhiMapValueFor(range->TopLevel())->set_assigned_register(reg);
   2853   }
   2854 }
   2855 
   2856 
   2857 void LinearScanAllocator::AddToActive(LiveRange* range) {
   2858   TRACE("Add live range %d:%d to active\n", range->TopLevel()->vreg(),
   2859         range->relative_id());
   2860   active_live_ranges().push_back(range);
   2861 }
   2862 
   2863 
   2864 void LinearScanAllocator::AddToInactive(LiveRange* range) {
   2865   TRACE("Add live range %d:%d to inactive\n", range->TopLevel()->vreg(),
   2866         range->relative_id());
   2867   inactive_live_ranges().push_back(range);
   2868 }
   2869 
   2870 
   2871 void LinearScanAllocator::AddToUnhandledSorted(LiveRange* range) {
   2872   if (range == nullptr || range->IsEmpty()) return;
   2873   DCHECK(!range->HasRegisterAssigned() && !range->spilled());
   2874   DCHECK(allocation_finger_ <= range->Start());
   2875   for (int i = static_cast<int>(unhandled_live_ranges().size() - 1); i >= 0;
   2876        --i) {
   2877     LiveRange* cur_range = unhandled_live_ranges().at(i);
   2878     if (!range->ShouldBeAllocatedBefore(cur_range)) continue;
   2879     TRACE("Add live range %d:%d to unhandled at %d\n",
   2880           range->TopLevel()->vreg(), range->relative_id(), i + 1);
   2881     auto it = unhandled_live_ranges().begin() + (i + 1);
   2882     unhandled_live_ranges().insert(it, range);
   2883     DCHECK(UnhandledIsSorted());
   2884     return;
   2885   }
   2886   TRACE("Add live range %d:%d to unhandled at start\n",
   2887         range->TopLevel()->vreg(), range->relative_id());
   2888   unhandled_live_ranges().insert(unhandled_live_ranges().begin(), range);
   2889   DCHECK(UnhandledIsSorted());
   2890 }
   2891 
   2892 
   2893 void LinearScanAllocator::AddToUnhandledUnsorted(LiveRange* range) {
   2894   if (range == nullptr || range->IsEmpty()) return;
   2895   DCHECK(!range->HasRegisterAssigned() && !range->spilled());
   2896   TRACE("Add live range %d:%d to unhandled unsorted at end\n",
   2897         range->TopLevel()->vreg(), range->relative_id());
   2898   unhandled_live_ranges().push_back(range);
   2899 }
   2900 
   2901 
   2902 static bool UnhandledSortHelper(LiveRange* a, LiveRange* b) {
   2903   DCHECK(!a->ShouldBeAllocatedBefore(b) || !b->ShouldBeAllocatedBefore(a));
   2904   if (a->ShouldBeAllocatedBefore(b)) return false;
   2905   if (b->ShouldBeAllocatedBefore(a)) return true;
   2906   return a->TopLevel()->vreg() < b->TopLevel()->vreg();
   2907 }
   2908 
   2909 
   2910 // Sort the unhandled live ranges so that the ranges to be processed first are
   2911 // at the end of the array list.  This is convenient for the register allocation
   2912 // algorithm because it is efficient to remove elements from the end.
   2913 void LinearScanAllocator::SortUnhandled() {
   2914   TRACE("Sort unhandled\n");
   2915   std::sort(unhandled_live_ranges().begin(), unhandled_live_ranges().end(),
   2916             &UnhandledSortHelper);
   2917 }
   2918 
   2919 
   2920 bool LinearScanAllocator::UnhandledIsSorted() {
   2921   size_t len = unhandled_live_ranges().size();
   2922   for (size_t i = 1; i < len; i++) {
   2923     LiveRange* a = unhandled_live_ranges().at(i - 1);
   2924     LiveRange* b = unhandled_live_ranges().at(i);
   2925     if (a->Start() < b->Start()) return false;
   2926   }
   2927   return true;
   2928 }
   2929 
   2930 
   2931 void LinearScanAllocator::ActiveToHandled(LiveRange* range) {
   2932   RemoveElement(&active_live_ranges(), range);
   2933   TRACE("Moving live range %d:%d from active to handled\n",
   2934         range->TopLevel()->vreg(), range->relative_id());
   2935 }
   2936 
   2937 
   2938 void LinearScanAllocator::ActiveToInactive(LiveRange* range) {
   2939   RemoveElement(&active_live_ranges(), range);
   2940   inactive_live_ranges().push_back(range);
   2941   TRACE("Moving live range %d:%d from active to inactive\n",
   2942         range->TopLevel()->vreg(), range->relative_id());
   2943 }
   2944 
   2945 
   2946 void LinearScanAllocator::InactiveToHandled(LiveRange* range) {
   2947   RemoveElement(&inactive_live_ranges(), range);
   2948   TRACE("Moving live range %d:%d from inactive to handled\n",
   2949         range->TopLevel()->vreg(), range->relative_id());
   2950 }
   2951 
   2952 
   2953 void LinearScanAllocator::InactiveToActive(LiveRange* range) {
   2954   RemoveElement(&inactive_live_ranges(), range);
   2955   active_live_ranges().push_back(range);
   2956   TRACE("Moving live range %d:%d from inactive to active\n",
   2957         range->TopLevel()->vreg(), range->relative_id());
   2958 }
   2959 
   2960 void LinearScanAllocator::GetFPRegisterSet(MachineRepresentation rep,
   2961                                            int* num_regs, int* num_codes,
   2962                                            const int** codes) const {
   2963   DCHECK(!kSimpleFPAliasing);
   2964   if (rep == MachineRepresentation::kFloat32) {
   2965     *num_regs = data()->config()->num_float_registers();
   2966     *num_codes = data()->config()->num_allocatable_float_registers();
   2967     *codes = data()->config()->allocatable_float_codes();
   2968   } else if (rep == MachineRepresentation::kSimd128) {
   2969     *num_regs = data()->config()->num_simd128_registers();
   2970     *num_codes = data()->config()->num_allocatable_simd128_registers();
   2971     *codes = data()->config()->allocatable_simd128_codes();
   2972   } else {
   2973     UNREACHABLE();
   2974   }
   2975 }
   2976 
   2977 void LinearScanAllocator::FindFreeRegistersForRange(
   2978     LiveRange* range, Vector<LifetimePosition> positions) {
   2979   int num_regs = num_registers();
   2980   int num_codes = num_allocatable_registers();
   2981   const int* codes = allocatable_register_codes();
   2982   MachineRepresentation rep = range->representation();
   2983   if (!kSimpleFPAliasing && (rep == MachineRepresentation::kFloat32 ||
   2984                              rep == MachineRepresentation::kSimd128))
   2985     GetFPRegisterSet(rep, &num_regs, &num_codes, &codes);
   2986   DCHECK_GE(positions.length(), num_regs);
   2987 
   2988   for (int i = 0; i < num_regs; i++) {
   2989     positions[i] = LifetimePosition::MaxPosition();
   2990   }
   2991 
   2992   for (LiveRange* cur_active : active_live_ranges()) {
   2993     int cur_reg = cur_active->assigned_register();
   2994     if (kSimpleFPAliasing || !check_fp_aliasing()) {
   2995       positions[cur_reg] = LifetimePosition::GapFromInstructionIndex(0);
   2996       TRACE("Register %s is free until pos %d (1)\n", RegisterName(cur_reg),
   2997             LifetimePosition::GapFromInstructionIndex(0).value());
   2998     } else {
   2999       int alias_base_index = -1;
   3000       int aliases = data()->config()->GetAliases(
   3001           cur_active->representation(), cur_reg, rep, &alias_base_index);
   3002       DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1));
   3003       while (aliases--) {
   3004         int aliased_reg = alias_base_index + aliases;
   3005         positions[aliased_reg] = LifetimePosition::GapFromInstructionIndex(0);
   3006       }
   3007     }
   3008   }
   3009 
   3010   for (LiveRange* cur_inactive : inactive_live_ranges()) {
   3011     DCHECK(cur_inactive->End() > range->Start());
   3012     LifetimePosition next_intersection = cur_inactive->FirstIntersection(range);
   3013     if (!next_intersection.IsValid()) continue;
   3014     int cur_reg = cur_inactive->assigned_register();
   3015     if (kSimpleFPAliasing || !check_fp_aliasing()) {
   3016       positions[cur_reg] = Min(positions[cur_reg], next_intersection);
   3017       TRACE("Register %s is free until pos %d (2)\n", RegisterName(cur_reg),
   3018             Min(positions[cur_reg], next_intersection).value());
   3019     } else {
   3020       int alias_base_index = -1;
   3021       int aliases = data()->config()->GetAliases(
   3022           cur_inactive->representation(), cur_reg, rep, &alias_base_index);
   3023       DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1));
   3024       while (aliases--) {
   3025         int aliased_reg = alias_base_index + aliases;
   3026         positions[aliased_reg] = Min(positions[aliased_reg], next_intersection);
   3027       }
   3028     }
   3029   }
   3030 }
   3031 
   3032 // High-level register allocation summary:
   3033 //
   3034 // For regular, or hot (i.e. not splinter) ranges, we attempt to first
   3035 // allocate first the preferred (hint) register. If that is not possible,
   3036 // we find a register that's free, and allocate that. If that's not possible,
   3037 // we search for a register to steal from a range that was allocated. The
   3038 // goal is to optimize for throughput by avoiding register-to-memory
   3039 // moves, which are expensive.
   3040 //
   3041 // For splinters, the goal is to minimize the number of moves. First we try
   3042 // to allocate the preferred register (more discussion follows). Failing that,
   3043 // we bail out and spill as far as we can, unless the first use is at start,
   3044 // case in which we apply the same behavior as we do for regular ranges.
   3045 // If there is no hint, we apply the hot-path behavior.
   3046 //
   3047 // For the splinter, the hint register may come from:
   3048 //
   3049 // - the hot path (we set it at splintering time with SetHint). In this case, if
   3050 // we cannot offer the hint register, spilling is better because it's at most
   3051 // 1 move, while trying to find and offer another register is at least 1 move.
   3052 //
   3053 // - a constraint. If we cannot offer that register, it's because  there is some
   3054 // interference. So offering the hint register up to the interference would
   3055 // result
   3056 // in a move at the interference, plus a move to satisfy the constraint. This is
   3057 // also the number of moves if we spill, with the potential of the range being
   3058 // already spilled and thus saving a move (the spill).
   3059 // Note that this can only be an input constraint, if it were an output one,
   3060 // the range wouldn't be a splinter because it means it'd be defined in a
   3061 // deferred
   3062 // block, and we don't mark those as splinters (they live in deferred blocks
   3063 // only).
   3064 //
   3065 // - a phi. The same analysis as in the case of the input constraint applies.
   3066 //
   3067 void LinearScanAllocator::ProcessCurrentRange(LiveRange* current) {
   3068   LifetimePosition free_until_pos_buff[RegisterConfiguration::kMaxFPRegisters];
   3069   Vector<LifetimePosition> free_until_pos(
   3070       free_until_pos_buff, RegisterConfiguration::kMaxFPRegisters);
   3071   FindFreeRegistersForRange(current, free_until_pos);
   3072   if (!TryAllocatePreferredReg(current, free_until_pos)) {
   3073     if (current->TopLevel()->IsSplinter()) {
   3074       if (TrySplitAndSpillSplinter(current)) return;
   3075     }
   3076     if (!TryAllocateFreeReg(current, free_until_pos)) {
   3077       AllocateBlockedReg(current);
   3078     }
   3079   }
   3080   if (current->HasRegisterAssigned()) {
   3081     AddToActive(current);
   3082   }
   3083 }
   3084 
   3085 bool LinearScanAllocator::TryAllocatePreferredReg(
   3086     LiveRange* current, const Vector<LifetimePosition>& free_until_pos) {
   3087   int hint_register;
   3088   if (current->FirstHintPosition(&hint_register) != nullptr) {
   3089     TRACE(
   3090         "Found reg hint %s (free until [%d) for live range %d:%d (end %d[).\n",
   3091         RegisterName(hint_register), free_until_pos[hint_register].value(),
   3092         current->TopLevel()->vreg(), current->relative_id(),
   3093         current->End().value());
   3094 
   3095     // The desired register is free until the end of the current live range.
   3096     if (free_until_pos[hint_register] >= current->End()) {
   3097       TRACE("Assigning preferred reg %s to live range %d:%d\n",
   3098             RegisterName(hint_register), current->TopLevel()->vreg(),
   3099             current->relative_id());
   3100       SetLiveRangeAssignedRegister(current, hint_register);
   3101       return true;
   3102     }
   3103   }
   3104   return false;
   3105 }
   3106 
   3107 bool LinearScanAllocator::TryAllocateFreeReg(
   3108     LiveRange* current, const Vector<LifetimePosition>& free_until_pos) {
   3109   int num_regs = 0;  // used only for the call to GetFPRegisterSet.
   3110   int num_codes = num_allocatable_registers();
   3111   const int* codes = allocatable_register_codes();
   3112   MachineRepresentation rep = current->representation();
   3113   if (!kSimpleFPAliasing && (rep == MachineRepresentation::kFloat32 ||
   3114                              rep == MachineRepresentation::kSimd128))
   3115     GetFPRegisterSet(rep, &num_regs, &num_codes, &codes);
   3116 
   3117   DCHECK_GE(free_until_pos.length(), num_codes);
   3118 
   3119   // Find the register which stays free for the longest time.
   3120   int reg = codes[0];
   3121   for (int i = 1; i < num_codes; ++i) {
   3122     int code = codes[i];
   3123     if (free_until_pos[code] > free_until_pos[reg]) {
   3124       reg = code;
   3125     }
   3126   }
   3127 
   3128   LifetimePosition pos = free_until_pos[reg];
   3129 
   3130   if (pos <= current->Start()) {
   3131     // All registers are blocked.
   3132     return false;
   3133   }
   3134 
   3135   if (pos < current->End()) {
   3136     // Register reg is available at the range start but becomes blocked before
   3137     // the range end. Split current at position where it becomes blocked.
   3138     LiveRange* tail = SplitRangeAt(current, pos);
   3139     AddToUnhandledSorted(tail);
   3140   }
   3141 
   3142   // Register reg is available at the range start and is free until the range
   3143   // end.
   3144   DCHECK(pos >= current->End());
   3145   TRACE("Assigning free reg %s to live range %d:%d\n", RegisterName(reg),
   3146         current->TopLevel()->vreg(), current->relative_id());
   3147   SetLiveRangeAssignedRegister(current, reg);
   3148 
   3149   return true;
   3150 }
   3151 
   3152 void LinearScanAllocator::AllocateBlockedReg(LiveRange* current) {
   3153   UsePosition* register_use = current->NextRegisterPosition(current->Start());
   3154   if (register_use == nullptr) {
   3155     // There is no use in the current live range that requires a register.
   3156     // We can just spill it.
   3157     Spill(current);
   3158     return;
   3159   }
   3160 
   3161   int num_regs = num_registers();
   3162   int num_codes = num_allocatable_registers();
   3163   const int* codes = allocatable_register_codes();
   3164   MachineRepresentation rep = current->representation();
   3165   if (!kSimpleFPAliasing && (rep == MachineRepresentation::kFloat32 ||
   3166                              rep == MachineRepresentation::kSimd128))
   3167     GetFPRegisterSet(rep, &num_regs, &num_codes, &codes);
   3168 
   3169   LifetimePosition use_pos[RegisterConfiguration::kMaxFPRegisters];
   3170   LifetimePosition block_pos[RegisterConfiguration::kMaxFPRegisters];
   3171   for (int i = 0; i < num_regs; i++) {
   3172     use_pos[i] = block_pos[i] = LifetimePosition::MaxPosition();
   3173   }
   3174 
   3175   for (LiveRange* range : active_live_ranges()) {
   3176     int cur_reg = range->assigned_register();
   3177     bool is_fixed_or_cant_spill =
   3178         range->TopLevel()->IsFixed() || !range->CanBeSpilled(current->Start());
   3179     if (kSimpleFPAliasing || !check_fp_aliasing()) {
   3180       if (is_fixed_or_cant_spill) {
   3181         block_pos[cur_reg] = use_pos[cur_reg] =
   3182             LifetimePosition::GapFromInstructionIndex(0);
   3183       } else {
   3184         use_pos[cur_reg] =
   3185             range->NextLifetimePositionRegisterIsBeneficial(current->Start());
   3186       }
   3187     } else {
   3188       int alias_base_index = -1;
   3189       int aliases = data()->config()->GetAliases(
   3190           range->representation(), cur_reg, rep, &alias_base_index);
   3191       DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1));
   3192       while (aliases--) {
   3193         int aliased_reg = alias_base_index + aliases;
   3194         if (is_fixed_or_cant_spill) {
   3195           block_pos[aliased_reg] = use_pos[aliased_reg] =
   3196               LifetimePosition::GapFromInstructionIndex(0);
   3197         } else {
   3198           use_pos[aliased_reg] =
   3199               range->NextLifetimePositionRegisterIsBeneficial(current->Start());
   3200         }
   3201       }
   3202     }
   3203   }
   3204 
   3205   for (LiveRange* range : inactive_live_ranges()) {
   3206     DCHECK(range->End() > current->Start());
   3207     LifetimePosition next_intersection = range->FirstIntersection(current);
   3208     if (!next_intersection.IsValid()) continue;
   3209     int cur_reg = range->assigned_register();
   3210     bool is_fixed = range->TopLevel()->IsFixed();
   3211     if (kSimpleFPAliasing || !check_fp_aliasing()) {
   3212       if (is_fixed) {
   3213         block_pos[cur_reg] = Min(block_pos[cur_reg], next_intersection);
   3214         use_pos[cur_reg] = Min(block_pos[cur_reg], use_pos[cur_reg]);
   3215       } else {
   3216         use_pos[cur_reg] = Min(use_pos[cur_reg], next_intersection);
   3217       }
   3218     } else {
   3219       int alias_base_index = -1;
   3220       int aliases = data()->config()->GetAliases(
   3221           range->representation(), cur_reg, rep, &alias_base_index);
   3222       DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1));
   3223       while (aliases--) {
   3224         int aliased_reg = alias_base_index + aliases;
   3225         if (is_fixed) {
   3226           block_pos[aliased_reg] =
   3227               Min(block_pos[aliased_reg], next_intersection);
   3228           use_pos[aliased_reg] =
   3229               Min(block_pos[aliased_reg], use_pos[aliased_reg]);
   3230         } else {
   3231           use_pos[aliased_reg] = Min(use_pos[aliased_reg], next_intersection);
   3232         }
   3233       }
   3234     }
   3235   }
   3236 
   3237   int reg = codes[0];
   3238   for (int i = 1; i < num_codes; ++i) {
   3239     int code = codes[i];
   3240     if (use_pos[code] > use_pos[reg]) {
   3241       reg = code;
   3242     }
   3243   }
   3244 
   3245   LifetimePosition pos = use_pos[reg];
   3246 
   3247   if (pos < register_use->pos()) {
   3248     if (LifetimePosition::ExistsGapPositionBetween(current->Start(),
   3249                                                    register_use->pos())) {
   3250       SpillBetween(current, current->Start(), register_use->pos());
   3251     } else {
   3252       SetLiveRangeAssignedRegister(current, reg);
   3253       SplitAndSpillIntersecting(current);
   3254     }
   3255     return;
   3256   }
   3257 
   3258   if (block_pos[reg] < current->End()) {
   3259     // Register becomes blocked before the current range end. Split before that
   3260     // position.
   3261     LiveRange* tail =
   3262         SplitBetween(current, current->Start(), block_pos[reg].Start());
   3263     AddToUnhandledSorted(tail);
   3264   }
   3265 
   3266   // Register reg is not blocked for the whole range.
   3267   DCHECK(block_pos[reg] >= current->End());
   3268   TRACE("Assigning blocked reg %s to live range %d:%d\n", RegisterName(reg),
   3269         current->TopLevel()->vreg(), current->relative_id());
   3270   SetLiveRangeAssignedRegister(current, reg);
   3271 
   3272   // This register was not free. Thus we need to find and spill
   3273   // parts of active and inactive live regions that use the same register
   3274   // at the same lifetime positions as current.
   3275   SplitAndSpillIntersecting(current);
   3276 }
   3277 
   3278 
   3279 void LinearScanAllocator::SplitAndSpillIntersecting(LiveRange* current) {
   3280   DCHECK(current->HasRegisterAssigned());
   3281   int reg = current->assigned_register();
   3282   LifetimePosition split_pos = current->Start();
   3283   for (size_t i = 0; i < active_live_ranges().size(); ++i) {
   3284     LiveRange* range = active_live_ranges()[i];
   3285     if (kSimpleFPAliasing || !check_fp_aliasing()) {
   3286       if (range->assigned_register() != reg) continue;
   3287     } else {
   3288       if (!data()->config()->AreAliases(current->representation(), reg,
   3289                                         range->representation(),
   3290                                         range->assigned_register())) {
   3291         continue;
   3292       }
   3293     }
   3294 
   3295     UsePosition* next_pos = range->NextRegisterPosition(current->Start());
   3296     LifetimePosition spill_pos = FindOptimalSpillingPos(range, split_pos);
   3297     if (next_pos == nullptr) {
   3298       SpillAfter(range, spill_pos);
   3299     } else {
   3300       // When spilling between spill_pos and next_pos ensure that the range
   3301       // remains spilled at least until the start of the current live range.
   3302       // This guarantees that we will not introduce new unhandled ranges that
   3303       // start before the current range as this violates allocation invariants
   3304       // and will lead to an inconsistent state of active and inactive
   3305       // live-ranges: ranges are allocated in order of their start positions,
   3306       // ranges are retired from active/inactive when the start of the
   3307       // current live-range is larger than their end.
   3308       DCHECK(LifetimePosition::ExistsGapPositionBetween(current->Start(),
   3309                                                         next_pos->pos()));
   3310       SpillBetweenUntil(range, spill_pos, current->Start(), next_pos->pos());
   3311     }
   3312     ActiveToHandled(range);
   3313     --i;
   3314   }
   3315 
   3316   for (size_t i = 0; i < inactive_live_ranges().size(); ++i) {
   3317     LiveRange* range = inactive_live_ranges()[i];
   3318     DCHECK(range->End() > current->Start());
   3319     if (range->TopLevel()->IsFixed()) continue;
   3320     if (kSimpleFPAliasing || !check_fp_aliasing()) {
   3321       if (range->assigned_register() != reg) continue;
   3322     } else {
   3323       if (!data()->config()->AreAliases(current->representation(), reg,
   3324                                         range->representation(),
   3325                                         range->assigned_register()))
   3326         continue;
   3327     }
   3328 
   3329     LifetimePosition next_intersection = range->FirstIntersection(current);
   3330     if (next_intersection.IsValid()) {
   3331       UsePosition* next_pos = range->NextRegisterPosition(current->Start());
   3332       if (next_pos == nullptr) {
   3333         SpillAfter(range, split_pos);
   3334       } else {
   3335         next_intersection = Min(next_intersection, next_pos->pos());
   3336         SpillBetween(range, split_pos, next_intersection);
   3337       }
   3338       InactiveToHandled(range);
   3339       --i;
   3340     }
   3341   }
   3342 }
   3343 
   3344 
   3345 bool LinearScanAllocator::TryReuseSpillForPhi(TopLevelLiveRange* range) {
   3346   if (!range->is_phi()) return false;
   3347 
   3348   DCHECK(!range->HasSpillOperand());
   3349   RegisterAllocationData::PhiMapValue* phi_map_value =
   3350       data()->GetPhiMapValueFor(range);
   3351   const PhiInstruction* phi = phi_map_value->phi();
   3352   const InstructionBlock* block = phi_map_value->block();
   3353   // Count the number of spilled operands.
   3354   size_t spilled_count = 0;
   3355   LiveRange* first_op = nullptr;
   3356   for (size_t i = 0; i < phi->operands().size(); i++) {
   3357     int op = phi->operands()[i];
   3358     LiveRange* op_range = data()->GetOrCreateLiveRangeFor(op);
   3359     if (!op_range->TopLevel()->HasSpillRange()) continue;
   3360     const InstructionBlock* pred =
   3361         code()->InstructionBlockAt(block->predecessors()[i]);
   3362     LifetimePosition pred_end =
   3363         LifetimePosition::InstructionFromInstructionIndex(
   3364             pred->last_instruction_index());
   3365     while (op_range != nullptr && !op_range->CanCover(pred_end)) {
   3366       op_range = op_range->next();
   3367     }
   3368     if (op_range != nullptr && op_range->spilled()) {
   3369       spilled_count++;
   3370       if (first_op == nullptr) {
   3371         first_op = op_range->TopLevel();
   3372       }
   3373     }
   3374   }
   3375 
   3376   // Only continue if more than half of the operands are spilled.
   3377   if (spilled_count * 2 <= phi->operands().size()) {
   3378     return false;
   3379   }
   3380 
   3381   // Try to merge the spilled operands and count the number of merged spilled
   3382   // operands.
   3383   DCHECK(first_op != nullptr);
   3384   SpillRange* first_op_spill = first_op->TopLevel()->GetSpillRange();
   3385   size_t num_merged = 1;
   3386   for (size_t i = 1; i < phi->operands().size(); i++) {
   3387     int op = phi->operands()[i];
   3388     TopLevelLiveRange* op_range = data()->live_ranges()[op];
   3389     if (!op_range->HasSpillRange()) continue;
   3390     SpillRange* op_spill = op_range->GetSpillRange();
   3391     if (op_spill == first_op_spill || first_op_spill->TryMerge(op_spill)) {
   3392       num_merged++;
   3393     }
   3394   }
   3395 
   3396   // Only continue if enough operands could be merged to the
   3397   // same spill slot.
   3398   if (num_merged * 2 <= phi->operands().size() ||
   3399       AreUseIntervalsIntersecting(first_op_spill->interval(),
   3400                                   range->first_interval())) {
   3401     return false;
   3402   }
   3403 
   3404   // If the range does not need register soon, spill it to the merged
   3405   // spill range.
   3406   LifetimePosition next_pos = range->Start();
   3407   if (next_pos.IsGapPosition()) next_pos = next_pos.NextStart();
   3408   UsePosition* pos = range->NextUsePositionRegisterIsBeneficial(next_pos);
   3409   if (pos == nullptr) {
   3410     SpillRange* spill_range =
   3411         range->TopLevel()->HasSpillRange()
   3412             ? range->TopLevel()->GetSpillRange()
   3413             : data()->AssignSpillRangeToLiveRange(range->TopLevel());
   3414     bool merged = first_op_spill->TryMerge(spill_range);
   3415     if (!merged) return false;
   3416     Spill(range);
   3417     return true;
   3418   } else if (pos->pos() > range->Start().NextStart()) {
   3419     SpillRange* spill_range =
   3420         range->TopLevel()->HasSpillRange()
   3421             ? range->TopLevel()->GetSpillRange()
   3422             : data()->AssignSpillRangeToLiveRange(range->TopLevel());
   3423     bool merged = first_op_spill->TryMerge(spill_range);
   3424     if (!merged) return false;
   3425     SpillBetween(range, range->Start(), pos->pos());
   3426     DCHECK(UnhandledIsSorted());
   3427     return true;
   3428   }
   3429   return false;
   3430 }
   3431 
   3432 
   3433 void LinearScanAllocator::SpillAfter(LiveRange* range, LifetimePosition pos) {
   3434   LiveRange* second_part = SplitRangeAt(range, pos);
   3435   Spill(second_part);
   3436 }
   3437 
   3438 
   3439 void LinearScanAllocator::SpillBetween(LiveRange* range, LifetimePosition start,
   3440                                        LifetimePosition end) {
   3441   SpillBetweenUntil(range, start, start, end);
   3442 }
   3443 
   3444 
   3445 void LinearScanAllocator::SpillBetweenUntil(LiveRange* range,
   3446                                             LifetimePosition start,
   3447                                             LifetimePosition until,
   3448                                             LifetimePosition end) {
   3449   CHECK(start < end);
   3450   LiveRange* second_part = SplitRangeAt(range, start);
   3451 
   3452   if (second_part->Start() < end) {
   3453     // The split result intersects with [start, end[.
   3454     // Split it at position between ]start+1, end[, spill the middle part
   3455     // and put the rest to unhandled.
   3456     LifetimePosition third_part_end = end.PrevStart().End();
   3457     if (data()->IsBlockBoundary(end.Start())) {
   3458       third_part_end = end.Start();
   3459     }
   3460     LiveRange* third_part = SplitBetween(
   3461         second_part, Max(second_part->Start().End(), until), third_part_end);
   3462 
   3463     DCHECK(third_part != second_part);
   3464 
   3465     Spill(second_part);
   3466     AddToUnhandledSorted(third_part);
   3467   } else {
   3468     // The split result does not intersect with [start, end[.
   3469     // Nothing to spill. Just put it to unhandled as whole.
   3470     AddToUnhandledSorted(second_part);
   3471   }
   3472 }
   3473 
   3474 
   3475 SpillSlotLocator::SpillSlotLocator(RegisterAllocationData* data)
   3476     : data_(data) {}
   3477 
   3478 
   3479 void SpillSlotLocator::LocateSpillSlots() {
   3480   const InstructionSequence* code = data()->code();
   3481   for (TopLevelLiveRange* range : data()->live_ranges()) {
   3482     if (range == nullptr || range->IsEmpty()) continue;
   3483     // We care only about ranges which spill in the frame.
   3484     if (!range->HasSpillRange() || range->IsSpilledOnlyInDeferredBlocks()) {
   3485       continue;
   3486     }
   3487     TopLevelLiveRange::SpillMoveInsertionList* spills =
   3488         range->GetSpillMoveInsertionLocations();
   3489     DCHECK_NOT_NULL(spills);
   3490     for (; spills != nullptr; spills = spills->next) {
   3491       code->GetInstructionBlock(spills->gap_index)->mark_needs_frame();
   3492     }
   3493   }
   3494 }
   3495 
   3496 
   3497 OperandAssigner::OperandAssigner(RegisterAllocationData* data) : data_(data) {}
   3498 
   3499 
   3500 void OperandAssigner::AssignSpillSlots() {
   3501   ZoneVector<SpillRange*>& spill_ranges = data()->spill_ranges();
   3502   // Merge disjoint spill ranges
   3503   for (size_t i = 0; i < spill_ranges.size(); ++i) {
   3504     SpillRange* range = spill_ranges[i];
   3505     if (range == nullptr) continue;
   3506     if (range->IsEmpty()) continue;
   3507     for (size_t j = i + 1; j < spill_ranges.size(); ++j) {
   3508       SpillRange* other = spill_ranges[j];
   3509       if (other != nullptr && !other->IsEmpty()) {
   3510         range->TryMerge(other);
   3511       }
   3512     }
   3513   }
   3514   // Allocate slots for the merged spill ranges.
   3515   for (SpillRange* range : spill_ranges) {
   3516     if (range == nullptr || range->IsEmpty()) continue;
   3517     // Allocate a new operand referring to the spill slot.
   3518     if (!range->HasSlot()) {
   3519       int index = data()->frame()->AllocateSpillSlot(range->byte_width());
   3520       range->set_assigned_slot(index);
   3521     }
   3522   }
   3523 }
   3524 
   3525 
   3526 void OperandAssigner::CommitAssignment() {
   3527   for (TopLevelLiveRange* top_range : data()->live_ranges()) {
   3528     if (top_range == nullptr || top_range->IsEmpty()) continue;
   3529     InstructionOperand spill_operand;
   3530     if (top_range->HasSpillOperand()) {
   3531       spill_operand = *top_range->TopLevel()->GetSpillOperand();
   3532     } else if (top_range->TopLevel()->HasSpillRange()) {
   3533       spill_operand = top_range->TopLevel()->GetSpillRangeOperand();
   3534     }
   3535     if (top_range->is_phi()) {
   3536       data()->GetPhiMapValueFor(top_range)->CommitAssignment(
   3537           top_range->GetAssignedOperand());
   3538     }
   3539     for (LiveRange* range = top_range; range != nullptr;
   3540          range = range->next()) {
   3541       InstructionOperand assigned = range->GetAssignedOperand();
   3542       range->ConvertUsesToOperand(assigned, spill_operand);
   3543     }
   3544 
   3545     if (!spill_operand.IsInvalid()) {
   3546       // If this top level range has a child spilled in a deferred block, we use
   3547       // the range and control flow connection mechanism instead of spilling at
   3548       // definition. Refer to the ConnectLiveRanges and ResolveControlFlow
   3549       // phases. Normally, when we spill at definition, we do not insert a
   3550       // connecting move when a successor child range is spilled - because the
   3551       // spilled range picks up its value from the slot which was assigned at
   3552       // definition. For ranges that are determined to spill only in deferred
   3553       // blocks, we let ConnectLiveRanges and ResolveControlFlow find the blocks
   3554       // where a spill operand is expected, and then finalize by inserting the
   3555       // spills in the deferred blocks dominators.
   3556       if (!top_range->IsSpilledOnlyInDeferredBlocks()) {
   3557         // Spill at definition if the range isn't spilled only in deferred
   3558         // blocks.
   3559         top_range->CommitSpillMoves(
   3560             data()->code(), spill_operand,
   3561             top_range->has_slot_use() || top_range->spilled());
   3562       }
   3563     }
   3564   }
   3565 }
   3566 
   3567 
   3568 ReferenceMapPopulator::ReferenceMapPopulator(RegisterAllocationData* data)
   3569     : data_(data) {}
   3570 
   3571 
   3572 bool ReferenceMapPopulator::SafePointsAreInOrder() const {
   3573   int safe_point = 0;
   3574   for (ReferenceMap* map : *data()->code()->reference_maps()) {
   3575     if (safe_point > map->instruction_position()) return false;
   3576     safe_point = map->instruction_position();
   3577   }
   3578   return true;
   3579 }
   3580 
   3581 
   3582 void ReferenceMapPopulator::PopulateReferenceMaps() {
   3583   DCHECK(SafePointsAreInOrder());
   3584   // Map all delayed references.
   3585   for (RegisterAllocationData::DelayedReference& delayed_reference :
   3586        data()->delayed_references()) {
   3587     delayed_reference.map->RecordReference(
   3588         AllocatedOperand::cast(*delayed_reference.operand));
   3589   }
   3590   // Iterate over all safe point positions and record a pointer
   3591   // for all spilled live ranges at this point.
   3592   int last_range_start = 0;
   3593   const ReferenceMapDeque* reference_maps = data()->code()->reference_maps();
   3594   ReferenceMapDeque::const_iterator first_it = reference_maps->begin();
   3595   for (TopLevelLiveRange* range : data()->live_ranges()) {
   3596     if (range == nullptr) continue;
   3597     // Skip non-reference values.
   3598     if (!data()->IsReference(range)) continue;
   3599     // Skip empty live ranges.
   3600     if (range->IsEmpty()) continue;
   3601     if (range->has_preassigned_slot()) continue;
   3602 
   3603     // Find the extent of the range and its children.
   3604     int start = range->Start().ToInstructionIndex();
   3605     int end = 0;
   3606     for (LiveRange* cur = range; cur != nullptr; cur = cur->next()) {
   3607       LifetimePosition this_end = cur->End();
   3608       if (this_end.ToInstructionIndex() > end)
   3609         end = this_end.ToInstructionIndex();
   3610       DCHECK(cur->Start().ToInstructionIndex() >= start);
   3611     }
   3612 
   3613     // Most of the ranges are in order, but not all.  Keep an eye on when they
   3614     // step backwards and reset the first_it so we don't miss any safe points.
   3615     if (start < last_range_start) first_it = reference_maps->begin();
   3616     last_range_start = start;
   3617 
   3618     // Step across all the safe points that are before the start of this range,
   3619     // recording how far we step in order to save doing this for the next range.
   3620     for (; first_it != reference_maps->end(); ++first_it) {
   3621       ReferenceMap* map = *first_it;
   3622       if (map->instruction_position() >= start) break;
   3623     }
   3624 
   3625     InstructionOperand spill_operand;
   3626     if (((range->HasSpillOperand() &&
   3627           !range->GetSpillOperand()->IsConstant()) ||
   3628          range->HasSpillRange())) {
   3629       if (range->HasSpillOperand()) {
   3630         spill_operand = *range->GetSpillOperand();
   3631       } else {
   3632         spill_operand = range->GetSpillRangeOperand();
   3633       }
   3634       DCHECK(spill_operand.IsStackSlot());
   3635       DCHECK(CanBeTaggedPointer(
   3636           AllocatedOperand::cast(spill_operand).representation()));
   3637     }
   3638 
   3639     LiveRange* cur = range;
   3640     // Step through the safe points to see whether they are in the range.
   3641     for (auto it = first_it; it != reference_maps->end(); ++it) {
   3642       ReferenceMap* map = *it;
   3643       int safe_point = map->instruction_position();
   3644 
   3645       // The safe points are sorted so we can stop searching here.
   3646       if (safe_point - 1 > end) break;
   3647 
   3648       // Advance to the next active range that covers the current
   3649       // safe point position.
   3650       LifetimePosition safe_point_pos =
   3651           LifetimePosition::InstructionFromInstructionIndex(safe_point);
   3652 
   3653       // Search for the child range (cur) that covers safe_point_pos. If we
   3654       // don't find it before the children pass safe_point_pos, keep cur at
   3655       // the last child, because the next safe_point_pos may be covered by cur.
   3656       // This may happen if cur has more than one interval, and the current
   3657       // safe_point_pos is in between intervals.
   3658       // For that reason, cur may be at most the last child.
   3659       DCHECK_NOT_NULL(cur);
   3660       DCHECK(safe_point_pos >= cur->Start() || range == cur);
   3661       bool found = false;
   3662       while (!found) {
   3663         if (cur->Covers(safe_point_pos)) {
   3664           found = true;
   3665         } else {
   3666           LiveRange* next = cur->next();
   3667           if (next == nullptr || next->Start() > safe_point_pos) {
   3668             break;
   3669           }
   3670           cur = next;
   3671         }
   3672       }
   3673 
   3674       if (!found) {
   3675         continue;
   3676       }
   3677 
   3678       // Check if the live range is spilled and the safe point is after
   3679       // the spill position.
   3680       int spill_index = range->IsSpilledOnlyInDeferredBlocks()
   3681                             ? cur->Start().ToInstructionIndex()
   3682                             : range->spill_start_index();
   3683 
   3684       if (!spill_operand.IsInvalid() && safe_point >= spill_index) {
   3685         TRACE("Pointer for range %d (spilled at %d) at safe point %d\n",
   3686               range->vreg(), spill_index, safe_point);
   3687         map->RecordReference(AllocatedOperand::cast(spill_operand));
   3688       }
   3689 
   3690       if (!cur->spilled()) {
   3691         TRACE(
   3692             "Pointer in register for range %d:%d (start at %d) "
   3693             "at safe point %d\n",
   3694             range->vreg(), cur->relative_id(), cur->Start().value(),
   3695             safe_point);
   3696         InstructionOperand operand = cur->GetAssignedOperand();
   3697         DCHECK(!operand.IsStackSlot());
   3698         DCHECK(CanBeTaggedPointer(
   3699             AllocatedOperand::cast(operand).representation()));
   3700         map->RecordReference(AllocatedOperand::cast(operand));
   3701       }
   3702     }
   3703   }
   3704 }
   3705 
   3706 
   3707 LiveRangeConnector::LiveRangeConnector(RegisterAllocationData* data)
   3708     : data_(data) {}
   3709 
   3710 
   3711 bool LiveRangeConnector::CanEagerlyResolveControlFlow(
   3712     const InstructionBlock* block) const {
   3713   if (block->PredecessorCount() != 1) return false;
   3714   return block->predecessors()[0].IsNext(block->rpo_number());
   3715 }
   3716 
   3717 
   3718 void LiveRangeConnector::ResolveControlFlow(Zone* local_zone) {
   3719   // Lazily linearize live ranges in memory for fast lookup.
   3720   LiveRangeFinder finder(data(), local_zone);
   3721   ZoneVector<BitVector*>& live_in_sets = data()->live_in_sets();
   3722   for (const InstructionBlock* block : code()->instruction_blocks()) {
   3723     if (CanEagerlyResolveControlFlow(block)) continue;
   3724     BitVector* live = live_in_sets[block->rpo_number().ToInt()];
   3725     BitVector::Iterator iterator(live);
   3726     while (!iterator.Done()) {
   3727       int vreg = iterator.Current();
   3728       LiveRangeBoundArray* array = finder.ArrayFor(vreg);
   3729       for (const RpoNumber& pred : block->predecessors()) {
   3730         FindResult result;
   3731         const InstructionBlock* pred_block = code()->InstructionBlockAt(pred);
   3732         if (!array->FindConnectableSubranges(block, pred_block, &result)) {
   3733           continue;
   3734         }
   3735         InstructionOperand pred_op = result.pred_cover_->GetAssignedOperand();
   3736         InstructionOperand cur_op = result.cur_cover_->GetAssignedOperand();
   3737         if (pred_op.Equals(cur_op)) continue;
   3738         if (!pred_op.IsAnyRegister() && cur_op.IsAnyRegister()) {
   3739           // We're doing a reload.
   3740           // We don't need to, if:
   3741           // 1) there's no register use in this block, and
   3742           // 2) the range ends before the block does, and
   3743           // 3) we don't have a successor, or the successor is spilled.
   3744           LifetimePosition block_start =
   3745               LifetimePosition::GapFromInstructionIndex(block->code_start());
   3746           LifetimePosition block_end =
   3747               LifetimePosition::GapFromInstructionIndex(block->code_end());
   3748           const LiveRange* current = result.cur_cover_;
   3749           const LiveRange* successor = current->next();
   3750           if (current->End() < block_end &&
   3751               (successor == nullptr || successor->spilled())) {
   3752             // verify point 1: no register use. We can go to the end of the
   3753             // range, since it's all within the block.
   3754 
   3755             bool uses_reg = false;
   3756             for (const UsePosition* use = current->NextUsePosition(block_start);
   3757                  use != nullptr; use = use->next()) {
   3758               if (use->operand()->IsAnyRegister()) {
   3759                 uses_reg = true;
   3760                 break;
   3761               }
   3762             }
   3763             if (!uses_reg) continue;
   3764           }
   3765           if (current->TopLevel()->IsSpilledOnlyInDeferredBlocks() &&
   3766               pred_block->IsDeferred()) {
   3767             // The spill location should be defined in pred_block, so add
   3768             // pred_block to the list of blocks requiring a spill operand.
   3769             current->TopLevel()->GetListOfBlocksRequiringSpillOperands()->Add(
   3770                 pred_block->rpo_number().ToInt());
   3771           }
   3772         }
   3773         int move_loc = ResolveControlFlow(block, cur_op, pred_block, pred_op);
   3774         USE(move_loc);
   3775         DCHECK_IMPLIES(
   3776             result.cur_cover_->TopLevel()->IsSpilledOnlyInDeferredBlocks() &&
   3777                 !(pred_op.IsAnyRegister() && cur_op.IsAnyRegister()),
   3778             code()->GetInstructionBlock(move_loc)->IsDeferred());
   3779       }
   3780       iterator.Advance();
   3781     }
   3782   }
   3783 
   3784   // At this stage, we collected blocks needing a spill operand from
   3785   // ConnectRanges and from ResolveControlFlow. Time to commit the spills for
   3786   // deferred blocks.
   3787   for (TopLevelLiveRange* top : data()->live_ranges()) {
   3788     if (top == nullptr || top->IsEmpty() ||
   3789         !top->IsSpilledOnlyInDeferredBlocks())
   3790       continue;
   3791     CommitSpillsInDeferredBlocks(top, finder.ArrayFor(top->vreg()), local_zone);
   3792   }
   3793 }
   3794 
   3795 
   3796 int LiveRangeConnector::ResolveControlFlow(const InstructionBlock* block,
   3797                                            const InstructionOperand& cur_op,
   3798                                            const InstructionBlock* pred,
   3799                                            const InstructionOperand& pred_op) {
   3800   DCHECK(!pred_op.Equals(cur_op));
   3801   int gap_index;
   3802   Instruction::GapPosition position;
   3803   if (block->PredecessorCount() == 1) {
   3804     gap_index = block->first_instruction_index();
   3805     position = Instruction::START;
   3806   } else {
   3807     DCHECK(pred->SuccessorCount() == 1);
   3808     DCHECK(!code()
   3809                 ->InstructionAt(pred->last_instruction_index())
   3810                 ->HasReferenceMap());
   3811     gap_index = pred->last_instruction_index();
   3812     position = Instruction::END;
   3813   }
   3814   data()->AddGapMove(gap_index, position, pred_op, cur_op);
   3815   return gap_index;
   3816 }
   3817 
   3818 void LiveRangeConnector::ConnectRanges(Zone* local_zone) {
   3819   DelayedInsertionMap delayed_insertion_map(local_zone);
   3820   for (TopLevelLiveRange* top_range : data()->live_ranges()) {
   3821     if (top_range == nullptr) continue;
   3822     bool connect_spilled = top_range->IsSpilledOnlyInDeferredBlocks();
   3823     LiveRange* first_range = top_range;
   3824     for (LiveRange *second_range = first_range->next(); second_range != nullptr;
   3825          first_range = second_range, second_range = second_range->next()) {
   3826       LifetimePosition pos = second_range->Start();
   3827       // Add gap move if the two live ranges touch and there is no block
   3828       // boundary.
   3829       if (second_range->spilled()) continue;
   3830       if (first_range->End() != pos) continue;
   3831       if (data()->IsBlockBoundary(pos) &&
   3832           !CanEagerlyResolveControlFlow(GetInstructionBlock(code(), pos))) {
   3833         continue;
   3834       }
   3835       InstructionOperand prev_operand = first_range->GetAssignedOperand();
   3836       InstructionOperand cur_operand = second_range->GetAssignedOperand();
   3837       if (prev_operand.Equals(cur_operand)) continue;
   3838       bool delay_insertion = false;
   3839       Instruction::GapPosition gap_pos;
   3840       int gap_index = pos.ToInstructionIndex();
   3841       if (connect_spilled && !prev_operand.IsAnyRegister() &&
   3842           cur_operand.IsAnyRegister()) {
   3843         const InstructionBlock* block = code()->GetInstructionBlock(gap_index);
   3844         DCHECK(block->IsDeferred());
   3845         // Performing a reload in this block, meaning the spill operand must
   3846         // be defined here.
   3847         top_range->GetListOfBlocksRequiringSpillOperands()->Add(
   3848             block->rpo_number().ToInt());
   3849       }
   3850 
   3851       if (pos.IsGapPosition()) {
   3852         gap_pos = pos.IsStart() ? Instruction::START : Instruction::END;
   3853       } else {
   3854         if (pos.IsStart()) {
   3855           delay_insertion = true;
   3856         } else {
   3857           gap_index++;
   3858         }
   3859         gap_pos = delay_insertion ? Instruction::END : Instruction::START;
   3860       }
   3861       // Reloads or spills for spilled in deferred blocks ranges must happen
   3862       // only in deferred blocks.
   3863       DCHECK_IMPLIES(
   3864           connect_spilled &&
   3865               !(prev_operand.IsAnyRegister() && cur_operand.IsAnyRegister()),
   3866           code()->GetInstructionBlock(gap_index)->IsDeferred());
   3867 
   3868       ParallelMove* move =
   3869           code()->InstructionAt(gap_index)->GetOrCreateParallelMove(
   3870               gap_pos, code_zone());
   3871       if (!delay_insertion) {
   3872         move->AddMove(prev_operand, cur_operand);
   3873       } else {
   3874         delayed_insertion_map.insert(
   3875             std::make_pair(std::make_pair(move, prev_operand), cur_operand));
   3876       }
   3877     }
   3878   }
   3879   if (delayed_insertion_map.empty()) return;
   3880   // Insert all the moves which should occur after the stored move.
   3881   ZoneVector<MoveOperands*> to_insert(local_zone);
   3882   ZoneVector<MoveOperands*> to_eliminate(local_zone);
   3883   to_insert.reserve(4);
   3884   to_eliminate.reserve(4);
   3885   ParallelMove* moves = delayed_insertion_map.begin()->first.first;
   3886   for (auto it = delayed_insertion_map.begin();; ++it) {
   3887     bool done = it == delayed_insertion_map.end();
   3888     if (done || it->first.first != moves) {
   3889       // Commit the MoveOperands for current ParallelMove.
   3890       for (MoveOperands* move : to_eliminate) {
   3891         move->Eliminate();
   3892       }
   3893       for (MoveOperands* move : to_insert) {
   3894         moves->push_back(move);
   3895       }
   3896       if (done) break;
   3897       // Reset state.
   3898       to_eliminate.clear();
   3899       to_insert.clear();
   3900       moves = it->first.first;
   3901     }
   3902     // Gather all MoveOperands for a single ParallelMove.
   3903     MoveOperands* move =
   3904         new (code_zone()) MoveOperands(it->first.second, it->second);
   3905     moves->PrepareInsertAfter(move, &to_eliminate);
   3906     to_insert.push_back(move);
   3907   }
   3908 }
   3909 
   3910 
   3911 void LiveRangeConnector::CommitSpillsInDeferredBlocks(
   3912     TopLevelLiveRange* range, LiveRangeBoundArray* array, Zone* temp_zone) {
   3913   DCHECK(range->IsSpilledOnlyInDeferredBlocks());
   3914   DCHECK(!range->spilled());
   3915 
   3916   InstructionSequence* code = data()->code();
   3917   InstructionOperand spill_operand = range->GetSpillRangeOperand();
   3918 
   3919   TRACE("Live Range %d will be spilled only in deferred blocks.\n",
   3920         range->vreg());
   3921   // If we have ranges that aren't spilled but require the operand on the stack,
   3922   // make sure we insert the spill.
   3923   for (const LiveRange* child = range; child != nullptr;
   3924        child = child->next()) {
   3925     for (const UsePosition* pos = child->first_pos(); pos != nullptr;
   3926          pos = pos->next()) {
   3927       if (pos->type() != UsePositionType::kRequiresSlot && !child->spilled())
   3928         continue;
   3929       range->AddBlockRequiringSpillOperand(
   3930           code->GetInstructionBlock(pos->pos().ToInstructionIndex())
   3931               ->rpo_number());
   3932     }
   3933   }
   3934 
   3935   ZoneQueue<int> worklist(temp_zone);
   3936 
   3937   for (BitVector::Iterator iterator(
   3938            range->GetListOfBlocksRequiringSpillOperands());
   3939        !iterator.Done(); iterator.Advance()) {
   3940     worklist.push(iterator.Current());
   3941   }
   3942 
   3943   ZoneSet<std::pair<RpoNumber, int>> done_moves(temp_zone);
   3944   // Seek the deferred blocks that dominate locations requiring spill operands,
   3945   // and spill there. We only need to spill at the start of such blocks.
   3946   BitVector done_blocks(
   3947       range->GetListOfBlocksRequiringSpillOperands()->length(), temp_zone);
   3948   while (!worklist.empty()) {
   3949     int block_id = worklist.front();
   3950     worklist.pop();
   3951     if (done_blocks.Contains(block_id)) continue;
   3952     done_blocks.Add(block_id);
   3953     InstructionBlock* spill_block =
   3954         code->InstructionBlockAt(RpoNumber::FromInt(block_id));
   3955 
   3956     for (const RpoNumber& pred : spill_block->predecessors()) {
   3957       const InstructionBlock* pred_block = code->InstructionBlockAt(pred);
   3958 
   3959       if (pred_block->IsDeferred()) {
   3960         worklist.push(pred_block->rpo_number().ToInt());
   3961       } else {
   3962         LifetimePosition pred_end =
   3963             LifetimePosition::InstructionFromInstructionIndex(
   3964                 pred_block->last_instruction_index());
   3965 
   3966         LiveRangeBound* bound = array->Find(pred_end);
   3967 
   3968         InstructionOperand pred_op = bound->range_->GetAssignedOperand();
   3969 
   3970         RpoNumber spill_block_number = spill_block->rpo_number();
   3971         if (done_moves.find(std::make_pair(
   3972                 spill_block_number, range->vreg())) == done_moves.end()) {
   3973           data()->AddGapMove(spill_block->first_instruction_index(),
   3974                              Instruction::GapPosition::START, pred_op,
   3975                              spill_operand);
   3976           done_moves.insert(std::make_pair(spill_block_number, range->vreg()));
   3977           spill_block->mark_needs_frame();
   3978         }
   3979       }
   3980     }
   3981   }
   3982 }
   3983 
   3984 
   3985 }  // namespace compiler
   3986 }  // namespace internal
   3987 }  // namespace v8
   3988