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