register-allocator.cc revision bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8
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
5014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#include "src/base/adapters.h"
6b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/linkage.h"
7958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/compiler/register-allocator.h"
8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/string-stream.h"
9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 {
11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal {
12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace compiler {
13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
14014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#define TRACE(...)                             \
15014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  do {                                         \
16014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (FLAG_trace_alloc) PrintF(__VA_ARGS__); \
17014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } while (false)
18014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
19014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
20014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochnamespace {
21014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
22014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid RemoveElement(ZoneVector<LiveRange*>* v, LiveRange* range) {
23014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  auto it = std::find(v->begin(), v->end(), range);
24014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(it != v->end());
25014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  v->erase(it);
26014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint GetRegisterCount(const RegisterConfiguration* cfg, RegisterKind kind) {
29bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return kind == FP_REGISTERS ? cfg->num_double_registers()
30bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                              : cfg->num_general_registers();
31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint GetAllocatableRegisterCount(const RegisterConfiguration* cfg,
35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                RegisterKind kind) {
36bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return kind == FP_REGISTERS ? cfg->num_allocatable_aliased_double_registers()
37bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                              : cfg->num_allocatable_general_registers();
38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst int* GetAllocatableRegisterCodes(const RegisterConfiguration* cfg,
42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       RegisterKind kind) {
43bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return kind == FP_REGISTERS ? cfg->allocatable_double_codes()
44bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                              : cfg->allocatable_general_codes();
45b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
48014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst InstructionBlock* GetContainingLoop(const InstructionSequence* sequence,
49014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                          const InstructionBlock* block) {
50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RpoNumber index = block->loop_header();
51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!index.IsValid()) return nullptr;
52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return sequence->InstructionBlockAt(index);
53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst InstructionBlock* GetInstructionBlock(const InstructionSequence* code,
57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            LifetimePosition pos) {
58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return code->GetInstructionBlock(pos.ToInstructionIndex());
59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochInstruction* GetLastInstruction(InstructionSequence* code,
63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                const InstructionBlock* block) {
64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return code->InstructionAt(block->last_instruction_index());
65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool IsOutputRegisterOf(Instruction* instr, Register reg) {
69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < instr->OutputCount(); i++) {
70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand* output = instr->OutputAt(i);
71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (output->IsRegister() &&
72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        LocationOperand::cast(output)->GetRegister().is(reg)) {
73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return true;
74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
75958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return false;
77958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
78958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
79958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
80014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool IsOutputDoubleRegisterOf(Instruction* instr, DoubleRegister reg) {
81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < instr->OutputCount(); i++) {
82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand* output = instr->OutputAt(i);
83bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (output->IsFPRegister() &&
84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        LocationOperand::cast(output)->GetDoubleRegister().is(reg)) {
85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return true;
86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return false;
89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// TODO(dcarney): fix frame to allow frame accesses to half size location.
93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint GetByteWidth(MachineRepresentation rep) {
94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (rep) {
95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kBit:
96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord8:
97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord16:
98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord32:
99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kTagged:
100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return kPointerSize;
101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kFloat32:
102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord64:
103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kFloat64:
104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return 8;
105109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case MachineRepresentation::kSimd128:
106109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return 16;
107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kNone:
108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UNREACHABLE();
111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return 0;
112958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace
115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
116109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochclass LiveRangeBound {
117109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch public:
118109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  explicit LiveRangeBound(LiveRange* range, bool skip)
119109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      : range_(range), start_(range->Start()), end_(range->End()), skip_(skip) {
120109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    DCHECK(!range->IsEmpty());
121109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
122109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
123109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  bool CanCover(LifetimePosition position) {
124109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return start_ <= position && position < end_;
125109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
126109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
127109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  LiveRange* const range_;
128109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  const LifetimePosition start_;
129109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  const LifetimePosition end_;
130109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  const bool skip_;
131109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
132109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch private:
133109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(LiveRangeBound);
134109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch};
135109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
136109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
137109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochstruct FindResult {
138109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  LiveRange* cur_cover_;
139109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  LiveRange* pred_cover_;
140109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch};
141109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
142109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
143109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochclass LiveRangeBoundArray {
144109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch public:
145109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  LiveRangeBoundArray() : length_(0), start_(nullptr) {}
146109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
147109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  bool ShouldInitialize() { return start_ == nullptr; }
148109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
149109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  void Initialize(Zone* zone, TopLevelLiveRange* range) {
150109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    length_ = range->GetChildCount();
151109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
152109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    start_ = zone->NewArray<LiveRangeBound>(length_);
153109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    LiveRangeBound* curr = start_;
154109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // Normally, spilled ranges do not need connecting moves, because the spill
155109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // location has been assigned at definition. For ranges spilled in deferred
156109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // blocks, that is not the case, so we need to connect the spilled children.
157109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    for (LiveRange *i = range; i != nullptr; i = i->next(), ++curr) {
158109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      new (curr) LiveRangeBound(i, i->spilled());
159109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
160109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
161109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
162109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  LiveRangeBound* Find(const LifetimePosition position) const {
163109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    size_t left_index = 0;
164109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    size_t right_index = length_;
165109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    while (true) {
166109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      size_t current_index = left_index + (right_index - left_index) / 2;
167109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      DCHECK(right_index > current_index);
168109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      LiveRangeBound* bound = &start_[current_index];
169109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (bound->start_ <= position) {
170109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        if (position < bound->end_) return bound;
171109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        DCHECK(left_index < current_index);
172109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        left_index = current_index;
173109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      } else {
174109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        right_index = current_index;
175109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
176109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
177109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
178109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
179109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  LiveRangeBound* FindPred(const InstructionBlock* pred) {
180109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    LifetimePosition pred_end =
181109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        LifetimePosition::InstructionFromInstructionIndex(
182109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            pred->last_instruction_index());
183109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return Find(pred_end);
184109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
185109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
186109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  LiveRangeBound* FindSucc(const InstructionBlock* succ) {
187109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    LifetimePosition succ_start = LifetimePosition::GapFromInstructionIndex(
188109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        succ->first_instruction_index());
189109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return Find(succ_start);
190109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
191109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
192109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  bool FindConnectableSubranges(const InstructionBlock* block,
193109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                const InstructionBlock* pred,
194109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                FindResult* result) const {
195109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    LifetimePosition pred_end =
196109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        LifetimePosition::InstructionFromInstructionIndex(
197109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            pred->last_instruction_index());
198109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    LiveRangeBound* bound = Find(pred_end);
199109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    result->pred_cover_ = bound->range_;
200109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    LifetimePosition cur_start = LifetimePosition::GapFromInstructionIndex(
201109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        block->first_instruction_index());
202109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
203109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (bound->CanCover(cur_start)) {
204109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // Both blocks are covered by the same range, so there is nothing to
205109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // connect.
206109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return false;
207109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
208109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    bound = Find(cur_start);
209109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (bound->skip_) {
210109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return false;
211109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
212109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    result->cur_cover_ = bound->range_;
213109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    DCHECK(result->pred_cover_ != nullptr && result->cur_cover_ != nullptr);
214109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return (result->cur_cover_ != result->pred_cover_);
215109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
216109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
217109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch private:
218109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  size_t length_;
219109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  LiveRangeBound* start_;
220109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
221109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(LiveRangeBoundArray);
222109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch};
223109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
224109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
225109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochclass LiveRangeFinder {
226109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch public:
227109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  explicit LiveRangeFinder(const RegisterAllocationData* data, Zone* zone)
228109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      : data_(data),
229109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        bounds_length_(static_cast<int>(data_->live_ranges().size())),
230109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        bounds_(zone->NewArray<LiveRangeBoundArray>(bounds_length_)),
231109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        zone_(zone) {
232109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    for (int i = 0; i < bounds_length_; ++i) {
233109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      new (&bounds_[i]) LiveRangeBoundArray();
234109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
235109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
236109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
237109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  LiveRangeBoundArray* ArrayFor(int operand_index) {
238109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    DCHECK(operand_index < bounds_length_);
239109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    TopLevelLiveRange* range = data_->live_ranges()[operand_index];
240109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    DCHECK(range != nullptr && !range->IsEmpty());
241109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    LiveRangeBoundArray* array = &bounds_[operand_index];
242109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (array->ShouldInitialize()) {
243109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      array->Initialize(zone_, range);
244109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
245109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return array;
246109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
247109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
248109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch private:
249109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  const RegisterAllocationData* const data_;
250109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  const int bounds_length_;
251109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  LiveRangeBoundArray* const bounds_;
252109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Zone* const zone_;
253109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
254109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(LiveRangeFinder);
255109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch};
256109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
257109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
258109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochtypedef std::pair<ParallelMove*, InstructionOperand> DelayedInsertionMapKey;
259109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
260109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
261109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochstruct DelayedInsertionMapCompare {
262109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  bool operator()(const DelayedInsertionMapKey& a,
263109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                  const DelayedInsertionMapKey& b) const {
264109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (a.first == b.first) {
265109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return a.second.Compare(b.second);
266109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
267109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return a.first < b.first;
268109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
269109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch};
270109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
271109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
272109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochtypedef ZoneMap<DelayedInsertionMapKey, InstructionOperand,
273109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                DelayedInsertionMapCompare> DelayedInsertionMap;
274109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
275958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochUsePosition::UsePosition(LifetimePosition pos, InstructionOperand* operand,
277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         void* hint, UsePositionHintType hint_type)
278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : operand_(operand), hint_(hint), next_(nullptr), pos_(pos), flags_(0) {
279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_IMPLIES(hint == nullptr, hint_type == UsePositionHintType::kNone);
280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool register_beneficial = true;
281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePositionType type = UsePositionType::kAny;
282958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (operand_ != nullptr && operand_->IsUnallocated()) {
283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const UnallocatedOperand* unalloc = UnallocatedOperand::cast(operand_);
284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (unalloc->HasRegisterPolicy()) {
285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      type = UsePositionType::kRequiresRegister;
286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (unalloc->HasSlotPolicy()) {
287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      type = UsePositionType::kRequiresSlot;
288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      register_beneficial = false;
289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      register_beneficial = !unalloc->HasAnyPolicy();
291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  flags_ = TypeField::encode(type) | HintTypeField::encode(hint_type) |
294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           RegisterBeneficialField::encode(register_beneficial) |
295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           AssignedRegisterField::encode(kUnassignedRegister);
296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(pos_.IsValid());
297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool UsePosition::HasHint() const {
301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int hint_register;
302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return HintRegister(&hint_register);
303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool UsePosition::HintRegister(int* register_code) const {
307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (hint_ == nullptr) return false;
308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (HintTypeField::decode(flags_)) {
309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case UsePositionHintType::kNone:
310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case UsePositionHintType::kUnresolved:
311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return false;
312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case UsePositionHintType::kUsePos: {
313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UsePosition* use_pos = reinterpret_cast<UsePosition*>(hint_);
314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int assigned_register = AssignedRegisterField::decode(use_pos->flags_);
315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (assigned_register == kUnassignedRegister) return false;
316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *register_code = assigned_register;
317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return true;
318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case UsePositionHintType::kOperand: {
320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionOperand* operand =
321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          reinterpret_cast<InstructionOperand*>(hint_);
322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int assigned_register =
323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          operand->IsRegister()
324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              ? LocationOperand::cast(operand)->GetRegister().code()
325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              : LocationOperand::cast(operand)->GetDoubleRegister().code();
326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *register_code = assigned_register;
327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return true;
328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case UsePositionHintType::kPhi: {
330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      RegisterAllocationData::PhiMapValue* phi =
331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          reinterpret_cast<RegisterAllocationData::PhiMapValue*>(hint_);
332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int assigned_register = phi->assigned_register();
333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (assigned_register == kUnassignedRegister) return false;
334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *register_code = assigned_register;
335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return true;
336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UNREACHABLE();
339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return false;
340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochUsePositionHintType UsePosition::HintTypeForOperand(
344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const InstructionOperand& op) {
345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (op.kind()) {
346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case InstructionOperand::CONSTANT:
347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case InstructionOperand::IMMEDIATE:
348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case InstructionOperand::EXPLICIT:
349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return UsePositionHintType::kNone;
350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case InstructionOperand::UNALLOCATED:
351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return UsePositionHintType::kUnresolved;
352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case InstructionOperand::ALLOCATED:
353bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (op.IsRegister() || op.IsFPRegister()) {
354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return UsePositionHintType::kOperand;
355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
356bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        DCHECK(op.IsStackSlot() || op.IsFPStackSlot());
357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return UsePositionHintType::kNone;
358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case InstructionOperand::INVALID:
360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UNREACHABLE();
363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return UsePositionHintType::kNone;
364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid UsePosition::ResolveHint(UsePosition* use_pos) {
368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_NOT_NULL(use_pos);
369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (HintTypeField::decode(flags_) != UsePositionHintType::kUnresolved) return;
370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  hint_ = use_pos;
371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  flags_ = HintTypeField::update(flags_, UsePositionHintType::kUsePos);
372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid UsePosition::set_type(UsePositionType type, bool register_beneficial) {
376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_IMPLIES(type == UsePositionType::kRequiresSlot, !register_beneficial);
377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(kUnassignedRegister, AssignedRegisterField::decode(flags_));
378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  flags_ = TypeField::encode(type) |
379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           RegisterBeneficialField::encode(register_beneficial) |
380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           HintTypeField::encode(HintTypeField::decode(flags_)) |
381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           AssignedRegisterField::encode(kUnassignedRegister);
382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
383958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
384958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochUseInterval* UseInterval::SplitAt(LifetimePosition pos, Zone* zone) {
386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(Contains(pos) && pos != start());
387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UseInterval* after = new (zone) UseInterval(pos, end_);
388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  after->next_ = next_;
389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  next_ = nullptr;
390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  end_ = pos;
391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return after;
392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LifetimePosition::Print() const {
396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  OFStream os(stdout);
397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  os << *this << std::endl;
398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstd::ostream& operator<<(std::ostream& os, const LifetimePosition pos) {
402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  os << '@' << pos.ToInstructionIndex();
403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (pos.IsGapPosition()) {
404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    os << 'g';
405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    os << 'i';
407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (pos.IsStart()) {
409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    os << 's';
410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    os << 'e';
412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return os;
414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst float LiveRange::kInvalidWeight = -1;
418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst float LiveRange::kMaxWeight = std::numeric_limits<float>::max();
419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLiveRange::LiveRange(int relative_id, MachineRepresentation rep,
422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                     TopLevelLiveRange* top_level)
423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : relative_id_(relative_id),
424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bits_(0),
425958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      last_interval_(nullptr),
426958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      first_interval_(nullptr),
427958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      first_pos_(nullptr),
428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      top_level_(top_level),
429958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      next_(nullptr),
430958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      current_interval_(nullptr),
431958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      last_processed_use_(nullptr),
432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      current_hint_position_(nullptr),
433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      splitting_pointer_(nullptr),
434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      size_(kInvalidSize),
435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      weight_(kInvalidWeight),
436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      group_(nullptr) {
437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(AllocatedOperand::IsSupportedRepresentation(rep));
438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bits_ = AssignedRegisterField::encode(kUnassignedRegister) |
439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          RepresentationField::encode(rep);
440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRange::VerifyPositions() const {
444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Walk the positions, verifying that each is in an interval.
445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UseInterval* interval = first_interval_;
446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (UsePosition* pos = first_pos_; pos != nullptr; pos = pos->next()) {
447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CHECK(Start() <= pos->pos());
448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CHECK(pos->pos() <= End());
449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CHECK_NOT_NULL(interval);
450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    while (!interval->Contains(pos->pos()) && interval->end() != pos->pos()) {
451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      interval = interval->next();
452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      CHECK_NOT_NULL(interval);
453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRange::VerifyIntervals() const {
459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(first_interval()->start() == Start());
460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition last_end = first_interval()->end();
461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (UseInterval* interval = first_interval()->next(); interval != nullptr;
462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       interval = interval->next()) {
463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(last_end <= interval->start());
464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    last_end = interval->end();
465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(last_end == End());
467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRange::set_assigned_register(int reg) {
471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!HasRegisterAssigned() && !spilled());
472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bits_ = AssignedRegisterField::update(bits_, reg);
473958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
474958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
475958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRange::UnsetAssignedRegister() {
477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(HasRegisterAssigned() && !spilled());
478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bits_ = AssignedRegisterField::update(bits_, kUnassignedRegister);
479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRange::Spill() {
483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!spilled());
484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!TopLevel()->HasNoSpillType());
485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_spilled(true);
486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bits_ = AssignedRegisterField::update(bits_, kUnassignedRegister);
487958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
488958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
489958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochRegisterKind LiveRange::kind() const {
491bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return IsFloatingPoint(representation()) ? FP_REGISTERS : GENERAL_REGISTERS;
492958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
493958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
494958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochUsePosition* LiveRange::FirstHintPosition(int* register_index) const {
496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (UsePosition* pos = first_pos_; pos != nullptr; pos = pos->next()) {
497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (pos->HintRegister(register_index)) return pos;
498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return nullptr;
500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochUsePosition* LiveRange::NextUsePosition(LifetimePosition start) const {
504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UsePosition* use_pos = last_processed_use_;
505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (use_pos == nullptr || use_pos->pos() > start) {
506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    use_pos = first_pos();
507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (use_pos != nullptr && use_pos->pos() < start) {
509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    use_pos = use_pos->next();
510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  last_processed_use_ = use_pos;
512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return use_pos;
513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochUsePosition* LiveRange::NextUsePositionRegisterIsBeneficial(
517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition start) const {
518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UsePosition* pos = NextUsePosition(start);
519958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  while (pos != nullptr && !pos->RegisterIsBeneficial()) {
520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    pos = pos->next();
521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return pos;
523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochUsePosition* LiveRange::PreviousUsePositionRegisterIsBeneficial(
527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition start) const {
528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePosition* pos = first_pos();
529958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  UsePosition* prev = nullptr;
530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (pos != nullptr && pos->pos() < start) {
531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (pos->RegisterIsBeneficial()) prev = pos;
532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    pos = pos->next();
533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return prev;
535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochUsePosition* LiveRange::NextRegisterPosition(LifetimePosition start) const {
539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UsePosition* pos = NextUsePosition(start);
540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (pos != nullptr && pos->type() != UsePositionType::kRequiresRegister) {
541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    pos = pos->next();
542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return pos;
544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochUsePosition* LiveRange::NextSlotPosition(LifetimePosition start) const {
548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (UsePosition* pos = NextUsePosition(start); pos != nullptr;
549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       pos = pos->next()) {
550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (pos->type() != UsePositionType::kRequiresSlot) continue;
551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return pos;
552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return nullptr;
554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool LiveRange::CanBeSpilled(LifetimePosition pos) const {
558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We cannot spill a live range that has a use requiring a register
559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // at the current or the immediate next position.
560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePosition* use_pos = NextRegisterPosition(pos);
561958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (use_pos == nullptr) return true;
562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return use_pos->pos() > pos.NextStart().End();
563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
565b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool LiveRange::IsTopLevel() const { return top_level_ == this; }
567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochInstructionOperand LiveRange::GetAssignedOperand() const {
570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (HasRegisterAssigned()) {
571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!spilled());
572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return AllocatedOperand(LocationOperand::REGISTER, representation(),
573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            assigned_register());
574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(spilled());
576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!HasRegisterAssigned());
577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (TopLevel()->HasSpillOperand()) {
578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand* op = TopLevel()->GetSpillOperand();
579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!op->IsUnallocated());
580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return *op;
581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return TopLevel()->GetSpillRangeOperand();
583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochUseInterval* LiveRange::FirstSearchIntervalForPosition(
587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LifetimePosition position) const {
588958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (current_interval_ == nullptr) return first_interval_;
589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (current_interval_->start() > position) {
590958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    current_interval_ = nullptr;
591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return first_interval_;
592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return current_interval_;
594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LiveRange::AdvanceLastProcessedMarker(
598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UseInterval* to_start_of, LifetimePosition but_not_past) const {
599958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (to_start_of == nullptr) return;
600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (to_start_of->start() > but_not_past) return;
601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition start = current_interval_ == nullptr
602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                               ? LifetimePosition::Invalid()
603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                               : current_interval_->start();
604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (to_start_of->start() > start) {
605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    current_interval_ = to_start_of;
606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLiveRange* LiveRange::SplitAt(LifetimePosition position, Zone* zone) {
611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int new_id = TopLevel()->GetNextChildId();
612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LiveRange* child = new (zone) LiveRange(new_id, representation(), TopLevel());
613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DetachAt(position, child, zone);
614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  child->top_level_ = TopLevel();
616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  child->next_ = next_;
617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  next_ = child;
618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return child;
619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochUsePosition* LiveRange::DetachAt(LifetimePosition position, LiveRange* result,
623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 Zone* zone) {
624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(Start() < position);
625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(End() > position);
626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(result->IsEmpty());
627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Find the last interval that ends before the position. If the
628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // position is contained in one of the intervals in the chain, we
629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // split that interval and use the first part.
630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UseInterval* current = FirstSearchIntervalForPosition(position);
631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // If the split position coincides with the beginning of a use interval
633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // we need to split use positons in a special way.
634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool split_at_start = false;
635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (current->start() == position) {
637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // When splitting at start we need to locate the previous use interval.
638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    current = first_interval_;
639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UseInterval* after = nullptr;
642958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  while (current != nullptr) {
643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (current->Contains(position)) {
644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      after = current->SplitAt(position, zone);
645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UseInterval* next = current->next();
648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (next->start() >= position) {
649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      split_at_start = (next->start() == position);
650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      after = next;
651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      current->set_next(nullptr);
652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    current = next;
655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(nullptr != after);
657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Partition original use intervals to the two live ranges.
659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UseInterval* before = current;
660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->last_interval_ =
661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (last_interval_ == before)
662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          ? after            // Only interval in the range after split.
663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          : last_interval_;  // Last interval of the original range.
664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->first_interval_ = after;
665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  last_interval_ = before;
666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Find the last use position before the split and the first use
668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // position after it.
669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePosition* use_after =
670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      splitting_pointer_ == nullptr || splitting_pointer_->pos() > position
671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          ? first_pos()
672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          : splitting_pointer_;
673958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  UsePosition* use_before = nullptr;
674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (split_at_start) {
675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // The split position coincides with the beginning of a use interval (the
676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // end of a lifetime hole). Use at this position should be attributed to
677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // the split child because split child owns use interval covering it.
678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    while (use_after != nullptr && use_after->pos() < position) {
679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      use_before = use_after;
680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      use_after = use_after->next();
681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    while (use_after != nullptr && use_after->pos() <= position) {
684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      use_before = use_after;
685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      use_after = use_after->next();
686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Partition original use positions to the two live ranges.
690958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (use_before != nullptr) {
691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    use_before->set_next(nullptr);
692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
693958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    first_pos_ = nullptr;
694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->first_pos_ = use_after;
696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Discard cached iteration state. It might be pointing
698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // to the use that no longer belongs to this live range.
699958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  last_processed_use_ = nullptr;
700958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  current_interval_ = nullptr;
701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Invalidate size and weight of this range. The child range has them
703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // invalid at construction.
704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_ = kInvalidSize;
705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  weight_ = kInvalidWeight;
706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VerifyChildStructure();
708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  result->VerifyChildStructure();
709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return use_before;
711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRange::UpdateParentForAllChildren(TopLevelLiveRange* new_top_level) {
715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LiveRange* child = this;
716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (; child != nullptr; child = child->next()) {
717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    child->top_level_ = new_top_level;
718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRange::ConvertUsesToOperand(const InstructionOperand& op,
723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     const InstructionOperand& spill_op) {
724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (UsePosition* pos = first_pos(); pos != nullptr; pos = pos->next()) {
725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(Start() <= pos->pos() && pos->pos() <= End());
726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!pos->HasOperand()) continue;
727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    switch (pos->type()) {
728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case UsePositionType::kRequiresSlot:
729bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        DCHECK(spill_op.IsStackSlot() || spill_op.IsFPStackSlot());
730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        InstructionOperand::ReplaceWith(pos->operand(), &spill_op);
731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case UsePositionType::kRequiresRegister:
733bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        DCHECK(op.IsRegister() || op.IsFPRegister());
734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Fall through.
735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case UsePositionType::kAny:
736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        InstructionOperand::ReplaceWith(pos->operand(), &op);
737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// This implements an ordering on live ranges so that they are ordered by their
744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// start positions.  This is needed for the correctness of the register
745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// allocation algorithm.  If two live ranges start at the same offset then there
746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// is a tie breaker based on where the value is first used.  This part of the
747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ordering is merely a heuristic.
748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool LiveRange::ShouldBeAllocatedBefore(const LiveRange* other) const {
749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LifetimePosition start = Start();
750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LifetimePosition other_start = other->Start();
751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (start == other_start) {
752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UsePosition* pos = first_pos();
753958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (pos == nullptr) return false;
754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UsePosition* other_pos = other->first_pos();
755958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (other_pos == nullptr) return true;
756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return pos->pos() < other_pos->pos();
757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return start < other_start;
759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRange::SetUseHints(int register_index) {
763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (UsePosition* pos = first_pos(); pos != nullptr; pos = pos->next()) {
764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!pos->HasOperand()) continue;
765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    switch (pos->type()) {
766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case UsePositionType::kRequiresSlot:
767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case UsePositionType::kRequiresRegister:
769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case UsePositionType::kAny:
770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        pos->set_assigned_register(register_index);
771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool LiveRange::CanCover(LifetimePosition position) const {
778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (IsEmpty()) return false;
779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return Start() <= position && position < End();
780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool LiveRange::Covers(LifetimePosition position) const {
784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!CanCover(position)) return false;
785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UseInterval* start_search = FirstSearchIntervalForPosition(position);
786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (UseInterval* interval = start_search; interval != nullptr;
787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       interval = interval->next()) {
788958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(interval->next() == nullptr ||
789014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           interval->next()->start() >= interval->start());
790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AdvanceLastProcessedMarker(interval, position);
791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (interval->Contains(position)) return true;
792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (interval->start() > position) return false;
793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return false;
795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLifetimePosition LiveRange::FirstIntersection(LiveRange* other) const {
799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UseInterval* b = other->first_interval();
800958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (b == nullptr) return LifetimePosition::Invalid();
801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition advance_last_processed_up_to = b->start();
802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UseInterval* a = FirstSearchIntervalForPosition(b->start());
803958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  while (a != nullptr && b != nullptr) {
804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (a->start() > other->End()) break;
805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (b->start() > End()) break;
806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition cur_intersection = a->Intersect(b);
807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (cur_intersection.IsValid()) {
808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return cur_intersection;
809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (a->start() < b->start()) {
811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      a = a->next();
812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (a == nullptr || a->start() > other->End()) break;
813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      AdvanceLastProcessedMarker(a, advance_last_processed_up_to);
814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      b = b->next();
816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return LifetimePosition::Invalid();
819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochunsigned LiveRange::GetSize() {
823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (size_ == kInvalidSize) {
824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    size_ = 0;
825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (const UseInterval* interval = first_interval(); interval != nullptr;
826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         interval = interval->next()) {
827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      size_ += (interval->end().value() - interval->start().value());
828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return static_cast<unsigned>(size_);
832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRange::Print(const RegisterConfiguration* config,
836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                      bool with_children) const {
837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  OFStream os(stdout);
838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  PrintableLiveRange wrapper;
839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  wrapper.register_configuration_ = config;
840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (const LiveRange* i = this; i != nullptr; i = i->next()) {
841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    wrapper.range_ = i;
842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    os << wrapper << std::endl;
843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!with_children) break;
844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRange::Print(bool with_children) const {
849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const RegisterConfiguration* config =
850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN);
851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Print(config, with_children);
852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstruct TopLevelLiveRange::SpillMoveInsertionList : ZoneObject {
856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SpillMoveInsertionList(int gap_index, InstructionOperand* operand,
857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         SpillMoveInsertionList* next)
858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : gap_index(gap_index), operand(operand), next(next) {}
859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const int gap_index;
860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand* const operand;
861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SpillMoveInsertionList* const next;
862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTopLevelLiveRange::TopLevelLiveRange(int vreg, MachineRepresentation rep)
866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : LiveRange(0, rep, this),
867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      vreg_(vreg),
868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      last_child_id_(0),
869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      splintered_from_(nullptr),
870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      spill_operand_(nullptr),
871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      spill_move_insertion_locations_(nullptr),
872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      spilled_in_deferred_blocks_(false),
873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      spill_start_index_(kMaxInt),
874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      last_pos_(nullptr),
875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      splinter_(nullptr),
876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      has_preassigned_slot_(false) {
877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bits_ |= SpillTypeField::encode(SpillType::kNoSpillType);
878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if DEBUG
882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint TopLevelLiveRange::debug_virt_reg() const {
883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return IsSplinter() ? splintered_from()->vreg() : vreg();
884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif
886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::RecordSpillLocation(Zone* zone, int gap_index,
889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            InstructionOperand* operand) {
890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(HasNoSpillType());
891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  spill_move_insertion_locations_ = new (zone) SpillMoveInsertionList(
892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      gap_index, operand, spill_move_insertion_locations_);
893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::CommitSpillMoves(InstructionSequence* sequence,
896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                         const InstructionOperand& op,
897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                         bool might_be_duplicated) {
898109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DCHECK_IMPLIES(op.IsConstant(), GetSpillMoveInsertionLocations() == nullptr);
899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Zone* zone = sequence->zone();
900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
901109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  for (SpillMoveInsertionList* to_spill = GetSpillMoveInsertionLocations();
902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       to_spill != nullptr; to_spill = to_spill->next) {
903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Instruction* instr = sequence->InstructionAt(to_spill->gap_index);
904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ParallelMove* move =
905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        instr->GetOrCreateParallelMove(Instruction::START, zone);
906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Skip insertion if it's possible that the move exists already as a
907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // constraint move from a fixed output register to a slot.
908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (might_be_duplicated || has_preassigned_slot()) {
909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bool found = false;
910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (MoveOperands* move_op : *move) {
911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (move_op->IsEliminated()) continue;
912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (move_op->source().Equals(*to_spill->operand) &&
913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            move_op->destination().Equals(op)) {
914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          found = true;
915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          if (has_preassigned_slot()) move_op->Eliminate();
916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          break;
917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (found) continue;
920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!has_preassigned_slot()) {
922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      move->AddMove(*to_spill->operand, op);
923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::SetSpillOperand(InstructionOperand* operand) {
929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(HasNoSpillType());
930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!operand->IsUnallocated() && !operand->IsImmediate());
931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_spill_type(SpillType::kSpillOperand);
932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  spill_operand_ = operand;
933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::SetSpillRange(SpillRange* spill_range) {
937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!HasSpillOperand());
938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(spill_range);
939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  spill_range_ = spill_range;
940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAllocatedOperand TopLevelLiveRange::GetSpillRangeOperand() const {
944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SpillRange* spill_range = GetSpillRange();
945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int index = spill_range->assigned_slot();
946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return AllocatedOperand(LocationOperand::STACK_SLOT, representation(), index);
947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::Splinter(LifetimePosition start, LifetimePosition end,
951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 Zone* zone) {
952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(start != Start() || end != End());
953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(start < end);
954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TopLevelLiveRange splinter_temp(-1, representation());
956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePosition* last_in_splinter = nullptr;
957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Live ranges defined in deferred blocks stay in deferred blocks, so we
958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // don't need to splinter them. That means that start should always be
959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // after the beginning of the range.
960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(start > Start());
961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (end >= End()) {
963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(start > Start());
964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DetachAt(start, &splinter_temp, zone);
965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    next_ = nullptr;
966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(start < End() && Start() < end);
968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const int kInvalidId = std::numeric_limits<int>::max();
970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UsePosition* last = DetachAt(start, &splinter_temp, zone);
972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange end_part(kInvalidId, this->representation(), nullptr);
974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    last_in_splinter = splinter_temp.DetachAt(end, &end_part, zone);
975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    next_ = end_part.next_;
977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    last_interval_->set_next(end_part.first_interval_);
978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // The next splinter will happen either at or after the current interval.
979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // We can optimize DetachAt by setting current_interval_ accordingly,
980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // which will then be picked up by FirstSearchIntervalForPosition.
981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    current_interval_ = last_interval_;
982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    last_interval_ = end_part.last_interval_;
983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (first_pos_ == nullptr) {
985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      first_pos_ = end_part.first_pos_;
986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      splitting_pointer_ = last;
988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (last != nullptr) last->set_next(end_part.first_pos_);
989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (splinter()->IsEmpty()) {
993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    splinter()->first_interval_ = splinter_temp.first_interval_;
994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    splinter()->last_interval_ = splinter_temp.last_interval_;
995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    splinter()->last_interval_->set_next(splinter_temp.first_interval_);
997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    splinter()->last_interval_ = splinter_temp.last_interval_;
998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (splinter()->first_pos() == nullptr) {
1000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    splinter()->first_pos_ = splinter_temp.first_pos_;
1001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    splinter()->last_pos_->set_next(splinter_temp.first_pos_);
1003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (last_in_splinter != nullptr) {
1005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    splinter()->last_pos_ = last_in_splinter;
1006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (splinter()->first_pos() != nullptr &&
1008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        splinter()->last_pos_ == nullptr) {
1009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      splinter()->last_pos_ = splinter()->first_pos();
1010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (UsePosition* pos = splinter()->first_pos(); pos != nullptr;
1011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           pos = pos->next()) {
1012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        splinter()->last_pos_ = pos;
1013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if DEBUG
1017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Verify();
1018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  splinter()->Verify();
1019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif
1020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::SetSplinteredFrom(TopLevelLiveRange* splinter_parent) {
1024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  splintered_from_ = splinter_parent;
1025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!HasSpillOperand() && splinter_parent->spill_range_ != nullptr) {
1026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SetSpillRange(splinter_parent->spill_range_);
1027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1028b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1029b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::UpdateSpillRangePostMerge(TopLevelLiveRange* merged) {
1032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(merged->TopLevel() == this);
1033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (HasNoSpillType() && merged->HasSpillRange()) {
1035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    set_spill_type(merged->spill_type());
1036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(GetSpillRange()->live_ranges().size() > 0);
1037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    merged->spill_range_ = nullptr;
1038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    merged->bits_ =
1039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        SpillTypeField::update(merged->bits_, SpillType::kNoSpillType);
1040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::Merge(TopLevelLiveRange* other, Zone* zone) {
1045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(Start() < other->Start());
1046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(other->splintered_from() == this);
1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LiveRange* first = this;
1049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LiveRange* second = other;
1050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(first->Start() < second->Start());
1051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (first != nullptr && second != nullptr) {
1052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(first != second);
1053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Make sure the ranges are in order each time we iterate.
1054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (second->Start() < first->Start()) {
1055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LiveRange* tmp = second;
1056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      second = first;
1057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      first = tmp;
1058014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      continue;
1059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (first->End() <= second->Start()) {
1062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (first->next() == nullptr ||
1063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          first->next()->Start() > second->Start()) {
1064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // First is in order before second.
1065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        LiveRange* temp = first->next();
1066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        first->next_ = second;
1067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        first = temp;
1068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // First is in order before its successor (or second), so advance first.
1070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        first = first->next();
1071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      continue;
1073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(first->Start() < second->Start());
1076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // If first and second intersect, split first.
1077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (first->Start() < second->End() && second->Start() < first->End()) {
1078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LiveRange* temp = first->SplitAt(second->Start(), zone);
1079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      CHECK(temp != first);
1080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      temp->set_spilled(first->spilled());
1081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!temp->spilled())
1082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        temp->set_assigned_register(first->assigned_register());
1083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      first->next_ = second;
1085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      first = temp;
1086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      continue;
1087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(first->End() <= second->Start());
1089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TopLevel()->UpdateParentForAllChildren(TopLevel());
1092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TopLevel()->UpdateSpillRangePostMerge(other);
1093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if DEBUG
1095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Verify();
1096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif
1097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::VerifyChildrenInOrder() const {
1101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition last_end = End();
1102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (const LiveRange* child = this->next(); child != nullptr;
1103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       child = child->next()) {
1104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(last_end <= child->Start());
1105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    last_end = child->End();
1106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::Verify() const {
1111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VerifyChildrenInOrder();
1112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (const LiveRange* child = this; child != nullptr; child = child->next()) {
1113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    VerifyChildStructure();
1114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::ShortenTo(LifetimePosition start) {
1119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Shorten live range %d to [%d\n", vreg(), start.value());
1120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(first_interval_ != nullptr);
1121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(first_interval_->start() <= start);
1122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(start < first_interval_->end());
1123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  first_interval_->set_start(start);
1124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::EnsureInterval(LifetimePosition start,
1128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       LifetimePosition end, Zone* zone) {
1129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Ensure live range %d in interval [%d %d[\n", vreg(), start.value(),
1130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        end.value());
1131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition new_end = end;
1132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (first_interval_ != nullptr && first_interval_->start() <= end) {
1133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (first_interval_->end() > end) {
1134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      new_end = first_interval_->end();
1135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    first_interval_ = first_interval_->next();
1137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UseInterval* new_interval = new (zone) UseInterval(start, new_end);
1140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  new_interval->set_next(first_interval_);
1141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  first_interval_ = new_interval;
1142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (new_interval->next() == nullptr) {
1143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    last_interval_ = new_interval;
1144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::AddUseInterval(LifetimePosition start,
1149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       LifetimePosition end, Zone* zone) {
1150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Add to live range %d interval [%d %d[\n", vreg(), start.value(),
1151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        end.value());
1152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (first_interval_ == nullptr) {
1153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UseInterval* interval = new (zone) UseInterval(start, end);
1154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    first_interval_ = interval;
1155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    last_interval_ = interval;
1156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (end == first_interval_->start()) {
1158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      first_interval_->set_start(start);
1159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (end < first_interval_->start()) {
1160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UseInterval* interval = new (zone) UseInterval(start, end);
1161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      interval->set_next(first_interval_);
1162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      first_interval_ = interval;
1163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
1164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Order of instruction's processing (see ProcessInstructions) guarantees
1165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // that each new use interval either precedes or intersects with
1166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // last added interval.
1167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(start < first_interval_->end());
1168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      first_interval_->set_start(Min(start, first_interval_->start()));
1169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      first_interval_->set_end(Max(end, first_interval_->end()));
1170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1171958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1173958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1174958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::AddUsePosition(UsePosition* use_pos) {
1176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition pos = use_pos->pos();
1177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Add to live range %d use position %d\n", vreg(), pos.value());
1178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePosition* prev_hint = nullptr;
1179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePosition* prev = nullptr;
1180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePosition* current = first_pos_;
1181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (current != nullptr && current->pos() < pos) {
1182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    prev_hint = current->HasHint() ? current : prev_hint;
1183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    prev = current;
1184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    current = current->next();
1185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (prev == nullptr) {
1188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    use_pos->set_next(first_pos_);
1189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    first_pos_ = use_pos;
1190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    use_pos->set_next(prev->next());
1192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    prev->set_next(use_pos);
1193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (prev_hint == nullptr && use_pos->HasHint()) {
1196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    current_hint_position_ = use_pos;
1197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1198958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1199958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1200958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1201958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic bool AreUseIntervalsIntersecting(UseInterval* interval1,
1202958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                        UseInterval* interval2) {
1203958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  while (interval1 != nullptr && interval2 != nullptr) {
1204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (interval1->start() < interval2->start()) {
1205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (interval1->end() > interval2->start()) {
1206958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        return true;
1207958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
1208958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      interval1 = interval1->next();
1209958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {
1210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (interval2->end() > interval1->start()) {
1211958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        return true;
1212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1213958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      interval2 = interval2->next();
1214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1216958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return false;
1217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstd::ostream& operator<<(std::ostream& os,
1221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         const PrintableLiveRange& printable_range) {
1222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const LiveRange* range = printable_range.range_;
1223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  os << "Range: " << range->TopLevel()->vreg() << ":" << range->relative_id()
1224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch     << " ";
1225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (range->TopLevel()->is_phi()) os << "phi ";
1226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (range->TopLevel()->is_non_loop_phi()) os << "nlphi ";
1227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  os << "{" << std::endl;
1229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UseInterval* interval = range->first_interval();
1230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePosition* use_pos = range->first_pos();
1231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  PrintableInstructionOperand pio;
1232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  pio.register_configuration_ = printable_range.register_configuration_;
1233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (use_pos != nullptr) {
1234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (use_pos->HasOperand()) {
1235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      pio.op_ = *use_pos->operand();
1236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      os << pio << use_pos->pos() << " ";
1237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    use_pos = use_pos->next();
1239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  os << std::endl;
1241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (interval != nullptr) {
1243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    os << '[' << interval->start() << ", " << interval->end() << ')'
1244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       << std::endl;
1245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    interval = interval->next();
1246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  os << "}";
1248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return os;
1249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochSpillRange::SpillRange(TopLevelLiveRange* parent, Zone* zone)
1253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : live_ranges_(zone),
1254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      assigned_slot_(kUnassignedSlot),
1255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      byte_width_(GetByteWidth(parent->representation())),
1256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      kind_(parent->kind()) {
1257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Spill ranges are created for top level, non-splintered ranges. This is so
1258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // that, when merging decisions are made, we consider the full extent of the
1259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // virtual register, and avoid clobbering it.
1260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!parent->IsSplinter());
1261958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  UseInterval* result = nullptr;
1262958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  UseInterval* node = nullptr;
1263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Copy the intervals for all ranges.
1264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (LiveRange* range = parent; range != nullptr; range = range->next()) {
1265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UseInterval* src = range->first_interval();
1266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    while (src != nullptr) {
1267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UseInterval* new_node = new (zone) UseInterval(src->start(), src->end());
1268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (result == nullptr) {
1269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        result = new_node;
1270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        node->set_next(new_node);
1272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      node = new_node;
1274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      src = src->next();
1275958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  use_interval_ = result;
1278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  live_ranges().push_back(parent);
1279958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  end_position_ = node->end();
1280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  parent->SetSpillRange(this);
1281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint SpillRange::ByteWidth() const {
1285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return GetByteWidth(live_ranges_[0]->representation());
1286958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1287958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1288958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1289958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool SpillRange::IsIntersectingWith(SpillRange* other) const {
1290958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (this->use_interval_ == nullptr || other->use_interval_ == nullptr ||
1291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      this->End() <= other->use_interval_->start() ||
1292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      other->End() <= this->use_interval_->start()) {
1293958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return false;
1294958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1295958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return AreUseIntervalsIntersecting(use_interval_, other->use_interval_);
1296958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1297958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1298958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1299958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool SpillRange::TryMerge(SpillRange* other) {
1300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (HasSlot() || other->HasSlot()) return false;
1301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // TODO(dcarney): byte widths should be compared here not kinds.
1302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (live_ranges_[0]->kind() != other->live_ranges_[0]->kind() ||
1303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      IsIntersectingWith(other)) {
1304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return false;
1305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1306958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition max = LifetimePosition::MaxPosition();
1308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (End() < other->End() && other->End() != max) {
1309958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    end_position_ = other->End();
1310958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1311958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  other->end_position_ = max;
1312958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1313958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MergeDisjointIntervals(other->use_interval_);
1314958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  other->use_interval_ = nullptr;
1315958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (TopLevelLiveRange* range : other->live_ranges()) {
1317958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(range->GetSpillRange() == other);
1318958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    range->SetSpillRange(this);
1319958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1320958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1321958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  live_ranges().insert(live_ranges().end(), other->live_ranges().begin(),
1322958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                       other->live_ranges().end());
1323958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  other->live_ranges().clear();
1324958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1325958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return true;
1326958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1327958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1328958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1329958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid SpillRange::MergeDisjointIntervals(UseInterval* other) {
1330958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  UseInterval* tail = nullptr;
1331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UseInterval* current = use_interval_;
1332958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  while (other != nullptr) {
1333958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // Make sure the 'current' list starts first
1334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (current == nullptr || current->start() > other->start()) {
1335958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      std::swap(current, other);
1336958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1337958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // Check disjointness
1338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(other == nullptr || current->end() <= other->start());
1339958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // Append the 'current' node to the result accumulator and move forward
1340958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (tail == nullptr) {
1341958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      use_interval_ = current;
1342958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {
1343958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      tail->set_next(current);
1344958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1345958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    tail = current;
1346958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    current = current->next();
1347958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1348958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Other list is empty => we are done
1349958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1350958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1351958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid SpillRange::Print() const {
1353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  OFStream os(stdout);
1354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  os << "{" << std::endl;
1355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (TopLevelLiveRange* range : live_ranges()) {
1356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    os << range->vreg() << " ";
1357958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  os << std::endl;
1359958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (UseInterval* i = interval(); i != nullptr; i = i->next()) {
1361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    os << '[' << i->start() << ", " << i->end() << ')' << std::endl;
1362958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  os << "}" << std::endl;
1364958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1365958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1366958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochRegisterAllocationData::PhiMapValue::PhiMapValue(PhiInstruction* phi,
1368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                 const InstructionBlock* block,
1369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                 Zone* zone)
1370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : phi_(phi),
1371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      block_(block),
1372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      incoming_operands_(zone),
1373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      assigned_register_(kUnassignedRegister) {
1374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  incoming_operands_.reserve(phi->operands().size());
1375958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1376958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1377958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid RegisterAllocationData::PhiMapValue::AddOperand(
1379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand* operand) {
1380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  incoming_operands_.push_back(operand);
1381958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1382958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1383958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid RegisterAllocationData::PhiMapValue::CommitAssignment(
1385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const InstructionOperand& assigned) {
1386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (InstructionOperand* operand : incoming_operands_) {
1387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand::ReplaceWith(operand, &assigned);
1388958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1390958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1391958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochRegisterAllocationData::RegisterAllocationData(
1393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const RegisterConfiguration* config, Zone* zone, Frame* frame,
1394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionSequence* code, const char* debug_name)
1395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : allocation_zone_(zone),
1396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      frame_(frame),
1397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      code_(code),
1398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      debug_name_(debug_name),
1399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      config_(config),
1400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      phi_map_(allocation_zone()),
1401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      live_in_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()),
1402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      live_out_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()),
1403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      live_ranges_(code->VirtualRegisterCount() * 2, nullptr,
1404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                   allocation_zone()),
1405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      fixed_live_ranges_(this->config()->num_general_registers(), nullptr,
1406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         allocation_zone()),
1407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      fixed_double_live_ranges_(this->config()->num_double_registers(), nullptr,
1408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                allocation_zone()),
1409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      spill_ranges_(code->VirtualRegisterCount(), nullptr, allocation_zone()),
1410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      delayed_references_(allocation_zone()),
1411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      assigned_registers_(nullptr),
1412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      assigned_double_registers_(nullptr),
1413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      virtual_register_count_(code->VirtualRegisterCount()),
1414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      preassigned_slot_ranges_(zone) {
1415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assigned_registers_ = new (code_zone())
1416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      BitVector(this->config()->num_general_registers(), code_zone());
1417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assigned_double_registers_ = new (code_zone())
1418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      BitVector(this->config()->num_double_registers(), code_zone());
1419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  this->frame()->SetAllocatedRegisters(assigned_registers_);
1420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  this->frame()->SetAllocatedDoubleRegisters(assigned_double_registers_);
1421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1422958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1423958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochMoveOperands* RegisterAllocationData::AddGapMove(
1425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int index, Instruction::GapPosition position,
1426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const InstructionOperand& from, const InstructionOperand& to) {
1427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Instruction* instr = code()->InstructionAt(index);
1428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ParallelMove* moves = instr->GetOrCreateParallelMove(position, code_zone());
1429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return moves->AddMove(from, to);
1430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochMachineRepresentation RegisterAllocationData::RepresentationFor(
1434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int virtual_register) {
1435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_LT(virtual_register, code()->VirtualRegisterCount());
1436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return code()->GetRepresentation(virtual_register);
1437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTopLevelLiveRange* RegisterAllocationData::GetOrCreateLiveRangeFor(int index) {
1441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (index >= static_cast<int>(live_ranges().size())) {
1442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    live_ranges().resize(index + 1, nullptr);
1443958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TopLevelLiveRange* result = live_ranges()[index];
1445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (result == nullptr) {
1446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    result = NewLiveRange(index, RepresentationFor(index));
1447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    live_ranges()[index] = result;
1448958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return result;
1450958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1451958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1452958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTopLevelLiveRange* RegisterAllocationData::NewLiveRange(
1454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int index, MachineRepresentation rep) {
1455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return new (allocation_zone()) TopLevelLiveRange(index, rep);
1456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint RegisterAllocationData::GetNextLiveRangeId() {
1460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int vreg = virtual_register_count_++;
1461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (vreg >= static_cast<int>(live_ranges().size())) {
1462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    live_ranges().resize(vreg + 1, nullptr);
1463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return vreg;
1465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTopLevelLiveRange* RegisterAllocationData::NextLiveRange(
1469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MachineRepresentation rep) {
1470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int vreg = GetNextLiveRangeId();
1471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TopLevelLiveRange* ret = NewLiveRange(vreg, rep);
1472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return ret;
1473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochRegisterAllocationData::PhiMapValue* RegisterAllocationData::InitializePhiMap(
1477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const InstructionBlock* block, PhiInstruction* phi) {
1478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RegisterAllocationData::PhiMapValue* map_value = new (allocation_zone())
1479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      RegisterAllocationData::PhiMapValue(phi, block, allocation_zone());
1480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  auto res =
1481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      phi_map_.insert(std::make_pair(phi->virtual_register(), map_value));
1482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(res.second);
1483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  USE(res);
1484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return map_value;
1485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochRegisterAllocationData::PhiMapValue* RegisterAllocationData::GetPhiMapValueFor(
1489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int virtual_register) {
1490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  auto it = phi_map_.find(virtual_register);
1491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(it != phi_map_.end());
1492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return it->second;
1493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochRegisterAllocationData::PhiMapValue* RegisterAllocationData::GetPhiMapValueFor(
1497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TopLevelLiveRange* top_range) {
1498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return GetPhiMapValueFor(top_range->vreg());
1499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool RegisterAllocationData::ExistsUseWithoutDefinition() {
1503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool found = false;
1504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BitVector::Iterator iterator(live_in_sets()[0]);
1505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (!iterator.Done()) {
1506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    found = true;
1507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int operand_index = iterator.Current();
1508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintF("Register allocator error: live v%d reached first block.\n",
1509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           operand_index);
1510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* range = GetOrCreateLiveRangeFor(operand_index);
1511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintF("  (first use is at %d)\n", range->first_pos()->pos().value());
1512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (debug_name() == nullptr) {
1513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      PrintF("\n");
1514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
1515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      PrintF("  (function: %s)\n", debug_name());
1516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    iterator.Advance();
1518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return found;
1520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// If a range is defined in a deferred block, we can expect all the range
1524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// to only cover positions in deferred blocks. Otherwise, a block on the
1525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// hot path would be dominated by a deferred block, meaning it is unreachable
1526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// without passing through the deferred block, which is contradictory.
1527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// In particular, when such a range contributes a result back on the hot
1528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// path, it will be as one of the inputs of a phi. In that case, the value
1529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// will be transferred via a move in the Gap::END's of the last instruction
1530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// of a deferred block.
1531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool RegisterAllocationData::RangesDefinedInDeferredStayInDeferred() {
1532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (const TopLevelLiveRange* range : live_ranges()) {
1533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range == nullptr || range->IsEmpty() ||
1534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        !code()
1535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             ->GetInstructionBlock(range->Start().ToInstructionIndex())
1536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             ->IsDeferred()) {
1537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      continue;
1538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (const UseInterval* i = range->first_interval(); i != nullptr;
1540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         i = i->next()) {
1541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int first = i->FirstGapIndex();
1542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int last = i->LastGapIndex();
1543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (int instr = first; instr <= last;) {
1544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        const InstructionBlock* block = code()->GetInstructionBlock(instr);
1545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (!block->IsDeferred()) return false;
1546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        instr = block->last_instruction_index() + 1;
1547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return true;
1551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochSpillRange* RegisterAllocationData::AssignSpillRangeToLiveRange(
1554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TopLevelLiveRange* range) {
1555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!range->HasSpillOperand());
1556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SpillRange* spill_range = range->GetAllocatedSpillRange();
1558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (spill_range == nullptr) {
1559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!range->IsSplinter());
1560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    spill_range = new (allocation_zone()) SpillRange(range, allocation_zone());
1561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  range->set_spill_type(TopLevelLiveRange::SpillType::kSpillRange);
1563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int spill_range_index =
1565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      range->IsSplinter() ? range->splintered_from()->vreg() : range->vreg();
1566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  spill_ranges()[spill_range_index] = spill_range;
1568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return spill_range;
1570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochSpillRange* RegisterAllocationData::CreateSpillRangeForLiveRange(
1574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TopLevelLiveRange* range) {
1575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!range->HasSpillOperand());
1576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!range->IsSplinter());
1577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SpillRange* spill_range =
1578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      new (allocation_zone()) SpillRange(range, allocation_zone());
1579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return spill_range;
1580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid RegisterAllocationData::MarkAllocated(RegisterKind kind, int index) {
1584bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  if (kind == FP_REGISTERS) {
1585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    assigned_double_registers_->Add(index);
1586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(kind == GENERAL_REGISTERS);
1588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    assigned_registers_->Add(index);
1589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool RegisterAllocationData::IsBlockBoundary(LifetimePosition pos) const {
1594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return pos.IsFullStart() &&
1595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         code()->GetInstructionBlock(pos.ToInstructionIndex())->code_start() ==
1596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             pos.ToInstructionIndex();
1597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochConstraintBuilder::ConstraintBuilder(RegisterAllocationData* data)
1601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : data_(data) {}
1602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochInstructionOperand* ConstraintBuilder::AllocateFixed(
1605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UnallocatedOperand* operand, int pos, bool is_tagged) {
1606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Allocating fixed reg for op %d\n", operand->virtual_register());
1607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(operand->HasFixedPolicy());
1608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand allocated;
1609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MachineRepresentation rep = InstructionSequence::DefaultRepresentation();
1610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int virtual_register = operand->virtual_register();
1611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (virtual_register != InstructionOperand::kInvalidVirtualRegister) {
1612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    rep = data()->RepresentationFor(virtual_register);
1613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (operand->HasFixedSlotPolicy()) {
1615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    allocated = AllocatedOperand(AllocatedOperand::STACK_SLOT, rep,
1616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 operand->fixed_slot_index());
1617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (operand->HasFixedRegisterPolicy()) {
1618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!IsFloatingPoint(rep));
1619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    allocated = AllocatedOperand(AllocatedOperand::REGISTER, rep,
1620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 operand->fixed_register_index());
1621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (operand->HasFixedDoubleRegisterPolicy()) {
1622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(IsFloatingPoint(rep));
1623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_NE(InstructionOperand::kInvalidVirtualRegister, virtual_register);
1624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    allocated = AllocatedOperand(AllocatedOperand::REGISTER, rep,
1625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 operand->fixed_register_index());
1626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UNREACHABLE();
1628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand::ReplaceWith(operand, &allocated);
1630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (is_tagged) {
1631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TRACE("Fixed reg is tagged at %d\n", pos);
1632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Instruction* instr = code()->InstructionAt(pos);
1633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (instr->HasReferenceMap()) {
1634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      instr->reference_map()->RecordReference(*AllocatedOperand::cast(operand));
1635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return operand;
1638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid ConstraintBuilder::MeetRegisterConstraints() {
1642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (InstructionBlock* block : code()->instruction_blocks()) {
1643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MeetRegisterConstraints(block);
1644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid ConstraintBuilder::MeetRegisterConstraints(const InstructionBlock* block) {
1649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int start = block->first_instruction_index();
1650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int end = block->last_instruction_index();
1651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_NE(-1, start);
1652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = start; i <= end; ++i) {
1653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MeetConstraintsBefore(i);
1654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (i != end) MeetConstraintsAfter(i);
1655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Meet register constraints for the instruction in the end.
1657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MeetRegisterConstraintsForLastInstructionInBlock(block);
1658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid ConstraintBuilder::MeetRegisterConstraintsForLastInstructionInBlock(
1662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const InstructionBlock* block) {
1663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int end = block->last_instruction_index();
1664014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Instruction* last_instruction = code()->InstructionAt(end);
1665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < last_instruction->OutputCount(); i++) {
1666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand* output_operand = last_instruction->OutputAt(i);
1667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!output_operand->IsConstant());
1668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UnallocatedOperand* output = UnallocatedOperand::cast(output_operand);
1669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int output_vreg = output->virtual_register();
1670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TopLevelLiveRange* range = data()->GetOrCreateLiveRangeFor(output_vreg);
1671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool assigned = false;
1672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (output->HasFixedPolicy()) {
1673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      AllocateFixed(output, -1, false);
1674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // This value is produced on the stack, we never need to spill it.
1675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (output->IsStackSlot()) {
1676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(LocationOperand::cast(output)->index() <
1677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               data()->frame()->GetSpillSlotCount());
1678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->SetSpillOperand(LocationOperand::cast(output));
1679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->SetSpillStartIndex(end);
1680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        assigned = true;
1681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (const RpoNumber& succ : block->successors()) {
1684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        const InstructionBlock* successor = code()->InstructionBlockAt(succ);
1685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(successor->PredecessorCount() == 1);
1686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int gap_index = successor->first_instruction_index();
1687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Create an unconstrained operand for the same virtual register
1688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // and insert a gap move from the fixed output to the operand.
1689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UnallocatedOperand output_copy(UnallocatedOperand::ANY, output_vreg);
1690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        data()->AddGapMove(gap_index, Instruction::START, *output, output_copy);
1691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!assigned) {
1695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (const RpoNumber& succ : block->successors()) {
1696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        const InstructionBlock* successor = code()->InstructionBlockAt(succ);
1697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(successor->PredecessorCount() == 1);
1698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int gap_index = successor->first_instruction_index();
1699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->RecordSpillLocation(allocation_zone(), gap_index, output);
1700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->SetSpillStartIndex(gap_index);
1701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid ConstraintBuilder::MeetConstraintsAfter(int instr_index) {
1708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Instruction* first = code()->InstructionAt(instr_index);
1709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Handle fixed temporaries.
1710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < first->TempCount(); i++) {
1711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UnallocatedOperand* temp = UnallocatedOperand::cast(first->TempAt(i));
1712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (temp->HasFixedPolicy()) AllocateFixed(temp, instr_index, false);
1713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Handle constant/fixed output operands.
1715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < first->OutputCount(); i++) {
1716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand* output = first->OutputAt(i);
1717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (output->IsConstant()) {
1718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int output_vreg = ConstantOperand::cast(output)->virtual_register();
1719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      TopLevelLiveRange* range = data()->GetOrCreateLiveRangeFor(output_vreg);
1720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      range->SetSpillStartIndex(instr_index + 1);
1721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      range->SetSpillOperand(output);
1722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      continue;
1723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UnallocatedOperand* first_output = UnallocatedOperand::cast(output);
1725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TopLevelLiveRange* range =
1726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        data()->GetOrCreateLiveRangeFor(first_output->virtual_register());
1727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool assigned = false;
1728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (first_output->HasFixedPolicy()) {
1729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int output_vreg = first_output->virtual_register();
1730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UnallocatedOperand output_copy(UnallocatedOperand::ANY, output_vreg);
1731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bool is_tagged = code()->IsReference(output_vreg);
1732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (first_output->HasSecondaryStorage()) {
1733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->MarkHasPreassignedSlot();
1734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        data()->preassigned_slot_ranges().push_back(
1735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            std::make_pair(range, first_output->GetSecondaryStorage()));
1736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      AllocateFixed(first_output, instr_index, is_tagged);
1738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // This value is produced on the stack, we never need to spill it.
1740014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (first_output->IsStackSlot()) {
1741014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(LocationOperand::cast(first_output)->index() <
1742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               data()->frame()->GetTotalFrameSlotCount());
1743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->SetSpillOperand(LocationOperand::cast(first_output));
1744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->SetSpillStartIndex(instr_index + 1);
1745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        assigned = true;
1746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      data()->AddGapMove(instr_index + 1, Instruction::START, *first_output,
1748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         output_copy);
1749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Make sure we add a gap move for spilling (if we have not done
1751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // so already).
1752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!assigned) {
1753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      range->RecordSpillLocation(allocation_zone(), instr_index + 1,
1754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 first_output);
1755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      range->SetSpillStartIndex(instr_index + 1);
1756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1760014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid ConstraintBuilder::MeetConstraintsBefore(int instr_index) {
1762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Instruction* second = code()->InstructionAt(instr_index);
1763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Handle fixed input operands of second instruction.
1764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < second->InputCount(); i++) {
1765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand* input = second->InputAt(i);
1766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (input->IsImmediate() || input->IsExplicit()) {
1767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      continue;  // Ignore immediates and explicitly reserved registers.
1768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UnallocatedOperand* cur_input = UnallocatedOperand::cast(input);
1770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (cur_input->HasFixedPolicy()) {
1771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int input_vreg = cur_input->virtual_register();
1772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UnallocatedOperand input_copy(UnallocatedOperand::ANY, input_vreg);
1773014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bool is_tagged = code()->IsReference(input_vreg);
1774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      AllocateFixed(cur_input, instr_index, is_tagged);
1775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      data()->AddGapMove(instr_index, Instruction::END, input_copy, *cur_input);
1776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Handle "output same as input" for second instruction.
1779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < second->OutputCount(); i++) {
1780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand* output = second->OutputAt(i);
1781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!output->IsUnallocated()) continue;
1782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UnallocatedOperand* second_output = UnallocatedOperand::cast(output);
1783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!second_output->HasSameAsInputPolicy()) continue;
1784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(i == 0);  // Only valid for first output.
1785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UnallocatedOperand* cur_input =
1786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UnallocatedOperand::cast(second->InputAt(0));
1787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int output_vreg = second_output->virtual_register();
1788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int input_vreg = cur_input->virtual_register();
1789014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UnallocatedOperand input_copy(UnallocatedOperand::ANY, input_vreg);
1790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    cur_input->set_virtual_register(second_output->virtual_register());
1791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MoveOperands* gap_move = data()->AddGapMove(instr_index, Instruction::END,
1792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                input_copy, *cur_input);
1793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (code()->IsReference(input_vreg) && !code()->IsReference(output_vreg)) {
1794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (second->HasReferenceMap()) {
1795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        RegisterAllocationData::DelayedReference delayed_reference = {
1796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            second->reference_map(), &gap_move->source()};
1797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        data()->delayed_references().push_back(delayed_reference);
1798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (!code()->IsReference(input_vreg) &&
1800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               code()->IsReference(output_vreg)) {
1801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // The input is assumed to immediately have a tagged representation,
1802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // before the pointer map can be used. I.e. the pointer map at the
1803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // instruction will include the output operand (whose value at the
1804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // beginning of the instruction is equal to the input operand). If
1805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // this is not desired, then the pointer map at this instruction needs
1806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // to be adjusted manually.
1807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid ConstraintBuilder::ResolvePhis() {
1813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Process the blocks in reverse order.
1814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (InstructionBlock* block : base::Reversed(code()->instruction_blocks())) {
1815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ResolvePhis(block);
1816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid ConstraintBuilder::ResolvePhis(const InstructionBlock* block) {
1821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (PhiInstruction* phi : block->phis()) {
1822958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    int phi_vreg = phi->virtual_register();
1823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    RegisterAllocationData::PhiMapValue* map_value =
1824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        data()->InitializePhiMap(block, phi);
1825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand& output = phi->output();
1826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Map the destination operands, so the commitment phase can find them.
1827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (size_t i = 0; i < phi->operands().size(); ++i) {
1828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionBlock* cur_block =
1829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          code()->InstructionBlockAt(block->predecessors()[i]);
1830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UnallocatedOperand input(UnallocatedOperand::ANY, phi->operands()[i]);
1831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      MoveOperands* move = data()->AddGapMove(
1832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          cur_block->last_instruction_index(), Instruction::END, input, output);
1833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      map_value->AddOperand(&move->destination());
1834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(!code()
1835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  ->InstructionAt(cur_block->last_instruction_index())
1836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  ->HasReferenceMap());
1837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TopLevelLiveRange* live_range = data()->GetOrCreateLiveRangeFor(phi_vreg);
1839958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    int gap_index = block->first_instruction_index();
1840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    live_range->RecordSpillLocation(allocation_zone(), gap_index, &output);
1841958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    live_range->SetSpillStartIndex(gap_index);
1842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // We use the phi-ness of some nodes in some later heuristics.
1843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    live_range->set_is_phi(true);
1844958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    live_range->set_is_non_loop_phi(!block->IsLoopHeader());
1845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLiveRangeBuilder::LiveRangeBuilder(RegisterAllocationData* data,
1850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                   Zone* local_zone)
1851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : data_(data), phi_hints_(local_zone) {}
1852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochBitVector* LiveRangeBuilder::ComputeLiveOut(const InstructionBlock* block,
1855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            RegisterAllocationData* data) {
1856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t block_index = block->rpo_number().ToSize();
1857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BitVector* live_out = data->live_out_sets()[block_index];
1858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (live_out == nullptr) {
1859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Compute live out for the given block, except not including backward
1860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // successor edges.
1861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Zone* zone = data->allocation_zone();
1862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const InstructionSequence* code = data->code();
1863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    live_out = new (zone) BitVector(code->VirtualRegisterCount(), zone);
1865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Process all successor blocks.
1867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (const RpoNumber& succ : block->successors()) {
1868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Add values live on entry to the successor.
1869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (succ <= block->rpo_number()) continue;
1870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      BitVector* live_in = data->live_in_sets()[succ.ToSize()];
1871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (live_in != nullptr) live_out->Union(*live_in);
1872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // All phi input operands corresponding to this successor edge are live
1874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // out from this block.
1875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      const InstructionBlock* successor = code->InstructionBlockAt(succ);
1876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      size_t index = successor->PredecessorIndexOf(block->rpo_number());
1877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(index < successor->PredecessorCount());
1878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (PhiInstruction* phi : successor->phis()) {
1879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        live_out->Add(phi->operands()[index]);
1880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    data->live_out_sets()[block_index] = live_out;
1883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return live_out;
1885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRangeBuilder::AddInitialIntervals(const InstructionBlock* block,
1889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           BitVector* live_out) {
1890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Add an interval that includes the entire block to the live range for
1891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // each live_out value.
1892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition start = LifetimePosition::GapFromInstructionIndex(
1893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      block->first_instruction_index());
1894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition end = LifetimePosition::InstructionFromInstructionIndex(
1895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             block->last_instruction_index())
1896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             .NextStart();
1897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BitVector::Iterator iterator(live_out);
1898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (!iterator.Done()) {
1899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int operand_index = iterator.Current();
1900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TopLevelLiveRange* range = data()->GetOrCreateLiveRangeFor(operand_index);
1901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    range->AddUseInterval(start, end, allocation_zone());
1902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    iterator.Advance();
1903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint LiveRangeBuilder::FixedDoubleLiveRangeID(int index) {
1908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return -index - 1 - config()->num_general_registers();
1909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTopLevelLiveRange* LiveRangeBuilder::FixedLiveRangeFor(int index) {
1913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(index < config()->num_general_registers());
1914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TopLevelLiveRange* result = data()->fixed_live_ranges()[index];
1915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (result == nullptr) {
1916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    result = data()->NewLiveRange(FixedLiveRangeID(index),
1917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  InstructionSequence::DefaultRepresentation());
1918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(result->IsFixed());
1919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    result->set_assigned_register(index);
1920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    data()->MarkAllocated(GENERAL_REGISTERS, index);
1921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    data()->fixed_live_ranges()[index] = result;
1922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return result;
1924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTopLevelLiveRange* LiveRangeBuilder::FixedDoubleLiveRangeFor(int index) {
1928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(index < config()->num_double_registers());
1929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TopLevelLiveRange* result = data()->fixed_double_live_ranges()[index];
1930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (result == nullptr) {
1931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    result = data()->NewLiveRange(FixedDoubleLiveRangeID(index),
1932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  MachineRepresentation::kFloat64);
1933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(result->IsFixed());
1934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    result->set_assigned_register(index);
1935bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    data()->MarkAllocated(FP_REGISTERS, index);
1936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    data()->fixed_double_live_ranges()[index] = result;
1937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return result;
1939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTopLevelLiveRange* LiveRangeBuilder::LiveRangeFor(InstructionOperand* operand) {
1943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (operand->IsUnallocated()) {
1944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return data()->GetOrCreateLiveRangeFor(
1945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UnallocatedOperand::cast(operand)->virtual_register());
1946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (operand->IsConstant()) {
1947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return data()->GetOrCreateLiveRangeFor(
1948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        ConstantOperand::cast(operand)->virtual_register());
1949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (operand->IsRegister()) {
1950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return FixedLiveRangeFor(
1951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        LocationOperand::cast(operand)->GetRegister().code());
1952bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  } else if (operand->IsFPRegister()) {
1953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return FixedDoubleLiveRangeFor(
1954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        LocationOperand::cast(operand)->GetDoubleRegister().code());
1955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return nullptr;
1957958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1959958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1960958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochUsePosition* LiveRangeBuilder::NewUsePosition(LifetimePosition pos,
1962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                              InstructionOperand* operand,
1963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                              void* hint,
1964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                              UsePositionHintType hint_type) {
1965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return new (allocation_zone()) UsePosition(pos, operand, hint, hint_type);
1966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1967958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1968958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochUsePosition* LiveRangeBuilder::Define(LifetimePosition position,
1970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                      InstructionOperand* operand, void* hint,
1971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                      UsePositionHintType hint_type) {
1972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TopLevelLiveRange* range = LiveRangeFor(operand);
1973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (range == nullptr) return nullptr;
1974958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (range->IsEmpty() || range->Start() > position) {
1976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Can happen if there is a definition without use.
1977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    range->AddUseInterval(position, position.NextStart(), allocation_zone());
1978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    range->AddUsePosition(NewUsePosition(position.NextStart()));
1979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    range->ShortenTo(position);
1981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!operand->IsUnallocated()) return nullptr;
1983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UnallocatedOperand* unalloc_operand = UnallocatedOperand::cast(operand);
1984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePosition* use_pos =
1985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      NewUsePosition(position, unalloc_operand, hint, hint_type);
1986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  range->AddUsePosition(use_pos);
1987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return use_pos;
1988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1989958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1990958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochUsePosition* LiveRangeBuilder::Use(LifetimePosition block_start,
1992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                   LifetimePosition position,
1993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                   InstructionOperand* operand, void* hint,
1994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                   UsePositionHintType hint_type) {
1995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TopLevelLiveRange* range = LiveRangeFor(operand);
1996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (range == nullptr) return nullptr;
1997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePosition* use_pos = nullptr;
1998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (operand->IsUnallocated()) {
1999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UnallocatedOperand* unalloc_operand = UnallocatedOperand::cast(operand);
2000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    use_pos = NewUsePosition(position, unalloc_operand, hint, hint_type);
2001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    range->AddUsePosition(use_pos);
2002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  range->AddUseInterval(block_start, position, allocation_zone());
2004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return use_pos;
2005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2006958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2007958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRangeBuilder::ProcessInstructions(const InstructionBlock* block,
2009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           BitVector* live) {
2010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int block_start = block->first_instruction_index();
2011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition block_start_position =
2012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LifetimePosition::GapFromInstructionIndex(block_start);
2013958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int index = block->last_instruction_index(); index >= block_start;
2015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       index--) {
2016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition curr_position =
2017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        LifetimePosition::InstructionFromInstructionIndex(index);
2018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Instruction* instr = code()->InstructionAt(index);
2019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(instr != nullptr);
2020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(curr_position.IsInstructionPosition());
2021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Process output, inputs, and temps of this instruction.
2022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (size_t i = 0; i < instr->OutputCount(); i++) {
2023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionOperand* output = instr->OutputAt(i);
2024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (output->IsUnallocated()) {
2025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Unsupported.
2026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(!UnallocatedOperand::cast(output)->HasSlotPolicy());
2027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int out_vreg = UnallocatedOperand::cast(output)->virtual_register();
2028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        live->Remove(out_vreg);
2029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else if (output->IsConstant()) {
2030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int out_vreg = ConstantOperand::cast(output)->virtual_register();
2031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        live->Remove(out_vreg);
2032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (block->IsHandler() && index == block_start && output->IsAllocated() &&
2034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          output->IsRegister() &&
2035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          AllocatedOperand::cast(output)->GetRegister().is(
2036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              v8::internal::kReturnRegister0)) {
2037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // The register defined here is blocked from gap start - it is the
2038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // exception value.
2039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // TODO(mtrofin): should we explore an explicit opcode for
2040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // the first instruction in the handler?
2041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Define(LifetimePosition::GapFromInstructionIndex(index), output);
2042958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      } else {
2043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Define(curr_position, output);
2044958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
2045958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2046958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (instr->ClobbersRegisters()) {
2048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (int i = 0; i < config()->num_allocatable_general_registers(); ++i) {
2049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int code = config()->GetAllocatableGeneralCode(i);
2050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (!IsOutputRegisterOf(instr, Register::from_code(code))) {
2051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          TopLevelLiveRange* range = FixedLiveRangeFor(code);
2052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          range->AddUseInterval(curr_position, curr_position.End(),
2053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                allocation_zone());
2054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
2055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2056958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2057958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2058014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (instr->ClobbersDoubleRegisters()) {
2059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (int i = 0; i < config()->num_allocatable_aliased_double_registers();
2060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           ++i) {
2061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int code = config()->GetAllocatableDoubleCode(i);
2062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (!IsOutputDoubleRegisterOf(instr, DoubleRegister::from_code(code))) {
2063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          TopLevelLiveRange* range = FixedDoubleLiveRangeFor(code);
2064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          range->AddUseInterval(curr_position, curr_position.End(),
2065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                allocation_zone());
2066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
2067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2068958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2069958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (size_t i = 0; i < instr->InputCount(); i++) {
2071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionOperand* input = instr->InputAt(i);
2072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (input->IsImmediate() || input->IsExplicit()) {
2073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        continue;  // Ignore immediates and explicitly reserved registers.
2074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LifetimePosition use_pos;
2076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (input->IsUnallocated() &&
2077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          UnallocatedOperand::cast(input)->IsUsedAtStart()) {
2078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        use_pos = curr_position;
2079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
2080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        use_pos = curr_position.End();
2081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2082958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (input->IsUnallocated()) {
2084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UnallocatedOperand* unalloc = UnallocatedOperand::cast(input);
2085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int vreg = unalloc->virtual_register();
2086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        live->Add(vreg);
2087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (unalloc->HasSlotPolicy()) {
2088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          data()->GetOrCreateLiveRangeFor(vreg)->set_has_slot_use(true);
2089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
2090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Use(block_start_position, use_pos, input);
2092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (size_t i = 0; i < instr->TempCount(); i++) {
2095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionOperand* temp = instr->TempAt(i);
2096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Unsupported.
2097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK_IMPLIES(temp->IsUnallocated(),
2098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                     !UnallocatedOperand::cast(temp)->HasSlotPolicy());
2099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->ClobbersTemps()) {
2100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (temp->IsRegister()) continue;
2101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (temp->IsUnallocated()) {
2102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          UnallocatedOperand* temp_unalloc = UnallocatedOperand::cast(temp);
2103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          if (temp_unalloc->HasFixedPolicy()) {
2104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            continue;
2105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
2106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
2107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Use(block_start_position, curr_position.End(), temp);
2109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Define(curr_position, temp);
2110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Process the moves of the instruction's gaps, making their sources live.
2113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const Instruction::GapPosition kPositions[] = {Instruction::END,
2114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                   Instruction::START};
2115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    curr_position = curr_position.PrevStart();
2116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(curr_position.IsGapPosition());
2117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (const Instruction::GapPosition& position : kPositions) {
2118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ParallelMove* move = instr->GetParallelMove(position);
2119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (move == nullptr) continue;
2120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (position == Instruction::END) {
2121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        curr_position = curr_position.End();
2122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
2123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        curr_position = curr_position.Start();
2124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (MoveOperands* cur : *move) {
2126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        InstructionOperand& from = cur->source();
2127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        InstructionOperand& to = cur->destination();
2128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        void* hint = &to;
2129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UsePositionHintType hint_type = UsePosition::HintTypeForOperand(to);
2130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UsePosition* to_use = nullptr;
2131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int phi_vreg = -1;
2132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (to.IsUnallocated()) {
2133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          int to_vreg = UnallocatedOperand::cast(to).virtual_register();
2134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          TopLevelLiveRange* to_range =
2135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              data()->GetOrCreateLiveRangeFor(to_vreg);
2136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          if (to_range->is_phi()) {
2137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            phi_vreg = to_vreg;
2138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            if (to_range->is_non_loop_phi()) {
2139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              hint = to_range->current_hint_position();
2140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              hint_type = hint == nullptr ? UsePositionHintType::kNone
2141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                          : UsePositionHintType::kUsePos;
2142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            } else {
2143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              hint_type = UsePositionHintType::kPhi;
2144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              hint = data()->GetPhiMapValueFor(to_vreg);
2145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            }
2146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          } else {
2147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            if (live->Contains(to_vreg)) {
2148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              to_use = Define(curr_position, &to, &from,
2149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              UsePosition::HintTypeForOperand(from));
2150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              live->Remove(to_vreg);
2151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            } else {
2152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              cur->Eliminate();
2153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              continue;
2154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            }
2155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
2156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else {
2157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Define(curr_position, &to);
2158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
2159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UsePosition* from_use =
2160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Use(block_start_position, curr_position, &from, hint, hint_type);
2161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Mark range live.
2162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (from.IsUnallocated()) {
2163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          live->Add(UnallocatedOperand::cast(from).virtual_register());
2164958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        }
2165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Resolve use position hints just created.
2166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (to_use != nullptr && from_use != nullptr) {
2167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          to_use->ResolveHint(from_use);
2168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          from_use->ResolveHint(to_use);
2169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
2170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK_IMPLIES(to_use != nullptr, to_use->IsResolved());
2171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK_IMPLIES(from_use != nullptr, from_use->IsResolved());
2172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Potentially resolve phi hint.
2173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (phi_vreg != -1) ResolvePhiHint(&from, from_use);
2174958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
2175958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRangeBuilder::ProcessPhis(const InstructionBlock* block,
2181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                   BitVector* live) {
2182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (PhiInstruction* phi : block->phis()) {
2183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // The live range interval already ends at the first instruction of the
2184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // block.
2185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int phi_vreg = phi->virtual_register();
2186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    live->Remove(phi_vreg);
2187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand* hint = nullptr;
21883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    const InstructionBlock::Predecessors& predecessors = block->predecessors();
21893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    const InstructionBlock* predecessor_block =
21903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        code()->InstructionBlockAt(predecessors[0]);
21913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    const Instruction* instr = GetLastInstruction(code(), predecessor_block);
21923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (predecessor_block->IsDeferred()) {
21933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // "Prefer the hint from the first non-deferred predecessor, if any.
21943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      for (size_t i = 1; i < predecessors.size(); ++i) {
21953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        predecessor_block = code()->InstructionBlockAt(predecessors[i]);
21963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        if (!predecessor_block->IsDeferred()) {
21973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          instr = GetLastInstruction(code(), predecessor_block);
21983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          break;
21993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        }
22003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
22013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
22023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    DCHECK_NOT_NULL(instr);
22033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
2204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (MoveOperands* move : *instr->GetParallelMove(Instruction::END)) {
2205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionOperand& to = move->destination();
2206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (to.IsUnallocated() &&
2207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          UnallocatedOperand::cast(to).virtual_register() == phi_vreg) {
2208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        hint = &move->source();
2209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
2210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(hint != nullptr);
2213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition block_start = LifetimePosition::GapFromInstructionIndex(
2214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        block->first_instruction_index());
2215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UsePosition* use_pos = Define(block_start, &phi->output(), hint,
2216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  UsePosition::HintTypeForOperand(*hint));
2217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MapPhiHint(hint, use_pos);
2218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRangeBuilder::ProcessLoopHeader(const InstructionBlock* block,
2223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                         BitVector* live) {
2224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(block->IsLoopHeader());
2225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Add a live range stretching from the first loop instruction to the last
2226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // for each value live on entry to the header.
2227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BitVector::Iterator iterator(live);
2228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition start = LifetimePosition::GapFromInstructionIndex(
2229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      block->first_instruction_index());
2230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition end = LifetimePosition::GapFromInstructionIndex(
2231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             code()->LastLoopInstructionIndex(block))
2232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             .NextFullStart();
2233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (!iterator.Done()) {
2234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int operand_index = iterator.Current();
2235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TopLevelLiveRange* range = data()->GetOrCreateLiveRangeFor(operand_index);
2236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    range->EnsureInterval(start, end, allocation_zone());
2237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    iterator.Advance();
2238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Insert all values into the live in sets of all blocks in the loop.
2240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = block->rpo_number().ToInt() + 1; i < block->loop_end().ToInt();
2241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       ++i) {
2242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    live_in_sets()[i]->Union(*live);
2243958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2244958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2245958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2246958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRangeBuilder::BuildLiveRanges() {
2248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Process the blocks in reverse order.
2249958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (int block_id = code()->InstructionBlockCount() - 1; block_id >= 0;
2250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       --block_id) {
2251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionBlock* block =
2252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        code()->InstructionBlockAt(RpoNumber::FromInt(block_id));
2253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    BitVector* live = ComputeLiveOut(block, data());
2254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Initially consider all live_out values live for the entire block. We
2255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // will shorten these intervals if necessary.
2256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AddInitialIntervals(block, live);
2257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Process the instructions in reverse order, generating and killing
2258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // live values.
2259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ProcessInstructions(block, live);
2260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // All phi output operands are killed by this block.
2261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ProcessPhis(block, live);
2262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Now live is live_in for this block except not including values live
2263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // out on backward successor edges.
2264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (block->IsLoopHeader()) ProcessLoopHeader(block, live);
2265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    live_in_sets()[block_id] = live;
2266958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Postprocess the ranges.
2268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (TopLevelLiveRange* range : data()->live_ranges()) {
2269958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (range == nullptr) continue;
2270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Give slots to all ranges with a non fixed slot use.
2271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range->has_slot_use() && range->HasNoSpillType()) {
2272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      data()->AssignSpillRangeToLiveRange(range);
2273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2274958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // TODO(bmeurer): This is a horrible hack to make sure that for constant
2275958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // live ranges, every use requires the constant to be in a register.
2276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // Without this hack, all uses with "any" policy would get the constant
2277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // operand assigned.
2278958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (range->HasSpillOperand() && range->GetSpillOperand()->IsConstant()) {
2279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (UsePosition* pos = range->first_pos(); pos != nullptr;
2280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           pos = pos->next()) {
2281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (pos->type() == UsePositionType::kRequiresSlot) continue;
2282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UsePositionType new_type = UsePositionType::kAny;
2283958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        // Can't mark phis as needing a register.
2284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (!pos->pos().IsGapPosition()) {
2285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          new_type = UsePositionType::kRequiresRegister;
2286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
2287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        pos->set_type(new_type, true);
2288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (auto preassigned : data()->preassigned_slot_ranges()) {
2292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TopLevelLiveRange* range = preassigned.first;
2293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int slot_id = preassigned.second;
2294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SpillRange* spill = range->HasSpillRange()
2295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            ? range->GetSpillRange()
2296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            : data()->AssignSpillRangeToLiveRange(range);
2297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    spill->set_assigned_slot(slot_id);
2298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifdef DEBUG
2300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Verify();
2301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif
2302958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2304958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRangeBuilder::MapPhiHint(InstructionOperand* operand,
2306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  UsePosition* use_pos) {
2307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!use_pos->IsResolved());
2308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  auto res = phi_hints_.insert(std::make_pair(operand, use_pos));
2309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(res.second);
2310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  USE(res);
2311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRangeBuilder::ResolvePhiHint(InstructionOperand* operand,
2315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                      UsePosition* use_pos) {
2316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  auto it = phi_hints_.find(operand);
2317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (it == phi_hints_.end()) return;
2318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!it->second->IsResolved());
2319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  it->second->ResolveHint(use_pos);
2320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRangeBuilder::Verify() const {
2324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (auto& hint : phi_hints_) {
2325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CHECK(hint.second->IsResolved());
2326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
23273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  for (const TopLevelLiveRange* current : data()->live_ranges()) {
23283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (current != nullptr && !current->IsEmpty()) {
23293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // New LiveRanges should not be split.
23303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      CHECK_NULL(current->next());
23313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // General integrity check.
23323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      current->Verify();
23333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      const UseInterval* first = current->first_interval();
23343b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (first->next() == nullptr) continue;
23353b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
23363b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // Consecutive intervals should not end and start in the same block,
23373b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // otherwise the intervals should have been joined, because the
23383b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // variable is live throughout that block.
23393b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      CHECK(NextIntervalStartsInDifferentBlocks(first));
23403b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
23413b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      for (const UseInterval* i = first->next(); i != nullptr; i = i->next()) {
23423b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // Except for the first interval, the other intevals must start at
23433b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // a block boundary, otherwise data wouldn't flow to them.
23443b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        CHECK(IntervalStartsAtBlockBoundary(i));
23453b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // The last instruction of the predecessors of the block the interval
23463b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // starts must be covered by the range.
23473b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        CHECK(IntervalPredecessorsCoveredByRange(i, current));
23483b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        if (i->next() != nullptr) {
23493b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          // Check the consecutive intervals property, except for the last
23503b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          // interval, where it doesn't apply.
23513b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          CHECK(NextIntervalStartsInDifferentBlocks(i));
23523b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        }
23533b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
23543b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
2355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2356b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
23583b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochbool LiveRangeBuilder::IntervalStartsAtBlockBoundary(
23593b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    const UseInterval* interval) const {
23603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  LifetimePosition start = interval->start();
23613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (!start.IsFullStart()) return false;
23623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  int instruction_index = start.ToInstructionIndex();
23633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  const InstructionBlock* block =
23643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      data()->code()->GetInstructionBlock(instruction_index);
23653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  return block->first_instruction_index() == instruction_index;
23663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
23673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
23683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochbool LiveRangeBuilder::IntervalPredecessorsCoveredByRange(
23693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    const UseInterval* interval, const TopLevelLiveRange* range) const {
23703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  LifetimePosition start = interval->start();
23713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  int instruction_index = start.ToInstructionIndex();
23723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  const InstructionBlock* block =
23733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      data()->code()->GetInstructionBlock(instruction_index);
23743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  for (RpoNumber pred_index : block->predecessors()) {
23753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    const InstructionBlock* predecessor =
23763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        data()->code()->InstructionBlockAt(pred_index);
23773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    LifetimePosition last_pos = LifetimePosition::GapFromInstructionIndex(
23783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        predecessor->last_instruction_index());
23793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    last_pos = last_pos.NextStart().End();
23803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (!range->Covers(last_pos)) return false;
23813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
23823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  return true;
23833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
23843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
23853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochbool LiveRangeBuilder::NextIntervalStartsInDifferentBlocks(
23863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    const UseInterval* interval) const {
23873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DCHECK_NOT_NULL(interval->next());
23883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  LifetimePosition end = interval->end();
23893b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  LifetimePosition next_start = interval->next()->start();
23903b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Since end is not covered, but the previous position is, move back a
23913b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // position
23923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  end = end.IsStart() ? end.PrevStart().End() : end.Start();
23933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  int last_covered_index = end.ToInstructionIndex();
23943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  const InstructionBlock* block =
23953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      data()->code()->GetInstructionBlock(last_covered_index);
23963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  const InstructionBlock* next_block =
23973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      data()->code()->GetInstructionBlock(next_start.ToInstructionIndex());
23983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  return block->rpo_number() < next_block->rpo_number();
23993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
2400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochRegisterAllocator::RegisterAllocator(RegisterAllocationData* data,
2402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     RegisterKind kind)
2403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : data_(data),
2404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      mode_(kind),
2405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      num_registers_(GetRegisterCount(data->config(), kind)),
2406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      num_allocatable_registers_(
2407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          GetAllocatableRegisterCount(data->config(), kind)),
2408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      allocatable_register_codes_(
2409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          GetAllocatableRegisterCodes(data->config(), kind)) {}
2410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLifetimePosition RegisterAllocator::GetSplitPositionForInstruction(
2413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const LiveRange* range, int instruction_index) {
2414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition ret = LifetimePosition::Invalid();
2415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ret = LifetimePosition::GapFromInstructionIndex(instruction_index);
2417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (range->Start() >= ret || ret >= range->End()) {
2418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return LifetimePosition::Invalid();
2419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return ret;
2421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid RegisterAllocator::SplitAndSpillRangesDefinedByMemoryOperand(
2425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool operands_only) {
2426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t initial_range_count = data()->live_ranges().size();
2427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < initial_range_count; ++i) {
2428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TopLevelLiveRange* range = data()->live_ranges()[i];
2429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!CanProcessRange(range)) continue;
2430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range->HasNoSpillType() || (operands_only && range->HasSpillRange())) {
2431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      continue;
2432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition start = range->Start();
2435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TRACE("Live range %d:%d is defined by a spill operand.\n",
2436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          range->TopLevel()->vreg(), range->relative_id());
2437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition next_pos = start;
2438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (next_pos.IsGapPosition()) {
2439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      next_pos = next_pos.NextStart();
2440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UsePosition* pos = range->NextUsePositionRegisterIsBeneficial(next_pos);
2442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // If the range already has a spill operand and it doesn't need a
2443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // register immediately, split it and spill the first part of the range.
2444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (pos == nullptr) {
2445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Spill(range);
2446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (pos->pos() > range->Start().NextStart()) {
2447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Do not spill live range eagerly if use position that can benefit from
2448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // the register is too close to the start of live range.
2449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LifetimePosition split_pos = GetSplitPositionForInstruction(
2450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          range, pos->pos().ToInstructionIndex());
2451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // There is no place to split, so we can't split and spill.
2452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!split_pos.IsValid()) continue;
2453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      split_pos =
2455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          FindOptimalSplitPos(range->Start().NextFullStart(), split_pos);
2456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SplitRangeAt(range, split_pos);
2458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Spill(range);
2459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLiveRange* RegisterAllocator::SplitRangeAt(LiveRange* range,
2465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           LifetimePosition pos) {
2466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!range->TopLevel()->IsFixed());
2467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Splitting live range %d:%d at %d\n", range->TopLevel()->vreg(),
2468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->relative_id(), pos.value());
2469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (pos <= range->Start()) return range;
2471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // We can't properly connect liveranges if splitting occurred at the end
2473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // a block.
2474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(pos.IsStart() || pos.IsGapPosition() ||
2475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         (GetInstructionBlock(code(), pos)->last_instruction_index() !=
2476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          pos.ToInstructionIndex()));
2477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LiveRange* result = range->SplitAt(pos, allocation_zone());
2479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return result;
2480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLiveRange* RegisterAllocator::SplitBetween(LiveRange* range,
2484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           LifetimePosition start,
2485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           LifetimePosition end) {
2486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!range->TopLevel()->IsFixed());
2487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Splitting live range %d:%d in position between [%d, %d]\n",
2488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->TopLevel()->vreg(), range->relative_id(), start.value(),
2489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        end.value());
2490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition split_pos = FindOptimalSplitPos(start, end);
2492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(split_pos >= start);
2493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return SplitRangeAt(range, split_pos);
2494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLifetimePosition RegisterAllocator::FindOptimalSplitPos(LifetimePosition start,
2498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                        LifetimePosition end) {
2499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int start_instr = start.ToInstructionIndex();
2500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int end_instr = end.ToInstructionIndex();
2501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(start_instr <= end_instr);
2502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // We have no choice
2504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (start_instr == end_instr) return end;
2505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const InstructionBlock* start_block = GetInstructionBlock(code(), start);
2507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const InstructionBlock* end_block = GetInstructionBlock(code(), end);
2508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (end_block == start_block) {
2510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // The interval is split in the same basic block. Split at the latest
2511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // possible position.
2512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return end;
2513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const InstructionBlock* block = end_block;
2516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Find header of outermost loop.
2517109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  do {
2518109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    const InstructionBlock* loop = GetContainingLoop(code(), block);
2519109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (loop == nullptr ||
2520109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        loop->rpo_number().ToInt() <= start_block->rpo_number().ToInt()) {
2521109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // No more loops or loop starts before the lifetime start.
2522109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      break;
2523109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
2524109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    block = loop;
2525109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  } while (true);
2526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // We did not find any suitable outer loop. Split at the latest possible
2528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // position unless end_block is a loop header itself.
2529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (block == end_block && !end_block->IsLoopHeader()) return end;
2530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return LifetimePosition::GapFromInstructionIndex(
2532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      block->first_instruction_index());
2533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLifetimePosition RegisterAllocator::FindOptimalSpillingPos(
2537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* range, LifetimePosition pos) {
2538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const InstructionBlock* block = GetInstructionBlock(code(), pos.Start());
2539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const InstructionBlock* loop_header =
2540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      block->IsLoopHeader() ? block : GetContainingLoop(code(), block);
2541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (loop_header == nullptr) return pos;
2543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const UsePosition* prev_use =
2545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      range->PreviousUsePositionRegisterIsBeneficial(pos);
2546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (loop_header != nullptr) {
2548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // We are going to spill live range inside the loop.
2549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // If possible try to move spilling position backwards to loop header.
2550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // This will reduce number of memory moves on the back edge.
2551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition loop_start = LifetimePosition::GapFromInstructionIndex(
2552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        loop_header->first_instruction_index());
2553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range->Covers(loop_start)) {
2555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (prev_use == nullptr || prev_use->pos() < loop_start) {
2556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // No register beneficial use inside the loop before the pos.
2557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        pos = loop_start;
2558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Try hoisting out to an outer loop.
2562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    loop_header = GetContainingLoop(code(), loop_header);
2563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return pos;
2566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid RegisterAllocator::Spill(LiveRange* range) {
2570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!range->spilled());
2571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TopLevelLiveRange* first = range->TopLevel();
2572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Spilling live range %d:%d\n", first->vreg(), range->relative_id());
2573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (first->HasNoSpillType()) {
2575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    data()->AssignSpillRangeToLiveRange(first);
2576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  range->Spill();
2578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst ZoneVector<TopLevelLiveRange*>& RegisterAllocator::GetFixedRegisters()
2582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const {
2583bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return mode() == FP_REGISTERS ? data()->fixed_double_live_ranges()
2584bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                : data()->fixed_live_ranges();
2585b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst char* RegisterAllocator::RegisterName(int register_code) const {
2589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (mode() == GENERAL_REGISTERS) {
2590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return data()->config()->GetGeneralRegisterName(register_code);
2591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
2592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return data()->config()->GetDoubleRegisterName(register_code);
2593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLinearScanAllocator::LinearScanAllocator(RegisterAllocationData* data,
2598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                         RegisterKind kind, Zone* local_zone)
2599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : RegisterAllocator(data, kind),
2600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      unhandled_live_ranges_(local_zone),
2601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      active_live_ranges_(local_zone),
2602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      inactive_live_ranges_(local_zone) {
2603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  unhandled_live_ranges().reserve(
2604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      static_cast<size_t>(code()->VirtualRegisterCount() * 2));
2605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  active_live_ranges().reserve(8);
2606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  inactive_live_ranges().reserve(8);
2607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // TryAllocateFreeReg and AllocateBlockedReg assume this
2608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // when allocating local arrays.
2609bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK(RegisterConfiguration::kMaxFPRegisters >=
2610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         this->data()->config()->num_general_registers());
2611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::AllocateRegisters() {
2615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(unhandled_live_ranges().empty());
2616958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(active_live_ranges().empty());
2617958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(inactive_live_ranges().empty());
2618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SplitAndSpillRangesDefinedByMemoryOperand(code()->VirtualRegisterCount() <=
2620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            num_allocatable_registers());
2621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (TopLevelLiveRange* range : data()->live_ranges()) {
2623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!CanProcessRange(range)) continue;
2624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (LiveRange* to_add = range; to_add != nullptr;
2625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         to_add = to_add->next()) {
2626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!to_add->spilled()) {
2627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        AddToUnhandledUnsorted(to_add);
2628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SortUnhandled();
2632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(UnhandledIsSorted());
2633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  auto& fixed_ranges = GetFixedRegisters();
2635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (TopLevelLiveRange* current : fixed_ranges) {
2636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (current != nullptr) {
2637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK_EQ(mode(), current->kind());
2638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      AddToInactive(current);
2639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2642958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  while (!unhandled_live_ranges().empty()) {
2643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(UnhandledIsSorted());
2644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* current = unhandled_live_ranges().back();
2645958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    unhandled_live_ranges().pop_back();
2646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(UnhandledIsSorted());
2647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition position = current->Start();
2648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
2649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    allocation_finger_ = position;
2650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
2651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TRACE("Processing interval %d:%d start=%d\n", current->TopLevel()->vreg(),
2652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          current->relative_id(), position.value());
2653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (current->IsTopLevel() && TryReuseSpillForPhi(current->TopLevel()))
2655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      continue;
2656958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2657958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (size_t i = 0; i < active_live_ranges().size(); ++i) {
2658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LiveRange* cur_active = active_live_ranges()[i];
2659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (cur_active->End() <= position) {
2660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ActiveToHandled(cur_active);
2661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        --i;  // The live range was removed from the list of active live ranges.
2662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else if (!cur_active->Covers(position)) {
2663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ActiveToInactive(cur_active);
2664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        --i;  // The live range was removed from the list of active live ranges.
2665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2668958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (size_t i = 0; i < inactive_live_ranges().size(); ++i) {
2669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LiveRange* cur_inactive = inactive_live_ranges()[i];
2670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (cur_inactive->End() <= position) {
2671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        InactiveToHandled(cur_inactive);
2672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        --i;  // Live range was removed from the list of inactive live ranges.
2673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else if (cur_inactive->Covers(position)) {
2674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        InactiveToActive(cur_inactive);
2675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        --i;  // Live range was removed from the list of inactive live ranges.
2676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!current->HasRegisterAssigned() && !current->spilled());
2680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool result = TryAllocateFreeReg(current);
2682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!result) AllocateBlockedReg(current);
2683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (current->HasRegisterAssigned()) {
2684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      AddToActive(current);
2685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::SetLiveRangeAssignedRegister(LiveRange* range,
2691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                       int reg) {
2692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  data()->MarkAllocated(range->kind(), reg);
2693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  range->set_assigned_register(reg);
2694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  range->SetUseHints(reg);
2695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (range->IsTopLevel() && range->TopLevel()->is_phi()) {
2696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    data()->GetPhiMapValueFor(range->TopLevel())->set_assigned_register(reg);
2697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::AddToActive(LiveRange* range) {
2702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Add live range %d:%d to active\n", range->TopLevel()->vreg(),
2703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->relative_id());
2704958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  active_live_ranges().push_back(range);
2705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::AddToInactive(LiveRange* range) {
2709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Add live range %d:%d to inactive\n", range->TopLevel()->vreg(),
2710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->relative_id());
2711958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  inactive_live_ranges().push_back(range);
2712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::AddToUnhandledSorted(LiveRange* range) {
2716958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (range == nullptr || range->IsEmpty()) return;
2717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!range->HasRegisterAssigned() && !range->spilled());
2718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(allocation_finger_ <= range->Start());
2719958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (int i = static_cast<int>(unhandled_live_ranges().size() - 1); i >= 0;
2720958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier       --i) {
2721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* cur_range = unhandled_live_ranges().at(i);
2722958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (!range->ShouldBeAllocatedBefore(cur_range)) continue;
2723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TRACE("Add live range %d:%d to unhandled at %d\n",
2724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          range->TopLevel()->vreg(), range->relative_id(), i + 1);
2725958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto it = unhandled_live_ranges().begin() + (i + 1);
2726958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    unhandled_live_ranges().insert(it, range);
2727958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(UnhandledIsSorted());
2728958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return;
2729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Add live range %d:%d to unhandled at start\n",
2731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->TopLevel()->vreg(), range->relative_id());
2732958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  unhandled_live_ranges().insert(unhandled_live_ranges().begin(), range);
2733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(UnhandledIsSorted());
2734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::AddToUnhandledUnsorted(LiveRange* range) {
2738958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (range == nullptr || range->IsEmpty()) return;
2739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!range->HasRegisterAssigned() && !range->spilled());
2740014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Add live range %d:%d to unhandled unsorted at end\n",
2741014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->TopLevel()->vreg(), range->relative_id());
2742958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  unhandled_live_ranges().push_back(range);
2743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2746958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic bool UnhandledSortHelper(LiveRange* a, LiveRange* b) {
2747958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(!a->ShouldBeAllocatedBefore(b) || !b->ShouldBeAllocatedBefore(a));
2748958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (a->ShouldBeAllocatedBefore(b)) return false;
2749958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (b->ShouldBeAllocatedBefore(a)) return true;
2750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return a->TopLevel()->vreg() < b->TopLevel()->vreg();
2751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Sort the unhandled live ranges so that the ranges to be processed first are
2755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// at the end of the array list.  This is convenient for the register allocation
2756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// algorithm because it is efficient to remove elements from the end.
2757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::SortUnhandled() {
2758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Sort unhandled\n");
2759958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  std::sort(unhandled_live_ranges().begin(), unhandled_live_ranges().end(),
2760958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            &UnhandledSortHelper);
2761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool LinearScanAllocator::UnhandledIsSorted() {
2765958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  size_t len = unhandled_live_ranges().size();
2766958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (size_t i = 1; i < len; i++) {
2767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* a = unhandled_live_ranges().at(i - 1);
2768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* b = unhandled_live_ranges().at(i);
2769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (a->Start() < b->Start()) return false;
2770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return true;
2772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::ActiveToHandled(LiveRange* range) {
2776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RemoveElement(&active_live_ranges(), range);
2777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Moving live range %d:%d from active to handled\n",
2778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->TopLevel()->vreg(), range->relative_id());
2779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::ActiveToInactive(LiveRange* range) {
2783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RemoveElement(&active_live_ranges(), range);
2784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  inactive_live_ranges().push_back(range);
2785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Moving live range %d:%d from active to inactive\n",
2786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->TopLevel()->vreg(), range->relative_id());
2787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::InactiveToHandled(LiveRange* range) {
2791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RemoveElement(&inactive_live_ranges(), range);
2792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Moving live range %d:%d from inactive to handled\n",
2793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->TopLevel()->vreg(), range->relative_id());
2794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::InactiveToActive(LiveRange* range) {
2798958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  RemoveElement(&inactive_live_ranges(), range);
2799958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  active_live_ranges().push_back(range);
2800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Moving live range %d:%d from inactive to active\n",
2801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->TopLevel()->vreg(), range->relative_id());
2802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool LinearScanAllocator::TryAllocateFreeReg(LiveRange* current) {
2806bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  LifetimePosition free_until_pos[RegisterConfiguration::kMaxFPRegisters];
2807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < num_registers(); i++) {
2809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    free_until_pos[i] = LifetimePosition::MaxPosition();
2810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (LiveRange* cur_active : active_live_ranges()) {
2813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    free_until_pos[cur_active->assigned_register()] =
2814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        LifetimePosition::GapFromInstructionIndex(0);
2815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TRACE("Register %s is free until pos %d (1)\n",
2816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          RegisterName(cur_active->assigned_register()),
2817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          LifetimePosition::GapFromInstructionIndex(0).value());
2818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (LiveRange* cur_inactive : inactive_live_ranges()) {
2821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(cur_inactive->End() > current->Start());
2822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition next_intersection =
2823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        cur_inactive->FirstIntersection(current);
2824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!next_intersection.IsValid()) continue;
2825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int cur_reg = cur_inactive->assigned_register();
2826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    free_until_pos[cur_reg] = Min(free_until_pos[cur_reg], next_intersection);
2827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TRACE("Register %s is free until pos %d (2)\n", RegisterName(cur_reg),
2828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Min(free_until_pos[cur_reg], next_intersection).value());
2829b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int hint_register;
2832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (current->FirstHintPosition(&hint_register) != nullptr) {
2833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TRACE(
2834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        "Found reg hint %s (free until [%d) for live range %d:%d (end %d[).\n",
2835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        RegisterName(hint_register), free_until_pos[hint_register].value(),
2836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        current->TopLevel()->vreg(), current->relative_id(),
2837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        current->End().value());
2838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // The desired register is free until the end of the current live range.
2840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (free_until_pos[hint_register] >= current->End()) {
2841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      TRACE("Assigning preferred reg %s to live range %d:%d\n",
2842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            RegisterName(hint_register), current->TopLevel()->vreg(),
2843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            current->relative_id());
2844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SetLiveRangeAssignedRegister(current, hint_register);
2845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return true;
2846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Find the register which stays free for the longest time.
2850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int reg = allocatable_register_code(0);
2851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 1; i < num_allocatable_registers(); ++i) {
2852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int code = allocatable_register_code(i);
2853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (free_until_pos[code] > free_until_pos[reg]) {
2854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      reg = code;
2855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition pos = free_until_pos[reg];
2859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (pos <= current->Start()) {
2861b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // All registers are blocked.
2862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return false;
2863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (pos < current->End()) {
2866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Register reg is available at the range start but becomes blocked before
2867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // the range end. Split current at position where it becomes blocked.
2868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* tail = SplitRangeAt(current, pos);
2869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AddToUnhandledSorted(tail);
2870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Register reg is available at the range start and is free until
2873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // the range end.
2874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(pos >= current->End());
2875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Assigning free reg %s to live range %d:%d\n", RegisterName(reg),
2876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        current->TopLevel()->vreg(), current->relative_id());
2877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SetLiveRangeAssignedRegister(current, reg);
2878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2879b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return true;
2880b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::AllocateBlockedReg(LiveRange* current) {
2884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePosition* register_use = current->NextRegisterPosition(current->Start());
2885958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (register_use == nullptr) {
2886b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // There is no use in the current live range that requires a register.
2887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // We can just spill it.
2888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Spill(current);
2889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return;
2890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2892bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  LifetimePosition use_pos[RegisterConfiguration::kMaxFPRegisters];
2893bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  LifetimePosition block_pos[RegisterConfiguration::kMaxFPRegisters];
2894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < num_registers(); i++) {
2896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    use_pos[i] = block_pos[i] = LifetimePosition::MaxPosition();
2897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (LiveRange* range : active_live_ranges()) {
2900b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int cur_reg = range->assigned_register();
2901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range->TopLevel()->IsFixed() ||
2902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        !range->CanBeSpilled(current->Start())) {
2903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      block_pos[cur_reg] = use_pos[cur_reg] =
2904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          LifetimePosition::GapFromInstructionIndex(0);
2905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
2906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UsePosition* next_use =
2907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          range->NextUsePositionRegisterIsBeneficial(current->Start());
2908958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (next_use == nullptr) {
2909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        use_pos[cur_reg] = range->End();
2910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
2911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        use_pos[cur_reg] = next_use->pos();
2912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (LiveRange* range : inactive_live_ranges()) {
2917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(range->End() > current->Start());
2918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition next_intersection = range->FirstIntersection(current);
2919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!next_intersection.IsValid()) continue;
2920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int cur_reg = range->assigned_register();
2921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range->TopLevel()->IsFixed()) {
2922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      block_pos[cur_reg] = Min(block_pos[cur_reg], next_intersection);
2923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      use_pos[cur_reg] = Min(block_pos[cur_reg], use_pos[cur_reg]);
2924b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
2925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      use_pos[cur_reg] = Min(use_pos[cur_reg], next_intersection);
2926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int reg = allocatable_register_code(0);
2930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 1; i < num_allocatable_registers(); ++i) {
2931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int code = allocatable_register_code(i);
2932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (use_pos[code] > use_pos[reg]) {
2933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      reg = code;
2934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition pos = use_pos[reg];
2938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (pos < register_use->pos()) {
2940bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (LifetimePosition::ExistsGapPositionBetween(current->Start(),
2941bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                                   register_use->pos())) {
2942bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      SpillBetween(current, current->Start(), register_use->pos());
2943bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    } else {
2944bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      SetLiveRangeAssignedRegister(current, reg);
2945bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      SplitAndSpillIntersecting(current);
2946bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
2947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return;
2948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (block_pos[reg] < current->End()) {
2951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Register becomes blocked before the current range end. Split before that
2952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // position.
2953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* tail =
2954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        SplitBetween(current, current->Start(), block_pos[reg].Start());
2955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AddToUnhandledSorted(tail);
2956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Register reg is not blocked for the whole range.
2959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(block_pos[reg] >= current->End());
2960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Assigning blocked reg %s to live range %d:%d\n", RegisterName(reg),
2961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        current->TopLevel()->vreg(), current->relative_id());
2962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SetLiveRangeAssignedRegister(current, reg);
2963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // This register was not free. Thus we need to find and spill
2965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // parts of active and inactive live regions that use the same register
2966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // at the same lifetime positions as current.
2967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SplitAndSpillIntersecting(current);
2968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::SplitAndSpillIntersecting(LiveRange* current) {
2972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(current->HasRegisterAssigned());
2973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int reg = current->assigned_register();
2974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition split_pos = current->Start();
2975958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (size_t i = 0; i < active_live_ranges().size(); ++i) {
2976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* range = active_live_ranges()[i];
2977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (range->assigned_register() == reg) {
2978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UsePosition* next_pos = range->NextRegisterPosition(current->Start());
2979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LifetimePosition spill_pos = FindOptimalSpillingPos(range, split_pos);
2980958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (next_pos == nullptr) {
2981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        SpillAfter(range, spill_pos);
2982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
2983b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // When spilling between spill_pos and next_pos ensure that the range
2984b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // remains spilled at least until the start of the current live range.
2985b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // This guarantees that we will not introduce new unhandled ranges that
2986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // start before the current range as this violates allocation invariant
2987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // and will lead to an inconsistent state of active and inactive
2988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // live-ranges: ranges are allocated in order of their start positions,
2989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // ranges are retired from active/inactive when the start of the
2990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // current live-range is larger than their end.
2991bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        DCHECK(LifetimePosition::ExistsGapPositionBetween(current->Start(),
2992bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                                          next_pos->pos()));
2993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        SpillBetweenUntil(range, spill_pos, current->Start(), next_pos->pos());
2994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ActiveToHandled(range);
2996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      --i;
2997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3000958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (size_t i = 0; i < inactive_live_ranges().size(); ++i) {
3001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* range = inactive_live_ranges()[i];
3002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(range->End() > current->Start());
3003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range->assigned_register() == reg && !range->TopLevel()->IsFixed()) {
3004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      LifetimePosition next_intersection = range->FirstIntersection(current);
3005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (next_intersection.IsValid()) {
3006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        UsePosition* next_pos = range->NextRegisterPosition(current->Start());
3007958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        if (next_pos == nullptr) {
3008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          SpillAfter(range, split_pos);
3009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        } else {
3010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          next_intersection = Min(next_intersection, next_pos->pos());
3011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          SpillBetween(range, split_pos, next_intersection);
3012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
3013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        InactiveToHandled(range);
3014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        --i;
3015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
3016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool LinearScanAllocator::TryReuseSpillForPhi(TopLevelLiveRange* range) {
3022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!range->is_phi()) return false;
3023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!range->HasSpillOperand());
3025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RegisterAllocationData::PhiMapValue* phi_map_value =
3026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      data()->GetPhiMapValueFor(range);
3027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const PhiInstruction* phi = phi_map_value->phi();
3028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const InstructionBlock* block = phi_map_value->block();
3029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Count the number of spilled operands.
3030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t spilled_count = 0;
3031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LiveRange* first_op = nullptr;
3032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < phi->operands().size(); i++) {
3033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int op = phi->operands()[i];
3034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* op_range = data()->GetOrCreateLiveRangeFor(op);
3035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!op_range->TopLevel()->HasSpillRange()) continue;
3036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const InstructionBlock* pred =
3037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        code()->InstructionBlockAt(block->predecessors()[i]);
3038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition pred_end =
3039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        LifetimePosition::InstructionFromInstructionIndex(
3040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            pred->last_instruction_index());
3041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    while (op_range != nullptr && !op_range->CanCover(pred_end)) {
3042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      op_range = op_range->next();
3043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (op_range != nullptr && op_range->spilled()) {
3045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      spilled_count++;
3046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (first_op == nullptr) {
3047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        first_op = op_range->TopLevel();
3048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Only continue if more than half of the operands are spilled.
3053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (spilled_count * 2 <= phi->operands().size()) {
3054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return false;
3055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Try to merge the spilled operands and count the number of merged spilled
3058014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // operands.
3059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(first_op != nullptr);
3060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SpillRange* first_op_spill = first_op->TopLevel()->GetSpillRange();
3061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t num_merged = 1;
3062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 1; i < phi->operands().size(); i++) {
3063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int op = phi->operands()[i];
3064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TopLevelLiveRange* op_range = data()->live_ranges()[op];
3065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!op_range->HasSpillRange()) continue;
3066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SpillRange* op_spill = op_range->GetSpillRange();
3067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (op_spill == first_op_spill || first_op_spill->TryMerge(op_spill)) {
3068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      num_merged++;
3069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Only continue if enough operands could be merged to the
3073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // same spill slot.
3074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (num_merged * 2 <= phi->operands().size() ||
3075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      AreUseIntervalsIntersecting(first_op_spill->interval(),
3076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  range->first_interval())) {
3077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return false;
3078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // If the range does not need register soon, spill it to the merged
3081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // spill range.
3082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition next_pos = range->Start();
3083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (next_pos.IsGapPosition()) next_pos = next_pos.NextStart();
3084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePosition* pos = range->NextUsePositionRegisterIsBeneficial(next_pos);
3085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (pos == nullptr) {
3086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SpillRange* spill_range =
3087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->TopLevel()->HasSpillRange()
3088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            ? range->TopLevel()->GetSpillRange()
3089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            : data()->AssignSpillRangeToLiveRange(range->TopLevel());
3090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool merged = first_op_spill->TryMerge(spill_range);
3091bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (!merged) return false;
3092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Spill(range);
3093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return true;
3094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (pos->pos() > range->Start().NextStart()) {
3095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SpillRange* spill_range =
3096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->TopLevel()->HasSpillRange()
3097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            ? range->TopLevel()->GetSpillRange()
3098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            : data()->AssignSpillRangeToLiveRange(range->TopLevel());
3099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool merged = first_op_spill->TryMerge(spill_range);
3100bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (!merged) return false;
3101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SpillBetween(range, range->Start(), pos->pos());
3102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(UnhandledIsSorted());
3103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return true;
3104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return false;
3106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::SpillAfter(LiveRange* range, LifetimePosition pos) {
3110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LiveRange* second_part = SplitRangeAt(range, pos);
3111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Spill(second_part);
3112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::SpillBetween(LiveRange* range, LifetimePosition start,
3116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       LifetimePosition end) {
3117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SpillBetweenUntil(range, start, start, end);
3118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::SpillBetweenUntil(LiveRange* range,
3122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            LifetimePosition start,
3123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            LifetimePosition until,
3124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            LifetimePosition end) {
3125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK(start < end);
3126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LiveRange* second_part = SplitRangeAt(range, start);
3127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (second_part->Start() < end) {
3129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // The split result intersects with [start, end[.
3130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Split it at position between ]start+1, end[, spill the middle part
3131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // and put the rest to unhandled.
3132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition third_part_end = end.PrevStart().End();
3133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (data()->IsBlockBoundary(end.Start())) {
3134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      third_part_end = end.Start();
3135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* third_part = SplitBetween(
3137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        second_part, Max(second_part->Start().End(), until), third_part_end);
3138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(third_part != second_part);
3140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Spill(second_part);
3142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AddToUnhandledSorted(third_part);
3143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
3144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // The split result does not intersect with [start, end[.
3145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Nothing to spill. Just put it to unhandled as whole.
3146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AddToUnhandledSorted(second_part);
3147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochSpillSlotLocator::SpillSlotLocator(RegisterAllocationData* data)
3152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : data_(data) {}
3153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid SpillSlotLocator::LocateSpillSlots() {
3156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const InstructionSequence* code = data()->code();
3157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (TopLevelLiveRange* range : data()->live_ranges()) {
3158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range == nullptr || range->IsEmpty()) continue;
3159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // We care only about ranges which spill in the frame.
31603b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (!range->HasSpillRange() || range->IsSpilledOnlyInDeferredBlocks()) {
31613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      continue;
31623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
31633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    TopLevelLiveRange::SpillMoveInsertionList* spills =
31643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        range->GetSpillMoveInsertionLocations();
31653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    DCHECK_NOT_NULL(spills);
31663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    for (; spills != nullptr; spills = spills->next) {
31673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      code->GetInstructionBlock(spills->gap_index)->mark_needs_frame();
3168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochOperandAssigner::OperandAssigner(RegisterAllocationData* data) : data_(data) {}
3174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid OperandAssigner::AssignSpillSlots() {
3177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ZoneVector<SpillRange*>& spill_ranges = data()->spill_ranges();
3178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Merge disjoint spill ranges
3179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < spill_ranges.size(); ++i) {
3180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SpillRange* range = spill_ranges[i];
3181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range == nullptr) continue;
3182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range->IsEmpty()) continue;
3183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (size_t j = i + 1; j < spill_ranges.size(); ++j) {
3184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SpillRange* other = spill_ranges[j];
3185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (other != nullptr && !other->IsEmpty()) {
3186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->TryMerge(other);
3187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Allocate slots for the merged spill ranges.
3191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (SpillRange* range : spill_ranges) {
3192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range == nullptr || range->IsEmpty()) continue;
3193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Allocate a new operand referring to the spill slot.
3194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!range->HasSlot()) {
3195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int byte_width = range->ByteWidth();
3196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int index = data()->frame()->AllocateSpillSlot(byte_width);
3197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      range->set_assigned_slot(index);
3198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid OperandAssigner::CommitAssignment() {
3204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (TopLevelLiveRange* top_range : data()->live_ranges()) {
3205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (top_range == nullptr || top_range->IsEmpty()) continue;
3206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand spill_operand;
3207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (top_range->HasSpillOperand()) {
3208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      spill_operand = *top_range->TopLevel()->GetSpillOperand();
3209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (top_range->TopLevel()->HasSpillRange()) {
3210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      spill_operand = top_range->TopLevel()->GetSpillRangeOperand();
3211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (top_range->is_phi()) {
3213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      data()->GetPhiMapValueFor(top_range)->CommitAssignment(
3214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          top_range->GetAssignedOperand());
3215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (LiveRange* range = top_range; range != nullptr;
3217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         range = range->next()) {
3218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionOperand assigned = range->GetAssignedOperand();
3219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      range->ConvertUsesToOperand(assigned, spill_operand);
3220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!spill_operand.IsInvalid()) {
3223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // If this top level range has a child spilled in a deferred block, we use
3224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // the range and control flow connection mechanism instead of spilling at
3225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // definition. Refer to the ConnectLiveRanges and ResolveControlFlow
3226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // phases. Normally, when we spill at definition, we do not insert a
3227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // connecting move when a successor child range is spilled - because the
3228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // spilled range picks up its value from the slot which was assigned at
3229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // definition. For ranges that are determined to spill only in deferred
3230109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // blocks, we let ConnectLiveRanges and ResolveControlFlow find the blocks
3231109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // where a spill operand is expected, and then finalize by inserting the
3232109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // spills in the deferred blocks dominators.
3233109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (!top_range->IsSpilledOnlyInDeferredBlocks()) {
3234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Spill at definition if the range isn't spilled only in deferred
3235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // blocks.
3236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        top_range->CommitSpillMoves(
3237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            data()->code(), spill_operand,
3238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            top_range->has_slot_use() || top_range->spilled());
3239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochReferenceMapPopulator::ReferenceMapPopulator(RegisterAllocationData* data)
3246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : data_(data) {}
3247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool ReferenceMapPopulator::SafePointsAreInOrder() const {
3250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int safe_point = 0;
3251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (ReferenceMap* map : *data()->code()->reference_maps()) {
3252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (safe_point > map->instruction_position()) return false;
3253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    safe_point = map->instruction_position();
3254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return true;
3256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid ReferenceMapPopulator::PopulateReferenceMaps() {
3260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(SafePointsAreInOrder());
3261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Map all delayed references.
3262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (RegisterAllocationData::DelayedReference& delayed_reference :
3263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       data()->delayed_references()) {
3264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    delayed_reference.map->RecordReference(
3265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        AllocatedOperand::cast(*delayed_reference.operand));
3266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Iterate over all safe point positions and record a pointer
3268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // for all spilled live ranges at this point.
3269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int last_range_start = 0;
3270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const ReferenceMapDeque* reference_maps = data()->code()->reference_maps();
3271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ReferenceMapDeque::const_iterator first_it = reference_maps->begin();
3272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (TopLevelLiveRange* range : data()->live_ranges()) {
3273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range == nullptr) continue;
3274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Skip non-reference values.
3275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!data()->IsReference(range)) continue;
3276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Skip empty live ranges.
3277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range->IsEmpty()) continue;
3278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range->has_preassigned_slot()) continue;
3279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Find the extent of the range and its children.
3281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int start = range->Start().ToInstructionIndex();
3282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int end = 0;
3283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (LiveRange* cur = range; cur != nullptr; cur = cur->next()) {
3284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LifetimePosition this_end = cur->End();
3285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (this_end.ToInstructionIndex() > end)
3286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        end = this_end.ToInstructionIndex();
3287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(cur->Start().ToInstructionIndex() >= start);
3288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Most of the ranges are in order, but not all.  Keep an eye on when they
3291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // step backwards and reset the first_it so we don't miss any safe points.
3292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (start < last_range_start) first_it = reference_maps->begin();
3293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    last_range_start = start;
3294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Step across all the safe points that are before the start of this range,
3296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // recording how far we step in order to save doing this for the next range.
3297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (; first_it != reference_maps->end(); ++first_it) {
3298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ReferenceMap* map = *first_it;
3299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (map->instruction_position() >= start) break;
3300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand spill_operand;
3303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (((range->HasSpillOperand() &&
3304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          !range->GetSpillOperand()->IsConstant()) ||
3305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         range->HasSpillRange())) {
3306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (range->HasSpillOperand()) {
3307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        spill_operand = *range->GetSpillOperand();
3308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
3309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        spill_operand = range->GetSpillRangeOperand();
3310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(spill_operand.IsStackSlot());
3312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK_EQ(MachineRepresentation::kTagged,
3313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                AllocatedOperand::cast(spill_operand).representation());
3314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* cur = range;
3317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Step through the safe points to see whether they are in the range.
3318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (auto it = first_it; it != reference_maps->end(); ++it) {
3319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ReferenceMap* map = *it;
3320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int safe_point = map->instruction_position();
3321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // The safe points are sorted so we can stop searching here.
3323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (safe_point - 1 > end) break;
3324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Advance to the next active range that covers the current
3326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // safe point position.
3327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LifetimePosition safe_point_pos =
3328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          LifetimePosition::InstructionFromInstructionIndex(safe_point);
3329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Search for the child range (cur) that covers safe_point_pos. If we
3331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // don't find it before the children pass safe_point_pos, keep cur at
3332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // the last child, because the next safe_point_pos may be covered by cur.
3333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // This may happen if cur has more than one interval, and the current
3334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // safe_point_pos is in between intervals.
3335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // For that reason, cur may be at most the last child.
3336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK_NOT_NULL(cur);
3337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(safe_point_pos >= cur->Start() || range == cur);
3338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bool found = false;
3339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      while (!found) {
3340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (cur->Covers(safe_point_pos)) {
3341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          found = true;
3342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else {
3343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          LiveRange* next = cur->next();
3344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          if (next == nullptr || next->Start() > safe_point_pos) {
3345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            break;
3346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
3347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          cur = next;
3348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!found) {
3352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        continue;
3353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Check if the live range is spilled and the safe point is after
3356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // the spill position.
3357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int spill_index = range->IsSpilledOnlyInDeferredBlocks()
3358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            ? cur->Start().ToInstructionIndex()
3359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            : range->spill_start_index();
3360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!spill_operand.IsInvalid() && safe_point >= spill_index) {
3362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        TRACE("Pointer for range %d (spilled at %d) at safe point %d\n",
3363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              range->vreg(), spill_index, safe_point);
3364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        map->RecordReference(AllocatedOperand::cast(spill_operand));
3365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!cur->spilled()) {
3368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        TRACE(
3369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            "Pointer in register for range %d:%d (start at %d) "
3370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            "at safe point %d\n",
3371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            range->vreg(), cur->relative_id(), cur->Start().value(),
3372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            safe_point);
3373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        InstructionOperand operand = cur->GetAssignedOperand();
3374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(!operand.IsStackSlot());
3375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK_EQ(MachineRepresentation::kTagged,
3376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  AllocatedOperand::cast(operand).representation());
3377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        map->RecordReference(AllocatedOperand::cast(operand));
3378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLiveRangeConnector::LiveRangeConnector(RegisterAllocationData* data)
3385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : data_(data) {}
3386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool LiveRangeConnector::CanEagerlyResolveControlFlow(
3389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const InstructionBlock* block) const {
3390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (block->PredecessorCount() != 1) return false;
3391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return block->predecessors()[0].IsNext(block->rpo_number());
3392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRangeConnector::ResolveControlFlow(Zone* local_zone) {
3396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Lazily linearize live ranges in memory for fast lookup.
3397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LiveRangeFinder finder(data(), local_zone);
3398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ZoneVector<BitVector*>& live_in_sets = data()->live_in_sets();
3399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (const InstructionBlock* block : code()->instruction_blocks()) {
3400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (CanEagerlyResolveControlFlow(block)) continue;
3401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    BitVector* live = live_in_sets[block->rpo_number().ToInt()];
3402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    BitVector::Iterator iterator(live);
3403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    while (!iterator.Done()) {
3404bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      int vreg = iterator.Current();
3405bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      LiveRangeBoundArray* array = finder.ArrayFor(vreg);
3406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (const RpoNumber& pred : block->predecessors()) {
3407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        FindResult result;
3408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        const InstructionBlock* pred_block = code()->InstructionBlockAt(pred);
3409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (!array->FindConnectableSubranges(block, pred_block, &result)) {
3410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          continue;
3411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        InstructionOperand pred_op = result.pred_cover_->GetAssignedOperand();
3413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        InstructionOperand cur_op = result.cur_cover_->GetAssignedOperand();
3414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (pred_op.Equals(cur_op)) continue;
3415109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        if (!pred_op.IsAnyRegister() && cur_op.IsAnyRegister()) {
3416109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          // We're doing a reload.
3417109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          // We don't need to, if:
3418109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          // 1) there's no register use in this block, and
3419109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          // 2) the range ends before the block does, and
3420109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          // 3) we don't have a successor, or the successor is spilled.
3421109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          LifetimePosition block_start =
3422109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch              LifetimePosition::GapFromInstructionIndex(block->code_start());
3423109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          LifetimePosition block_end =
3424109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch              LifetimePosition::GapFromInstructionIndex(block->code_end());
3425109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          const LiveRange* current = result.cur_cover_;
3426109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          const LiveRange* successor = current->next();
3427109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          if (current->End() < block_end &&
3428109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch              (successor == nullptr || successor->spilled())) {
3429109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            // verify point 1: no register use. We can go to the end of the
3430109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            // range, since it's all within the block.
3431109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3432109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            bool uses_reg = false;
3433109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            for (const UsePosition* use = current->NextUsePosition(block_start);
3434109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                 use != nullptr; use = use->next()) {
3435109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch              if (use->operand()->IsAnyRegister()) {
3436109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                uses_reg = true;
3437109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                break;
3438109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch              }
3439109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            }
3440109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            if (!uses_reg) continue;
3441109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          }
3442109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          if (current->TopLevel()->IsSpilledOnlyInDeferredBlocks() &&
3443109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch              pred_block->IsDeferred()) {
3444109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            // The spill location should be defined in pred_block, so add
3445109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            // pred_block to the list of blocks requiring a spill operand.
3446109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            current->TopLevel()->GetListOfBlocksRequiringSpillOperands()->Add(
3447109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                pred_block->rpo_number().ToInt());
3448109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          }
3449109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        }
3450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int move_loc = ResolveControlFlow(block, cur_op, pred_block, pred_op);
3451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        USE(move_loc);
3452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK_IMPLIES(
3453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            result.cur_cover_->TopLevel()->IsSpilledOnlyInDeferredBlocks() &&
3454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                !(pred_op.IsAnyRegister() && cur_op.IsAnyRegister()),
3455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            code()->GetInstructionBlock(move_loc)->IsDeferred());
3456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      iterator.Advance();
3458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3460109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3461109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // At this stage, we collected blocks needing a spill operand from
3462109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // ConnectRanges and from ResolveControlFlow. Time to commit the spills for
3463109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // deferred blocks.
3464109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  for (TopLevelLiveRange* top : data()->live_ranges()) {
3465109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (top == nullptr || top->IsEmpty() ||
3466109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        !top->IsSpilledOnlyInDeferredBlocks())
3467109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      continue;
3468109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    CommitSpillsInDeferredBlocks(top, finder.ArrayFor(top->vreg()), local_zone);
3469109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
3470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint LiveRangeConnector::ResolveControlFlow(const InstructionBlock* block,
3474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           const InstructionOperand& cur_op,
3475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           const InstructionBlock* pred,
3476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           const InstructionOperand& pred_op) {
3477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!pred_op.Equals(cur_op));
3478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int gap_index;
3479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Instruction::GapPosition position;
3480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (block->PredecessorCount() == 1) {
3481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    gap_index = block->first_instruction_index();
3482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    position = Instruction::START;
3483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
3484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(pred->SuccessorCount() == 1);
3485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!code()
3486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                ->InstructionAt(pred->last_instruction_index())
3487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                ->HasReferenceMap());
3488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    gap_index = pred->last_instruction_index();
3489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    position = Instruction::END;
3490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  data()->AddGapMove(gap_index, position, pred_op, cur_op);
3492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return gap_index;
3493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRangeConnector::ConnectRanges(Zone* local_zone) {
3497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DelayedInsertionMap delayed_insertion_map(local_zone);
3498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (TopLevelLiveRange* top_range : data()->live_ranges()) {
3499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (top_range == nullptr) continue;
3500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool connect_spilled = top_range->IsSpilledOnlyInDeferredBlocks();
3501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* first_range = top_range;
3502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (LiveRange *second_range = first_range->next(); second_range != nullptr;
3503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         first_range = second_range, second_range = second_range->next()) {
3504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LifetimePosition pos = second_range->Start();
3505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Add gap move if the two live ranges touch and there is no block
3506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // boundary.
3507109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (second_range->spilled()) continue;
3508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (first_range->End() != pos) continue;
3509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (data()->IsBlockBoundary(pos) &&
3510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          !CanEagerlyResolveControlFlow(GetInstructionBlock(code(), pos))) {
3511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        continue;
3512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionOperand prev_operand = first_range->GetAssignedOperand();
3514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionOperand cur_operand = second_range->GetAssignedOperand();
3515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (prev_operand.Equals(cur_operand)) continue;
3516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bool delay_insertion = false;
3517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Instruction::GapPosition gap_pos;
3518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int gap_index = pos.ToInstructionIndex();
3519109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (connect_spilled && !prev_operand.IsAnyRegister() &&
3520109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          cur_operand.IsAnyRegister()) {
3521109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        const InstructionBlock* block = code()->GetInstructionBlock(gap_index);
3522109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        DCHECK(block->IsDeferred());
3523109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        // Performing a reload in this block, meaning the spill operand must
3524109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        // be defined here.
3525109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        top_range->GetListOfBlocksRequiringSpillOperands()->Add(
3526109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            block->rpo_number().ToInt());
3527109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
3528109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (pos.IsGapPosition()) {
3530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        gap_pos = pos.IsStart() ? Instruction::START : Instruction::END;
3531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
3532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (pos.IsStart()) {
3533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          delay_insertion = true;
3534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else {
3535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          gap_index++;
3536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        gap_pos = delay_insertion ? Instruction::END : Instruction::START;
3538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3539109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // Reloads or spills for spilled in deferred blocks ranges must happen
3540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // only in deferred blocks.
3541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK_IMPLIES(
3542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          connect_spilled &&
3543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              !(prev_operand.IsAnyRegister() && cur_operand.IsAnyRegister()),
3544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          code()->GetInstructionBlock(gap_index)->IsDeferred());
3545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ParallelMove* move =
3547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          code()->InstructionAt(gap_index)->GetOrCreateParallelMove(
3548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              gap_pos, code_zone());
3549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!delay_insertion) {
3550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        move->AddMove(prev_operand, cur_operand);
3551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
3552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        delayed_insertion_map.insert(
3553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            std::make_pair(std::make_pair(move, prev_operand), cur_operand));
3554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (delayed_insertion_map.empty()) return;
3558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Insert all the moves which should occur after the stored move.
3559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ZoneVector<MoveOperands*> to_insert(local_zone);
3560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ZoneVector<MoveOperands*> to_eliminate(local_zone);
3561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  to_insert.reserve(4);
3562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  to_eliminate.reserve(4);
3563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ParallelMove* moves = delayed_insertion_map.begin()->first.first;
3564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (auto it = delayed_insertion_map.begin();; ++it) {
3565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool done = it == delayed_insertion_map.end();
3566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (done || it->first.first != moves) {
3567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Commit the MoveOperands for current ParallelMove.
3568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (MoveOperands* move : to_eliminate) {
3569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        move->Eliminate();
3570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (MoveOperands* move : to_insert) {
3572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        moves->push_back(move);
3573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (done) break;
3575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Reset state.
3576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      to_eliminate.clear();
3577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      to_insert.clear();
3578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      moves = it->first.first;
3579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Gather all MoveOperands for a single ParallelMove.
3581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MoveOperands* move =
3582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        new (code_zone()) MoveOperands(it->first.second, it->second);
3583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MoveOperands* eliminate = moves->PrepareInsertAfter(move);
3584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    to_insert.push_back(move);
3585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (eliminate != nullptr) to_eliminate.push_back(eliminate);
3586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3590109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid LiveRangeConnector::CommitSpillsInDeferredBlocks(
3591109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    TopLevelLiveRange* range, LiveRangeBoundArray* array, Zone* temp_zone) {
3592109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DCHECK(range->IsSpilledOnlyInDeferredBlocks());
3593109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DCHECK(!range->spilled());
3594109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3595109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  InstructionSequence* code = data()->code();
3596109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  InstructionOperand spill_operand = range->GetSpillRangeOperand();
3597109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3598109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  TRACE("Live Range %d will be spilled only in deferred blocks.\n",
3599109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        range->vreg());
3600109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // If we have ranges that aren't spilled but require the operand on the stack,
3601109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // make sure we insert the spill.
3602109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  for (const LiveRange* child = range; child != nullptr;
3603109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch       child = child->next()) {
3604109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    for (const UsePosition* pos = child->first_pos(); pos != nullptr;
3605109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch         pos = pos->next()) {
3606109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (pos->type() != UsePositionType::kRequiresSlot && !child->spilled())
3607109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        continue;
3608109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      range->AddBlockRequiringSpillOperand(
3609109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          code->GetInstructionBlock(pos->pos().ToInstructionIndex())
3610109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch              ->rpo_number());
3611109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
3612109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
3613109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3614109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  ZoneQueue<int> worklist(temp_zone);
3615109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3616109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  for (BitVector::Iterator iterator(
3617109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch           range->GetListOfBlocksRequiringSpillOperands());
3618109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch       !iterator.Done(); iterator.Advance()) {
3619109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    worklist.push(iterator.Current());
3620109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
3621109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3622bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  ZoneSet<std::pair<RpoNumber, int>> done_moves(temp_zone);
3623109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Seek the deferred blocks that dominate locations requiring spill operands,
3624109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // and spill there. We only need to spill at the start of such blocks.
3625109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  BitVector done_blocks(
3626109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      range->GetListOfBlocksRequiringSpillOperands()->length(), temp_zone);
3627109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  while (!worklist.empty()) {
3628109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    int block_id = worklist.front();
3629109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    worklist.pop();
3630109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (done_blocks.Contains(block_id)) continue;
3631109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    done_blocks.Add(block_id);
36323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    InstructionBlock* spill_block =
3633109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        code->InstructionBlockAt(RpoNumber::FromInt(block_id));
3634109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3635109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    for (const RpoNumber& pred : spill_block->predecessors()) {
3636109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      const InstructionBlock* pred_block = code->InstructionBlockAt(pred);
3637109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3638109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (pred_block->IsDeferred()) {
3639109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        worklist.push(pred_block->rpo_number().ToInt());
3640109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      } else {
3641109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        LifetimePosition pred_end =
3642109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            LifetimePosition::InstructionFromInstructionIndex(
3643109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                pred_block->last_instruction_index());
3644109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3645109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        LiveRangeBound* bound = array->Find(pred_end);
3646109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3647109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        InstructionOperand pred_op = bound->range_->GetAssignedOperand();
3648109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3649bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        RpoNumber spill_block_number = spill_block->rpo_number();
3650bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        if (done_moves.find(std::make_pair(
3651bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                spill_block_number, range->vreg())) == done_moves.end()) {
3652bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          data()->AddGapMove(spill_block->first_instruction_index(),
3653bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                             Instruction::GapPosition::START, pred_op,
3654bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                             spill_operand);
3655bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          done_moves.insert(std::make_pair(spill_block_number, range->vreg()));
3656bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          spill_block->mark_needs_frame();
3657bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        }
3658109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
3659109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
3660109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
3661109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
3662109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3663109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3664958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}  // namespace compiler
3665958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}  // namespace internal
3666958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}  // namespace v8
3667