register-allocator.cc revision 958fae7ec3f466955f8e5b50fa5b8d38b9e91675
1b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Copyright 2014 the V8 project authors. All rights reserved.
2b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// found in the LICENSE file.
4b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/linkage.h"
6958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/compiler/register-allocator.h"
7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/string-stream.h"
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace compiler {
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic inline LifetimePosition Min(LifetimePosition a, LifetimePosition b) {
14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return a.Value() < b.Value() ? a : b;
15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic inline LifetimePosition Max(LifetimePosition a, LifetimePosition b) {
19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return a.Value() > b.Value() ? a : b;
20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
23958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic void TraceAlloc(const char* msg, ...) {
24958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (FLAG_trace_alloc) {
25958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    va_list arguments;
26958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    va_start(arguments, msg);
27958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    base::OS::VPrint(msg, arguments);
28958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    va_end(arguments);
29958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
30958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
31958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
32958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
33958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic void RemoveElement(ZoneVector<LiveRange*>* v, LiveRange* range) {
34958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto it = std::find(v->begin(), v->end(), range);
35958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(it != v->end());
36958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  v->erase(it);
37958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
38958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
39958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochUsePosition::UsePosition(LifetimePosition pos, InstructionOperand* operand,
41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                         InstructionOperand* hint)
42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : operand_(operand),
43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      hint_(hint),
44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      pos_(pos),
45958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      next_(nullptr),
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      requires_reg_(false),
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      register_beneficial_(true) {
48958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (operand_ != nullptr && operand_->IsUnallocated()) {
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const UnallocatedOperand* unalloc = UnallocatedOperand::cast(operand_);
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    requires_reg_ = unalloc->HasRegisterPolicy();
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    register_beneficial_ = !unalloc->HasAnyPolicy();
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(pos_.IsValid());
54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool UsePosition::HasHint() const {
58958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return hint_ != nullptr && !hint_->IsUnallocated();
59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool UsePosition::RequiresRegister() const { return requires_reg_; }
63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool UsePosition::RegisterIsBeneficial() const { return register_beneficial_; }
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid UseInterval::SplitAt(LifetimePosition pos, Zone* zone) {
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(Contains(pos) && pos.Value() != start().Value());
70958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto after = new (zone) UseInterval(pos, end_);
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  after->next_ = next_;
72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  next_ = after;
73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  end_ = pos;
74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
77958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstruct LiveRange::SpillAtDefinitionList : ZoneObject {
78958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  SpillAtDefinitionList(int gap_index, InstructionOperand* operand,
79958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                        SpillAtDefinitionList* next)
80958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      : gap_index(gap_index), operand(operand), next(next) {}
81958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const int gap_index;
82958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  InstructionOperand* const operand;
83958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  SpillAtDefinitionList* const next;
84958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier};
85958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
86958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LiveRange::Verify() const {
91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UsePosition* cur = first_pos_;
92958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  while (cur != nullptr) {
93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(Start().Value() <= cur->pos().Value() &&
94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           cur->pos().Value() <= End().Value());
95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    cur = cur->next();
96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool LiveRange::HasOverlap(UseInterval* target) const {
101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UseInterval* current_interval = first_interval_;
102958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  while (current_interval != nullptr) {
103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Intervals overlap if the start of one is contained in the other.
104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (current_interval->Contains(target->start()) ||
105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        target->Contains(current_interval->start())) {
106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return true;
107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    current_interval = current_interval->next();
109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return false;
111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLiveRange::LiveRange(int id, Zone* zone)
118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    : id_(id),
119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      spilled_(false),
120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      is_phi_(false),
121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      is_non_loop_phi_(false),
122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      kind_(UNALLOCATED_REGISTERS),
123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      assigned_register_(kInvalidAssignment),
124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      last_interval_(nullptr),
125958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      first_interval_(nullptr),
126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      first_pos_(nullptr),
127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      parent_(nullptr),
128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      next_(nullptr),
129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      current_interval_(nullptr),
130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      last_processed_use_(nullptr),
131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      current_hint_operand_(nullptr),
132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      spill_start_index_(kMaxInt),
133958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      spill_type_(SpillType::kNoSpillType),
134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      spill_operand_(nullptr),
135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      spills_at_definition_(nullptr) {}
136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LiveRange::set_assigned_register(int reg, Zone* zone) {
139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!HasRegisterAssigned() && !IsSpilled());
140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  assigned_register_ = reg;
141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // TODO(dcarney): stop aliasing hint operands.
142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  ConvertUsesToOperand(CreateAssignedOperand(zone));
143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid LiveRange::MakeSpilled() {
147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!IsSpilled());
148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(!TopLevel()->HasNoSpillType());
149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  spilled_ = true;
150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  assigned_register_ = kInvalidAssignment;
151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
154958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid LiveRange::SpillAtDefinition(Zone* zone, int gap_index,
155958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                  InstructionOperand* operand) {
156958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(HasNoSpillType());
157958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  spills_at_definition_ = new (zone)
158958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      SpillAtDefinitionList(gap_index, operand, spills_at_definition_);
159958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
160958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
161958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
162958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid LiveRange::CommitSpillsAtDefinition(InstructionSequence* sequence,
163958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                         InstructionOperand* op) {
164958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto to_spill = TopLevel()->spills_at_definition_;
165958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (to_spill == nullptr) return;
166958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto zone = sequence->zone();
167958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (; to_spill != nullptr; to_spill = to_spill->next) {
168958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto gap = sequence->GapAt(to_spill->gap_index);
169958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto move = gap->GetOrCreateParallelMove(GapInstruction::START, zone);
170958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    move->AddMove(to_spill->operand, op, zone);
171958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  TopLevel()->spills_at_definition_ = nullptr;
173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LiveRange::SetSpillOperand(InstructionOperand* operand) {
177958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(HasNoSpillType());
178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!operand->IsUnallocated());
179958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  spill_type_ = SpillType::kSpillOperand;
180958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  spill_operand_ = operand;
181958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
182958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
183958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid LiveRange::SetSpillRange(SpillRange* spill_range) {
185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(HasNoSpillType() || HasSpillRange());
186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK_NE(spill_range, nullptr);
187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  spill_type_ = SpillType::kSpillRange;
188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  spill_range_ = spill_range;
189958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
190958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
191958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
192958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid LiveRange::CommitSpillOperand(InstructionOperand* operand) {
193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(HasSpillRange());
194958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(!operand->IsUnallocated());
195958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(!IsChild());
196958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  spill_type_ = SpillType::kSpillOperand;
197958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  spill_operand_ = operand;
198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochUsePosition* LiveRange::NextUsePosition(LifetimePosition start) {
202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UsePosition* use_pos = last_processed_use_;
203958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (use_pos == nullptr) use_pos = first_pos();
204958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  while (use_pos != nullptr && use_pos->pos().Value() < start.Value()) {
205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    use_pos = use_pos->next();
206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  last_processed_use_ = use_pos;
208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return use_pos;
209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochUsePosition* LiveRange::NextUsePositionRegisterIsBeneficial(
213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LifetimePosition start) {
214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UsePosition* pos = NextUsePosition(start);
215958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  while (pos != nullptr && !pos->RegisterIsBeneficial()) {
216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    pos = pos->next();
217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return pos;
219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochUsePosition* LiveRange::PreviousUsePositionRegisterIsBeneficial(
223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LifetimePosition start) {
224958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto pos = first_pos();
225958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  UsePosition* prev = nullptr;
226958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  while (pos != nullptr && pos->pos().Value() < start.Value()) {
227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (pos->RegisterIsBeneficial()) prev = pos;
228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    pos = pos->next();
229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return prev;
231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochUsePosition* LiveRange::NextRegisterPosition(LifetimePosition start) {
235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UsePosition* pos = NextUsePosition(start);
236958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  while (pos != nullptr && !pos->RequiresRegister()) {
237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    pos = pos->next();
238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return pos;
240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool LiveRange::CanBeSpilled(LifetimePosition pos) {
244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We cannot spill a live range that has a use requiring a register
245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // at the current or the immediate next position.
246958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto use_pos = NextRegisterPosition(pos);
247958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (use_pos == nullptr) return true;
248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return use_pos->pos().Value() >
249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         pos.NextInstruction().InstructionEnd().Value();
250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
253958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierInstructionOperand* LiveRange::CreateAssignedOperand(Zone* zone) const {
254958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  InstructionOperand* op = nullptr;
255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (HasRegisterAssigned()) {
256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!IsSpilled());
257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    switch (Kind()) {
258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case GENERAL_REGISTERS:
259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        op = RegisterOperand::Create(assigned_register(), zone);
260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      case DOUBLE_REGISTERS:
262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        op = DoubleRegisterOperand::Create(assigned_register(), zone);
263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        break;
264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      default:
265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        UNREACHABLE();
266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
267958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } else {
268958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(IsSpilled());
269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!HasRegisterAssigned());
270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    op = TopLevel()->GetSpillOperand();
271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!op->IsUnallocated());
272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return op;
274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochUseInterval* LiveRange::FirstSearchIntervalForPosition(
278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LifetimePosition position) const {
279958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (current_interval_ == nullptr) return first_interval_;
280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (current_interval_->start().Value() > position.Value()) {
281958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    current_interval_ = nullptr;
282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return first_interval_;
283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return current_interval_;
285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LiveRange::AdvanceLastProcessedMarker(
289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UseInterval* to_start_of, LifetimePosition but_not_past) const {
290958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (to_start_of == nullptr) return;
291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (to_start_of->start().Value() > but_not_past.Value()) return;
292958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto start = current_interval_ == nullptr ? LifetimePosition::Invalid()
293958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                            : current_interval_->start();
294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (to_start_of->start().Value() > start.Value()) {
295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    current_interval_ = to_start_of;
296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LiveRange::SplitAt(LifetimePosition position, LiveRange* result,
301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                        Zone* zone) {
302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(Start().Value() < position.Value());
303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(result->IsEmpty());
304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Find the last interval that ends before the position. If the
305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // position is contained in one of the intervals in the chain, we
306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // split that interval and use the first part.
307958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto current = FirstSearchIntervalForPosition(position);
308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // If the split position coincides with the beginning of a use interval
310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // we need to split use positons in a special way.
311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool split_at_start = false;
312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (current->start().Value() == position.Value()) {
314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // When splitting at start we need to locate the previous use interval.
315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    current = first_interval_;
316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
318958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  while (current != nullptr) {
319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (current->Contains(position)) {
320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      current->SplitAt(position, zone);
321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
323958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto next = current->next();
324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (next->start().Value() >= position.Value()) {
325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      split_at_start = (next->start().Value() == position.Value());
326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    current = next;
329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Partition original use intervals to the two live ranges.
332958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto before = current;
333958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto after = before->next();
334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->last_interval_ =
335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (last_interval_ == before)
336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          ? after            // Only interval in the range after split.
337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          : last_interval_;  // Last interval of the original range.
338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->first_interval_ = after;
339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  last_interval_ = before;
340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Find the last use position before the split and the first use
342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // position after it.
343958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto use_after = first_pos_;
344958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  UsePosition* use_before = nullptr;
345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (split_at_start) {
346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // The split position coincides with the beginning of a use interval (the
347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // end of a lifetime hole). Use at this position should be attributed to
348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // the split child because split child owns use interval covering it.
349958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    while (use_after != nullptr &&
350958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier           use_after->pos().Value() < position.Value()) {
351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      use_before = use_after;
352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      use_after = use_after->next();
353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
355958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    while (use_after != nullptr &&
356958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier           use_after->pos().Value() <= position.Value()) {
357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      use_before = use_after;
358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      use_after = use_after->next();
359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Partition original use positions to the two live ranges.
363958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (use_before != nullptr) {
364958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    use_before->next_ = nullptr;
365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
366958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    first_pos_ = nullptr;
367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->first_pos_ = use_after;
369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Discard cached iteration state. It might be pointing
371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // to the use that no longer belongs to this live range.
372958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  last_processed_use_ = nullptr;
373958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  current_interval_ = nullptr;
374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Link the new live range in the chain before any of the other
376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // ranges linked from the range before the split.
377958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  result->parent_ = (parent_ == nullptr) ? this : parent_;
378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->kind_ = result->parent_->kind_;
379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->next_ = next_;
380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  next_ = result;
381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Verify();
384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->Verify();
385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// This implements an ordering on live ranges so that they are ordered by their
390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// start positions.  This is needed for the correctness of the register
391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// allocation algorithm.  If two live ranges start at the same offset then there
392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// is a tie breaker based on where the value is first used.  This part of the
393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ordering is merely a heuristic.
394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool LiveRange::ShouldBeAllocatedBefore(const LiveRange* other) const {
395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LifetimePosition start = Start();
396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LifetimePosition other_start = other->Start();
397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (start.Value() == other_start.Value()) {
398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UsePosition* pos = first_pos();
399958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (pos == nullptr) return false;
400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UsePosition* other_pos = other->first_pos();
401958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (other_pos == nullptr) return true;
402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return pos->pos().Value() < other_pos->pos().Value();
403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return start.Value() < other_start.Value();
405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LiveRange::ShortenTo(LifetimePosition start) {
409958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  TraceAlloc("Shorten live range %d to [%d\n", id_, start.Value());
410958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(first_interval_ != nullptr);
411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(first_interval_->start().Value() <= start.Value());
412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(start.Value() < first_interval_->end().Value());
413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  first_interval_->set_start(start);
414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LiveRange::EnsureInterval(LifetimePosition start, LifetimePosition end,
418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               Zone* zone) {
419958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  TraceAlloc("Ensure live range %d in interval [%d %d[\n", id_, start.Value(),
420958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier             end.Value());
421958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto new_end = end;
422958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  while (first_interval_ != nullptr &&
423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         first_interval_->start().Value() <= end.Value()) {
424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (first_interval_->end().Value() > end.Value()) {
425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      new_end = first_interval_->end();
426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    first_interval_ = first_interval_->next();
428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
430958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto new_interval = new (zone) UseInterval(start, new_end);
431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  new_interval->next_ = first_interval_;
432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  first_interval_ = new_interval;
433958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (new_interval->next() == nullptr) {
434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    last_interval_ = new_interval;
435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LiveRange::AddUseInterval(LifetimePosition start, LifetimePosition end,
440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               Zone* zone) {
441958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  TraceAlloc("Add to live range %d interval [%d %d[\n", id_, start.Value(),
442958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier             end.Value());
443958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (first_interval_ == nullptr) {
444958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto interval = new (zone) UseInterval(start, end);
445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    first_interval_ = interval;
446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    last_interval_ = interval;
447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (end.Value() == first_interval_->start().Value()) {
449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      first_interval_->set_start(start);
450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else if (end.Value() < first_interval_->start().Value()) {
451958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto interval = new (zone) UseInterval(start, end);
452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      interval->set_next(first_interval_);
453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      first_interval_ = interval;
454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Order of instruction's processing (see ProcessInstructions) guarantees
456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // that each new use interval either precedes or intersects with
457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // last added interval.
458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(start.Value() < first_interval_->end().Value());
459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      first_interval_->start_ = Min(start, first_interval_->start_);
460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      first_interval_->end_ = Max(end, first_interval_->end_);
461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LiveRange::AddUsePosition(LifetimePosition pos,
467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               InstructionOperand* operand,
468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               InstructionOperand* hint, Zone* zone) {
469958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  TraceAlloc("Add to live range %d use position %d\n", id_, pos.Value());
470958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto use_pos = new (zone) UsePosition(pos, operand, hint);
471958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  UsePosition* prev_hint = nullptr;
472958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  UsePosition* prev = nullptr;
473958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto current = first_pos_;
474958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  while (current != nullptr && current->pos().Value() < pos.Value()) {
475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    prev_hint = current->HasHint() ? current : prev_hint;
476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    prev = current;
477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    current = current->next();
478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
480958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (prev == nullptr) {
481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    use_pos->set_next(first_pos_);
482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    first_pos_ = use_pos;
483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    use_pos->next_ = prev->next_;
485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    prev->next_ = use_pos;
486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
488958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (prev_hint == nullptr && use_pos->HasHint()) {
489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    current_hint_operand_ = hint;
490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
494958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid LiveRange::ConvertUsesToOperand(InstructionOperand* op) {
495958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto use_pos = first_pos();
496958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  while (use_pos != nullptr) {
497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(Start().Value() <= use_pos->pos().Value() &&
498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           use_pos->pos().Value() <= End().Value());
499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (use_pos->HasOperand()) {
501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(op->IsRegister() || op->IsDoubleRegister() ||
502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             !use_pos->RequiresRegister());
503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      use_pos->operand()->ConvertTo(op->kind(), op->index());
504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    use_pos = use_pos->next();
506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool LiveRange::CanCover(LifetimePosition position) const {
511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (IsEmpty()) return false;
512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return Start().Value() <= position.Value() &&
513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         position.Value() < End().Value();
514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool LiveRange::Covers(LifetimePosition position) {
518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!CanCover(position)) return false;
519958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto start_search = FirstSearchIntervalForPosition(position);
520958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (auto interval = start_search; interval != nullptr;
521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       interval = interval->next()) {
522958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(interval->next() == nullptr ||
523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch           interval->next()->start().Value() >= interval->start().Value());
524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AdvanceLastProcessedMarker(interval, position);
525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (interval->Contains(position)) return true;
526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (interval->start().Value() > position.Value()) return false;
527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return false;
529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLifetimePosition LiveRange::FirstIntersection(LiveRange* other) {
533958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto b = other->first_interval();
534958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (b == nullptr) return LifetimePosition::Invalid();
535958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto advance_last_processed_up_to = b->start();
536958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto a = FirstSearchIntervalForPosition(b->start());
537958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  while (a != nullptr && b != nullptr) {
538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (a->start().Value() > other->End().Value()) break;
539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (b->start().Value() > End().Value()) break;
540958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto cur_intersection = a->Intersect(b);
541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (cur_intersection.IsValid()) {
542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return cur_intersection;
543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (a->start().Value() < b->start().Value()) {
545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      a = a->next();
546958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (a == nullptr || a->start().Value() > other->End().Value()) break;
547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      AdvanceLastProcessedMarker(a, advance_last_processed_up_to);
548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      b = b->next();
550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return LifetimePosition::Invalid();
553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
556958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierRegisterAllocator::RegisterAllocator(const RegisterConfiguration* config,
557958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                     Zone* zone, Frame* frame,
558958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                     InstructionSequence* code,
559958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                     const char* debug_name)
560958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    : local_zone_(zone),
561958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      frame_(frame),
562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      code_(code),
563958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      debug_name_(debug_name),
564958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      config_(config),
565958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      phi_map_(PhiMap::key_compare(), PhiMap::allocator_type(local_zone())),
566958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      live_in_sets_(code->InstructionBlockCount(), nullptr, local_zone()),
567958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      live_ranges_(code->VirtualRegisterCount() * 2, nullptr, local_zone()),
568958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      fixed_live_ranges_(this->config()->num_general_registers(), nullptr,
569958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                         local_zone()),
570958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      fixed_double_live_ranges_(this->config()->num_double_registers(), nullptr,
571958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                local_zone()),
572958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      unhandled_live_ranges_(local_zone()),
573958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      active_live_ranges_(local_zone()),
574958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      inactive_live_ranges_(local_zone()),
575958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      reusable_slots_(local_zone()),
576958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      spill_ranges_(local_zone()),
577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      mode_(UNALLOCATED_REGISTERS),
578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      num_registers_(-1),
579958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      allocation_ok_(true) {
580958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(this->config()->num_general_registers() <=
581958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier         RegisterConfiguration::kMaxGeneralRegisters);
582958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(this->config()->num_double_registers() <=
583958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier         RegisterConfiguration::kMaxDoubleRegisters);
584958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // TryAllocateFreeReg and AllocateBlockedReg assume this
585958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // when allocating local arrays.
586958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(RegisterConfiguration::kMaxDoubleRegisters >=
587958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier         this->config()->num_general_registers());
588958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  unhandled_live_ranges().reserve(
589958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      static_cast<size_t>(code->VirtualRegisterCount() * 2));
590958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  active_live_ranges().reserve(8);
591958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  inactive_live_ranges().reserve(8);
592958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  reusable_slots().reserve(8);
593958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  spill_ranges().reserve(8);
594958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  assigned_registers_ =
595958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      new (code_zone()) BitVector(config->num_general_registers(), code_zone());
596958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  assigned_double_registers_ = new (code_zone())
597958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      BitVector(config->num_aliased_double_registers(), code_zone());
598958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  frame->SetAllocatedRegisters(assigned_registers_);
599958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  frame->SetAllocatedDoubleRegisters(assigned_double_registers_);
600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
603958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierBitVector* RegisterAllocator::ComputeLiveOut(const InstructionBlock* block) {
604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Compute live out for the given block, except not including backward
605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // successor edges.
606958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto live_out = new (local_zone())
607958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      BitVector(code()->VirtualRegisterCount(), local_zone());
608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Process all successor blocks.
610958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (auto succ : block->successors()) {
611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Add values live on entry to the successor. Note the successor's
612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // live_in will not be computed yet for backwards edges.
613958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto live_in = live_in_sets_[succ.ToSize()];
614958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (live_in != nullptr) live_out->Union(*live_in);
615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // All phi input operands corresponding to this successor edge are live
617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // out from this block.
618958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto successor = code()->InstructionBlockAt(succ);
619958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    size_t index = successor->PredecessorIndexOf(block->rpo_number());
620958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(index < successor->PredecessorCount());
621958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (auto phi : successor->phis()) {
622958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      live_out->Add(phi->operands()[index]);
623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return live_out;
626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
629958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid RegisterAllocator::AddInitialIntervals(const InstructionBlock* block,
630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                            BitVector* live_out) {
631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Add an interval that includes the entire block to the live range for
632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // each live_out value.
633958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto start =
634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      LifetimePosition::FromInstructionIndex(block->first_instruction_index());
635958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto end = LifetimePosition::FromInstructionIndex(
636958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                 block->last_instruction_index()).NextInstruction();
637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  BitVector::Iterator iterator(live_out);
638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  while (!iterator.Done()) {
639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int operand_index = iterator.Current();
640958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto range = LiveRangeFor(operand_index);
641958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    range->AddUseInterval(start, end, local_zone());
642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    iterator.Advance();
643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint RegisterAllocator::FixedDoubleLiveRangeID(int index) {
648958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return -index - 1 - config()->num_general_registers();
649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochInstructionOperand* RegisterAllocator::AllocateFixed(
653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UnallocatedOperand* operand, int pos, bool is_tagged) {
654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TraceAlloc("Allocating fixed reg for op %d\n", operand->virtual_register());
655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(operand->HasFixedPolicy());
656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (operand->HasFixedSlotPolicy()) {
657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    operand->ConvertTo(InstructionOperand::STACK_SLOT,
658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                       operand->fixed_slot_index());
659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (operand->HasFixedRegisterPolicy()) {
660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int reg_index = operand->fixed_register_index();
661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    operand->ConvertTo(InstructionOperand::REGISTER, reg_index);
662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (operand->HasFixedDoubleRegisterPolicy()) {
663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int reg_index = operand->fixed_register_index();
664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    operand->ConvertTo(InstructionOperand::DOUBLE_REGISTER, reg_index);
665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UNREACHABLE();
667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (is_tagged) {
669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    TraceAlloc("Fixed reg is tagged at %d\n", pos);
670958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto instr = InstructionAt(pos);
671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (instr->HasPointerMap()) {
672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      instr->pointer_map()->RecordPointer(operand, code_zone());
673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return operand;
676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLiveRange* RegisterAllocator::FixedLiveRangeFor(int index) {
680958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(index < config()->num_general_registers());
681958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto result = fixed_live_ranges()[index];
682958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (result == nullptr) {
683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // TODO(titzer): add a utility method to allocate a new LiveRange:
684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // The LiveRange object itself can go in this zone, but the
685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // InstructionOperand needs
686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // to go in the code zone, since it may survive register allocation.
687958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    result = new (local_zone()) LiveRange(FixedLiveRangeID(index), code_zone());
688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(result->IsFixed());
689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result->kind_ = GENERAL_REGISTERS;
690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetLiveRangeAssignedRegister(result, index);
691958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    fixed_live_ranges()[index] = result;
692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLiveRange* RegisterAllocator::FixedDoubleLiveRangeFor(int index) {
698958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(index < config()->num_aliased_double_registers());
699958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto result = fixed_double_live_ranges()[index];
700958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (result == nullptr) {
701958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    result = new (local_zone())
702958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        LiveRange(FixedDoubleLiveRangeID(index), code_zone());
703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(result->IsFixed());
704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    result->kind_ = DOUBLE_REGISTERS;
705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SetLiveRangeAssignedRegister(result, index);
706958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    fixed_double_live_ranges()[index] = result;
707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLiveRange* RegisterAllocator::LiveRangeFor(int index) {
713958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (index >= static_cast<int>(live_ranges().size())) {
714958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    live_ranges().resize(index + 1, nullptr);
715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
716958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto result = live_ranges()[index];
717958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (result == nullptr) {
718958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    result = new (local_zone()) LiveRange(index, code_zone());
719958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    live_ranges()[index] = result;
720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
725958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierGapInstruction* RegisterAllocator::GetLastGap(const InstructionBlock* block) {
726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int last_instruction = block->last_instruction_index();
727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return code()->GapAt(last_instruction - 1);
728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLiveRange* RegisterAllocator::LiveRangeFor(InstructionOperand* operand) {
732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (operand->IsUnallocated()) {
733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return LiveRangeFor(UnallocatedOperand::cast(operand)->virtual_register());
734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (operand->IsRegister()) {
735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return FixedLiveRangeFor(operand->index());
736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else if (operand->IsDoubleRegister()) {
737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return FixedDoubleLiveRangeFor(operand->index());
738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
739958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return nullptr;
740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::Define(LifetimePosition position,
745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               InstructionOperand* operand,
746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                               InstructionOperand* hint) {
747958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto range = LiveRangeFor(operand);
748958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (range == nullptr) return;
749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (range->IsEmpty() || range->Start().Value() > position.Value()) {
751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Can happen if there is a definition without use.
752958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    range->AddUseInterval(position, position.NextInstruction(), local_zone());
753958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    range->AddUsePosition(position.NextInstruction(), nullptr, nullptr,
754958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                          local_zone());
755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    range->ShortenTo(position);
757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (operand->IsUnallocated()) {
760958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto unalloc_operand = UnallocatedOperand::cast(operand);
761958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    range->AddUsePosition(position, unalloc_operand, hint, local_zone());
762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::Use(LifetimePosition block_start,
767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            LifetimePosition position,
768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            InstructionOperand* operand,
769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                            InstructionOperand* hint) {
770958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto range = LiveRangeFor(operand);
771958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (range == nullptr) return;
772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (operand->IsUnallocated()) {
773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UnallocatedOperand* unalloc_operand = UnallocatedOperand::cast(operand);
774958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    range->AddUsePosition(position, unalloc_operand, hint, local_zone());
775958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
776958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  range->AddUseInterval(block_start, position, local_zone());
777958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
778958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
779958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
780958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid RegisterAllocator::AddGapMove(int index,
781958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                   GapInstruction::InnerPosition position,
782958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                   InstructionOperand* from,
783958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                   InstructionOperand* to) {
784958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto gap = code()->GapAt(index);
785958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto move = gap->GetOrCreateParallelMove(position, code_zone());
786958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  move->AddMove(from, to, code_zone());
787958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
788958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
789958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
790958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic bool AreUseIntervalsIntersecting(UseInterval* interval1,
791958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                        UseInterval* interval2) {
792958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  while (interval1 != nullptr && interval2 != nullptr) {
793958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (interval1->start().Value() < interval2->start().Value()) {
794958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (interval1->end().Value() > interval2->start().Value()) {
795958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        return true;
796958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
797958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      interval1 = interval1->next();
798958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {
799958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (interval2->end().Value() > interval1->start().Value()) {
800958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        return true;
801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
802958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      interval2 = interval2->next();
803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
805958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return false;
806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
809958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierSpillRange::SpillRange(LiveRange* range, Zone* zone) : live_ranges_(zone) {
810958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto src = range->first_interval();
811958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  UseInterval* result = nullptr;
812958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  UseInterval* node = nullptr;
813958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Copy the nodes
814958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  while (src != nullptr) {
815958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto new_node = new (zone) UseInterval(src->start(), src->end());
816958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (result == nullptr) {
817958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      result = new_node;
818958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {
819958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      node->set_next(new_node);
820958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
821958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    node = new_node;
822958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    src = src->next();
823958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
824958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  use_interval_ = result;
825958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  live_ranges().push_back(range);
826958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  end_position_ = node->end();
827958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(!range->HasSpillRange());
828958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  range->SetSpillRange(this);
829958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
830958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
831958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
832958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool SpillRange::IsIntersectingWith(SpillRange* other) const {
833958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (this->use_interval_ == nullptr || other->use_interval_ == nullptr ||
834958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      this->End().Value() <= other->use_interval_->start().Value() ||
835958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      other->End().Value() <= this->use_interval_->start().Value()) {
836958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return false;
837958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
838958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return AreUseIntervalsIntersecting(use_interval_, other->use_interval_);
839958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
840958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
841958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
842958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool SpillRange::TryMerge(SpillRange* other) {
843958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (Kind() != other->Kind() || IsIntersectingWith(other)) return false;
844958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
845958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto max = LifetimePosition::MaxPosition();
846958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (End().Value() < other->End().Value() &&
847958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      other->End().Value() != max.Value()) {
848958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    end_position_ = other->End();
849958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
850958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  other->end_position_ = max;
851958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
852958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MergeDisjointIntervals(other->use_interval_);
853958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  other->use_interval_ = nullptr;
854958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
855958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (auto range : other->live_ranges()) {
856958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(range->GetSpillRange() == other);
857958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    range->SetSpillRange(this);
858958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
859958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
860958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  live_ranges().insert(live_ranges().end(), other->live_ranges().begin(),
861958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                       other->live_ranges().end());
862958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  other->live_ranges().clear();
863958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
864958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return true;
865958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
866958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
867958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
868958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid SpillRange::SetOperand(InstructionOperand* op) {
869958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (auto range : live_ranges()) {
870958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(range->GetSpillRange() == this);
871958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    range->CommitSpillOperand(op);
872958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
873958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
874958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
875958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
876958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid SpillRange::MergeDisjointIntervals(UseInterval* other) {
877958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  UseInterval* tail = nullptr;
878958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto current = use_interval_;
879958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  while (other != nullptr) {
880958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // Make sure the 'current' list starts first
881958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (current == nullptr ||
882958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        current->start().Value() > other->start().Value()) {
883958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      std::swap(current, other);
884958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
885958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // Check disjointness
886958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(other == nullptr ||
887958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier           current->end().Value() <= other->start().Value());
888958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // Append the 'current' node to the result accumulator and move forward
889958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (tail == nullptr) {
890958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      use_interval_ = current;
891958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {
892958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      tail->set_next(current);
893958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
894958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    tail = current;
895958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    current = current->next();
896958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
897958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Other list is empty => we are done
898958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
899958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
900958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
901958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid RegisterAllocator::ReuseSpillSlots() {
902958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(FLAG_turbo_reuse_spill_slots);
903958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
904958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Merge disjoint spill ranges
905958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (size_t i = 0; i < spill_ranges().size(); i++) {
906958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto range = spill_ranges()[i];
907958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (range->IsEmpty()) continue;
908958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (size_t j = i + 1; j < spill_ranges().size(); j++) {
909958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto other = spill_ranges()[j];
910958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (!other->IsEmpty()) {
911958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        range->TryMerge(other);
912958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
913958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
914958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
915958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
916958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Allocate slots for the merged spill ranges.
917958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (auto range : spill_ranges()) {
918958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (range->IsEmpty()) continue;
919958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // Allocate a new operand referring to the spill slot.
920958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto kind = range->Kind();
921958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    int index = frame()->AllocateSpillSlot(kind == DOUBLE_REGISTERS);
922958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto op_kind = kind == DOUBLE_REGISTERS
923958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                       ? InstructionOperand::DOUBLE_STACK_SLOT
924958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                       : InstructionOperand::STACK_SLOT;
925958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto op = new (code_zone()) InstructionOperand(op_kind, index);
926958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    range->SetOperand(op);
927958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
928958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
929958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
930958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
931958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid RegisterAllocator::CommitAssignment() {
932958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (auto range : live_ranges()) {
933958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (range == nullptr || range->IsEmpty()) continue;
934958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // Register assignments were committed in set_assigned_register.
935958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (range->HasRegisterAssigned()) continue;
936958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto assigned = range->CreateAssignedOperand(code_zone());
937958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    range->ConvertUsesToOperand(assigned);
938958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (range->IsSpilled()) {
939958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      range->CommitSpillsAtDefinition(code(), assigned);
940958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
941958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
942958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
943958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
944958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
945958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierSpillRange* RegisterAllocator::AssignSpillRangeToLiveRange(LiveRange* range) {
946958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(FLAG_turbo_reuse_spill_slots);
947958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto spill_range = new (local_zone()) SpillRange(range, local_zone());
948958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  spill_ranges().push_back(spill_range);
949958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return spill_range;
950958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
951958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
952958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
953958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool RegisterAllocator::TryReuseSpillForPhi(LiveRange* range) {
954958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(FLAG_turbo_reuse_spill_slots);
955958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (range->IsChild() || !range->is_phi()) return false;
956958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(range->HasNoSpillType());
957958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
958958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto lookup = phi_map_.find(range->id());
959958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(lookup != phi_map_.end());
960958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto phi = lookup->second.phi;
961958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto block = lookup->second.block;
962958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Count the number of spilled operands.
963958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  size_t spilled_count = 0;
964958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  LiveRange* first_op = nullptr;
965958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (size_t i = 0; i < phi->operands().size(); i++) {
966958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    int op = phi->operands()[i];
967958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    LiveRange* op_range = LiveRangeFor(op);
968958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (op_range->GetSpillRange() == nullptr) continue;
969958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto pred = code()->InstructionBlockAt(block->predecessors()[i]);
970958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto pred_end =
971958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        LifetimePosition::FromInstructionIndex(pred->last_instruction_index());
972958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    while (op_range != nullptr && !op_range->CanCover(pred_end)) {
973958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      op_range = op_range->next();
974958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
975958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (op_range != nullptr && op_range->IsSpilled()) {
976958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      spilled_count++;
977958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (first_op == nullptr) {
978958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        first_op = op_range->TopLevel();
979958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
980958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
981958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
982958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
983958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Only continue if more than half of the operands are spilled.
984958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (spilled_count * 2 <= phi->operands().size()) {
985958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return false;
986958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
987958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
988958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Try to merge the spilled operands and count the number of merged spilled
989958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // operands.
990958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(first_op != nullptr);
991958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto first_op_spill = first_op->GetSpillRange();
992958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  size_t num_merged = 1;
993958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (size_t i = 1; i < phi->operands().size(); i++) {
994958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    int op = phi->operands()[i];
995958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto op_range = LiveRangeFor(op);
996958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto op_spill = op_range->GetSpillRange();
997958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (op_spill != nullptr &&
998958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        (op_spill == first_op_spill || first_op_spill->TryMerge(op_spill))) {
999958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      num_merged++;
1000958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1001958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1002958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1003958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Only continue if enough operands could be merged to the
1004958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // same spill slot.
1005958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (num_merged * 2 <= phi->operands().size() ||
1006958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      AreUseIntervalsIntersecting(first_op_spill->interval(),
1007958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                  range->first_interval())) {
1008958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return false;
1009958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1010958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1011958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // If the range does not need register soon, spill it to the merged
1012958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // spill range.
1013958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto next_pos = range->Start();
1014958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (code()->IsGapAt(next_pos.InstructionIndex())) {
1015958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    next_pos = next_pos.NextInstruction();
1016958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1017958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto pos = range->NextUsePositionRegisterIsBeneficial(next_pos);
1018958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (pos == nullptr) {
1019958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto spill_range = AssignSpillRangeToLiveRange(range->TopLevel());
1020958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    CHECK(first_op_spill->TryMerge(spill_range));
1021958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    Spill(range);
1022958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return true;
1023958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } else if (pos->pos().Value() > range->Start().NextInstruction().Value()) {
1024958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto spill_range = AssignSpillRangeToLiveRange(range->TopLevel());
1025958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    CHECK(first_op_spill->TryMerge(spill_range));
1026958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    SpillBetween(range, range->Start(), pos->pos());
1027958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (!AllocationOk()) return false;
1028958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(UnhandledIsSorted());
1029958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return true;
1030958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1031958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return false;
1032958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1033958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1034958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1035958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid RegisterAllocator::MeetRegisterConstraints(const InstructionBlock* block) {
1036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int start = block->first_instruction_index();
1037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int end = block->last_instruction_index();
1038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK_NE(-1, start);
1039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = start; i <= end; ++i) {
1040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (code()->IsGapAt(i)) {
1041958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      Instruction* instr = nullptr;
1042958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      Instruction* prev_instr = nullptr;
1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (i < end) instr = InstructionAt(i + 1);
1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (i > start) prev_instr = InstructionAt(i - 1);
1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      MeetConstraintsBetween(prev_instr, instr, i);
1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!AllocationOk()) return;
1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Meet register constraints for the instruction in the end.
1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!code()->IsGapAt(end)) {
1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    MeetRegisterConstraintsForLastInstructionInBlock(block);
1053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::MeetRegisterConstraintsForLastInstructionInBlock(
1058958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    const InstructionBlock* block) {
1059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int end = block->last_instruction_index();
1060958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto last_instruction = InstructionAt(end);
1061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (size_t i = 0; i < last_instruction->OutputCount(); i++) {
1062958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto output_operand = last_instruction->OutputAt(i);
1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!output_operand->IsConstant());
1064958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto output = UnallocatedOperand::cast(output_operand);
1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int output_vreg = output->virtual_register();
1066958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto range = LiveRangeFor(output_vreg);
1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool assigned = false;
1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (output->HasFixedPolicy()) {
1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      AllocateFixed(output, -1, false);
1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // This value is produced on the stack, we never need to spill it.
1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (output->IsStackSlot()) {
1072958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        DCHECK(output->index() < 0);
1073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        range->SetSpillOperand(output);
1074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        range->SetSpillStartIndex(end);
1075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        assigned = true;
1076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1078958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      for (auto succ : block->successors()) {
1079958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        const InstructionBlock* successor = code()->InstructionBlockAt(succ);
1080958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        DCHECK(successor->PredecessorCount() == 1);
1081958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        int gap_index = successor->first_instruction_index() + 1;
1082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        DCHECK(code()->IsGapAt(gap_index));
1083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Create an unconstrained operand for the same virtual register
1085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // and insert a gap move from the fixed output to the operand.
1086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        UnallocatedOperand* output_copy =
1087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            new (code_zone()) UnallocatedOperand(UnallocatedOperand::ANY);
1088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        output_copy->set_virtual_register(output_vreg);
1089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1090958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        AddGapMove(gap_index, GapInstruction::START, output, output_copy);
1091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!assigned) {
1095958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      for (auto succ : block->successors()) {
1096958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        const InstructionBlock* successor = code()->InstructionBlockAt(succ);
1097958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        DCHECK(successor->PredecessorCount() == 1);
1098958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        int gap_index = successor->first_instruction_index() + 1;
1099958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        range->SpillAtDefinition(local_zone(), gap_index, output);
1100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        range->SetSpillStartIndex(gap_index);
1101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::MeetConstraintsBetween(Instruction* first,
1108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                               Instruction* second,
1109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                               int gap_index) {
1110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (first != nullptr) {
1111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Handle fixed temporaries.
1112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (size_t i = 0; i < first->TempCount(); i++) {
1113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto temp = UnallocatedOperand::cast(first->TempAt(i));
1114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (temp->HasFixedPolicy()) {
1115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        AllocateFixed(temp, gap_index - 1, false);
1116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Handle constant/fixed output operands.
1120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (size_t i = 0; i < first->OutputCount(); i++) {
1121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      InstructionOperand* output = first->OutputAt(i);
1122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (output->IsConstant()) {
1123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        int output_vreg = output->index();
1124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        auto range = LiveRangeFor(output_vreg);
1125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        range->SetSpillStartIndex(gap_index - 1);
1126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        range->SetSpillOperand(output);
1127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
1128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        auto first_output = UnallocatedOperand::cast(output);
1129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        auto range = LiveRangeFor(first_output->virtual_register());
1130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        bool assigned = false;
1131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (first_output->HasFixedPolicy()) {
1132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          auto output_copy = first_output->CopyUnconstrained(code_zone());
1133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          bool is_tagged = HasTaggedValue(first_output->virtual_register());
1134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          AllocateFixed(first_output, gap_index, is_tagged);
1135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // This value is produced on the stack, we never need to spill it.
1137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          if (first_output->IsStackSlot()) {
1138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            DCHECK(first_output->index() < 0);
1139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            range->SetSpillOperand(first_output);
1140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            range->SetSpillStartIndex(gap_index - 1);
1141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            assigned = true;
1142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          }
1143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          AddGapMove(gap_index, GapInstruction::START, first_output,
1144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                     output_copy);
1145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
1146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Make sure we add a gap move for spilling (if we have not done
1148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // so already).
1149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (!assigned) {
1150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          range->SpillAtDefinition(local_zone(), gap_index, first_output);
1151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          range->SetSpillStartIndex(gap_index);
1152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
1153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1157958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (second != nullptr) {
1158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Handle fixed input operands of second instruction.
1159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (size_t i = 0; i < second->InputCount(); i++) {
1160958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto input = second->InputAt(i);
1161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (input->IsImmediate()) continue;  // Ignore immediates.
1162958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto cur_input = UnallocatedOperand::cast(input);
1163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (cur_input->HasFixedPolicy()) {
1164958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        auto input_copy = cur_input->CopyUnconstrained(code_zone());
1165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        bool is_tagged = HasTaggedValue(cur_input->virtual_register());
1166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        AllocateFixed(cur_input, gap_index + 1, is_tagged);
1167958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        AddGapMove(gap_index, GapInstruction::END, input_copy, cur_input);
1168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Handle "output same as input" for second instruction.
1172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (size_t i = 0; i < second->OutputCount(); i++) {
1173958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto output = second->OutputAt(i);
1174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!output->IsUnallocated()) continue;
1175958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto second_output = UnallocatedOperand::cast(output);
1176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (second_output->HasSameAsInputPolicy()) {
1177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        DCHECK(i == 0);  // Only valid for first output.
1178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        UnallocatedOperand* cur_input =
1179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            UnallocatedOperand::cast(second->InputAt(0));
1180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        int output_vreg = second_output->virtual_register();
1181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        int input_vreg = cur_input->virtual_register();
1182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1183958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        auto input_copy = cur_input->CopyUnconstrained(code_zone());
1184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        cur_input->set_virtual_register(second_output->virtual_register());
1185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        AddGapMove(gap_index, GapInstruction::END, input_copy, cur_input);
1186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (HasTaggedValue(input_vreg) && !HasTaggedValue(output_vreg)) {
1188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          int index = gap_index + 1;
1189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          Instruction* instr = InstructionAt(index);
1190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          if (instr->HasPointerMap()) {
1191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            instr->pointer_map()->RecordPointer(input_copy, code_zone());
1192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          }
1193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        } else if (!HasTaggedValue(input_vreg) && HasTaggedValue(output_vreg)) {
1194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // The input is assumed to immediately have a tagged representation,
1195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // before the pointer map can be used. I.e. the pointer map at the
1196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // instruction will include the output operand (whose value at the
1197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // beginning of the instruction is equal to the input operand). If
1198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // this is not desired, then the pointer map at this instruction needs
1199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          // to be adjusted manually.
1200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
1201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool RegisterAllocator::IsOutputRegisterOf(Instruction* instr, int index) {
1208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (size_t i = 0; i < instr->OutputCount(); i++) {
1209958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto output = instr->OutputAt(i);
1210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (output->IsRegister() && output->index() == index) return true;
1211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return false;
1213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool RegisterAllocator::IsOutputDoubleRegisterOf(Instruction* instr,
1217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                 int index) {
1218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (size_t i = 0; i < instr->OutputCount(); i++) {
1219958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto output = instr->OutputAt(i);
1220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (output->IsDoubleRegister() && output->index() == index) return true;
1221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return false;
1223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1226958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid RegisterAllocator::ProcessInstructions(const InstructionBlock* block,
1227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                            BitVector* live) {
1228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int block_start = block->first_instruction_index();
1229958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto block_start_position =
1230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      LifetimePosition::FromInstructionIndex(block_start);
1231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int index = block->last_instruction_index(); index >= block_start;
1233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       index--) {
1234958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto curr_position = LifetimePosition::FromInstructionIndex(index);
1235958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto instr = InstructionAt(index);
1236958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(instr != nullptr);
1237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (instr->IsGapMoves()) {
1238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Process the moves of the gap instruction, making their sources live.
1239958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto gap = code()->GapAt(index);
1240958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      const GapInstruction::InnerPosition kPositions[] = {
1241958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          GapInstruction::END, GapInstruction::START};
1242958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      for (auto position : kPositions) {
1243958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        auto move = gap->GetParallelMove(position);
1244958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        if (move == nullptr) continue;
1245958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        if (position == GapInstruction::END) {
1246958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          curr_position = curr_position.InstructionEnd();
1247958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        } else {
1248958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          curr_position = curr_position.InstructionStart();
1249958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        }
1250958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        auto move_ops = move->move_operands();
1251958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        for (auto cur = move_ops->begin(); cur != move_ops->end(); ++cur) {
1252958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          auto from = cur->source();
1253958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          auto to = cur->destination();
1254958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          auto hint = to;
1255958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          if (to->IsUnallocated()) {
1256958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            int to_vreg = UnallocatedOperand::cast(to)->virtual_register();
1257958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            auto to_range = LiveRangeFor(to_vreg);
1258958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            if (to_range->is_phi()) {
1259958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier              DCHECK(!FLAG_turbo_delay_ssa_decon);
1260958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier              if (to_range->is_non_loop_phi()) {
1261958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                hint = to_range->current_hint_operand();
1262958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier              }
1263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            } else {
1264958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier              if (live->Contains(to_vreg)) {
1265958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                Define(curr_position, to, from);
1266958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                live->Remove(to_vreg);
1267958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier              } else {
1268958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                cur->Eliminate();
1269958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                continue;
1270958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier              }
1271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            }
1272958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          } else {
1273958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            Define(curr_position, to, from);
1274958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          }
1275958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          Use(block_start_position, curr_position, from, hint);
1276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          if (from->IsUnallocated()) {
1277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            live->Add(UnallocatedOperand::cast(from)->virtual_register());
1278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          }
1279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
1280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
1282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Process output, inputs, and temps of this non-gap instruction.
1283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (size_t i = 0; i < instr->OutputCount(); i++) {
1284958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        auto output = instr->OutputAt(i);
1285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (output->IsUnallocated()) {
1286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          int out_vreg = UnallocatedOperand::cast(output)->virtual_register();
1287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          live->Remove(out_vreg);
1288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        } else if (output->IsConstant()) {
1289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          int out_vreg = output->index();
1290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          live->Remove(out_vreg);
1291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
1292958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        Define(curr_position, output, nullptr);
1293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (instr->ClobbersRegisters()) {
1296958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        for (int i = 0; i < config()->num_general_registers(); ++i) {
1297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          if (!IsOutputRegisterOf(instr, i)) {
1298958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            auto range = FixedLiveRangeFor(i);
1299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            range->AddUseInterval(curr_position, curr_position.InstructionEnd(),
1300958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                  local_zone());
1301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          }
1302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
1303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (instr->ClobbersDoubleRegisters()) {
1306958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        for (int i = 0; i < config()->num_aliased_double_registers(); ++i) {
1307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          if (!IsOutputDoubleRegisterOf(instr, i)) {
1308958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            auto range = FixedDoubleLiveRangeFor(i);
1309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            range->AddUseInterval(curr_position, curr_position.InstructionEnd(),
1310958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                  local_zone());
1311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          }
1312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
1313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (size_t i = 0; i < instr->InputCount(); i++) {
1316958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        auto input = instr->InputAt(i);
1317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (input->IsImmediate()) continue;  // Ignore immediates.
1318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        LifetimePosition use_pos;
1319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (input->IsUnallocated() &&
1320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            UnallocatedOperand::cast(input)->IsUsedAtStart()) {
1321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          use_pos = curr_position;
1322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        } else {
1323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          use_pos = curr_position.InstructionEnd();
1324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
1325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1326958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        Use(block_start_position, use_pos, input, nullptr);
1327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (input->IsUnallocated()) {
1328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          live->Add(UnallocatedOperand::cast(input)->virtual_register());
1329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
1330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      for (size_t i = 0; i < instr->TempCount(); i++) {
1333958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        auto temp = instr->TempAt(i);
1334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (instr->ClobbersTemps()) {
1335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          if (temp->IsRegister()) continue;
1336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          if (temp->IsUnallocated()) {
1337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            UnallocatedOperand* temp_unalloc = UnallocatedOperand::cast(temp);
1338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            if (temp_unalloc->HasFixedPolicy()) {
1339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch              continue;
1340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            }
1341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          }
1342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
1343958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        Use(block_start_position, curr_position.InstructionEnd(), temp,
1344958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            nullptr);
1345958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        Define(curr_position, temp, nullptr);
1346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1352958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid RegisterAllocator::ResolvePhis(const InstructionBlock* block) {
1353958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (auto phi : block->phis()) {
1354958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (FLAG_turbo_reuse_spill_slots) {
1355958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto res = phi_map_.insert(
1356958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          std::make_pair(phi->virtual_register(), PhiMapValue(phi, block)));
1357958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      DCHECK(res.second);
1358958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      USE(res);
1359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1360958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto output = phi->output();
1361958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    int phi_vreg = phi->virtual_register();
1362958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (!FLAG_turbo_delay_ssa_decon) {
1363958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      for (size_t i = 0; i < phi->operands().size(); ++i) {
1364958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        InstructionBlock* cur_block =
1365958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            code()->InstructionBlockAt(block->predecessors()[i]);
1366958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        AddGapMove(cur_block->last_instruction_index() - 1, GapInstruction::END,
1367958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                   phi->inputs()[i], output);
1368958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        DCHECK(!InstructionAt(cur_block->last_instruction_index())
1369958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                    ->HasPointerMap());
1370958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
1371958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1372958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto live_range = LiveRangeFor(phi_vreg);
1373958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    int gap_index = block->first_instruction_index();
1374958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    live_range->SpillAtDefinition(local_zone(), gap_index, output);
1375958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    live_range->SetSpillStartIndex(gap_index);
1376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // We use the phi-ness of some nodes in some later heuristics.
1377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    live_range->set_is_phi(true);
1378958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    live_range->set_is_non_loop_phi(!block->IsLoopHeader());
1379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::MeetRegisterConstraints() {
1384958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (auto block : code()->instruction_blocks()) {
1385958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    MeetRegisterConstraints(block);
1386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::ResolvePhis() {
1391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Process the blocks in reverse order.
1392958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (auto i = code()->instruction_blocks().rbegin();
1393958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier       i != code()->instruction_blocks().rend(); ++i) {
1394958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    ResolvePhis(*i);
1395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochParallelMove* RegisterAllocator::GetConnectingParallelMove(
1400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LifetimePosition pos) {
1401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int index = pos.InstructionIndex();
1402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (code()->IsGapAt(index)) {
1403958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto gap = code()->GapAt(index);
1404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return gap->GetOrCreateParallelMove(
1405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        pos.IsInstructionStart() ? GapInstruction::START : GapInstruction::END,
1406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        code_zone());
1407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int gap_pos = pos.IsInstructionStart() ? (index - 1) : (index + 1);
1409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return code()->GapAt(gap_pos)->GetOrCreateParallelMove(
1410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (gap_pos < index) ? GapInstruction::AFTER : GapInstruction::BEFORE,
1411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      code_zone());
1412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1415958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierconst InstructionBlock* RegisterAllocator::GetInstructionBlock(
1416958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    LifetimePosition pos) {
1417958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return code()->GetInstructionBlock(pos.InstructionIndex());
1418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::ConnectRanges() {
1422958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (auto first_range : live_ranges()) {
1423958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (first_range == nullptr || first_range->IsChild()) continue;
1424958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto second_range = first_range->next();
1425958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    while (second_range != nullptr) {
1426958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto pos = second_range->Start();
1427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!second_range->IsSpilled()) {
1428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Add gap move if the two live ranges touch and there is no block
1429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // boundary.
1430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (first_range->End().Value() == pos.Value()) {
1431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          bool should_insert = true;
1432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          if (IsBlockBoundary(pos)) {
1433958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            should_insert =
1434958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                CanEagerlyResolveControlFlow(GetInstructionBlock(pos));
1435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          }
1436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          if (should_insert) {
1437958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            auto move = GetConnectingParallelMove(pos);
1438958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            auto prev_operand = first_range->CreateAssignedOperand(code_zone());
1439958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            auto cur_operand = second_range->CreateAssignedOperand(code_zone());
1440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            move->AddMove(prev_operand, cur_operand, code_zone());
1441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          }
1442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
1443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      first_range = second_range;
1445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      second_range = second_range->next();
1446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1451958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool RegisterAllocator::CanEagerlyResolveControlFlow(
1452958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    const InstructionBlock* block) const {
1453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (block->PredecessorCount() != 1) return false;
1454958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return block->predecessors()[0].IsNext(block->rpo_number());
1455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1458958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace {
1459958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1460958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass LiveRangeBound {
1461958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public:
1462958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  explicit LiveRangeBound(const LiveRange* range)
1463958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      : range_(range), start_(range->Start()), end_(range->End()) {
1464958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(!range->IsEmpty());
1465958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1466958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1467958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool CanCover(LifetimePosition position) {
1468958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return start_.Value() <= position.Value() &&
1469958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier           position.Value() < end_.Value();
1470958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1471958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1472958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const LiveRange* const range_;
1473958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const LifetimePosition start_;
1474958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const LifetimePosition end_;
1475958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1476958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private:
1477958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DISALLOW_COPY_AND_ASSIGN(LiveRangeBound);
1478958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier};
1479958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1480958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1481958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstruct FindResult {
1482958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const LiveRange* cur_cover_;
1483958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const LiveRange* pred_cover_;
1484958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier};
1485958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1486958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1487958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass LiveRangeBoundArray {
1488958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public:
1489958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  LiveRangeBoundArray() : length_(0), start_(nullptr) {}
1490958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1491958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool ShouldInitialize() { return start_ == nullptr; }
1492958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1493958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void Initialize(Zone* zone, const LiveRange* const range) {
1494958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    size_t length = 0;
1495958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (auto i = range; i != nullptr; i = i->next()) length++;
1496958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    start_ = zone->NewArray<LiveRangeBound>(static_cast<int>(length));
1497958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    length_ = length;
1498958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto curr = start_;
1499958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (auto i = range; i != nullptr; i = i->next(), ++curr) {
1500958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      new (curr) LiveRangeBound(i);
1501958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1502958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1503958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1504958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  LiveRangeBound* Find(const LifetimePosition position) const {
1505958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    size_t left_index = 0;
1506958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    size_t right_index = length_;
1507958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    while (true) {
1508958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      size_t current_index = left_index + (right_index - left_index) / 2;
1509958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      DCHECK(right_index > current_index);
1510958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto bound = &start_[current_index];
1511958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (bound->start_.Value() <= position.Value()) {
1512958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        if (position.Value() < bound->end_.Value()) return bound;
1513958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        DCHECK(left_index < current_index);
1514958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        left_index = current_index;
1515958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      } else {
1516958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        right_index = current_index;
1517958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
1518958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1519958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1520958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1521958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  LiveRangeBound* FindPred(const InstructionBlock* pred) {
1522958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto pred_end =
1523958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        LifetimePosition::FromInstructionIndex(pred->last_instruction_index());
1524958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return Find(pred_end);
1525958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1526958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1527958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  LiveRangeBound* FindSucc(const InstructionBlock* succ) {
1528958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto succ_start =
1529958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        LifetimePosition::FromInstructionIndex(succ->first_instruction_index());
1530958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return Find(succ_start);
1531958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1532958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1533958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  void Find(const InstructionBlock* block, const InstructionBlock* pred,
1534958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            FindResult* result) const {
1535958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto pred_end =
1536958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        LifetimePosition::FromInstructionIndex(pred->last_instruction_index());
1537958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto bound = Find(pred_end);
1538958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    result->pred_cover_ = bound->range_;
1539958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto cur_start = LifetimePosition::FromInstructionIndex(
1540958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        block->first_instruction_index());
1541958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // Common case.
1542958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (bound->CanCover(cur_start)) {
1543958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      result->cur_cover_ = bound->range_;
1544958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      return;
1545958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1546958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    result->cur_cover_ = Find(cur_start)->range_;
1547958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(result->pred_cover_ != nullptr && result->cur_cover_ != nullptr);
1548958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1549958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1550958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private:
1551958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  size_t length_;
1552958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  LiveRangeBound* start_;
1553958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1554958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DISALLOW_COPY_AND_ASSIGN(LiveRangeBoundArray);
1555958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier};
1556958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1557958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1558958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass LiveRangeFinder {
1559958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public:
1560958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  explicit LiveRangeFinder(const RegisterAllocator& allocator)
1561958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      : allocator_(allocator),
1562958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        bounds_length_(static_cast<int>(allocator.live_ranges().size())),
1563958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        bounds_(allocator.local_zone()->NewArray<LiveRangeBoundArray>(
1564958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            bounds_length_)) {
1565958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (int i = 0; i < bounds_length_; ++i) {
1566958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      new (&bounds_[i]) LiveRangeBoundArray();
1567958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1568958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1569958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1570958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  LiveRangeBoundArray* ArrayFor(int operand_index) {
1571958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(operand_index < bounds_length_);
1572958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto range = allocator_.live_ranges()[operand_index];
1573958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(range != nullptr && !range->IsEmpty());
1574958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto array = &bounds_[operand_index];
1575958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (array->ShouldInitialize()) {
1576958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      array->Initialize(allocator_.local_zone(), range);
1577958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1578958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return array;
1579958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1580958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1581958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private:
1582958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const RegisterAllocator& allocator_;
1583958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  const int bounds_length_;
1584958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  LiveRangeBoundArray* const bounds_;
1585958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1586958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DISALLOW_COPY_AND_ASSIGN(LiveRangeFinder);
1587958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier};
1588958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1589958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}  // namespace
1590958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1591958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::ResolveControlFlow() {
1593958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Lazily linearize live ranges in memory for fast lookup.
1594958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  LiveRangeFinder finder(*this);
1595958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (auto block : code()->instruction_blocks()) {
1596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (CanEagerlyResolveControlFlow(block)) continue;
1597958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (FLAG_turbo_delay_ssa_decon) {
1598958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      // resolve phis
1599958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      for (auto phi : block->phis()) {
1600958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        auto* block_bound =
1601958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            finder.ArrayFor(phi->virtual_register())->FindSucc(block);
1602958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        auto phi_output =
1603958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            block_bound->range_->CreateAssignedOperand(code_zone());
1604958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        phi->output()->ConvertTo(phi_output->kind(), phi_output->index());
1605958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        size_t pred_index = 0;
1606958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        for (auto pred : block->predecessors()) {
1607958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          const InstructionBlock* pred_block = code()->InstructionBlockAt(pred);
1608958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          auto* pred_bound = finder.ArrayFor(phi->operands()[pred_index])
1609958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                 ->FindPred(pred_block);
1610958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          auto pred_op = pred_bound->range_->CreateAssignedOperand(code_zone());
1611958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          phi->inputs()[pred_index] = pred_op;
1612958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          ResolveControlFlow(block, phi_output, pred_block, pred_op);
1613958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          pred_index++;
1614958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        }
1615958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
1616958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1617958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto live = live_in_sets_[block->rpo_number().ToInt()];
1618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    BitVector::Iterator iterator(live);
1619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    while (!iterator.Done()) {
1620958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto* array = finder.ArrayFor(iterator.Current());
1621958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      for (auto pred : block->predecessors()) {
1622958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        FindResult result;
1623958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        const auto* pred_block = code()->InstructionBlockAt(pred);
1624958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        array->Find(block, pred_block, &result);
1625958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        if (result.cur_cover_ == result.pred_cover_ ||
1626958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            result.cur_cover_->IsSpilled())
1627958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          continue;
1628958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        auto pred_op = result.pred_cover_->CreateAssignedOperand(code_zone());
1629958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        auto cur_op = result.cur_cover_->CreateAssignedOperand(code_zone());
1630958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        ResolveControlFlow(block, cur_op, pred_block, pred_op);
1631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      iterator.Advance();
1633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1638958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid RegisterAllocator::ResolveControlFlow(const InstructionBlock* block,
1639958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                           InstructionOperand* cur_op,
1640958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                           const InstructionBlock* pred,
1641958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                           InstructionOperand* pred_op) {
1642958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (pred_op->Equals(cur_op)) return;
1643958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  int gap_index;
1644958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  GapInstruction::InnerPosition position;
1645958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (block->PredecessorCount() == 1) {
1646958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    gap_index = block->first_instruction_index();
1647958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    position = GapInstruction::START;
1648958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  } else {
1649958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(pred->SuccessorCount() == 1);
1650958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(!InstructionAt(pred->last_instruction_index())->HasPointerMap());
1651958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    gap_index = pred->last_instruction_index() - 1;
1652958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    position = GapInstruction::END;
1653958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1654958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  AddGapMove(gap_index, position, pred_op, cur_op);
1655958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1656958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1657958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::BuildLiveRanges() {
1659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Process the blocks in reverse order.
1660958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (int block_id = code()->InstructionBlockCount() - 1; block_id >= 0;
1661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       --block_id) {
1662958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto block =
1663958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        code()->InstructionBlockAt(BasicBlock::RpoNumber::FromInt(block_id));
1664958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto live = ComputeLiveOut(block);
1665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Initially consider all live_out values live for the entire block. We
1666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // will shorten these intervals if necessary.
1667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AddInitialIntervals(block, live);
1668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Process the instructions in reverse order, generating and killing
1670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // live values.
1671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ProcessInstructions(block, live);
1672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // All phi output operands are killed by this block.
1673958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (auto phi : block->phis()) {
1674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // The live range interval already ends at the first instruction of the
1675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // block.
1676958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      int phi_vreg = phi->virtual_register();
1677958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      live->Remove(phi_vreg);
1678958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (!FLAG_turbo_delay_ssa_decon) {
1679958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        InstructionOperand* hint = nullptr;
1680958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        InstructionOperand* phi_operand = nullptr;
1681958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        auto gap =
1682958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            GetLastGap(code()->InstructionBlockAt(block->predecessors()[0]));
1683958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        auto move =
1684958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            gap->GetOrCreateParallelMove(GapInstruction::END, code_zone());
1685958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        for (int j = 0; j < move->move_operands()->length(); ++j) {
1686958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          auto to = move->move_operands()->at(j).destination();
1687958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          if (to->IsUnallocated() &&
1688958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier              UnallocatedOperand::cast(to)->virtual_register() == phi_vreg) {
1689958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            hint = move->move_operands()->at(j).source();
1690958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            phi_operand = to;
1691958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            break;
1692958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          }
1693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
1694958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        DCHECK(hint != nullptr);
1695958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        auto block_start = LifetimePosition::FromInstructionIndex(
1696958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            block->first_instruction_index());
1697958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        Define(block_start, phi_operand, hint);
1698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Now live is live_in for this block except not including values live
1702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // out on backward successor edges.
1703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    live_in_sets_[block_id] = live;
1704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (block->IsLoopHeader()) {
1706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Add a live range stretching from the first loop instruction to the last
1707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // for each value live on entry to the header.
1708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      BitVector::Iterator iterator(live);
1709958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto start = LifetimePosition::FromInstructionIndex(
1710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          block->first_instruction_index());
1711958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto end = LifetimePosition::FromInstructionIndex(
1712958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                     code()->LastLoopInstructionIndex(block)).NextInstruction();
1713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      while (!iterator.Done()) {
1714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        int operand_index = iterator.Current();
1715958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        auto range = LiveRangeFor(operand_index);
1716958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        range->EnsureInterval(start, end, local_zone());
1717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        iterator.Advance();
1718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Insert all values into the live in sets of all blocks in the loop.
1720958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      for (int i = block->rpo_number().ToInt() + 1;
1721958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier           i < block->loop_end().ToInt(); ++i) {
1722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        live_in_sets_[i]->Union(*live);
1723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1725958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1727958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (auto range : live_ranges()) {
1728958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (range == nullptr) continue;
1729958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    range->kind_ = RequiredRegisterKind(range->id());
1730958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // TODO(bmeurer): This is a horrible hack to make sure that for constant
1731958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // live ranges, every use requires the constant to be in a register.
1732958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // Without this hack, all uses with "any" policy would get the constant
1733958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // operand assigned.
1734958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (range->HasSpillOperand() && range->GetSpillOperand()->IsConstant()) {
1735958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      for (auto pos = range->first_pos(); pos != nullptr; pos = pos->next_) {
1736958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        pos->register_beneficial_ = true;
1737958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        // TODO(dcarney): should the else case assert requires_reg_ == false?
1738958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        // Can't mark phis as needing a register.
1739958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        if (!code()
1740958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                 ->InstructionAt(pos->pos().InstructionIndex())
1741958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                 ->IsGapMoves()) {
1742958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier          pos->requires_reg_ = true;
1743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
1744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1747958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1749958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1750958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool RegisterAllocator::ExistsUseWithoutDefinition() {
1751958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  bool found = false;
1752958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  BitVector::Iterator iterator(live_in_sets_[0]);
1753958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  while (!iterator.Done()) {
1754958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    found = true;
1755958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    int operand_index = iterator.Current();
1756958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    PrintF("Register allocator error: live v%d reached first block.\n",
1757958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier           operand_index);
1758958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    LiveRange* range = LiveRangeFor(operand_index);
1759958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    PrintF("  (first use is at %d)\n", range->first_pos()->pos().Value());
1760958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (debug_name() == nullptr) {
1761958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      PrintF("\n");
1762958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {
1763958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      PrintF("  (function: %s)\n", debug_name());
1764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1765958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    iterator.Advance();
1766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1767958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return found;
1768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool RegisterAllocator::SafePointsAreInOrder() const {
1772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int safe_point = 0;
1773958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (auto map : *code()->pointer_maps()) {
1774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (safe_point > map->instruction_position()) return false;
1775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    safe_point = map->instruction_position();
1776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return true;
1778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::PopulatePointerMaps() {
1782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(SafePointsAreInOrder());
1783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Iterate over all safe point positions and record a pointer
1785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // for all spilled live ranges at this point.
1786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int last_range_start = 0;
1787958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto pointer_maps = code()->pointer_maps();
1788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  PointerMapDeque::const_iterator first_it = pointer_maps->begin();
1789958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (LiveRange* range : live_ranges()) {
1790958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (range == nullptr) continue;
1791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Iterate over the first parts of multi-part live ranges.
1792958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (range->IsChild()) continue;
1793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Skip non-reference values.
1794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!HasTaggedValue(range->id())) continue;
1795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Skip empty live ranges.
1796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (range->IsEmpty()) continue;
1797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Find the extent of the range and its children.
1799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int start = range->Start().InstructionIndex();
1800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int end = 0;
1801958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (auto cur = range; cur != nullptr; cur = cur->next()) {
1802958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto this_end = cur->End();
1803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (this_end.InstructionIndex() > end) end = this_end.InstructionIndex();
1804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      DCHECK(cur->Start().InstructionIndex() >= start);
1805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Most of the ranges are in order, but not all.  Keep an eye on when they
1808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // step backwards and reset the first_it so we don't miss any safe points.
1809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (start < last_range_start) first_it = pointer_maps->begin();
1810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    last_range_start = start;
1811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Step across all the safe points that are before the start of this range,
1813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // recording how far we step in order to save doing this for the next range.
1814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    for (; first_it != pointer_maps->end(); ++first_it) {
1815958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto map = *first_it;
1816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (map->instruction_position() >= start) break;
1817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Step through the safe points to see whether they are in the range.
1820958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (auto it = first_it; it != pointer_maps->end(); ++it) {
1821958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto map = *it;
1822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      int safe_point = map->instruction_position();
1823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // The safe points are sorted so we can stop searching here.
1825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (safe_point - 1 > end) break;
1826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Advance to the next active range that covers the current
1828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // safe point position.
1829958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto safe_point_pos = LifetimePosition::FromInstructionIndex(safe_point);
1830958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto cur = range;
1831958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      while (cur != nullptr && !cur->Covers(safe_point_pos)) {
1832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        cur = cur->next();
1833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1834958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (cur == nullptr) continue;
1835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // Check if the live range is spilled and the safe point is after
1837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // the spill position.
1838958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (range->HasSpillOperand() &&
1839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          safe_point >= range->spill_start_index() &&
1840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          !range->GetSpillOperand()->IsConstant()) {
1841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TraceAlloc("Pointer for range %d (spilled at %d) at safe point %d\n",
1842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                   range->id(), range->spill_start_index(), safe_point);
1843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        map->RecordPointer(range->GetSpillOperand(), code_zone());
1844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!cur->IsSpilled()) {
1847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        TraceAlloc(
1848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            "Pointer in register for range %d (start at %d) "
1849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            "at safe point %d\n",
1850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch            cur->id(), cur->Start().Value(), safe_point);
1851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        InstructionOperand* operand = cur->CreateAssignedOperand(code_zone());
1852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        DCHECK(!operand->IsStackSlot());
1853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        map->RecordPointer(operand, code_zone());
1854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::AllocateGeneralRegisters() {
1861958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  num_registers_ = config()->num_general_registers();
1862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  mode_ = GENERAL_REGISTERS;
1863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AllocateRegisters();
1864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::AllocateDoubleRegisters() {
1868958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  num_registers_ = config()->num_aliased_double_registers();
1869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  mode_ = DOUBLE_REGISTERS;
1870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  AllocateRegisters();
1871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::AllocateRegisters() {
1875958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(unhandled_live_ranges().empty());
1876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1877958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (auto range : live_ranges()) {
1878958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (range == nullptr) continue;
1879958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (range->Kind() == mode_) {
1880958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      AddToUnhandledUnsorted(range);
1881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SortUnhandled();
1884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(UnhandledIsSorted());
1885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1886958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(reusable_slots().empty());
1887958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(active_live_ranges().empty());
1888958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(inactive_live_ranges().empty());
1889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (mode_ == DOUBLE_REGISTERS) {
1891958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (int i = 0; i < config()->num_aliased_double_registers(); ++i) {
1892958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto current = fixed_double_live_ranges()[i];
1893958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (current != nullptr) {
1894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        AddToInactive(current);
1895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(mode_ == GENERAL_REGISTERS);
1899958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (auto current : fixed_live_ranges()) {
1900958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (current != nullptr) {
1901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        AddToInactive(current);
1902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1906958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  while (!unhandled_live_ranges().empty()) {
1907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(UnhandledIsSorted());
1908958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto current = unhandled_live_ranges().back();
1909958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    unhandled_live_ranges().pop_back();
1910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(UnhandledIsSorted());
1911958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto position = current->Start();
1912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
1913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    allocation_finger_ = position;
1914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
1915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    TraceAlloc("Processing interval %d start=%d\n", current->id(),
1916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch               position.Value());
1917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1918958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (!current->HasNoSpillType()) {
1919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TraceAlloc("Live range %d already has a spill operand\n", current->id());
1920958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto next_pos = position;
1921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (code()->IsGapAt(next_pos.InstructionIndex())) {
1922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        next_pos = next_pos.NextInstruction();
1923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1924958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto pos = current->NextUsePositionRegisterIsBeneficial(next_pos);
1925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // If the range already has a spill operand and it doesn't need a
1926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      // register immediately, split it and spill the first part of the range.
1927958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (pos == nullptr) {
1928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        Spill(current);
1929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        continue;
1930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else if (pos->pos().Value() >
1931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                 current->Start().NextInstruction().Value()) {
1932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // Do not spill live range eagerly if use position that can benefit from
1933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // the register is too close to the start of live range.
1934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        SpillBetween(current, current->Start(), pos->pos());
1935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (!AllocationOk()) return;
1936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        DCHECK(UnhandledIsSorted());
1937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        continue;
1938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1941958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (FLAG_turbo_reuse_spill_slots) {
1942958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (TryReuseSpillForPhi(current)) {
1943958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        continue;
1944958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
1945958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (!AllocationOk()) return;
1946958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1947958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1948958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (size_t i = 0; i < active_live_ranges().size(); ++i) {
1949958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto cur_active = active_live_ranges()[i];
1950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (cur_active->End().Value() <= position.Value()) {
1951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ActiveToHandled(cur_active);
1952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        --i;  // The live range was removed from the list of active live ranges.
1953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else if (!cur_active->Covers(position)) {
1954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ActiveToInactive(cur_active);
1955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        --i;  // The live range was removed from the list of active live ranges.
1956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1959958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (size_t i = 0; i < inactive_live_ranges().size(); ++i) {
1960958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto cur_inactive = inactive_live_ranges()[i];
1961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (cur_inactive->End().Value() <= position.Value()) {
1962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        InactiveToHandled(cur_inactive);
1963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        --i;  // Live range was removed from the list of inactive live ranges.
1964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else if (cur_inactive->Covers(position)) {
1965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        InactiveToActive(cur_inactive);
1966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        --i;  // Live range was removed from the list of inactive live ranges.
1967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!current->HasRegisterAssigned() && !current->IsSpilled());
1971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool result = TryAllocateFreeReg(current);
1973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!AllocationOk()) return;
1974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!result) AllocateBlockedReg(current);
1976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!AllocationOk()) return;
1977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (current->HasRegisterAssigned()) {
1979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      AddToActive(current);
1980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1983958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  reusable_slots().clear();
1984958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  active_live_ranges().clear();
1985958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  inactive_live_ranges().clear();
1986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst char* RegisterAllocator::RegisterName(int allocation_index) {
1990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (mode_ == GENERAL_REGISTERS) {
1991958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return config()->general_register_name(allocation_index);
1992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
1993958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return config()->double_register_name(allocation_index);
1994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool RegisterAllocator::HasTaggedValue(int virtual_register) const {
1999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return code()->IsReference(virtual_register);
2000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochRegisterKind RegisterAllocator::RequiredRegisterKind(
2004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int virtual_register) const {
2005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return (code()->IsDouble(virtual_register)) ? DOUBLE_REGISTERS
2006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                              : GENERAL_REGISTERS;
2007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::AddToActive(LiveRange* range) {
2011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TraceAlloc("Add live range %d to active\n", range->id());
2012958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  active_live_ranges().push_back(range);
2013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::AddToInactive(LiveRange* range) {
2017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TraceAlloc("Add live range %d to inactive\n", range->id());
2018958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  inactive_live_ranges().push_back(range);
2019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::AddToUnhandledSorted(LiveRange* range) {
2023958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (range == nullptr || range->IsEmpty()) return;
2024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!range->HasRegisterAssigned() && !range->IsSpilled());
2025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(allocation_finger_.Value() <= range->Start().Value());
2026958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (int i = static_cast<int>(unhandled_live_ranges().size() - 1); i >= 0;
2027958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier       --i) {
2028958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto cur_range = unhandled_live_ranges().at(i);
2029958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (!range->ShouldBeAllocatedBefore(cur_range)) continue;
2030958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    TraceAlloc("Add live range %d to unhandled at %d\n", range->id(), i + 1);
2031958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto it = unhandled_live_ranges().begin() + (i + 1);
2032958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    unhandled_live_ranges().insert(it, range);
2033958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(UnhandledIsSorted());
2034958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return;
2035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TraceAlloc("Add live range %d to unhandled at start\n", range->id());
2037958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  unhandled_live_ranges().insert(unhandled_live_ranges().begin(), range);
2038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(UnhandledIsSorted());
2039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::AddToUnhandledUnsorted(LiveRange* range) {
2043958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (range == nullptr || range->IsEmpty()) return;
2044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!range->HasRegisterAssigned() && !range->IsSpilled());
2045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TraceAlloc("Add live range %d to unhandled unsorted at end\n", range->id());
2046958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  unhandled_live_ranges().push_back(range);
2047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2050958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic bool UnhandledSortHelper(LiveRange* a, LiveRange* b) {
2051958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(!a->ShouldBeAllocatedBefore(b) || !b->ShouldBeAllocatedBefore(a));
2052958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (a->ShouldBeAllocatedBefore(b)) return false;
2053958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (b->ShouldBeAllocatedBefore(a)) return true;
2054958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return a->id() < b->id();
2055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Sort the unhandled live ranges so that the ranges to be processed first are
2059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// at the end of the array list.  This is convenient for the register allocation
2060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// algorithm because it is efficient to remove elements from the end.
2061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::SortUnhandled() {
2062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TraceAlloc("Sort unhandled\n");
2063958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  std::sort(unhandled_live_ranges().begin(), unhandled_live_ranges().end(),
2064958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            &UnhandledSortHelper);
2065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool RegisterAllocator::UnhandledIsSorted() {
2069958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  size_t len = unhandled_live_ranges().size();
2070958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (size_t i = 1; i < len; i++) {
2071958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto a = unhandled_live_ranges().at(i - 1);
2072958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto b = unhandled_live_ranges().at(i);
2073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (a->Start().Value() < b->Start().Value()) return false;
2074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return true;
2076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::FreeSpillSlot(LiveRange* range) {
2080958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(!FLAG_turbo_reuse_spill_slots);
2081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Check that we are the last range.
2082958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (range->next() != nullptr) return;
2083958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (!range->TopLevel()->HasSpillOperand()) return;
2084958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto spill_operand = range->TopLevel()->GetSpillOperand();
2085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (spill_operand->IsConstant()) return;
2086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (spill_operand->index() >= 0) {
2087958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    reusable_slots().push_back(range);
2088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochInstructionOperand* RegisterAllocator::TryReuseSpillSlot(LiveRange* range) {
2093958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(!FLAG_turbo_reuse_spill_slots);
2094958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (reusable_slots().empty()) return nullptr;
2095958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (reusable_slots().front()->End().Value() >
2096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      range->TopLevel()->Start().Value()) {
2097958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return nullptr;
2098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2099958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto result = reusable_slots().front()->TopLevel()->GetSpillOperand();
2100958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  reusable_slots().erase(reusable_slots().begin());
2101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
2102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::ActiveToHandled(LiveRange* range) {
2106958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  RemoveElement(&active_live_ranges(), range);
2107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TraceAlloc("Moving live range %d from active to handled\n", range->id());
2108958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (!FLAG_turbo_reuse_spill_slots) FreeSpillSlot(range);
2109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::ActiveToInactive(LiveRange* range) {
2113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  RemoveElement(&active_live_ranges(), range);
2114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  inactive_live_ranges().push_back(range);
2115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TraceAlloc("Moving live range %d from active to inactive\n", range->id());
2116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::InactiveToHandled(LiveRange* range) {
2120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  RemoveElement(&inactive_live_ranges(), range);
2121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TraceAlloc("Moving live range %d from inactive to handled\n", range->id());
2122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (!FLAG_turbo_reuse_spill_slots) FreeSpillSlot(range);
2123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::InactiveToActive(LiveRange* range) {
2127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  RemoveElement(&inactive_live_ranges(), range);
2128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  active_live_ranges().push_back(range);
2129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TraceAlloc("Moving live range %d from inactive to active\n", range->id());
2130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool RegisterAllocator::TryAllocateFreeReg(LiveRange* current) {
2134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  LifetimePosition free_until_pos[RegisterConfiguration::kMaxDoubleRegisters];
2135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < num_registers_; i++) {
2137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    free_until_pos[i] = LifetimePosition::MaxPosition();
2138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (auto cur_active : active_live_ranges()) {
2141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    free_until_pos[cur_active->assigned_register()] =
2142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        LifetimePosition::FromInstructionIndex(0);
2143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (auto cur_inactive : inactive_live_ranges()) {
2146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(cur_inactive->End().Value() > current->Start().Value());
2147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto next_intersection = cur_inactive->FirstIntersection(current);
2148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!next_intersection.IsValid()) continue;
2149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int cur_reg = cur_inactive->assigned_register();
2150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    free_until_pos[cur_reg] = Min(free_until_pos[cur_reg], next_intersection);
2151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto hint = current->FirstHint();
2154958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (hint != nullptr && (hint->IsRegister() || hint->IsDoubleRegister())) {
2155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int register_index = hint->index();
2156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    TraceAlloc(
2157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        "Found reg hint %s (free until [%d) for live range %d (end %d[).\n",
2158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        RegisterName(register_index), free_until_pos[register_index].Value(),
2159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        current->id(), current->End().Value());
2160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // The desired register is free until the end of the current live range.
2162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (free_until_pos[register_index].Value() >= current->End().Value()) {
2163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      TraceAlloc("Assigning preferred reg %s to live range %d\n",
2164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                 RegisterName(register_index), current->id());
2165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      SetLiveRangeAssignedRegister(current, register_index);
2166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return true;
2167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Find the register which stays free for the longest time.
2171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int reg = 0;
2172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 1; i < RegisterCount(); ++i) {
2173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (free_until_pos[i].Value() > free_until_pos[reg].Value()) {
2174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      reg = i;
2175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2178958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto pos = free_until_pos[reg];
2179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (pos.Value() <= current->Start().Value()) {
2181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // All registers are blocked.
2182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return false;
2183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (pos.Value() < current->End().Value()) {
2186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Register reg is available at the range start but becomes blocked before
2187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // the range end. Split current at position where it becomes blocked.
2188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto tail = SplitRangeAt(current, pos);
2189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!AllocationOk()) return false;
2190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AddToUnhandledSorted(tail);
2191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Register reg is available at the range start and is free until
2194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // the range end.
2195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(pos.Value() >= current->End().Value());
2196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TraceAlloc("Assigning free reg %s to live range %d\n", RegisterName(reg),
2197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             current->id());
2198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SetLiveRangeAssignedRegister(current, reg);
2199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return true;
2201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::AllocateBlockedReg(LiveRange* current) {
2205958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto register_use = current->NextRegisterPosition(current->Start());
2206958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (register_use == nullptr) {
2207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // There is no use in the current live range that requires a register.
2208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // We can just spill it.
2209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Spill(current);
2210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return;
2211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2213958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  LifetimePosition use_pos[RegisterConfiguration::kMaxDoubleRegisters];
2214958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  LifetimePosition block_pos[RegisterConfiguration::kMaxDoubleRegisters];
2215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 0; i < num_registers_; i++) {
2217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    use_pos[i] = block_pos[i] = LifetimePosition::MaxPosition();
2218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2220958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (auto range : active_live_ranges()) {
2221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int cur_reg = range->assigned_register();
2222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (range->IsFixed() || !range->CanBeSpilled(current->Start())) {
2223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      block_pos[cur_reg] = use_pos[cur_reg] =
2224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          LifetimePosition::FromInstructionIndex(0);
2225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
2226958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto next_use =
2227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          range->NextUsePositionRegisterIsBeneficial(current->Start());
2228958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (next_use == nullptr) {
2229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        use_pos[cur_reg] = range->End();
2230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
2231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        use_pos[cur_reg] = next_use->pos();
2232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2236958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (auto range : inactive_live_ranges()) {
2237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(range->End().Value() > current->Start().Value());
2238958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto next_intersection = range->FirstIntersection(current);
2239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!next_intersection.IsValid()) continue;
2240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int cur_reg = range->assigned_register();
2241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (range->IsFixed()) {
2242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      block_pos[cur_reg] = Min(block_pos[cur_reg], next_intersection);
2243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      use_pos[cur_reg] = Min(block_pos[cur_reg], use_pos[cur_reg]);
2244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
2245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      use_pos[cur_reg] = Min(use_pos[cur_reg], next_intersection);
2246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int reg = 0;
2250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  for (int i = 1; i < RegisterCount(); ++i) {
2251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (use_pos[i].Value() > use_pos[reg].Value()) {
2252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      reg = i;
2253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2256958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto pos = use_pos[reg];
2257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (pos.Value() < register_use->pos().Value()) {
2259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // All registers are blocked before the first use that requires a register.
2260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Spill starting part of live range up to that use.
2261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SpillBetween(current, current->Start(), register_use->pos());
2262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return;
2263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (block_pos[reg].Value() < current->End().Value()) {
2266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Register becomes blocked before the current range end. Split before that
2267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // position.
2268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LiveRange* tail = SplitBetween(current, current->Start(),
2269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                   block_pos[reg].InstructionStart());
2270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!AllocationOk()) return;
2271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AddToUnhandledSorted(tail);
2272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Register reg is not blocked for the whole range.
2275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(block_pos[reg].Value() >= current->End().Value());
2276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TraceAlloc("Assigning blocked reg %s to live range %d\n", RegisterName(reg),
2277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             current->id());
2278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SetLiveRangeAssignedRegister(current, reg);
2279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // This register was not free. Thus we need to find and spill
2281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // parts of active and inactive live regions that use the same register
2282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // at the same lifetime positions as current.
2283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SplitAndSpillIntersecting(current);
2284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2287958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic const InstructionBlock* GetContainingLoop(
2288958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    const InstructionSequence* sequence, const InstructionBlock* block) {
2289958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto index = block->loop_header();
2290958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (!index.IsValid()) return nullptr;
2291958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return sequence->InstructionBlockAt(index);
2292958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2293958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2294958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLifetimePosition RegisterAllocator::FindOptimalSpillingPos(
2296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LiveRange* range, LifetimePosition pos) {
2297958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto block = GetInstructionBlock(pos.InstructionStart());
2298958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto loop_header =
2299958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      block->IsLoopHeader() ? block : GetContainingLoop(code(), block);
2300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2301958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (loop_header == nullptr) return pos;
2302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2303958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto prev_use = range->PreviousUsePositionRegisterIsBeneficial(pos);
2304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2305958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  while (loop_header != nullptr) {
2306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // We are going to spill live range inside the loop.
2307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // If possible try to move spilling position backwards to loop header.
2308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // This will reduce number of memory moves on the back edge.
2309958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto loop_start = LifetimePosition::FromInstructionIndex(
2310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        loop_header->first_instruction_index());
2311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (range->Covers(loop_start)) {
2313958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (prev_use == nullptr || prev_use->pos().Value() < loop_start.Value()) {
2314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // No register beneficial use inside the loop before the pos.
2315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        pos = loop_start;
2316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Try hoisting out to an outer loop.
2320958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    loop_header = GetContainingLoop(code(), loop_header);
2321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return pos;
2324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::SplitAndSpillIntersecting(LiveRange* current) {
2328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(current->HasRegisterAssigned());
2329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int reg = current->assigned_register();
2330958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto split_pos = current->Start();
2331958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (size_t i = 0; i < active_live_ranges().size(); ++i) {
2332958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto range = active_live_ranges()[i];
2333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (range->assigned_register() == reg) {
2334958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto next_pos = range->NextRegisterPosition(current->Start());
2335958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto spill_pos = FindOptimalSpillingPos(range, split_pos);
2336958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (next_pos == nullptr) {
2337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        SpillAfter(range, spill_pos);
2338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
2339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // When spilling between spill_pos and next_pos ensure that the range
2340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // remains spilled at least until the start of the current live range.
2341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // This guarantees that we will not introduce new unhandled ranges that
2342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // start before the current range as this violates allocation invariant
2343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // and will lead to an inconsistent state of active and inactive
2344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // live-ranges: ranges are allocated in order of their start positions,
2345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // ranges are retired from active/inactive when the start of the
2346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // current live-range is larger than their end.
2347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        SpillBetweenUntil(range, spill_pos, current->Start(), next_pos->pos());
2348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (!AllocationOk()) return;
2350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ActiveToHandled(range);
2351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      --i;
2352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2355958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (size_t i = 0; i < inactive_live_ranges().size(); ++i) {
2356958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto range = inactive_live_ranges()[i];
2357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(range->End().Value() > current->Start().Value());
2358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (range->assigned_register() == reg && !range->IsFixed()) {
2359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      LifetimePosition next_intersection = range->FirstIntersection(current);
2360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (next_intersection.IsValid()) {
2361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        UsePosition* next_pos = range->NextRegisterPosition(current->Start());
2362958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        if (next_pos == nullptr) {
2363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          SpillAfter(range, split_pos);
2364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        } else {
2365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          next_intersection = Min(next_intersection, next_pos->pos());
2366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          SpillBetween(range, split_pos, next_intersection);
2367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
2368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        if (!AllocationOk()) return;
2369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        InactiveToHandled(range);
2370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        --i;
2371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool RegisterAllocator::IsBlockBoundary(LifetimePosition pos) {
2378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return pos.IsInstructionStart() &&
2379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         InstructionAt(pos.InstructionIndex())->IsBlockStart();
2380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLiveRange* RegisterAllocator::SplitRangeAt(LiveRange* range,
2384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           LifetimePosition pos) {
2385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!range->IsFixed());
2386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TraceAlloc("Splitting live range %d at %d\n", range->id(), pos.Value());
2387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (pos.Value() <= range->Start().Value()) return range;
2389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We can't properly connect liveranges if split occured at the end
2391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // of control instruction.
2392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(pos.IsInstructionStart() ||
2393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch         !InstructionAt(pos.InstructionIndex())->IsControl());
2394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int vreg = GetVirtualRegister();
2396958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (!AllocationOk()) return nullptr;
2397958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto result = LiveRangeFor(vreg);
2398958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  range->SplitAt(pos, result, local_zone());
2399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return result;
2400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLiveRange* RegisterAllocator::SplitBetween(LiveRange* range,
2404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           LifetimePosition start,
2405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                           LifetimePosition end) {
2406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!range->IsFixed());
2407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TraceAlloc("Splitting live range %d in position between [%d, %d]\n",
2408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch             range->id(), start.Value(), end.Value());
2409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2410958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto split_pos = FindOptimalSplitPos(start, end);
2411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(split_pos.Value() >= start.Value());
2412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return SplitRangeAt(range, split_pos);
2413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLifetimePosition RegisterAllocator::FindOptimalSplitPos(LifetimePosition start,
2417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                        LifetimePosition end) {
2418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int start_instr = start.InstructionIndex();
2419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int end_instr = end.InstructionIndex();
2420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(start_instr <= end_instr);
2421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We have no choice
2423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (start_instr == end_instr) return end;
2424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2425958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto start_block = GetInstructionBlock(start);
2426958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto end_block = GetInstructionBlock(end);
2427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (end_block == start_block) {
2429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // The interval is split in the same basic block. Split at the latest
2430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // possible position.
2431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return end;
2432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2434958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto block = end_block;
2435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Find header of outermost loop.
2436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // TODO(titzer): fix redundancy below.
2437958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  while (GetContainingLoop(code(), block) != nullptr &&
2438958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier         GetContainingLoop(code(), block)->rpo_number().ToInt() >
2439958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier             start_block->rpo_number().ToInt()) {
2440958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    block = GetContainingLoop(code(), block);
2441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We did not find any suitable outer loop. Split at the latest possible
2444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // position unless end_block is a loop header itself.
2445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (block == end_block && !end_block->IsLoopHeader()) return end;
2446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return LifetimePosition::FromInstructionIndex(
2448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      block->first_instruction_index());
2449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::SpillAfter(LiveRange* range, LifetimePosition pos) {
2453958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto second_part = SplitRangeAt(range, pos);
2454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!AllocationOk()) return;
2455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Spill(second_part);
2456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::SpillBetween(LiveRange* range, LifetimePosition start,
2460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                     LifetimePosition end) {
2461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SpillBetweenUntil(range, start, start, end);
2462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::SpillBetweenUntil(LiveRange* range,
2466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          LifetimePosition start,
2467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          LifetimePosition until,
2468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                          LifetimePosition end) {
2469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  CHECK(start.Value() < end.Value());
2470958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto second_part = SplitRangeAt(range, start);
2471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!AllocationOk()) return;
2472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (second_part->Start().Value() < end.Value()) {
2474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // The split result intersects with [start, end[.
2475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Split it at position between ]start+1, end[, spill the middle part
2476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // and put the rest to unhandled.
2477958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto third_part = SplitBetween(
2478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        second_part, Max(second_part->Start().InstructionEnd(), until),
2479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        end.PrevInstruction().InstructionEnd());
2480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!AllocationOk()) return;
2481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(third_part != second_part);
2483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Spill(second_part);
2485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AddToUnhandledSorted(third_part);
2486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
2487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // The split result does not intersect with [start, end[.
2488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Nothing to spill. Just put it to unhandled as whole.
2489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AddToUnhandledSorted(second_part);
2490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::Spill(LiveRange* range) {
2495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(!range->IsSpilled());
2496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  TraceAlloc("Spilling live range %d\n", range->id());
2497958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  auto first = range->TopLevel();
2498958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (first->HasNoSpillType()) {
2499958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (FLAG_turbo_reuse_spill_slots) {
2500958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      AssignSpillRangeToLiveRange(first);
2501958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {
2502958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      auto op = TryReuseSpillSlot(range);
2503958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (op == nullptr) {
2504958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        // Allocate a new operand referring to the spill slot.
2505958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        RegisterKind kind = range->Kind();
2506958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        int index = frame()->AllocateSpillSlot(kind == DOUBLE_REGISTERS);
2507958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        auto op_kind = kind == DOUBLE_REGISTERS
2508958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                           ? InstructionOperand::DOUBLE_STACK_SLOT
2509958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                           : InstructionOperand::STACK_SLOT;
2510958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        op = new (code_zone()) InstructionOperand(op_kind, index);
2511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2512958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      first->SetSpillOperand(op);
2513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2515958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  range->MakeSpilled();
2516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint RegisterAllocator::RegisterCount() const { return num_registers_; }
2520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
2523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::Verify() const {
2526958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (auto current : live_ranges()) {
2527958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (current != nullptr) current->Verify();
2528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
2533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::SetLiveRangeAssignedRegister(LiveRange* range,
2536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch                                                     int reg) {
2537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (range->Kind() == DOUBLE_REGISTERS) {
2538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assigned_double_registers_->Add(reg);
2539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
2540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(range->Kind() == GENERAL_REGISTERS);
2541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    assigned_registers_->Add(reg);
2542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  range->set_assigned_register(reg, code_zone());
2544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2546958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}  // namespace compiler
2547958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}  // namespace internal
2548958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}  // namespace v8
2549