register-allocator.cc revision 109988c7ccb6f3fd1a58574fa3dfb88beaef6632
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 Murdoch
29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint GetRegisterCount(const RegisterConfiguration* cfg, RegisterKind kind) {
30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return kind == DOUBLE_REGISTERS ? cfg->num_double_registers()
31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  : cfg->num_general_registers();
32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
34014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
35014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint GetAllocatableRegisterCount(const RegisterConfiguration* cfg,
36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                RegisterKind kind) {
37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return kind == DOUBLE_REGISTERS
38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             ? cfg->num_allocatable_aliased_double_registers()
39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             : cfg->num_allocatable_general_registers();
40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
41014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
42014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst int* GetAllocatableRegisterCodes(const RegisterConfiguration* cfg,
44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       RegisterKind kind) {
45014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return kind == DOUBLE_REGISTERS ? cfg->allocatable_double_codes()
46014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  : cfg->allocatable_general_codes();
47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
48b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
50014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst InstructionBlock* GetContainingLoop(const InstructionSequence* sequence,
51014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                          const InstructionBlock* block) {
52014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RpoNumber index = block->loop_header();
53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!index.IsValid()) return nullptr;
54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return sequence->InstructionBlockAt(index);
55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst InstructionBlock* GetInstructionBlock(const InstructionSequence* code,
59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            LifetimePosition pos) {
60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return code->GetInstructionBlock(pos.ToInstructionIndex());
61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochInstruction* GetLastInstruction(InstructionSequence* code,
65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                const InstructionBlock* block) {
66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return code->InstructionAt(block->last_instruction_index());
67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
70014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool IsOutputRegisterOf(Instruction* instr, Register reg) {
71014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < instr->OutputCount(); i++) {
72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand* output = instr->OutputAt(i);
73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (output->IsRegister() &&
74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        LocationOperand::cast(output)->GetRegister().is(reg)) {
75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return true;
76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
77958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return false;
79958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
80958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
81958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool IsOutputDoubleRegisterOf(Instruction* instr, DoubleRegister reg) {
83014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < instr->OutputCount(); i++) {
84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand* output = instr->OutputAt(i);
85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (output->IsDoubleRegister() &&
86014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        LocationOperand::cast(output)->GetDoubleRegister().is(reg)) {
87014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return true;
88014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
89014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
90014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return false;
91014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
92014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// TODO(dcarney): fix frame to allow frame accesses to half size location.
95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint GetByteWidth(MachineRepresentation rep) {
96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (rep) {
97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kBit:
98014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord8:
99014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord16:
100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord32:
101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kTagged:
102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return kPointerSize;
103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kFloat32:
104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord64:
105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kFloat64:
106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return 8;
107109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case MachineRepresentation::kSimd128:
108109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return 16;
109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kNone:
110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UNREACHABLE();
113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return 0;
114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
115958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace
117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
118109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochclass LiveRangeBound {
119109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch public:
120109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  explicit LiveRangeBound(LiveRange* range, bool skip)
121109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      : range_(range), start_(range->Start()), end_(range->End()), skip_(skip) {
122109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    DCHECK(!range->IsEmpty());
123109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
124109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
125109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  bool CanCover(LifetimePosition position) {
126109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return start_ <= position && position < end_;
127109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
128109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
129109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  LiveRange* const range_;
130109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  const LifetimePosition start_;
131109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  const LifetimePosition end_;
132109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  const bool skip_;
133109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
134109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch private:
135109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(LiveRangeBound);
136109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch};
137109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
138109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
139109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochstruct FindResult {
140109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  LiveRange* cur_cover_;
141109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  LiveRange* pred_cover_;
142109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch};
143109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
144109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
145109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochclass LiveRangeBoundArray {
146109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch public:
147109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  LiveRangeBoundArray() : length_(0), start_(nullptr) {}
148109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
149109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  bool ShouldInitialize() { return start_ == nullptr; }
150109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
151109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  void Initialize(Zone* zone, TopLevelLiveRange* range) {
152109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    length_ = range->GetChildCount();
153109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
154109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    start_ = zone->NewArray<LiveRangeBound>(length_);
155109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    LiveRangeBound* curr = start_;
156109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // Normally, spilled ranges do not need connecting moves, because the spill
157109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // location has been assigned at definition. For ranges spilled in deferred
158109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // blocks, that is not the case, so we need to connect the spilled children.
159109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    for (LiveRange *i = range; i != nullptr; i = i->next(), ++curr) {
160109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      new (curr) LiveRangeBound(i, i->spilled());
161109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
162109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
163109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
164109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  LiveRangeBound* Find(const LifetimePosition position) const {
165109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    size_t left_index = 0;
166109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    size_t right_index = length_;
167109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    while (true) {
168109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      size_t current_index = left_index + (right_index - left_index) / 2;
169109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      DCHECK(right_index > current_index);
170109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      LiveRangeBound* bound = &start_[current_index];
171109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (bound->start_ <= position) {
172109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        if (position < bound->end_) return bound;
173109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        DCHECK(left_index < current_index);
174109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        left_index = current_index;
175109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      } else {
176109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        right_index = current_index;
177109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
178109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
179109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
180109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
181109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  LiveRangeBound* FindPred(const InstructionBlock* pred) {
182109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    LifetimePosition pred_end =
183109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        LifetimePosition::InstructionFromInstructionIndex(
184109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            pred->last_instruction_index());
185109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return Find(pred_end);
186109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
187109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
188109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  LiveRangeBound* FindSucc(const InstructionBlock* succ) {
189109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    LifetimePosition succ_start = LifetimePosition::GapFromInstructionIndex(
190109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        succ->first_instruction_index());
191109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return Find(succ_start);
192109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
193109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
194109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  bool FindConnectableSubranges(const InstructionBlock* block,
195109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                const InstructionBlock* pred,
196109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                FindResult* result) const {
197109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    LifetimePosition pred_end =
198109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        LifetimePosition::InstructionFromInstructionIndex(
199109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            pred->last_instruction_index());
200109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    LiveRangeBound* bound = Find(pred_end);
201109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    result->pred_cover_ = bound->range_;
202109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    LifetimePosition cur_start = LifetimePosition::GapFromInstructionIndex(
203109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        block->first_instruction_index());
204109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
205109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (bound->CanCover(cur_start)) {
206109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // Both blocks are covered by the same range, so there is nothing to
207109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // connect.
208109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return false;
209109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
210109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    bound = Find(cur_start);
211109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (bound->skip_) {
212109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return false;
213109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
214109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    result->cur_cover_ = bound->range_;
215109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    DCHECK(result->pred_cover_ != nullptr && result->cur_cover_ != nullptr);
216109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return (result->cur_cover_ != result->pred_cover_);
217109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
218109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
219109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch private:
220109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  size_t length_;
221109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  LiveRangeBound* start_;
222109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
223109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(LiveRangeBoundArray);
224109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch};
225109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
226109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
227109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochclass LiveRangeFinder {
228109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch public:
229109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  explicit LiveRangeFinder(const RegisterAllocationData* data, Zone* zone)
230109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      : data_(data),
231109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        bounds_length_(static_cast<int>(data_->live_ranges().size())),
232109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        bounds_(zone->NewArray<LiveRangeBoundArray>(bounds_length_)),
233109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        zone_(zone) {
234109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    for (int i = 0; i < bounds_length_; ++i) {
235109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      new (&bounds_[i]) LiveRangeBoundArray();
236109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
237109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
238109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
239109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  LiveRangeBoundArray* ArrayFor(int operand_index) {
240109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    DCHECK(operand_index < bounds_length_);
241109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    TopLevelLiveRange* range = data_->live_ranges()[operand_index];
242109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    DCHECK(range != nullptr && !range->IsEmpty());
243109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    LiveRangeBoundArray* array = &bounds_[operand_index];
244109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (array->ShouldInitialize()) {
245109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      array->Initialize(zone_, range);
246109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
247109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return array;
248109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
249109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
250109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch private:
251109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  const RegisterAllocationData* const data_;
252109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  const int bounds_length_;
253109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  LiveRangeBoundArray* const bounds_;
254109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Zone* const zone_;
255109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
256109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(LiveRangeFinder);
257109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch};
258109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
259109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
260109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochtypedef std::pair<ParallelMove*, InstructionOperand> DelayedInsertionMapKey;
261109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
262109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
263109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochstruct DelayedInsertionMapCompare {
264109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  bool operator()(const DelayedInsertionMapKey& a,
265109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                  const DelayedInsertionMapKey& b) const {
266109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (a.first == b.first) {
267109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return a.second.Compare(b.second);
268109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
269109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return a.first < b.first;
270109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
271109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch};
272109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
273109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
274109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochtypedef ZoneMap<DelayedInsertionMapKey, InstructionOperand,
275109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                DelayedInsertionMapCompare> DelayedInsertionMap;
276109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochUsePosition::UsePosition(LifetimePosition pos, InstructionOperand* operand,
279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         void* hint, UsePositionHintType hint_type)
280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : operand_(operand), hint_(hint), next_(nullptr), pos_(pos), flags_(0) {
281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_IMPLIES(hint == nullptr, hint_type == UsePositionHintType::kNone);
282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool register_beneficial = true;
283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePositionType type = UsePositionType::kAny;
284958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (operand_ != nullptr && operand_->IsUnallocated()) {
285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const UnallocatedOperand* unalloc = UnallocatedOperand::cast(operand_);
286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (unalloc->HasRegisterPolicy()) {
287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      type = UsePositionType::kRequiresRegister;
288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (unalloc->HasSlotPolicy()) {
289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      type = UsePositionType::kRequiresSlot;
290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      register_beneficial = false;
291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      register_beneficial = !unalloc->HasAnyPolicy();
293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  flags_ = TypeField::encode(type) | HintTypeField::encode(hint_type) |
296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           RegisterBeneficialField::encode(register_beneficial) |
297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           AssignedRegisterField::encode(kUnassignedRegister);
298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(pos_.IsValid());
299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool UsePosition::HasHint() const {
303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int hint_register;
304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return HintRegister(&hint_register);
305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool UsePosition::HintRegister(int* register_code) const {
309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (hint_ == nullptr) return false;
310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (HintTypeField::decode(flags_)) {
311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case UsePositionHintType::kNone:
312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case UsePositionHintType::kUnresolved:
313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return false;
314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case UsePositionHintType::kUsePos: {
315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UsePosition* use_pos = reinterpret_cast<UsePosition*>(hint_);
316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int assigned_register = AssignedRegisterField::decode(use_pos->flags_);
317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (assigned_register == kUnassignedRegister) return false;
318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *register_code = assigned_register;
319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return true;
320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case UsePositionHintType::kOperand: {
322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionOperand* operand =
323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          reinterpret_cast<InstructionOperand*>(hint_);
324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int assigned_register =
325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          operand->IsRegister()
326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              ? LocationOperand::cast(operand)->GetRegister().code()
327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              : LocationOperand::cast(operand)->GetDoubleRegister().code();
328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *register_code = assigned_register;
329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return true;
330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case UsePositionHintType::kPhi: {
332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      RegisterAllocationData::PhiMapValue* phi =
333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          reinterpret_cast<RegisterAllocationData::PhiMapValue*>(hint_);
334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int assigned_register = phi->assigned_register();
335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (assigned_register == kUnassignedRegister) return false;
336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *register_code = assigned_register;
337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return true;
338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UNREACHABLE();
341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return false;
342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochUsePositionHintType UsePosition::HintTypeForOperand(
346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const InstructionOperand& op) {
347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (op.kind()) {
348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case InstructionOperand::CONSTANT:
349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case InstructionOperand::IMMEDIATE:
350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case InstructionOperand::EXPLICIT:
351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return UsePositionHintType::kNone;
352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case InstructionOperand::UNALLOCATED:
353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return UsePositionHintType::kUnresolved;
354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case InstructionOperand::ALLOCATED:
355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (op.IsRegister() || op.IsDoubleRegister()) {
356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return UsePositionHintType::kOperand;
357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(op.IsStackSlot() || op.IsDoubleStackSlot());
359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return UsePositionHintType::kNone;
360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case InstructionOperand::INVALID:
362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UNREACHABLE();
365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return UsePositionHintType::kNone;
366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid UsePosition::ResolveHint(UsePosition* use_pos) {
370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_NOT_NULL(use_pos);
371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (HintTypeField::decode(flags_) != UsePositionHintType::kUnresolved) return;
372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  hint_ = use_pos;
373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  flags_ = HintTypeField::update(flags_, UsePositionHintType::kUsePos);
374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid UsePosition::set_type(UsePositionType type, bool register_beneficial) {
378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_IMPLIES(type == UsePositionType::kRequiresSlot, !register_beneficial);
379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(kUnassignedRegister, AssignedRegisterField::decode(flags_));
380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  flags_ = TypeField::encode(type) |
381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           RegisterBeneficialField::encode(register_beneficial) |
382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           HintTypeField::encode(HintTypeField::decode(flags_)) |
383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           AssignedRegisterField::encode(kUnassignedRegister);
384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
385958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
386958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochUseInterval* UseInterval::SplitAt(LifetimePosition pos, Zone* zone) {
388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(Contains(pos) && pos != start());
389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UseInterval* after = new (zone) UseInterval(pos, end_);
390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  after->next_ = next_;
391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  next_ = nullptr;
392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  end_ = pos;
393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return after;
394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LifetimePosition::Print() const {
398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  OFStream os(stdout);
399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  os << *this << std::endl;
400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstd::ostream& operator<<(std::ostream& os, const LifetimePosition pos) {
404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  os << '@' << pos.ToInstructionIndex();
405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (pos.IsGapPosition()) {
406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    os << 'g';
407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    os << 'i';
409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (pos.IsStart()) {
411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    os << 's';
412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    os << 'e';
414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return os;
416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst float LiveRange::kInvalidWeight = -1;
420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst float LiveRange::kMaxWeight = std::numeric_limits<float>::max();
421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLiveRange::LiveRange(int relative_id, MachineRepresentation rep,
424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                     TopLevelLiveRange* top_level)
425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : relative_id_(relative_id),
426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bits_(0),
427958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      last_interval_(nullptr),
428958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      first_interval_(nullptr),
429958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      first_pos_(nullptr),
430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      top_level_(top_level),
431958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      next_(nullptr),
432958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      current_interval_(nullptr),
433958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      last_processed_use_(nullptr),
434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      current_hint_position_(nullptr),
435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      splitting_pointer_(nullptr),
436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      size_(kInvalidSize),
437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      weight_(kInvalidWeight),
438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      group_(nullptr) {
439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(AllocatedOperand::IsSupportedRepresentation(rep));
440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bits_ = AssignedRegisterField::encode(kUnassignedRegister) |
441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          RepresentationField::encode(rep);
442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRange::VerifyPositions() const {
446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Walk the positions, verifying that each is in an interval.
447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UseInterval* interval = first_interval_;
448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (UsePosition* pos = first_pos_; pos != nullptr; pos = pos->next()) {
449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CHECK(Start() <= pos->pos());
450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CHECK(pos->pos() <= End());
451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CHECK_NOT_NULL(interval);
452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    while (!interval->Contains(pos->pos()) && interval->end() != pos->pos()) {
453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      interval = interval->next();
454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      CHECK_NOT_NULL(interval);
455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRange::VerifyIntervals() const {
461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(first_interval()->start() == Start());
462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition last_end = first_interval()->end();
463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (UseInterval* interval = first_interval()->next(); interval != nullptr;
464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       interval = interval->next()) {
465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(last_end <= interval->start());
466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    last_end = interval->end();
467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(last_end == End());
469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRange::set_assigned_register(int reg) {
473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!HasRegisterAssigned() && !spilled());
474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bits_ = AssignedRegisterField::update(bits_, reg);
475958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
476958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
477958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRange::UnsetAssignedRegister() {
479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(HasRegisterAssigned() && !spilled());
480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bits_ = AssignedRegisterField::update(bits_, kUnassignedRegister);
481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRange::Spill() {
485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!spilled());
486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!TopLevel()->HasNoSpillType());
487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_spilled(true);
488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bits_ = AssignedRegisterField::update(bits_, kUnassignedRegister);
489958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
490958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
491958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochRegisterKind LiveRange::kind() const {
493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return IsFloatingPoint(representation()) ? DOUBLE_REGISTERS
494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           : GENERAL_REGISTERS;
495958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
496958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
497958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochUsePosition* LiveRange::FirstHintPosition(int* register_index) const {
499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (UsePosition* pos = first_pos_; pos != nullptr; pos = pos->next()) {
500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (pos->HintRegister(register_index)) return pos;
501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return nullptr;
503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochUsePosition* LiveRange::NextUsePosition(LifetimePosition start) const {
507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UsePosition* use_pos = last_processed_use_;
508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (use_pos == nullptr || use_pos->pos() > start) {
509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    use_pos = first_pos();
510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (use_pos != nullptr && use_pos->pos() < start) {
512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    use_pos = use_pos->next();
513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  last_processed_use_ = use_pos;
515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return use_pos;
516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochUsePosition* LiveRange::NextUsePositionRegisterIsBeneficial(
520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition start) const {
521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UsePosition* pos = NextUsePosition(start);
522958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  while (pos != nullptr && !pos->RegisterIsBeneficial()) {
523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    pos = pos->next();
524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return pos;
526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochUsePosition* LiveRange::PreviousUsePositionRegisterIsBeneficial(
530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition start) const {
531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePosition* pos = first_pos();
532958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  UsePosition* prev = nullptr;
533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (pos != nullptr && pos->pos() < start) {
534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (pos->RegisterIsBeneficial()) prev = pos;
535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    pos = pos->next();
536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return prev;
538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochUsePosition* LiveRange::NextRegisterPosition(LifetimePosition start) const {
542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UsePosition* pos = NextUsePosition(start);
543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (pos != nullptr && pos->type() != UsePositionType::kRequiresRegister) {
544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    pos = pos->next();
545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return pos;
547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochUsePosition* LiveRange::NextSlotPosition(LifetimePosition start) const {
551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (UsePosition* pos = NextUsePosition(start); pos != nullptr;
552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       pos = pos->next()) {
553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (pos->type() != UsePositionType::kRequiresSlot) continue;
554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return pos;
555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return nullptr;
557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool LiveRange::CanBeSpilled(LifetimePosition pos) const {
561b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We cannot spill a live range that has a use requiring a register
562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // at the current or the immediate next position.
563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePosition* use_pos = NextRegisterPosition(pos);
564958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (use_pos == nullptr) return true;
565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return use_pos->pos() > pos.NextStart().End();
566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
567b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool LiveRange::IsTopLevel() const { return top_level_ == this; }
570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochInstructionOperand LiveRange::GetAssignedOperand() const {
573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (HasRegisterAssigned()) {
574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!spilled());
575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return AllocatedOperand(LocationOperand::REGISTER, representation(),
576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            assigned_register());
577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(spilled());
579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!HasRegisterAssigned());
580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (TopLevel()->HasSpillOperand()) {
581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand* op = TopLevel()->GetSpillOperand();
582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!op->IsUnallocated());
583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return *op;
584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return TopLevel()->GetSpillRangeOperand();
586b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
587b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
588b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochUseInterval* LiveRange::FirstSearchIntervalForPosition(
590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LifetimePosition position) const {
591958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (current_interval_ == nullptr) return first_interval_;
592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (current_interval_->start() > position) {
593958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    current_interval_ = nullptr;
594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return first_interval_;
595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return current_interval_;
597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
598b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
599b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LiveRange::AdvanceLastProcessedMarker(
601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UseInterval* to_start_of, LifetimePosition but_not_past) const {
602958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (to_start_of == nullptr) return;
603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (to_start_of->start() > but_not_past) return;
604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition start = current_interval_ == nullptr
605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                               ? LifetimePosition::Invalid()
606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                               : current_interval_->start();
607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (to_start_of->start() > start) {
608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    current_interval_ = to_start_of;
609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLiveRange* LiveRange::SplitAt(LifetimePosition position, Zone* zone) {
614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int new_id = TopLevel()->GetNextChildId();
615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LiveRange* child = new (zone) LiveRange(new_id, representation(), TopLevel());
616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DetachAt(position, child, zone);
617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  child->top_level_ = TopLevel();
619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  child->next_ = next_;
620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  next_ = child;
621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return child;
622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochUsePosition* LiveRange::DetachAt(LifetimePosition position, LiveRange* result,
626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 Zone* zone) {
627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(Start() < position);
628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(End() > position);
629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(result->IsEmpty());
630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Find the last interval that ends before the position. If the
631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // position is contained in one of the intervals in the chain, we
632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // split that interval and use the first part.
633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UseInterval* current = FirstSearchIntervalForPosition(position);
634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // If the split position coincides with the beginning of a use interval
636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // we need to split use positons in a special way.
637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool split_at_start = false;
638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (current->start() == position) {
640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // When splitting at start we need to locate the previous use interval.
641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    current = first_interval_;
642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UseInterval* after = nullptr;
645958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  while (current != nullptr) {
646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (current->Contains(position)) {
647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      after = current->SplitAt(position, zone);
648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UseInterval* next = current->next();
651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (next->start() >= position) {
652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      split_at_start = (next->start() == position);
653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      after = next;
654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      current->set_next(nullptr);
655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    current = next;
658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(nullptr != after);
660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Partition original use intervals to the two live ranges.
662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UseInterval* before = current;
663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->last_interval_ =
664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (last_interval_ == before)
665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          ? after            // Only interval in the range after split.
666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          : last_interval_;  // Last interval of the original range.
667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->first_interval_ = after;
668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  last_interval_ = before;
669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Find the last use position before the split and the first use
671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // position after it.
672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePosition* use_after =
673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      splitting_pointer_ == nullptr || splitting_pointer_->pos() > position
674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          ? first_pos()
675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          : splitting_pointer_;
676958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  UsePosition* use_before = nullptr;
677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (split_at_start) {
678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // The split position coincides with the beginning of a use interval (the
679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // end of a lifetime hole). Use at this position should be attributed to
680b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // the split child because split child owns use interval covering it.
681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    while (use_after != nullptr && use_after->pos() < position) {
682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      use_before = use_after;
683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      use_after = use_after->next();
684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    while (use_after != nullptr && use_after->pos() <= position) {
687b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      use_before = use_after;
688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      use_after = use_after->next();
689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Partition original use positions to the two live ranges.
693958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (use_before != nullptr) {
694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    use_before->set_next(nullptr);
695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
696958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    first_pos_ = nullptr;
697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->first_pos_ = use_after;
699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Discard cached iteration state. It might be pointing
701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // to the use that no longer belongs to this live range.
702958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  last_processed_use_ = nullptr;
703958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  current_interval_ = nullptr;
704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Invalidate size and weight of this range. The child range has them
706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // invalid at construction.
707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_ = kInvalidSize;
708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  weight_ = kInvalidWeight;
709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VerifyChildStructure();
711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  result->VerifyChildStructure();
712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return use_before;
714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRange::UpdateParentForAllChildren(TopLevelLiveRange* new_top_level) {
718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LiveRange* child = this;
719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (; child != nullptr; child = child->next()) {
720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    child->top_level_ = new_top_level;
721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRange::ConvertUsesToOperand(const InstructionOperand& op,
726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     const InstructionOperand& spill_op) {
727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (UsePosition* pos = first_pos(); pos != nullptr; pos = pos->next()) {
728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(Start() <= pos->pos() && pos->pos() <= End());
729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!pos->HasOperand()) continue;
730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    switch (pos->type()) {
731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case UsePositionType::kRequiresSlot:
732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(spill_op.IsStackSlot() || spill_op.IsDoubleStackSlot());
733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        InstructionOperand::ReplaceWith(pos->operand(), &spill_op);
734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case UsePositionType::kRequiresRegister:
736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(op.IsRegister() || op.IsDoubleRegister());
737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Fall through.
738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case UsePositionType::kAny:
739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        InstructionOperand::ReplaceWith(pos->operand(), &op);
740014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
741014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// This implements an ordering on live ranges so that they are ordered by their
747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// start positions.  This is needed for the correctness of the register
748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// allocation algorithm.  If two live ranges start at the same offset then there
749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// is a tie breaker based on where the value is first used.  This part of the
750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ordering is merely a heuristic.
751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool LiveRange::ShouldBeAllocatedBefore(const LiveRange* other) const {
752b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LifetimePosition start = Start();
753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LifetimePosition other_start = other->Start();
754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (start == other_start) {
755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UsePosition* pos = first_pos();
756958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (pos == nullptr) return false;
757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UsePosition* other_pos = other->first_pos();
758958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (other_pos == nullptr) return true;
759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return pos->pos() < other_pos->pos();
760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return start < other_start;
762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRange::SetUseHints(int register_index) {
766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (UsePosition* pos = first_pos(); pos != nullptr; pos = pos->next()) {
767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!pos->HasOperand()) continue;
768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    switch (pos->type()) {
769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case UsePositionType::kRequiresSlot:
770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case UsePositionType::kRequiresRegister:
772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case UsePositionType::kAny:
773014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        pos->set_assigned_register(register_index);
774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool LiveRange::CanCover(LifetimePosition position) const {
781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (IsEmpty()) return false;
782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return Start() <= position && position < End();
783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool LiveRange::Covers(LifetimePosition position) const {
787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!CanCover(position)) return false;
788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UseInterval* start_search = FirstSearchIntervalForPosition(position);
789014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (UseInterval* interval = start_search; interval != nullptr;
790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       interval = interval->next()) {
791958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(interval->next() == nullptr ||
792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           interval->next()->start() >= interval->start());
793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AdvanceLastProcessedMarker(interval, position);
794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (interval->Contains(position)) return true;
795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (interval->start() > position) return false;
796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return false;
798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLifetimePosition LiveRange::FirstIntersection(LiveRange* other) const {
802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UseInterval* b = other->first_interval();
803958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (b == nullptr) return LifetimePosition::Invalid();
804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition advance_last_processed_up_to = b->start();
805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UseInterval* a = FirstSearchIntervalForPosition(b->start());
806958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  while (a != nullptr && b != nullptr) {
807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (a->start() > other->End()) break;
808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (b->start() > End()) break;
809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition cur_intersection = a->Intersect(b);
810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (cur_intersection.IsValid()) {
811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return cur_intersection;
812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (a->start() < b->start()) {
814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      a = a->next();
815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (a == nullptr || a->start() > other->End()) break;
816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      AdvanceLastProcessedMarker(a, advance_last_processed_up_to);
817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      b = b->next();
819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return LifetimePosition::Invalid();
822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochunsigned LiveRange::GetSize() {
826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (size_ == kInvalidSize) {
827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    size_ = 0;
828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (const UseInterval* interval = first_interval(); interval != nullptr;
829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         interval = interval->next()) {
830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      size_ += (interval->end().value() - interval->start().value());
831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return static_cast<unsigned>(size_);
835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRange::Print(const RegisterConfiguration* config,
839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                      bool with_children) const {
840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  OFStream os(stdout);
841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  PrintableLiveRange wrapper;
842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  wrapper.register_configuration_ = config;
843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (const LiveRange* i = this; i != nullptr; i = i->next()) {
844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    wrapper.range_ = i;
845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    os << wrapper << std::endl;
846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!with_children) break;
847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRange::Print(bool with_children) const {
852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const RegisterConfiguration* config =
853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN);
854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Print(config, with_children);
855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstruct TopLevelLiveRange::SpillMoveInsertionList : ZoneObject {
859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SpillMoveInsertionList(int gap_index, InstructionOperand* operand,
860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         SpillMoveInsertionList* next)
861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : gap_index(gap_index), operand(operand), next(next) {}
862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const int gap_index;
863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand* const operand;
864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SpillMoveInsertionList* const next;
865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTopLevelLiveRange::TopLevelLiveRange(int vreg, MachineRepresentation rep)
869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : LiveRange(0, rep, this),
870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      vreg_(vreg),
871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      last_child_id_(0),
872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      splintered_from_(nullptr),
873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      spill_operand_(nullptr),
874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      spill_move_insertion_locations_(nullptr),
875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      spilled_in_deferred_blocks_(false),
876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      spill_start_index_(kMaxInt),
877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      last_pos_(nullptr),
878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      splinter_(nullptr),
879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      has_preassigned_slot_(false) {
880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bits_ |= SpillTypeField::encode(SpillType::kNoSpillType);
881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if DEBUG
885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint TopLevelLiveRange::debug_virt_reg() const {
886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return IsSplinter() ? splintered_from()->vreg() : vreg();
887b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif
889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::RecordSpillLocation(Zone* zone, int gap_index,
892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            InstructionOperand* operand) {
893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(HasNoSpillType());
894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  spill_move_insertion_locations_ = new (zone) SpillMoveInsertionList(
895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      gap_index, operand, spill_move_insertion_locations_);
896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::CommitSpillMoves(InstructionSequence* sequence,
899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                         const InstructionOperand& op,
900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                         bool might_be_duplicated) {
901109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DCHECK_IMPLIES(op.IsConstant(), GetSpillMoveInsertionLocations() == nullptr);
902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Zone* zone = sequence->zone();
903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
904109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  for (SpillMoveInsertionList* to_spill = GetSpillMoveInsertionLocations();
905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       to_spill != nullptr; to_spill = to_spill->next) {
906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Instruction* instr = sequence->InstructionAt(to_spill->gap_index);
907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ParallelMove* move =
908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        instr->GetOrCreateParallelMove(Instruction::START, zone);
909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Skip insertion if it's possible that the move exists already as a
910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // constraint move from a fixed output register to a slot.
911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (might_be_duplicated || has_preassigned_slot()) {
912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bool found = false;
913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (MoveOperands* move_op : *move) {
914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (move_op->IsEliminated()) continue;
915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (move_op->source().Equals(*to_spill->operand) &&
916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            move_op->destination().Equals(op)) {
917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          found = true;
918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          if (has_preassigned_slot()) move_op->Eliminate();
919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          break;
920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (found) continue;
923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!has_preassigned_slot()) {
925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      move->AddMove(*to_spill->operand, op);
926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
927b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::SetSpillOperand(InstructionOperand* operand) {
932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(HasNoSpillType());
933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!operand->IsUnallocated() && !operand->IsImmediate());
934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_spill_type(SpillType::kSpillOperand);
935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  spill_operand_ = operand;
936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::SetSpillRange(SpillRange* spill_range) {
940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!HasSpillOperand());
941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(spill_range);
942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  spill_range_ = spill_range;
943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAllocatedOperand TopLevelLiveRange::GetSpillRangeOperand() const {
947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SpillRange* spill_range = GetSpillRange();
948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int index = spill_range->assigned_slot();
949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return AllocatedOperand(LocationOperand::STACK_SLOT, representation(), index);
950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::Splinter(LifetimePosition start, LifetimePosition end,
954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 Zone* zone) {
955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(start != Start() || end != End());
956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(start < end);
957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TopLevelLiveRange splinter_temp(-1, representation());
959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePosition* last_in_splinter = nullptr;
960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Live ranges defined in deferred blocks stay in deferred blocks, so we
961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // don't need to splinter them. That means that start should always be
962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // after the beginning of the range.
963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(start > Start());
964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (end >= End()) {
966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(start > Start());
967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DetachAt(start, &splinter_temp, zone);
968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    next_ = nullptr;
969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(start < End() && Start() < end);
971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const int kInvalidId = std::numeric_limits<int>::max();
973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UsePosition* last = DetachAt(start, &splinter_temp, zone);
975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange end_part(kInvalidId, this->representation(), nullptr);
977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    last_in_splinter = splinter_temp.DetachAt(end, &end_part, zone);
978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    next_ = end_part.next_;
980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    last_interval_->set_next(end_part.first_interval_);
981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // The next splinter will happen either at or after the current interval.
982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // We can optimize DetachAt by setting current_interval_ accordingly,
983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // which will then be picked up by FirstSearchIntervalForPosition.
984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    current_interval_ = last_interval_;
985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    last_interval_ = end_part.last_interval_;
986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (first_pos_ == nullptr) {
988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      first_pos_ = end_part.first_pos_;
989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      splitting_pointer_ = last;
991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (last != nullptr) last->set_next(end_part.first_pos_);
992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
993b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (splinter()->IsEmpty()) {
996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    splinter()->first_interval_ = splinter_temp.first_interval_;
997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    splinter()->last_interval_ = splinter_temp.last_interval_;
998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    splinter()->last_interval_->set_next(splinter_temp.first_interval_);
1000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    splinter()->last_interval_ = splinter_temp.last_interval_;
1001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (splinter()->first_pos() == nullptr) {
1003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    splinter()->first_pos_ = splinter_temp.first_pos_;
1004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    splinter()->last_pos_->set_next(splinter_temp.first_pos_);
1006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (last_in_splinter != nullptr) {
1008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    splinter()->last_pos_ = last_in_splinter;
1009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (splinter()->first_pos() != nullptr &&
1011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        splinter()->last_pos_ == nullptr) {
1012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      splinter()->last_pos_ = splinter()->first_pos();
1013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (UsePosition* pos = splinter()->first_pos(); pos != nullptr;
1014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           pos = pos->next()) {
1015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        splinter()->last_pos_ = pos;
1016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if DEBUG
1020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Verify();
1021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  splinter()->Verify();
1022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif
1023b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::SetSplinteredFrom(TopLevelLiveRange* splinter_parent) {
1027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  splintered_from_ = splinter_parent;
1028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!HasSpillOperand() && splinter_parent->spill_range_ != nullptr) {
1029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SetSpillRange(splinter_parent->spill_range_);
1030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1033b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::UpdateSpillRangePostMerge(TopLevelLiveRange* merged) {
1035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(merged->TopLevel() == this);
1036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (HasNoSpillType() && merged->HasSpillRange()) {
1038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    set_spill_type(merged->spill_type());
1039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(GetSpillRange()->live_ranges().size() > 0);
1040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    merged->spill_range_ = nullptr;
1041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    merged->bits_ =
1042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        SpillTypeField::update(merged->bits_, SpillType::kNoSpillType);
1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::Merge(TopLevelLiveRange* other, Zone* zone) {
1048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(Start() < other->Start());
1049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(other->splintered_from() == this);
1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LiveRange* first = this;
1052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LiveRange* second = other;
1053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(first->Start() < second->Start());
1054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (first != nullptr && second != nullptr) {
1055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(first != second);
1056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Make sure the ranges are in order each time we iterate.
1057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (second->Start() < first->Start()) {
1058014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LiveRange* tmp = second;
1059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      second = first;
1060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      first = tmp;
1061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      continue;
1062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (first->End() <= second->Start()) {
1065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (first->next() == nullptr ||
1066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          first->next()->Start() > second->Start()) {
1067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // First is in order before second.
1068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        LiveRange* temp = first->next();
1069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        first->next_ = second;
1070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        first = temp;
1071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // First is in order before its successor (or second), so advance first.
1073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        first = first->next();
1074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      continue;
1076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(first->Start() < second->Start());
1079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // If first and second intersect, split first.
1080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (first->Start() < second->End() && second->Start() < first->End()) {
1081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LiveRange* temp = first->SplitAt(second->Start(), zone);
1082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      CHECK(temp != first);
1083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      temp->set_spilled(first->spilled());
1084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!temp->spilled())
1085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        temp->set_assigned_register(first->assigned_register());
1086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      first->next_ = second;
1088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      first = temp;
1089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      continue;
1090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(first->End() <= second->Start());
1092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TopLevel()->UpdateParentForAllChildren(TopLevel());
1095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TopLevel()->UpdateSpillRangePostMerge(other);
1096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if DEBUG
1098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Verify();
1099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif
1100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::VerifyChildrenInOrder() const {
1104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition last_end = End();
1105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (const LiveRange* child = this->next(); child != nullptr;
1106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       child = child->next()) {
1107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(last_end <= child->Start());
1108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    last_end = child->End();
1109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::Verify() const {
1114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VerifyChildrenInOrder();
1115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (const LiveRange* child = this; child != nullptr; child = child->next()) {
1116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    VerifyChildStructure();
1117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::ShortenTo(LifetimePosition start) {
1122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Shorten live range %d to [%d\n", vreg(), start.value());
1123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(first_interval_ != nullptr);
1124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(first_interval_->start() <= start);
1125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(start < first_interval_->end());
1126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  first_interval_->set_start(start);
1127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::EnsureInterval(LifetimePosition start,
1131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       LifetimePosition end, Zone* zone) {
1132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Ensure live range %d in interval [%d %d[\n", vreg(), start.value(),
1133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        end.value());
1134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition new_end = end;
1135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (first_interval_ != nullptr && first_interval_->start() <= end) {
1136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (first_interval_->end() > end) {
1137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      new_end = first_interval_->end();
1138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    first_interval_ = first_interval_->next();
1140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UseInterval* new_interval = new (zone) UseInterval(start, new_end);
1143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  new_interval->set_next(first_interval_);
1144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  first_interval_ = new_interval;
1145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (new_interval->next() == nullptr) {
1146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    last_interval_ = new_interval;
1147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::AddUseInterval(LifetimePosition start,
1152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       LifetimePosition end, Zone* zone) {
1153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Add to live range %d interval [%d %d[\n", vreg(), start.value(),
1154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        end.value());
1155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (first_interval_ == nullptr) {
1156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UseInterval* interval = new (zone) UseInterval(start, end);
1157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    first_interval_ = interval;
1158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    last_interval_ = interval;
1159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (end == first_interval_->start()) {
1161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      first_interval_->set_start(start);
1162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (end < first_interval_->start()) {
1163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UseInterval* interval = new (zone) UseInterval(start, end);
1164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      interval->set_next(first_interval_);
1165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      first_interval_ = interval;
1166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
1167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Order of instruction's processing (see ProcessInstructions) guarantees
1168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // that each new use interval either precedes or intersects with
1169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // last added interval.
1170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(start < first_interval_->end());
1171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      first_interval_->set_start(Min(start, first_interval_->start()));
1172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      first_interval_->set_end(Max(end, first_interval_->end()));
1173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1174958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1175958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1176958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1177958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::AddUsePosition(UsePosition* use_pos) {
1179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition pos = use_pos->pos();
1180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Add to live range %d use position %d\n", vreg(), pos.value());
1181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePosition* prev_hint = nullptr;
1182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePosition* prev = nullptr;
1183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePosition* current = first_pos_;
1184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (current != nullptr && current->pos() < pos) {
1185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    prev_hint = current->HasHint() ? current : prev_hint;
1186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    prev = current;
1187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    current = current->next();
1188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (prev == nullptr) {
1191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    use_pos->set_next(first_pos_);
1192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    first_pos_ = use_pos;
1193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    use_pos->set_next(prev->next());
1195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    prev->set_next(use_pos);
1196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (prev_hint == nullptr && use_pos->HasHint()) {
1199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    current_hint_position_ = use_pos;
1200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1201958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1202958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1203958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1204958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic bool AreUseIntervalsIntersecting(UseInterval* interval1,
1205958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                        UseInterval* interval2) {
1206958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  while (interval1 != nullptr && interval2 != nullptr) {
1207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (interval1->start() < interval2->start()) {
1208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (interval1->end() > interval2->start()) {
1209958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        return true;
1210958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
1211958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      interval1 = interval1->next();
1212958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {
1213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (interval2->end() > interval1->start()) {
1214958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        return true;
1215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1216958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      interval2 = interval2->next();
1217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1219958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return false;
1220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstd::ostream& operator<<(std::ostream& os,
1224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         const PrintableLiveRange& printable_range) {
1225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const LiveRange* range = printable_range.range_;
1226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  os << "Range: " << range->TopLevel()->vreg() << ":" << range->relative_id()
1227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch     << " ";
1228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (range->TopLevel()->is_phi()) os << "phi ";
1229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (range->TopLevel()->is_non_loop_phi()) os << "nlphi ";
1230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  os << "{" << std::endl;
1232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UseInterval* interval = range->first_interval();
1233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePosition* use_pos = range->first_pos();
1234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  PrintableInstructionOperand pio;
1235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  pio.register_configuration_ = printable_range.register_configuration_;
1236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (use_pos != nullptr) {
1237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (use_pos->HasOperand()) {
1238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      pio.op_ = *use_pos->operand();
1239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      os << pio << use_pos->pos() << " ";
1240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    use_pos = use_pos->next();
1242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  os << std::endl;
1244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (interval != nullptr) {
1246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    os << '[' << interval->start() << ", " << interval->end() << ')'
1247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       << std::endl;
1248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    interval = interval->next();
1249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  os << "}";
1251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return os;
1252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochSpillRange::SpillRange(TopLevelLiveRange* parent, Zone* zone)
1256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : live_ranges_(zone),
1257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      assigned_slot_(kUnassignedSlot),
1258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      byte_width_(GetByteWidth(parent->representation())),
1259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      kind_(parent->kind()) {
1260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Spill ranges are created for top level, non-splintered ranges. This is so
1261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // that, when merging decisions are made, we consider the full extent of the
1262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // virtual register, and avoid clobbering it.
1263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!parent->IsSplinter());
1264958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  UseInterval* result = nullptr;
1265958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  UseInterval* node = nullptr;
1266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Copy the intervals for all ranges.
1267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (LiveRange* range = parent; range != nullptr; range = range->next()) {
1268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UseInterval* src = range->first_interval();
1269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    while (src != nullptr) {
1270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UseInterval* new_node = new (zone) UseInterval(src->start(), src->end());
1271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (result == nullptr) {
1272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        result = new_node;
1273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        node->set_next(new_node);
1275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      node = new_node;
1277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      src = src->next();
1278958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1279958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1280958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  use_interval_ = result;
1281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  live_ranges().push_back(parent);
1282958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  end_position_ = node->end();
1283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  parent->SetSpillRange(this);
1284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint SpillRange::ByteWidth() const {
1288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return GetByteWidth(live_ranges_[0]->representation());
1289958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1290958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1291958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1292958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool SpillRange::IsIntersectingWith(SpillRange* other) const {
1293958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (this->use_interval_ == nullptr || other->use_interval_ == nullptr ||
1294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      this->End() <= other->use_interval_->start() ||
1295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      other->End() <= this->use_interval_->start()) {
1296958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return false;
1297958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1298958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return AreUseIntervalsIntersecting(use_interval_, other->use_interval_);
1299958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1300958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1301958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1302958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool SpillRange::TryMerge(SpillRange* other) {
1303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (HasSlot() || other->HasSlot()) return false;
1304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // TODO(dcarney): byte widths should be compared here not kinds.
1305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (live_ranges_[0]->kind() != other->live_ranges_[0]->kind() ||
1306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      IsIntersectingWith(other)) {
1307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return false;
1308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1309958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition max = LifetimePosition::MaxPosition();
1311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (End() < other->End() && other->End() != max) {
1312958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    end_position_ = other->End();
1313958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1314958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  other->end_position_ = max;
1315958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1316958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MergeDisjointIntervals(other->use_interval_);
1317958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  other->use_interval_ = nullptr;
1318958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (TopLevelLiveRange* range : other->live_ranges()) {
1320958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(range->GetSpillRange() == other);
1321958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    range->SetSpillRange(this);
1322958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1323958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1324958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  live_ranges().insert(live_ranges().end(), other->live_ranges().begin(),
1325958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                       other->live_ranges().end());
1326958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  other->live_ranges().clear();
1327958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1328958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return true;
1329958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1330958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1331958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1332958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid SpillRange::MergeDisjointIntervals(UseInterval* other) {
1333958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  UseInterval* tail = nullptr;
1334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UseInterval* current = use_interval_;
1335958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  while (other != nullptr) {
1336958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // Make sure the 'current' list starts first
1337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (current == nullptr || current->start() > other->start()) {
1338958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      std::swap(current, other);
1339958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1340958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // Check disjointness
1341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(other == nullptr || current->end() <= other->start());
1342958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // Append the 'current' node to the result accumulator and move forward
1343958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (tail == nullptr) {
1344958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      use_interval_ = current;
1345958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {
1346958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      tail->set_next(current);
1347958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1348958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    tail = current;
1349958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    current = current->next();
1350958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1351958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Other list is empty => we are done
1352958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1353958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1354958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid SpillRange::Print() const {
1356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  OFStream os(stdout);
1357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  os << "{" << std::endl;
1358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (TopLevelLiveRange* range : live_ranges()) {
1359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    os << range->vreg() << " ";
1360958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  os << std::endl;
1362958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (UseInterval* i = interval(); i != nullptr; i = i->next()) {
1364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    os << '[' << i->start() << ", " << i->end() << ')' << std::endl;
1365958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  os << "}" << std::endl;
1367958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1368958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1369958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochRegisterAllocationData::PhiMapValue::PhiMapValue(PhiInstruction* phi,
1371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                 const InstructionBlock* block,
1372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                 Zone* zone)
1373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : phi_(phi),
1374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      block_(block),
1375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      incoming_operands_(zone),
1376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      assigned_register_(kUnassignedRegister) {
1377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  incoming_operands_.reserve(phi->operands().size());
1378958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1379958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1380958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid RegisterAllocationData::PhiMapValue::AddOperand(
1382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand* operand) {
1383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  incoming_operands_.push_back(operand);
1384958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1385958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1386958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid RegisterAllocationData::PhiMapValue::CommitAssignment(
1388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const InstructionOperand& assigned) {
1389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (InstructionOperand* operand : incoming_operands_) {
1390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand::ReplaceWith(operand, &assigned);
1391958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1393958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1394958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochRegisterAllocationData::RegisterAllocationData(
1396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const RegisterConfiguration* config, Zone* zone, Frame* frame,
1397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionSequence* code, const char* debug_name)
1398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : allocation_zone_(zone),
1399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      frame_(frame),
1400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      code_(code),
1401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      debug_name_(debug_name),
1402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      config_(config),
1403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      phi_map_(allocation_zone()),
1404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      allocatable_codes_(this->config()->num_general_registers(), -1,
1405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         allocation_zone()),
1406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      allocatable_double_codes_(this->config()->num_double_registers(), -1,
1407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                allocation_zone()),
1408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      live_in_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()),
1409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      live_out_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()),
1410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      live_ranges_(code->VirtualRegisterCount() * 2, nullptr,
1411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                   allocation_zone()),
1412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      fixed_live_ranges_(this->config()->num_general_registers(), nullptr,
1413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         allocation_zone()),
1414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      fixed_double_live_ranges_(this->config()->num_double_registers(), nullptr,
1415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                allocation_zone()),
1416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      spill_ranges_(code->VirtualRegisterCount(), nullptr, allocation_zone()),
1417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      delayed_references_(allocation_zone()),
1418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      assigned_registers_(nullptr),
1419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      assigned_double_registers_(nullptr),
1420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      virtual_register_count_(code->VirtualRegisterCount()),
1421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      preassigned_slot_ranges_(zone) {
1422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(this->config()->num_general_registers() <=
1423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         RegisterConfiguration::kMaxGeneralRegisters);
1424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(this->config()->num_double_registers() <=
1425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         RegisterConfiguration::kMaxDoubleRegisters);
1426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assigned_registers_ = new (code_zone())
1427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      BitVector(this->config()->num_general_registers(), code_zone());
1428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assigned_double_registers_ = new (code_zone())
1429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      BitVector(this->config()->num_double_registers(), code_zone());
1430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  this->frame()->SetAllocatedRegisters(assigned_registers_);
1431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  this->frame()->SetAllocatedDoubleRegisters(assigned_double_registers_);
1432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1433958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1434958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochMoveOperands* RegisterAllocationData::AddGapMove(
1436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int index, Instruction::GapPosition position,
1437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const InstructionOperand& from, const InstructionOperand& to) {
1438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Instruction* instr = code()->InstructionAt(index);
1439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ParallelMove* moves = instr->GetOrCreateParallelMove(position, code_zone());
1440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return moves->AddMove(from, to);
1441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochMachineRepresentation RegisterAllocationData::RepresentationFor(
1445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int virtual_register) {
1446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_LT(virtual_register, code()->VirtualRegisterCount());
1447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return code()->GetRepresentation(virtual_register);
1448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTopLevelLiveRange* RegisterAllocationData::GetOrCreateLiveRangeFor(int index) {
1452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (index >= static_cast<int>(live_ranges().size())) {
1453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    live_ranges().resize(index + 1, nullptr);
1454958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TopLevelLiveRange* result = live_ranges()[index];
1456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (result == nullptr) {
1457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    result = NewLiveRange(index, RepresentationFor(index));
1458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    live_ranges()[index] = result;
1459958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return result;
1461958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1462958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1463958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTopLevelLiveRange* RegisterAllocationData::NewLiveRange(
1465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int index, MachineRepresentation rep) {
1466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return new (allocation_zone()) TopLevelLiveRange(index, rep);
1467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint RegisterAllocationData::GetNextLiveRangeId() {
1471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int vreg = virtual_register_count_++;
1472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (vreg >= static_cast<int>(live_ranges().size())) {
1473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    live_ranges().resize(vreg + 1, nullptr);
1474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return vreg;
1476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTopLevelLiveRange* RegisterAllocationData::NextLiveRange(
1480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MachineRepresentation rep) {
1481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int vreg = GetNextLiveRangeId();
1482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TopLevelLiveRange* ret = NewLiveRange(vreg, rep);
1483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return ret;
1484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochRegisterAllocationData::PhiMapValue* RegisterAllocationData::InitializePhiMap(
1488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const InstructionBlock* block, PhiInstruction* phi) {
1489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RegisterAllocationData::PhiMapValue* map_value = new (allocation_zone())
1490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      RegisterAllocationData::PhiMapValue(phi, block, allocation_zone());
1491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  auto res =
1492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      phi_map_.insert(std::make_pair(phi->virtual_register(), map_value));
1493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(res.second);
1494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  USE(res);
1495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return map_value;
1496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochRegisterAllocationData::PhiMapValue* RegisterAllocationData::GetPhiMapValueFor(
1500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int virtual_register) {
1501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  auto it = phi_map_.find(virtual_register);
1502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(it != phi_map_.end());
1503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return it->second;
1504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochRegisterAllocationData::PhiMapValue* RegisterAllocationData::GetPhiMapValueFor(
1508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TopLevelLiveRange* top_range) {
1509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return GetPhiMapValueFor(top_range->vreg());
1510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool RegisterAllocationData::ExistsUseWithoutDefinition() {
1514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool found = false;
1515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BitVector::Iterator iterator(live_in_sets()[0]);
1516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (!iterator.Done()) {
1517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    found = true;
1518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int operand_index = iterator.Current();
1519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintF("Register allocator error: live v%d reached first block.\n",
1520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           operand_index);
1521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* range = GetOrCreateLiveRangeFor(operand_index);
1522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintF("  (first use is at %d)\n", range->first_pos()->pos().value());
1523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (debug_name() == nullptr) {
1524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      PrintF("\n");
1525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
1526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      PrintF("  (function: %s)\n", debug_name());
1527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    iterator.Advance();
1529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return found;
1531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// If a range is defined in a deferred block, we can expect all the range
1535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// to only cover positions in deferred blocks. Otherwise, a block on the
1536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// hot path would be dominated by a deferred block, meaning it is unreachable
1537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// without passing through the deferred block, which is contradictory.
1538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// In particular, when such a range contributes a result back on the hot
1539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// path, it will be as one of the inputs of a phi. In that case, the value
1540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// will be transferred via a move in the Gap::END's of the last instruction
1541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// of a deferred block.
1542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool RegisterAllocationData::RangesDefinedInDeferredStayInDeferred() {
1543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (const TopLevelLiveRange* range : live_ranges()) {
1544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range == nullptr || range->IsEmpty() ||
1545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        !code()
1546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             ->GetInstructionBlock(range->Start().ToInstructionIndex())
1547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             ->IsDeferred()) {
1548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      continue;
1549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (const UseInterval* i = range->first_interval(); i != nullptr;
1551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         i = i->next()) {
1552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int first = i->FirstGapIndex();
1553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int last = i->LastGapIndex();
1554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (int instr = first; instr <= last;) {
1555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        const InstructionBlock* block = code()->GetInstructionBlock(instr);
1556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (!block->IsDeferred()) return false;
1557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        instr = block->last_instruction_index() + 1;
1558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1560b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return true;
1562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1563b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochSpillRange* RegisterAllocationData::AssignSpillRangeToLiveRange(
1566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TopLevelLiveRange* range) {
1567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!range->HasSpillOperand());
1568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SpillRange* spill_range = range->GetAllocatedSpillRange();
1570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (spill_range == nullptr) {
1571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!range->IsSplinter());
1572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    spill_range = new (allocation_zone()) SpillRange(range, allocation_zone());
1573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  range->set_spill_type(TopLevelLiveRange::SpillType::kSpillRange);
1575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int spill_range_index =
1577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      range->IsSplinter() ? range->splintered_from()->vreg() : range->vreg();
1578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  spill_ranges()[spill_range_index] = spill_range;
1580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return spill_range;
1582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1584b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochSpillRange* RegisterAllocationData::CreateSpillRangeForLiveRange(
1586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TopLevelLiveRange* range) {
1587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!range->HasSpillOperand());
1588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!range->IsSplinter());
1589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SpillRange* spill_range =
1590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      new (allocation_zone()) SpillRange(range, allocation_zone());
1591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return spill_range;
1592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid RegisterAllocationData::MarkAllocated(RegisterKind kind, int index) {
1596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (kind == DOUBLE_REGISTERS) {
1597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    assigned_double_registers_->Add(index);
1598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(kind == GENERAL_REGISTERS);
1600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    assigned_registers_->Add(index);
1601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool RegisterAllocationData::IsBlockBoundary(LifetimePosition pos) const {
1606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return pos.IsFullStart() &&
1607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         code()->GetInstructionBlock(pos.ToInstructionIndex())->code_start() ==
1608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             pos.ToInstructionIndex();
1609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochConstraintBuilder::ConstraintBuilder(RegisterAllocationData* data)
1613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : data_(data) {}
1614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochInstructionOperand* ConstraintBuilder::AllocateFixed(
1617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UnallocatedOperand* operand, int pos, bool is_tagged) {
1618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Allocating fixed reg for op %d\n", operand->virtual_register());
1619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(operand->HasFixedPolicy());
1620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand allocated;
1621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MachineRepresentation rep = InstructionSequence::DefaultRepresentation();
1622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int virtual_register = operand->virtual_register();
1623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (virtual_register != InstructionOperand::kInvalidVirtualRegister) {
1624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    rep = data()->RepresentationFor(virtual_register);
1625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (operand->HasFixedSlotPolicy()) {
1627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    allocated = AllocatedOperand(AllocatedOperand::STACK_SLOT, rep,
1628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 operand->fixed_slot_index());
1629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (operand->HasFixedRegisterPolicy()) {
1630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!IsFloatingPoint(rep));
1631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    allocated = AllocatedOperand(AllocatedOperand::REGISTER, rep,
1632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 operand->fixed_register_index());
1633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (operand->HasFixedDoubleRegisterPolicy()) {
1634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(IsFloatingPoint(rep));
1635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_NE(InstructionOperand::kInvalidVirtualRegister, virtual_register);
1636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    allocated = AllocatedOperand(AllocatedOperand::REGISTER, rep,
1637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 operand->fixed_register_index());
1638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UNREACHABLE();
1640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand::ReplaceWith(operand, &allocated);
1642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (is_tagged) {
1643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TRACE("Fixed reg is tagged at %d\n", pos);
1644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Instruction* instr = code()->InstructionAt(pos);
1645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (instr->HasReferenceMap()) {
1646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      instr->reference_map()->RecordReference(*AllocatedOperand::cast(operand));
1647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return operand;
1650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid ConstraintBuilder::MeetRegisterConstraints() {
1654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (InstructionBlock* block : code()->instruction_blocks()) {
1655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MeetRegisterConstraints(block);
1656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid ConstraintBuilder::MeetRegisterConstraints(const InstructionBlock* block) {
1661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int start = block->first_instruction_index();
1662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int end = block->last_instruction_index();
1663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_NE(-1, start);
1664014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = start; i <= end; ++i) {
1665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MeetConstraintsBefore(i);
1666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (i != end) MeetConstraintsAfter(i);
1667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Meet register constraints for the instruction in the end.
1669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MeetRegisterConstraintsForLastInstructionInBlock(block);
1670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid ConstraintBuilder::MeetRegisterConstraintsForLastInstructionInBlock(
1674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const InstructionBlock* block) {
1675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int end = block->last_instruction_index();
1676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Instruction* last_instruction = code()->InstructionAt(end);
1677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < last_instruction->OutputCount(); i++) {
1678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand* output_operand = last_instruction->OutputAt(i);
1679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!output_operand->IsConstant());
1680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UnallocatedOperand* output = UnallocatedOperand::cast(output_operand);
1681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int output_vreg = output->virtual_register();
1682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TopLevelLiveRange* range = data()->GetOrCreateLiveRangeFor(output_vreg);
1683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool assigned = false;
1684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (output->HasFixedPolicy()) {
1685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      AllocateFixed(output, -1, false);
1686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // This value is produced on the stack, we never need to spill it.
1687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (output->IsStackSlot()) {
1688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(LocationOperand::cast(output)->index() <
1689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               data()->frame()->GetSpillSlotCount());
1690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->SetSpillOperand(LocationOperand::cast(output));
1691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->SetSpillStartIndex(end);
1692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        assigned = true;
1693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
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        // Create an unconstrained operand for the same virtual register
1700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // and insert a gap move from the fixed output to the operand.
1701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UnallocatedOperand output_copy(UnallocatedOperand::ANY, output_vreg);
1702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        data()->AddGapMove(gap_index, Instruction::START, *output, output_copy);
1703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!assigned) {
1707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (const RpoNumber& succ : block->successors()) {
1708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        const InstructionBlock* successor = code()->InstructionBlockAt(succ);
1709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(successor->PredecessorCount() == 1);
1710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int gap_index = successor->first_instruction_index();
1711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->RecordSpillLocation(allocation_zone(), gap_index, output);
1712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->SetSpillStartIndex(gap_index);
1713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid ConstraintBuilder::MeetConstraintsAfter(int instr_index) {
1720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Instruction* first = code()->InstructionAt(instr_index);
1721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Handle fixed temporaries.
1722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < first->TempCount(); i++) {
1723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UnallocatedOperand* temp = UnallocatedOperand::cast(first->TempAt(i));
1724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (temp->HasFixedPolicy()) AllocateFixed(temp, instr_index, false);
1725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Handle constant/fixed output operands.
1727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < first->OutputCount(); i++) {
1728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand* output = first->OutputAt(i);
1729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (output->IsConstant()) {
1730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int output_vreg = ConstantOperand::cast(output)->virtual_register();
1731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      TopLevelLiveRange* range = data()->GetOrCreateLiveRangeFor(output_vreg);
1732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      range->SetSpillStartIndex(instr_index + 1);
1733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      range->SetSpillOperand(output);
1734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      continue;
1735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UnallocatedOperand* first_output = UnallocatedOperand::cast(output);
1737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TopLevelLiveRange* range =
1738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        data()->GetOrCreateLiveRangeFor(first_output->virtual_register());
1739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool assigned = false;
1740014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (first_output->HasFixedPolicy()) {
1741014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int output_vreg = first_output->virtual_register();
1742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UnallocatedOperand output_copy(UnallocatedOperand::ANY, output_vreg);
1743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bool is_tagged = code()->IsReference(output_vreg);
1744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (first_output->HasSecondaryStorage()) {
1745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->MarkHasPreassignedSlot();
1746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        data()->preassigned_slot_ranges().push_back(
1747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            std::make_pair(range, first_output->GetSecondaryStorage()));
1748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      AllocateFixed(first_output, instr_index, is_tagged);
1750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // This value is produced on the stack, we never need to spill it.
1752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (first_output->IsStackSlot()) {
1753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(LocationOperand::cast(first_output)->index() <
1754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               data()->frame()->GetTotalFrameSlotCount());
1755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->SetSpillOperand(LocationOperand::cast(first_output));
1756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->SetSpillStartIndex(instr_index + 1);
1757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        assigned = true;
1758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      data()->AddGapMove(instr_index + 1, Instruction::START, *first_output,
1760014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         output_copy);
1761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Make sure we add a gap move for spilling (if we have not done
1763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // so already).
1764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!assigned) {
1765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      range->RecordSpillLocation(allocation_zone(), instr_index + 1,
1766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 first_output);
1767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      range->SetSpillStartIndex(instr_index + 1);
1768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1773014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid ConstraintBuilder::MeetConstraintsBefore(int instr_index) {
1774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Instruction* second = code()->InstructionAt(instr_index);
1775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Handle fixed input operands of second instruction.
1776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < second->InputCount(); i++) {
1777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand* input = second->InputAt(i);
1778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (input->IsImmediate() || input->IsExplicit()) {
1779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      continue;  // Ignore immediates and explicitly reserved registers.
1780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UnallocatedOperand* cur_input = UnallocatedOperand::cast(input);
1782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (cur_input->HasFixedPolicy()) {
1783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int input_vreg = cur_input->virtual_register();
1784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UnallocatedOperand input_copy(UnallocatedOperand::ANY, input_vreg);
1785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bool is_tagged = code()->IsReference(input_vreg);
1786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      AllocateFixed(cur_input, instr_index, is_tagged);
1787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      data()->AddGapMove(instr_index, Instruction::END, input_copy, *cur_input);
1788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1789014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Handle "output same as input" for second instruction.
1791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < second->OutputCount(); i++) {
1792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand* output = second->OutputAt(i);
1793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!output->IsUnallocated()) continue;
1794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UnallocatedOperand* second_output = UnallocatedOperand::cast(output);
1795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!second_output->HasSameAsInputPolicy()) continue;
1796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(i == 0);  // Only valid for first output.
1797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UnallocatedOperand* cur_input =
1798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UnallocatedOperand::cast(second->InputAt(0));
1799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int output_vreg = second_output->virtual_register();
1800014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int input_vreg = cur_input->virtual_register();
1801014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UnallocatedOperand input_copy(UnallocatedOperand::ANY, input_vreg);
1802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    cur_input->set_virtual_register(second_output->virtual_register());
1803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MoveOperands* gap_move = data()->AddGapMove(instr_index, Instruction::END,
1804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                input_copy, *cur_input);
1805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (code()->IsReference(input_vreg) && !code()->IsReference(output_vreg)) {
1806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (second->HasReferenceMap()) {
1807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        RegisterAllocationData::DelayedReference delayed_reference = {
1808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            second->reference_map(), &gap_move->source()};
1809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        data()->delayed_references().push_back(delayed_reference);
1810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (!code()->IsReference(input_vreg) &&
1812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               code()->IsReference(output_vreg)) {
1813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // The input is assumed to immediately have a tagged representation,
1814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // before the pointer map can be used. I.e. the pointer map at the
1815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // instruction will include the output operand (whose value at the
1816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // beginning of the instruction is equal to the input operand). If
1817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // this is not desired, then the pointer map at this instruction needs
1818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // to be adjusted manually.
1819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid ConstraintBuilder::ResolvePhis() {
1825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Process the blocks in reverse order.
1826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (InstructionBlock* block : base::Reversed(code()->instruction_blocks())) {
1827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ResolvePhis(block);
1828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid ConstraintBuilder::ResolvePhis(const InstructionBlock* block) {
1833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (PhiInstruction* phi : block->phis()) {
1834958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    int phi_vreg = phi->virtual_register();
1835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    RegisterAllocationData::PhiMapValue* map_value =
1836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        data()->InitializePhiMap(block, phi);
1837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand& output = phi->output();
1838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Map the destination operands, so the commitment phase can find them.
1839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (size_t i = 0; i < phi->operands().size(); ++i) {
1840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionBlock* cur_block =
1841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          code()->InstructionBlockAt(block->predecessors()[i]);
1842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UnallocatedOperand input(UnallocatedOperand::ANY, phi->operands()[i]);
1843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      MoveOperands* move = data()->AddGapMove(
1844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          cur_block->last_instruction_index(), Instruction::END, input, output);
1845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      map_value->AddOperand(&move->destination());
1846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(!code()
1847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  ->InstructionAt(cur_block->last_instruction_index())
1848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  ->HasReferenceMap());
1849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TopLevelLiveRange* live_range = data()->GetOrCreateLiveRangeFor(phi_vreg);
1851958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    int gap_index = block->first_instruction_index();
1852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    live_range->RecordSpillLocation(allocation_zone(), gap_index, &output);
1853958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    live_range->SetSpillStartIndex(gap_index);
1854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // We use the phi-ness of some nodes in some later heuristics.
1855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    live_range->set_is_phi(true);
1856958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    live_range->set_is_non_loop_phi(!block->IsLoopHeader());
1857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLiveRangeBuilder::LiveRangeBuilder(RegisterAllocationData* data,
1862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                   Zone* local_zone)
1863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : data_(data), phi_hints_(local_zone) {}
1864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochBitVector* LiveRangeBuilder::ComputeLiveOut(const InstructionBlock* block,
1867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            RegisterAllocationData* data) {
1868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t block_index = block->rpo_number().ToSize();
1869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BitVector* live_out = data->live_out_sets()[block_index];
1870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (live_out == nullptr) {
1871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Compute live out for the given block, except not including backward
1872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // successor edges.
1873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Zone* zone = data->allocation_zone();
1874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const InstructionSequence* code = data->code();
1875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    live_out = new (zone) BitVector(code->VirtualRegisterCount(), zone);
1877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Process all successor blocks.
1879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (const RpoNumber& succ : block->successors()) {
1880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Add values live on entry to the successor.
1881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (succ <= block->rpo_number()) continue;
1882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      BitVector* live_in = data->live_in_sets()[succ.ToSize()];
1883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (live_in != nullptr) live_out->Union(*live_in);
1884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // All phi input operands corresponding to this successor edge are live
1886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // out from this block.
1887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      const InstructionBlock* successor = code->InstructionBlockAt(succ);
1888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      size_t index = successor->PredecessorIndexOf(block->rpo_number());
1889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(index < successor->PredecessorCount());
1890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (PhiInstruction* phi : successor->phis()) {
1891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        live_out->Add(phi->operands()[index]);
1892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    data->live_out_sets()[block_index] = live_out;
1895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return live_out;
1897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRangeBuilder::AddInitialIntervals(const InstructionBlock* block,
1901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           BitVector* live_out) {
1902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Add an interval that includes the entire block to the live range for
1903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // each live_out value.
1904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition start = LifetimePosition::GapFromInstructionIndex(
1905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      block->first_instruction_index());
1906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition end = LifetimePosition::InstructionFromInstructionIndex(
1907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             block->last_instruction_index())
1908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             .NextStart();
1909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BitVector::Iterator iterator(live_out);
1910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (!iterator.Done()) {
1911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int operand_index = iterator.Current();
1912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TopLevelLiveRange* range = data()->GetOrCreateLiveRangeFor(operand_index);
1913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    range->AddUseInterval(start, end, allocation_zone());
1914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    iterator.Advance();
1915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint LiveRangeBuilder::FixedDoubleLiveRangeID(int index) {
1920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return -index - 1 - config()->num_general_registers();
1921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTopLevelLiveRange* LiveRangeBuilder::FixedLiveRangeFor(int index) {
1925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(index < config()->num_general_registers());
1926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TopLevelLiveRange* result = data()->fixed_live_ranges()[index];
1927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (result == nullptr) {
1928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    result = data()->NewLiveRange(FixedLiveRangeID(index),
1929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  InstructionSequence::DefaultRepresentation());
1930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(result->IsFixed());
1931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    result->set_assigned_register(index);
1932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    data()->MarkAllocated(GENERAL_REGISTERS, index);
1933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    data()->fixed_live_ranges()[index] = result;
1934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return result;
1936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTopLevelLiveRange* LiveRangeBuilder::FixedDoubleLiveRangeFor(int index) {
1940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(index < config()->num_double_registers());
1941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TopLevelLiveRange* result = data()->fixed_double_live_ranges()[index];
1942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (result == nullptr) {
1943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    result = data()->NewLiveRange(FixedDoubleLiveRangeID(index),
1944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  MachineRepresentation::kFloat64);
1945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(result->IsFixed());
1946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    result->set_assigned_register(index);
1947014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    data()->MarkAllocated(DOUBLE_REGISTERS, index);
1948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    data()->fixed_double_live_ranges()[index] = result;
1949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return result;
1951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTopLevelLiveRange* LiveRangeBuilder::LiveRangeFor(InstructionOperand* operand) {
1955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (operand->IsUnallocated()) {
1956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return data()->GetOrCreateLiveRangeFor(
1957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UnallocatedOperand::cast(operand)->virtual_register());
1958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (operand->IsConstant()) {
1959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return data()->GetOrCreateLiveRangeFor(
1960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        ConstantOperand::cast(operand)->virtual_register());
1961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (operand->IsRegister()) {
1962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return FixedLiveRangeFor(
1963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        LocationOperand::cast(operand)->GetRegister().code());
1964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (operand->IsDoubleRegister()) {
1965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return FixedDoubleLiveRangeFor(
1966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        LocationOperand::cast(operand)->GetDoubleRegister().code());
1967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return nullptr;
1969958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1971958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1972958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochUsePosition* LiveRangeBuilder::NewUsePosition(LifetimePosition pos,
1974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                              InstructionOperand* operand,
1975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                              void* hint,
1976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                              UsePositionHintType hint_type) {
1977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return new (allocation_zone()) UsePosition(pos, operand, hint, hint_type);
1978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1979958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1980958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochUsePosition* LiveRangeBuilder::Define(LifetimePosition position,
1982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                      InstructionOperand* operand, void* hint,
1983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                      UsePositionHintType hint_type) {
1984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TopLevelLiveRange* range = LiveRangeFor(operand);
1985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (range == nullptr) return nullptr;
1986958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (range->IsEmpty() || range->Start() > position) {
1988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Can happen if there is a definition without use.
1989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    range->AddUseInterval(position, position.NextStart(), allocation_zone());
1990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    range->AddUsePosition(NewUsePosition(position.NextStart()));
1991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    range->ShortenTo(position);
1993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!operand->IsUnallocated()) return nullptr;
1995014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UnallocatedOperand* unalloc_operand = UnallocatedOperand::cast(operand);
1996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePosition* use_pos =
1997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      NewUsePosition(position, unalloc_operand, hint, hint_type);
1998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  range->AddUsePosition(use_pos);
1999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return use_pos;
2000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2001958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2002958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochUsePosition* LiveRangeBuilder::Use(LifetimePosition block_start,
2004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                   LifetimePosition position,
2005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                   InstructionOperand* operand, void* hint,
2006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                   UsePositionHintType hint_type) {
2007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TopLevelLiveRange* range = LiveRangeFor(operand);
2008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (range == nullptr) return nullptr;
2009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePosition* use_pos = nullptr;
2010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (operand->IsUnallocated()) {
2011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UnallocatedOperand* unalloc_operand = UnallocatedOperand::cast(operand);
2012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    use_pos = NewUsePosition(position, unalloc_operand, hint, hint_type);
2013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    range->AddUsePosition(use_pos);
2014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  range->AddUseInterval(block_start, position, allocation_zone());
2016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return use_pos;
2017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2018958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2019958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRangeBuilder::ProcessInstructions(const InstructionBlock* block,
2021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           BitVector* live) {
2022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int block_start = block->first_instruction_index();
2023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition block_start_position =
2024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LifetimePosition::GapFromInstructionIndex(block_start);
2025958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int index = block->last_instruction_index(); index >= block_start;
2027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       index--) {
2028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition curr_position =
2029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        LifetimePosition::InstructionFromInstructionIndex(index);
2030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Instruction* instr = code()->InstructionAt(index);
2031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(instr != nullptr);
2032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(curr_position.IsInstructionPosition());
2033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Process output, inputs, and temps of this instruction.
2034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (size_t i = 0; i < instr->OutputCount(); i++) {
2035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionOperand* output = instr->OutputAt(i);
2036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (output->IsUnallocated()) {
2037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Unsupported.
2038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(!UnallocatedOperand::cast(output)->HasSlotPolicy());
2039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int out_vreg = UnallocatedOperand::cast(output)->virtual_register();
2040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        live->Remove(out_vreg);
2041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else if (output->IsConstant()) {
2042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int out_vreg = ConstantOperand::cast(output)->virtual_register();
2043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        live->Remove(out_vreg);
2044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (block->IsHandler() && index == block_start && output->IsAllocated() &&
2046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          output->IsRegister() &&
2047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          AllocatedOperand::cast(output)->GetRegister().is(
2048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              v8::internal::kReturnRegister0)) {
2049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // The register defined here is blocked from gap start - it is the
2050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // exception value.
2051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // TODO(mtrofin): should we explore an explicit opcode for
2052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // the first instruction in the handler?
2053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Define(LifetimePosition::GapFromInstructionIndex(index), output);
2054958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      } else {
2055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Define(curr_position, output);
2056958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
2057958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2058958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (instr->ClobbersRegisters()) {
2060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (int i = 0; i < config()->num_allocatable_general_registers(); ++i) {
2061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int code = config()->GetAllocatableGeneralCode(i);
2062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (!IsOutputRegisterOf(instr, Register::from_code(code))) {
2063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          TopLevelLiveRange* range = FixedLiveRangeFor(code);
2064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          range->AddUseInterval(curr_position, curr_position.End(),
2065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                allocation_zone());
2066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
2067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2068958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2069958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (instr->ClobbersDoubleRegisters()) {
2071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (int i = 0; i < config()->num_allocatable_aliased_double_registers();
2072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           ++i) {
2073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int code = config()->GetAllocatableDoubleCode(i);
2074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (!IsOutputDoubleRegisterOf(instr, DoubleRegister::from_code(code))) {
2075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          TopLevelLiveRange* range = FixedDoubleLiveRangeFor(code);
2076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          range->AddUseInterval(curr_position, curr_position.End(),
2077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                allocation_zone());
2078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
2079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2080958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2081958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (size_t i = 0; i < instr->InputCount(); i++) {
2083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionOperand* input = instr->InputAt(i);
2084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (input->IsImmediate() || input->IsExplicit()) {
2085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        continue;  // Ignore immediates and explicitly reserved registers.
2086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LifetimePosition use_pos;
2088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (input->IsUnallocated() &&
2089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          UnallocatedOperand::cast(input)->IsUsedAtStart()) {
2090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        use_pos = curr_position;
2091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
2092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        use_pos = curr_position.End();
2093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2094958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (input->IsUnallocated()) {
2096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UnallocatedOperand* unalloc = UnallocatedOperand::cast(input);
2097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int vreg = unalloc->virtual_register();
2098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        live->Add(vreg);
2099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (unalloc->HasSlotPolicy()) {
2100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          data()->GetOrCreateLiveRangeFor(vreg)->set_has_slot_use(true);
2101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
2102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Use(block_start_position, use_pos, input);
2104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (size_t i = 0; i < instr->TempCount(); i++) {
2107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionOperand* temp = instr->TempAt(i);
2108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Unsupported.
2109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK_IMPLIES(temp->IsUnallocated(),
2110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                     !UnallocatedOperand::cast(temp)->HasSlotPolicy());
2111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->ClobbersTemps()) {
2112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (temp->IsRegister()) continue;
2113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (temp->IsUnallocated()) {
2114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          UnallocatedOperand* temp_unalloc = UnallocatedOperand::cast(temp);
2115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          if (temp_unalloc->HasFixedPolicy()) {
2116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            continue;
2117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
2118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
2119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Use(block_start_position, curr_position.End(), temp);
2121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Define(curr_position, temp);
2122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Process the moves of the instruction's gaps, making their sources live.
2125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const Instruction::GapPosition kPositions[] = {Instruction::END,
2126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                   Instruction::START};
2127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    curr_position = curr_position.PrevStart();
2128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(curr_position.IsGapPosition());
2129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (const Instruction::GapPosition& position : kPositions) {
2130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ParallelMove* move = instr->GetParallelMove(position);
2131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (move == nullptr) continue;
2132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (position == Instruction::END) {
2133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        curr_position = curr_position.End();
2134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
2135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        curr_position = curr_position.Start();
2136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (MoveOperands* cur : *move) {
2138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        InstructionOperand& from = cur->source();
2139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        InstructionOperand& to = cur->destination();
2140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        void* hint = &to;
2141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UsePositionHintType hint_type = UsePosition::HintTypeForOperand(to);
2142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UsePosition* to_use = nullptr;
2143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int phi_vreg = -1;
2144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (to.IsUnallocated()) {
2145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          int to_vreg = UnallocatedOperand::cast(to).virtual_register();
2146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          TopLevelLiveRange* to_range =
2147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              data()->GetOrCreateLiveRangeFor(to_vreg);
2148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          if (to_range->is_phi()) {
2149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            phi_vreg = to_vreg;
2150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            if (to_range->is_non_loop_phi()) {
2151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              hint = to_range->current_hint_position();
2152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              hint_type = hint == nullptr ? UsePositionHintType::kNone
2153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                          : UsePositionHintType::kUsePos;
2154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            } else {
2155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              hint_type = UsePositionHintType::kPhi;
2156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              hint = data()->GetPhiMapValueFor(to_vreg);
2157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            }
2158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          } else {
2159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            if (live->Contains(to_vreg)) {
2160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              to_use = Define(curr_position, &to, &from,
2161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              UsePosition::HintTypeForOperand(from));
2162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              live->Remove(to_vreg);
2163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            } else {
2164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              cur->Eliminate();
2165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              continue;
2166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            }
2167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
2168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else {
2169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Define(curr_position, &to);
2170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
2171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UsePosition* from_use =
2172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Use(block_start_position, curr_position, &from, hint, hint_type);
2173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Mark range live.
2174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (from.IsUnallocated()) {
2175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          live->Add(UnallocatedOperand::cast(from).virtual_register());
2176958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        }
2177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Resolve use position hints just created.
2178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (to_use != nullptr && from_use != nullptr) {
2179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          to_use->ResolveHint(from_use);
2180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          from_use->ResolveHint(to_use);
2181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
2182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK_IMPLIES(to_use != nullptr, to_use->IsResolved());
2183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK_IMPLIES(from_use != nullptr, from_use->IsResolved());
2184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Potentially resolve phi hint.
2185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (phi_vreg != -1) ResolvePhiHint(&from, from_use);
2186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
2187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRangeBuilder::ProcessPhis(const InstructionBlock* block,
2193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                   BitVector* live) {
2194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (PhiInstruction* phi : block->phis()) {
2195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // The live range interval already ends at the first instruction of the
2196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // block.
2197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int phi_vreg = phi->virtual_register();
2198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    live->Remove(phi_vreg);
2199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand* hint = nullptr;
2200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Instruction* instr = GetLastInstruction(
2201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        code(), code()->InstructionBlockAt(block->predecessors()[0]));
2202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (MoveOperands* move : *instr->GetParallelMove(Instruction::END)) {
2203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionOperand& to = move->destination();
2204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (to.IsUnallocated() &&
2205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          UnallocatedOperand::cast(to).virtual_register() == phi_vreg) {
2206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        hint = &move->source();
2207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
2208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(hint != nullptr);
2211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition block_start = LifetimePosition::GapFromInstructionIndex(
2212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        block->first_instruction_index());
2213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UsePosition* use_pos = Define(block_start, &phi->output(), hint,
2214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  UsePosition::HintTypeForOperand(*hint));
2215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MapPhiHint(hint, use_pos);
2216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRangeBuilder::ProcessLoopHeader(const InstructionBlock* block,
2221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                         BitVector* live) {
2222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(block->IsLoopHeader());
2223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Add a live range stretching from the first loop instruction to the last
2224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // for each value live on entry to the header.
2225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BitVector::Iterator iterator(live);
2226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition start = LifetimePosition::GapFromInstructionIndex(
2227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      block->first_instruction_index());
2228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition end = LifetimePosition::GapFromInstructionIndex(
2229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             code()->LastLoopInstructionIndex(block))
2230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             .NextFullStart();
2231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (!iterator.Done()) {
2232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int operand_index = iterator.Current();
2233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TopLevelLiveRange* range = data()->GetOrCreateLiveRangeFor(operand_index);
2234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    range->EnsureInterval(start, end, allocation_zone());
2235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    iterator.Advance();
2236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Insert all values into the live in sets of all blocks in the loop.
2238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = block->rpo_number().ToInt() + 1; i < block->loop_end().ToInt();
2239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       ++i) {
2240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    live_in_sets()[i]->Union(*live);
2241958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2242958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2243958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2244958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRangeBuilder::BuildLiveRanges() {
2246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Process the blocks in reverse order.
2247958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (int block_id = code()->InstructionBlockCount() - 1; block_id >= 0;
2248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       --block_id) {
2249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionBlock* block =
2250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        code()->InstructionBlockAt(RpoNumber::FromInt(block_id));
2251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    BitVector* live = ComputeLiveOut(block, data());
2252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Initially consider all live_out values live for the entire block. We
2253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // will shorten these intervals if necessary.
2254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AddInitialIntervals(block, live);
2255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Process the instructions in reverse order, generating and killing
2256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // live values.
2257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ProcessInstructions(block, live);
2258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // All phi output operands are killed by this block.
2259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ProcessPhis(block, live);
2260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Now live is live_in for this block except not including values live
2261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // out on backward successor edges.
2262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (block->IsLoopHeader()) ProcessLoopHeader(block, live);
2263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    live_in_sets()[block_id] = live;
2264958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Postprocess the ranges.
2266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (TopLevelLiveRange* range : data()->live_ranges()) {
2267958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (range == nullptr) continue;
2268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Give slots to all ranges with a non fixed slot use.
2269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range->has_slot_use() && range->HasNoSpillType()) {
2270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      data()->AssignSpillRangeToLiveRange(range);
2271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2272958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // TODO(bmeurer): This is a horrible hack to make sure that for constant
2273958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // live ranges, every use requires the constant to be in a register.
2274958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // Without this hack, all uses with "any" policy would get the constant
2275958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // operand assigned.
2276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (range->HasSpillOperand() && range->GetSpillOperand()->IsConstant()) {
2277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (UsePosition* pos = range->first_pos(); pos != nullptr;
2278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           pos = pos->next()) {
2279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (pos->type() == UsePositionType::kRequiresSlot) continue;
2280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UsePositionType new_type = UsePositionType::kAny;
2281958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        // Can't mark phis as needing a register.
2282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (!pos->pos().IsGapPosition()) {
2283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          new_type = UsePositionType::kRequiresRegister;
2284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
2285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        pos->set_type(new_type, true);
2286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (auto preassigned : data()->preassigned_slot_ranges()) {
2290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TopLevelLiveRange* range = preassigned.first;
2291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int slot_id = preassigned.second;
2292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SpillRange* spill = range->HasSpillRange()
2293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            ? range->GetSpillRange()
2294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            : data()->AssignSpillRangeToLiveRange(range);
2295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    spill->set_assigned_slot(slot_id);
2296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifdef DEBUG
2298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Verify();
2299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif
2300958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2302958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRangeBuilder::MapPhiHint(InstructionOperand* operand,
2304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  UsePosition* use_pos) {
2305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!use_pos->IsResolved());
2306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  auto res = phi_hints_.insert(std::make_pair(operand, use_pos));
2307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(res.second);
2308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  USE(res);
2309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRangeBuilder::ResolvePhiHint(InstructionOperand* operand,
2313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                      UsePosition* use_pos) {
2314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  auto it = phi_hints_.find(operand);
2315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (it == phi_hints_.end()) return;
2316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!it->second->IsResolved());
2317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  it->second->ResolveHint(use_pos);
2318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRangeBuilder::Verify() const {
2322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (auto& hint : phi_hints_) {
2323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CHECK(hint.second->IsResolved());
2324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (TopLevelLiveRange* current : data()->live_ranges()) {
2326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (current != nullptr && !current->IsEmpty()) current->Verify();
2327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochRegisterAllocator::RegisterAllocator(RegisterAllocationData* data,
2332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     RegisterKind kind)
2333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : data_(data),
2334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      mode_(kind),
2335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      num_registers_(GetRegisterCount(data->config(), kind)),
2336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      num_allocatable_registers_(
2337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          GetAllocatableRegisterCount(data->config(), kind)),
2338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      allocatable_register_codes_(
2339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          GetAllocatableRegisterCodes(data->config(), kind)) {}
2340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLifetimePosition RegisterAllocator::GetSplitPositionForInstruction(
2343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const LiveRange* range, int instruction_index) {
2344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition ret = LifetimePosition::Invalid();
2345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ret = LifetimePosition::GapFromInstructionIndex(instruction_index);
2347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (range->Start() >= ret || ret >= range->End()) {
2348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return LifetimePosition::Invalid();
2349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return ret;
2351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid RegisterAllocator::SplitAndSpillRangesDefinedByMemoryOperand(
2355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool operands_only) {
2356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t initial_range_count = data()->live_ranges().size();
2357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < initial_range_count; ++i) {
2358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TopLevelLiveRange* range = data()->live_ranges()[i];
2359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!CanProcessRange(range)) continue;
2360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range->HasNoSpillType() || (operands_only && range->HasSpillRange())) {
2361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      continue;
2362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition start = range->Start();
2365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TRACE("Live range %d:%d is defined by a spill operand.\n",
2366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          range->TopLevel()->vreg(), range->relative_id());
2367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition next_pos = start;
2368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (next_pos.IsGapPosition()) {
2369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      next_pos = next_pos.NextStart();
2370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UsePosition* pos = range->NextUsePositionRegisterIsBeneficial(next_pos);
2372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // If the range already has a spill operand and it doesn't need a
2373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // register immediately, split it and spill the first part of the range.
2374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (pos == nullptr) {
2375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Spill(range);
2376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (pos->pos() > range->Start().NextStart()) {
2377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Do not spill live range eagerly if use position that can benefit from
2378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // the register is too close to the start of live range.
2379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LifetimePosition split_pos = GetSplitPositionForInstruction(
2380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          range, pos->pos().ToInstructionIndex());
2381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // There is no place to split, so we can't split and spill.
2382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!split_pos.IsValid()) continue;
2383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      split_pos =
2385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          FindOptimalSplitPos(range->Start().NextFullStart(), split_pos);
2386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SplitRangeAt(range, split_pos);
2388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Spill(range);
2389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLiveRange* RegisterAllocator::SplitRangeAt(LiveRange* range,
2395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           LifetimePosition pos) {
2396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!range->TopLevel()->IsFixed());
2397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Splitting live range %d:%d at %d\n", range->TopLevel()->vreg(),
2398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->relative_id(), pos.value());
2399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (pos <= range->Start()) return range;
2401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // We can't properly connect liveranges if splitting occurred at the end
2403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // a block.
2404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(pos.IsStart() || pos.IsGapPosition() ||
2405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         (GetInstructionBlock(code(), pos)->last_instruction_index() !=
2406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          pos.ToInstructionIndex()));
2407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LiveRange* result = range->SplitAt(pos, allocation_zone());
2409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return result;
2410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLiveRange* RegisterAllocator::SplitBetween(LiveRange* range,
2414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           LifetimePosition start,
2415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           LifetimePosition end) {
2416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!range->TopLevel()->IsFixed());
2417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Splitting live range %d:%d in position between [%d, %d]\n",
2418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->TopLevel()->vreg(), range->relative_id(), start.value(),
2419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        end.value());
2420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition split_pos = FindOptimalSplitPos(start, end);
2422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(split_pos >= start);
2423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return SplitRangeAt(range, split_pos);
2424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLifetimePosition RegisterAllocator::FindOptimalSplitPos(LifetimePosition start,
2428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                        LifetimePosition end) {
2429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int start_instr = start.ToInstructionIndex();
2430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int end_instr = end.ToInstructionIndex();
2431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(start_instr <= end_instr);
2432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // We have no choice
2434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (start_instr == end_instr) return end;
2435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const InstructionBlock* start_block = GetInstructionBlock(code(), start);
2437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const InstructionBlock* end_block = GetInstructionBlock(code(), end);
2438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (end_block == start_block) {
2440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // The interval is split in the same basic block. Split at the latest
2441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // possible position.
2442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return end;
2443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const InstructionBlock* block = end_block;
2446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Find header of outermost loop.
2447109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  do {
2448109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    const InstructionBlock* loop = GetContainingLoop(code(), block);
2449109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (loop == nullptr ||
2450109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        loop->rpo_number().ToInt() <= start_block->rpo_number().ToInt()) {
2451109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // No more loops or loop starts before the lifetime start.
2452109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      break;
2453109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
2454109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    block = loop;
2455109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  } while (true);
2456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // We did not find any suitable outer loop. Split at the latest possible
2458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // position unless end_block is a loop header itself.
2459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (block == end_block && !end_block->IsLoopHeader()) return end;
2460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return LifetimePosition::GapFromInstructionIndex(
2462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      block->first_instruction_index());
2463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLifetimePosition RegisterAllocator::FindOptimalSpillingPos(
2467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* range, LifetimePosition pos) {
2468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const InstructionBlock* block = GetInstructionBlock(code(), pos.Start());
2469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const InstructionBlock* loop_header =
2470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      block->IsLoopHeader() ? block : GetContainingLoop(code(), block);
2471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (loop_header == nullptr) return pos;
2473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const UsePosition* prev_use =
2475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      range->PreviousUsePositionRegisterIsBeneficial(pos);
2476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (loop_header != nullptr) {
2478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // We are going to spill live range inside the loop.
2479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // If possible try to move spilling position backwards to loop header.
2480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // This will reduce number of memory moves on the back edge.
2481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition loop_start = LifetimePosition::GapFromInstructionIndex(
2482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        loop_header->first_instruction_index());
2483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range->Covers(loop_start)) {
2485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (prev_use == nullptr || prev_use->pos() < loop_start) {
2486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // No register beneficial use inside the loop before the pos.
2487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        pos = loop_start;
2488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Try hoisting out to an outer loop.
2492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    loop_header = GetContainingLoop(code(), loop_header);
2493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return pos;
2496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid RegisterAllocator::Spill(LiveRange* range) {
2500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!range->spilled());
2501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TopLevelLiveRange* first = range->TopLevel();
2502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Spilling live range %d:%d\n", first->vreg(), range->relative_id());
2503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (first->HasNoSpillType()) {
2505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    data()->AssignSpillRangeToLiveRange(first);
2506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  range->Spill();
2508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst ZoneVector<TopLevelLiveRange*>& RegisterAllocator::GetFixedRegisters()
2512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const {
2513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return mode() == DOUBLE_REGISTERS ? data()->fixed_double_live_ranges()
2514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                    : data()->fixed_live_ranges();
2515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst char* RegisterAllocator::RegisterName(int register_code) const {
2519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (mode() == GENERAL_REGISTERS) {
2520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return data()->config()->GetGeneralRegisterName(register_code);
2521014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
2522014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return data()->config()->GetDoubleRegisterName(register_code);
2523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2526014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLinearScanAllocator::LinearScanAllocator(RegisterAllocationData* data,
2528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                         RegisterKind kind, Zone* local_zone)
2529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : RegisterAllocator(data, kind),
2530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      unhandled_live_ranges_(local_zone),
2531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      active_live_ranges_(local_zone),
2532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      inactive_live_ranges_(local_zone) {
2533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  unhandled_live_ranges().reserve(
2534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      static_cast<size_t>(code()->VirtualRegisterCount() * 2));
2535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  active_live_ranges().reserve(8);
2536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  inactive_live_ranges().reserve(8);
2537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // TryAllocateFreeReg and AllocateBlockedReg assume this
2538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // when allocating local arrays.
2539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(RegisterConfiguration::kMaxDoubleRegisters >=
2540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         this->data()->config()->num_general_registers());
2541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::AllocateRegisters() {
2545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(unhandled_live_ranges().empty());
2546958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(active_live_ranges().empty());
2547958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(inactive_live_ranges().empty());
2548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SplitAndSpillRangesDefinedByMemoryOperand(code()->VirtualRegisterCount() <=
2550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            num_allocatable_registers());
2551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (TopLevelLiveRange* range : data()->live_ranges()) {
2553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!CanProcessRange(range)) continue;
2554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (LiveRange* to_add = range; to_add != nullptr;
2555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         to_add = to_add->next()) {
2556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!to_add->spilled()) {
2557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        AddToUnhandledUnsorted(to_add);
2558b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2559b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SortUnhandled();
2562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(UnhandledIsSorted());
2563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  auto& fixed_ranges = GetFixedRegisters();
2565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (TopLevelLiveRange* current : fixed_ranges) {
2566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (current != nullptr) {
2567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK_EQ(mode(), current->kind());
2568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      AddToInactive(current);
2569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2572958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  while (!unhandled_live_ranges().empty()) {
2573b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(UnhandledIsSorted());
2574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* current = unhandled_live_ranges().back();
2575958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    unhandled_live_ranges().pop_back();
2576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(UnhandledIsSorted());
2577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition position = current->Start();
2578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
2579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    allocation_finger_ = position;
2580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
2581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TRACE("Processing interval %d:%d start=%d\n", current->TopLevel()->vreg(),
2582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          current->relative_id(), position.value());
2583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (current->IsTopLevel() && TryReuseSpillForPhi(current->TopLevel()))
2585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      continue;
2586958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2587958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (size_t i = 0; i < active_live_ranges().size(); ++i) {
2588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LiveRange* cur_active = active_live_ranges()[i];
2589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (cur_active->End() <= position) {
2590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ActiveToHandled(cur_active);
2591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        --i;  // The live range was removed from the list of active live ranges.
2592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else if (!cur_active->Covers(position)) {
2593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ActiveToInactive(cur_active);
2594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        --i;  // The live range was removed from the list of active live ranges.
2595b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2597b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2598958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (size_t i = 0; i < inactive_live_ranges().size(); ++i) {
2599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LiveRange* cur_inactive = inactive_live_ranges()[i];
2600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (cur_inactive->End() <= position) {
2601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        InactiveToHandled(cur_inactive);
2602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        --i;  // Live range was removed from the list of inactive live ranges.
2603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else if (cur_inactive->Covers(position)) {
2604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        InactiveToActive(cur_inactive);
2605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        --i;  // Live range was removed from the list of inactive live ranges.
2606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2607b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!current->HasRegisterAssigned() && !current->spilled());
2610b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    bool result = TryAllocateFreeReg(current);
2612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!result) AllocateBlockedReg(current);
2613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (current->HasRegisterAssigned()) {
2614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      AddToActive(current);
2615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::SetLiveRangeAssignedRegister(LiveRange* range,
2621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                       int reg) {
2622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  data()->MarkAllocated(range->kind(), reg);
2623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  range->set_assigned_register(reg);
2624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  range->SetUseHints(reg);
2625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (range->IsTopLevel() && range->TopLevel()->is_phi()) {
2626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    data()->GetPhiMapValueFor(range->TopLevel())->set_assigned_register(reg);
2627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2629b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::AddToActive(LiveRange* range) {
2632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Add live range %d:%d to active\n", range->TopLevel()->vreg(),
2633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->relative_id());
2634958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  active_live_ranges().push_back(range);
2635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::AddToInactive(LiveRange* range) {
2639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Add live range %d:%d to inactive\n", range->TopLevel()->vreg(),
2640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->relative_id());
2641958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  inactive_live_ranges().push_back(range);
2642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::AddToUnhandledSorted(LiveRange* range) {
2646958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (range == nullptr || range->IsEmpty()) return;
2647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!range->HasRegisterAssigned() && !range->spilled());
2648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(allocation_finger_ <= range->Start());
2649958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (int i = static_cast<int>(unhandled_live_ranges().size() - 1); i >= 0;
2650958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier       --i) {
2651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* cur_range = unhandled_live_ranges().at(i);
2652958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (!range->ShouldBeAllocatedBefore(cur_range)) continue;
2653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TRACE("Add live range %d:%d to unhandled at %d\n",
2654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          range->TopLevel()->vreg(), range->relative_id(), i + 1);
2655958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto it = unhandled_live_ranges().begin() + (i + 1);
2656958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    unhandled_live_ranges().insert(it, range);
2657958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(UnhandledIsSorted());
2658958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return;
2659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Add live range %d:%d to unhandled at start\n",
2661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->TopLevel()->vreg(), range->relative_id());
2662958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  unhandled_live_ranges().insert(unhandled_live_ranges().begin(), range);
2663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(UnhandledIsSorted());
2664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::AddToUnhandledUnsorted(LiveRange* range) {
2668958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (range == nullptr || range->IsEmpty()) return;
2669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!range->HasRegisterAssigned() && !range->spilled());
2670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Add live range %d:%d to unhandled unsorted at end\n",
2671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->TopLevel()->vreg(), range->relative_id());
2672958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  unhandled_live_ranges().push_back(range);
2673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2676958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic bool UnhandledSortHelper(LiveRange* a, LiveRange* b) {
2677958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(!a->ShouldBeAllocatedBefore(b) || !b->ShouldBeAllocatedBefore(a));
2678958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (a->ShouldBeAllocatedBefore(b)) return false;
2679958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (b->ShouldBeAllocatedBefore(a)) return true;
2680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return a->TopLevel()->vreg() < b->TopLevel()->vreg();
2681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Sort the unhandled live ranges so that the ranges to be processed first are
2685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// at the end of the array list.  This is convenient for the register allocation
2686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// algorithm because it is efficient to remove elements from the end.
2687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::SortUnhandled() {
2688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Sort unhandled\n");
2689958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  std::sort(unhandled_live_ranges().begin(), unhandled_live_ranges().end(),
2690958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            &UnhandledSortHelper);
2691b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool LinearScanAllocator::UnhandledIsSorted() {
2695958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  size_t len = unhandled_live_ranges().size();
2696958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (size_t i = 1; i < len; i++) {
2697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* a = unhandled_live_ranges().at(i - 1);
2698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* b = unhandled_live_ranges().at(i);
2699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (a->Start() < b->Start()) return false;
2700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return true;
2702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::ActiveToHandled(LiveRange* range) {
2706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RemoveElement(&active_live_ranges(), range);
2707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Moving live range %d:%d from active to handled\n",
2708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->TopLevel()->vreg(), range->relative_id());
2709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::ActiveToInactive(LiveRange* range) {
2713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RemoveElement(&active_live_ranges(), range);
2714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  inactive_live_ranges().push_back(range);
2715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Moving live range %d:%d from active to inactive\n",
2716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->TopLevel()->vreg(), range->relative_id());
2717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::InactiveToHandled(LiveRange* range) {
2721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RemoveElement(&inactive_live_ranges(), range);
2722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Moving live range %d:%d from inactive to handled\n",
2723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->TopLevel()->vreg(), range->relative_id());
2724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2725b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::InactiveToActive(LiveRange* range) {
2728958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  RemoveElement(&inactive_live_ranges(), range);
2729958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  active_live_ranges().push_back(range);
2730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Moving live range %d:%d from inactive to active\n",
2731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->TopLevel()->vreg(), range->relative_id());
2732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool LinearScanAllocator::TryAllocateFreeReg(LiveRange* current) {
2736958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  LifetimePosition free_until_pos[RegisterConfiguration::kMaxDoubleRegisters];
2737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < num_registers(); i++) {
2739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    free_until_pos[i] = LifetimePosition::MaxPosition();
2740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (LiveRange* cur_active : active_live_ranges()) {
2743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    free_until_pos[cur_active->assigned_register()] =
2744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        LifetimePosition::GapFromInstructionIndex(0);
2745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TRACE("Register %s is free until pos %d (1)\n",
2746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          RegisterName(cur_active->assigned_register()),
2747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          LifetimePosition::GapFromInstructionIndex(0).value());
2748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (LiveRange* cur_inactive : inactive_live_ranges()) {
2751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(cur_inactive->End() > current->Start());
2752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition next_intersection =
2753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        cur_inactive->FirstIntersection(current);
2754b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!next_intersection.IsValid()) continue;
2755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int cur_reg = cur_inactive->assigned_register();
2756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    free_until_pos[cur_reg] = Min(free_until_pos[cur_reg], next_intersection);
2757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TRACE("Register %s is free until pos %d (2)\n", RegisterName(cur_reg),
2758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Min(free_until_pos[cur_reg], next_intersection).value());
2759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int hint_register;
2762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (current->FirstHintPosition(&hint_register) != nullptr) {
2763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TRACE(
2764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        "Found reg hint %s (free until [%d) for live range %d:%d (end %d[).\n",
2765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        RegisterName(hint_register), free_until_pos[hint_register].value(),
2766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        current->TopLevel()->vreg(), current->relative_id(),
2767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        current->End().value());
2768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // The desired register is free until the end of the current live range.
2770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (free_until_pos[hint_register] >= current->End()) {
2771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      TRACE("Assigning preferred reg %s to live range %d:%d\n",
2772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            RegisterName(hint_register), current->TopLevel()->vreg(),
2773014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            current->relative_id());
2774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SetLiveRangeAssignedRegister(current, hint_register);
2775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return true;
2776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Find the register which stays free for the longest time.
2780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int reg = allocatable_register_code(0);
2781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 1; i < num_allocatable_registers(); ++i) {
2782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int code = allocatable_register_code(i);
2783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (free_until_pos[code] > free_until_pos[reg]) {
2784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      reg = code;
2785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition pos = free_until_pos[reg];
2789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (pos <= current->Start()) {
2791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // All registers are blocked.
2792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return false;
2793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (pos < current->End()) {
2796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Register reg is available at the range start but becomes blocked before
2797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // the range end. Split current at position where it becomes blocked.
2798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* tail = SplitRangeAt(current, pos);
2799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AddToUnhandledSorted(tail);
2800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Register reg is available at the range start and is free until
2803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // the range end.
2804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(pos >= current->End());
2805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Assigning free reg %s to live range %d:%d\n", RegisterName(reg),
2806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        current->TopLevel()->vreg(), current->relative_id());
2807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SetLiveRangeAssignedRegister(current, reg);
2808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return true;
2810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::AllocateBlockedReg(LiveRange* current) {
2814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePosition* register_use = current->NextRegisterPosition(current->Start());
2815958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (register_use == nullptr) {
2816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // There is no use in the current live range that requires a register.
2817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // We can just spill it.
2818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Spill(current);
2819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return;
2820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2822958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  LifetimePosition use_pos[RegisterConfiguration::kMaxDoubleRegisters];
2823958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  LifetimePosition block_pos[RegisterConfiguration::kMaxDoubleRegisters];
2824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 0; i < num_registers(); i++) {
2826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    use_pos[i] = block_pos[i] = LifetimePosition::MaxPosition();
2827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (LiveRange* range : active_live_ranges()) {
2830b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int cur_reg = range->assigned_register();
2831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range->TopLevel()->IsFixed() ||
2832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        !range->CanBeSpilled(current->Start())) {
2833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      block_pos[cur_reg] = use_pos[cur_reg] =
2834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          LifetimePosition::GapFromInstructionIndex(0);
2835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
2836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UsePosition* next_use =
2837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          range->NextUsePositionRegisterIsBeneficial(current->Start());
2838958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (next_use == nullptr) {
2839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        use_pos[cur_reg] = range->End();
2840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
2841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        use_pos[cur_reg] = next_use->pos();
2842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (LiveRange* range : inactive_live_ranges()) {
2847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(range->End() > current->Start());
2848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition next_intersection = range->FirstIntersection(current);
2849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!next_intersection.IsValid()) continue;
2850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int cur_reg = range->assigned_register();
2851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range->TopLevel()->IsFixed()) {
2852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      block_pos[cur_reg] = Min(block_pos[cur_reg], next_intersection);
2853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      use_pos[cur_reg] = Min(block_pos[cur_reg], use_pos[cur_reg]);
2854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
2855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      use_pos[cur_reg] = Min(use_pos[cur_reg], next_intersection);
2856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int reg = allocatable_register_code(0);
2860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = 1; i < num_allocatable_registers(); ++i) {
2861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int code = allocatable_register_code(i);
2862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (use_pos[code] > use_pos[reg]) {
2863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      reg = code;
2864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition pos = use_pos[reg];
2868b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (pos < register_use->pos()) {
2870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // All registers are blocked before the first use that requires a register.
2871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Spill starting part of live range up to that use.
2872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    SpillBetween(current, current->Start(), register_use->pos());
2873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return;
2874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2875b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (block_pos[reg] < current->End()) {
2877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Register becomes blocked before the current range end. Split before that
2878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // position.
2879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* tail =
2880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        SplitBetween(current, current->Start(), block_pos[reg].Start());
2881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AddToUnhandledSorted(tail);
2882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Register reg is not blocked for the whole range.
2885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(block_pos[reg] >= current->End());
2886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Assigning blocked reg %s to live range %d:%d\n", RegisterName(reg),
2887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        current->TopLevel()->vreg(), current->relative_id());
2888b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SetLiveRangeAssignedRegister(current, reg);
2889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // This register was not free. Thus we need to find and spill
2891b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // parts of active and inactive live regions that use the same register
2892b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // at the same lifetime positions as current.
2893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SplitAndSpillIntersecting(current);
2894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::SplitAndSpillIntersecting(LiveRange* current) {
2898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(current->HasRegisterAssigned());
2899b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int reg = current->assigned_register();
2900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition split_pos = current->Start();
2901958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (size_t i = 0; i < active_live_ranges().size(); ++i) {
2902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* range = active_live_ranges()[i];
2903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (range->assigned_register() == reg) {
2904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UsePosition* next_pos = range->NextRegisterPosition(current->Start());
2905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LifetimePosition spill_pos = FindOptimalSpillingPos(range, split_pos);
2906958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      if (next_pos == nullptr) {
2907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        SpillAfter(range, spill_pos);
2908b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else {
2909b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // When spilling between spill_pos and next_pos ensure that the range
2910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // remains spilled at least until the start of the current live range.
2911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // This guarantees that we will not introduce new unhandled ranges that
2912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // start before the current range as this violates allocation invariant
2913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // and will lead to an inconsistent state of active and inactive
2914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // live-ranges: ranges are allocated in order of their start positions,
2915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // ranges are retired from active/inactive when the start of the
2916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        // current live-range is larger than their end.
2917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        SpillBetweenUntil(range, spill_pos, current->Start(), next_pos->pos());
2918b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      ActiveToHandled(range);
2920b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      --i;
2921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2924958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (size_t i = 0; i < inactive_live_ranges().size(); ++i) {
2925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* range = inactive_live_ranges()[i];
2926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(range->End() > current->Start());
2927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range->assigned_register() == reg && !range->TopLevel()->IsFixed()) {
2928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      LifetimePosition next_intersection = range->FirstIntersection(current);
2929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      if (next_intersection.IsValid()) {
2930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        UsePosition* next_pos = range->NextRegisterPosition(current->Start());
2931958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        if (next_pos == nullptr) {
2932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          SpillAfter(range, split_pos);
2933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        } else {
2934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          next_intersection = Min(next_intersection, next_pos->pos());
2935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          SpillBetween(range, split_pos, next_intersection);
2936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
2937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        InactiveToHandled(range);
2938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        --i;
2939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2942b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2943b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2944b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool LinearScanAllocator::TryReuseSpillForPhi(TopLevelLiveRange* range) {
2946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!range->is_phi()) return false;
2947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2948014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!range->HasSpillOperand());
2949014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RegisterAllocationData::PhiMapValue* phi_map_value =
2950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      data()->GetPhiMapValueFor(range);
2951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const PhiInstruction* phi = phi_map_value->phi();
2952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const InstructionBlock* block = phi_map_value->block();
2953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Count the number of spilled operands.
2954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t spilled_count = 0;
2955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LiveRange* first_op = nullptr;
2956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < phi->operands().size(); i++) {
2957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int op = phi->operands()[i];
2958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* op_range = data()->GetOrCreateLiveRangeFor(op);
2959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!op_range->TopLevel()->HasSpillRange()) continue;
2960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const InstructionBlock* pred =
2961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        code()->InstructionBlockAt(block->predecessors()[i]);
2962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition pred_end =
2963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        LifetimePosition::InstructionFromInstructionIndex(
2964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            pred->last_instruction_index());
2965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    while (op_range != nullptr && !op_range->CanCover(pred_end)) {
2966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      op_range = op_range->next();
2967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (op_range != nullptr && op_range->spilled()) {
2969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      spilled_count++;
2970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (first_op == nullptr) {
2971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        first_op = op_range->TopLevel();
2972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2973014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Only continue if more than half of the operands are spilled.
2977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (spilled_count * 2 <= phi->operands().size()) {
2978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return false;
2979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Try to merge the spilled operands and count the number of merged spilled
2982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // operands.
2983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(first_op != nullptr);
2984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SpillRange* first_op_spill = first_op->TopLevel()->GetSpillRange();
2985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t num_merged = 1;
2986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 1; i < phi->operands().size(); i++) {
2987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int op = phi->operands()[i];
2988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TopLevelLiveRange* op_range = data()->live_ranges()[op];
2989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!op_range->HasSpillRange()) continue;
2990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SpillRange* op_spill = op_range->GetSpillRange();
2991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (op_spill == first_op_spill || first_op_spill->TryMerge(op_spill)) {
2992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      num_merged++;
2993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Only continue if enough operands could be merged to the
2997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // same spill slot.
2998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (num_merged * 2 <= phi->operands().size() ||
2999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      AreUseIntervalsIntersecting(first_op_spill->interval(),
3000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  range->first_interval())) {
3001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return false;
3002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // If the range does not need register soon, spill it to the merged
3005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // spill range.
3006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition next_pos = range->Start();
3007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (next_pos.IsGapPosition()) next_pos = next_pos.NextStart();
3008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePosition* pos = range->NextUsePositionRegisterIsBeneficial(next_pos);
3009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (pos == nullptr) {
3010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SpillRange* spill_range =
3011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->TopLevel()->HasSpillRange()
3012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            ? range->TopLevel()->GetSpillRange()
3013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            : data()->AssignSpillRangeToLiveRange(range->TopLevel());
3014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool merged = first_op_spill->TryMerge(spill_range);
3015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CHECK(merged);
3016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Spill(range);
3017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return true;
3018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (pos->pos() > range->Start().NextStart()) {
3019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SpillRange* spill_range =
3020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->TopLevel()->HasSpillRange()
3021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            ? range->TopLevel()->GetSpillRange()
3022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            : data()->AssignSpillRangeToLiveRange(range->TopLevel());
3023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool merged = first_op_spill->TryMerge(spill_range);
3024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CHECK(merged);
3025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SpillBetween(range, range->Start(), pos->pos());
3026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(UnhandledIsSorted());
3027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return true;
3028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return false;
3030b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3031b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3032b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::SpillAfter(LiveRange* range, LifetimePosition pos) {
3034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LiveRange* second_part = SplitRangeAt(range, pos);
3035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Spill(second_part);
3036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::SpillBetween(LiveRange* range, LifetimePosition start,
3040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       LifetimePosition end) {
3041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SpillBetweenUntil(range, start, start, end);
3042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::SpillBetweenUntil(LiveRange* range,
3046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            LifetimePosition start,
3047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            LifetimePosition until,
3048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            LifetimePosition end) {
3049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK(start < end);
3050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LiveRange* second_part = SplitRangeAt(range, start);
3051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (second_part->Start() < end) {
3053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // The split result intersects with [start, end[.
3054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Split it at position between ]start+1, end[, spill the middle part
3055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // and put the rest to unhandled.
3056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition third_part_end = end.PrevStart().End();
3057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (data()->IsBlockBoundary(end.Start())) {
3058014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      third_part_end = end.Start();
3059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* third_part = SplitBetween(
3061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        second_part, Max(second_part->Start().End(), until), third_part_end);
3062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(third_part != second_part);
3064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Spill(second_part);
3066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AddToUnhandledSorted(third_part);
3067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
3068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // The split result does not intersect with [start, end[.
3069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Nothing to spill. Just put it to unhandled as whole.
3070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AddToUnhandledSorted(second_part);
3071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3072b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochSpillSlotLocator::SpillSlotLocator(RegisterAllocationData* data)
3076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : data_(data) {}
3077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid SpillSlotLocator::LocateSpillSlots() {
3080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const InstructionSequence* code = data()->code();
3081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (TopLevelLiveRange* range : data()->live_ranges()) {
3082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range == nullptr || range->IsEmpty()) continue;
3083014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // We care only about ranges which spill in the frame.
3084014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!range->HasSpillRange()) continue;
3085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range->IsSpilledOnlyInDeferredBlocks()) {
3086014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (LiveRange* child = range; child != nullptr; child = child->next()) {
3087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (child->spilled()) {
3088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          code->GetInstructionBlock(child->Start().ToInstructionIndex())
3089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              ->mark_needs_frame();
3090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3092958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {
3093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      TopLevelLiveRange::SpillMoveInsertionList* spills =
3094109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          range->GetSpillMoveInsertionLocations();
3095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK_NOT_NULL(spills);
3096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (; spills != nullptr; spills = spills->next) {
3097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        code->GetInstructionBlock(spills->gap_index)->mark_needs_frame();
3098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
3099b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochOperandAssigner::OperandAssigner(RegisterAllocationData* data) : data_(data) {}
3105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid OperandAssigner::AssignSpillSlots() {
3108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ZoneVector<SpillRange*>& spill_ranges = data()->spill_ranges();
3109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Merge disjoint spill ranges
3110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < spill_ranges.size(); ++i) {
3111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SpillRange* range = spill_ranges[i];
3112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range == nullptr) continue;
3113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range->IsEmpty()) continue;
3114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (size_t j = i + 1; j < spill_ranges.size(); ++j) {
3115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SpillRange* other = spill_ranges[j];
3116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (other != nullptr && !other->IsEmpty()) {
3117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->TryMerge(other);
3118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Allocate slots for the merged spill ranges.
3122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (SpillRange* range : spill_ranges) {
3123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range == nullptr || range->IsEmpty()) continue;
3124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Allocate a new operand referring to the spill slot.
3125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!range->HasSlot()) {
3126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int byte_width = range->ByteWidth();
3127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int index = data()->frame()->AllocateSpillSlot(byte_width);
3128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      range->set_assigned_slot(index);
3129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid OperandAssigner::CommitAssignment() {
3135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (TopLevelLiveRange* top_range : data()->live_ranges()) {
3136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (top_range == nullptr || top_range->IsEmpty()) continue;
3137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand spill_operand;
3138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (top_range->HasSpillOperand()) {
3139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      spill_operand = *top_range->TopLevel()->GetSpillOperand();
3140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (top_range->TopLevel()->HasSpillRange()) {
3141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      spill_operand = top_range->TopLevel()->GetSpillRangeOperand();
3142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (top_range->is_phi()) {
3144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      data()->GetPhiMapValueFor(top_range)->CommitAssignment(
3145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          top_range->GetAssignedOperand());
3146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (LiveRange* range = top_range; range != nullptr;
3148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         range = range->next()) {
3149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionOperand assigned = range->GetAssignedOperand();
3150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      range->ConvertUsesToOperand(assigned, spill_operand);
3151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!spill_operand.IsInvalid()) {
3154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // If this top level range has a child spilled in a deferred block, we use
3155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // the range and control flow connection mechanism instead of spilling at
3156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // definition. Refer to the ConnectLiveRanges and ResolveControlFlow
3157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // phases. Normally, when we spill at definition, we do not insert a
3158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // connecting move when a successor child range is spilled - because the
3159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // spilled range picks up its value from the slot which was assigned at
3160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // definition. For ranges that are determined to spill only in deferred
3161109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // blocks, we let ConnectLiveRanges and ResolveControlFlow find the blocks
3162109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // where a spill operand is expected, and then finalize by inserting the
3163109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // spills in the deferred blocks dominators.
3164109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (!top_range->IsSpilledOnlyInDeferredBlocks()) {
3165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Spill at definition if the range isn't spilled only in deferred
3166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // blocks.
3167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        top_range->CommitSpillMoves(
3168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            data()->code(), spill_operand,
3169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            top_range->has_slot_use() || top_range->spilled());
3170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochReferenceMapPopulator::ReferenceMapPopulator(RegisterAllocationData* data)
3177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : data_(data) {}
3178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool ReferenceMapPopulator::SafePointsAreInOrder() const {
3181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int safe_point = 0;
3182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (ReferenceMap* map : *data()->code()->reference_maps()) {
3183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (safe_point > map->instruction_position()) return false;
3184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    safe_point = map->instruction_position();
3185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return true;
3187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid ReferenceMapPopulator::PopulateReferenceMaps() {
3191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(SafePointsAreInOrder());
3192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Map all delayed references.
3193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (RegisterAllocationData::DelayedReference& delayed_reference :
3194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       data()->delayed_references()) {
3195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    delayed_reference.map->RecordReference(
3196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        AllocatedOperand::cast(*delayed_reference.operand));
3197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Iterate over all safe point positions and record a pointer
3199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // for all spilled live ranges at this point.
3200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int last_range_start = 0;
3201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const ReferenceMapDeque* reference_maps = data()->code()->reference_maps();
3202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ReferenceMapDeque::const_iterator first_it = reference_maps->begin();
3203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (TopLevelLiveRange* range : data()->live_ranges()) {
3204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range == nullptr) continue;
3205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Skip non-reference values.
3206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!data()->IsReference(range)) continue;
3207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Skip empty live ranges.
3208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range->IsEmpty()) continue;
3209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range->has_preassigned_slot()) continue;
3210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Find the extent of the range and its children.
3212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int start = range->Start().ToInstructionIndex();
3213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int end = 0;
3214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (LiveRange* cur = range; cur != nullptr; cur = cur->next()) {
3215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LifetimePosition this_end = cur->End();
3216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (this_end.ToInstructionIndex() > end)
3217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        end = this_end.ToInstructionIndex();
3218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(cur->Start().ToInstructionIndex() >= start);
3219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Most of the ranges are in order, but not all.  Keep an eye on when they
3222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // step backwards and reset the first_it so we don't miss any safe points.
3223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (start < last_range_start) first_it = reference_maps->begin();
3224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    last_range_start = start;
3225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Step across all the safe points that are before the start of this range,
3227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // recording how far we step in order to save doing this for the next range.
3228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (; first_it != reference_maps->end(); ++first_it) {
3229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ReferenceMap* map = *first_it;
3230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (map->instruction_position() >= start) break;
3231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand spill_operand;
3234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (((range->HasSpillOperand() &&
3235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          !range->GetSpillOperand()->IsConstant()) ||
3236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         range->HasSpillRange())) {
3237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (range->HasSpillOperand()) {
3238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        spill_operand = *range->GetSpillOperand();
3239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
3240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        spill_operand = range->GetSpillRangeOperand();
3241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(spill_operand.IsStackSlot());
3243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK_EQ(MachineRepresentation::kTagged,
3244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                AllocatedOperand::cast(spill_operand).representation());
3245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* cur = range;
3248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Step through the safe points to see whether they are in the range.
3249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (auto it = first_it; it != reference_maps->end(); ++it) {
3250014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ReferenceMap* map = *it;
3251014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int safe_point = map->instruction_position();
3252014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // The safe points are sorted so we can stop searching here.
3254014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (safe_point - 1 > end) break;
3255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Advance to the next active range that covers the current
3257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // safe point position.
3258014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LifetimePosition safe_point_pos =
3259014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          LifetimePosition::InstructionFromInstructionIndex(safe_point);
3260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Search for the child range (cur) that covers safe_point_pos. If we
3262014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // don't find it before the children pass safe_point_pos, keep cur at
3263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // the last child, because the next safe_point_pos may be covered by cur.
3264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // This may happen if cur has more than one interval, and the current
3265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // safe_point_pos is in between intervals.
3266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // For that reason, cur may be at most the last child.
3267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK_NOT_NULL(cur);
3268014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(safe_point_pos >= cur->Start() || range == cur);
3269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bool found = false;
3270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      while (!found) {
3271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (cur->Covers(safe_point_pos)) {
3272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          found = true;
3273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else {
3274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          LiveRange* next = cur->next();
3275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          if (next == nullptr || next->Start() > safe_point_pos) {
3276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            break;
3277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
3278014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          cur = next;
3279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!found) {
3283014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        continue;
3284014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3285014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3286014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Check if the live range is spilled and the safe point is after
3287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // the spill position.
3288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int spill_index = range->IsSpilledOnlyInDeferredBlocks()
3289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            ? cur->Start().ToInstructionIndex()
3290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            : range->spill_start_index();
3291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!spill_operand.IsInvalid() && safe_point >= spill_index) {
3293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        TRACE("Pointer for range %d (spilled at %d) at safe point %d\n",
3294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              range->vreg(), spill_index, safe_point);
3295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        map->RecordReference(AllocatedOperand::cast(spill_operand));
3296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!cur->spilled()) {
3299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        TRACE(
3300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            "Pointer in register for range %d:%d (start at %d) "
3301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            "at safe point %d\n",
3302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            range->vreg(), cur->relative_id(), cur->Start().value(),
3303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            safe_point);
3304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        InstructionOperand operand = cur->GetAssignedOperand();
3305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(!operand.IsStackSlot());
3306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK_EQ(MachineRepresentation::kTagged,
3307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  AllocatedOperand::cast(operand).representation());
3308014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        map->RecordReference(AllocatedOperand::cast(operand));
3309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLiveRangeConnector::LiveRangeConnector(RegisterAllocationData* data)
3316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : data_(data) {}
3317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool LiveRangeConnector::CanEagerlyResolveControlFlow(
3320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const InstructionBlock* block) const {
3321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (block->PredecessorCount() != 1) return false;
3322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return block->predecessors()[0].IsNext(block->rpo_number());
3323014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRangeConnector::ResolveControlFlow(Zone* local_zone) {
3327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Lazily linearize live ranges in memory for fast lookup.
3328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LiveRangeFinder finder(data(), local_zone);
3329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ZoneVector<BitVector*>& live_in_sets = data()->live_in_sets();
3330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (const InstructionBlock* block : code()->instruction_blocks()) {
3331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (CanEagerlyResolveControlFlow(block)) continue;
3332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    BitVector* live = live_in_sets[block->rpo_number().ToInt()];
3333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    BitVector::Iterator iterator(live);
3334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    while (!iterator.Done()) {
3335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LiveRangeBoundArray* array = finder.ArrayFor(iterator.Current());
3336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (const RpoNumber& pred : block->predecessors()) {
3337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        FindResult result;
3338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        const InstructionBlock* pred_block = code()->InstructionBlockAt(pred);
3339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (!array->FindConnectableSubranges(block, pred_block, &result)) {
3340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          continue;
3341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        InstructionOperand pred_op = result.pred_cover_->GetAssignedOperand();
3343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        InstructionOperand cur_op = result.cur_cover_->GetAssignedOperand();
3344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (pred_op.Equals(cur_op)) continue;
3345109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        if (!pred_op.IsAnyRegister() && cur_op.IsAnyRegister()) {
3346109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          // We're doing a reload.
3347109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          // We don't need to, if:
3348109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          // 1) there's no register use in this block, and
3349109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          // 2) the range ends before the block does, and
3350109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          // 3) we don't have a successor, or the successor is spilled.
3351109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          LifetimePosition block_start =
3352109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch              LifetimePosition::GapFromInstructionIndex(block->code_start());
3353109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          LifetimePosition block_end =
3354109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch              LifetimePosition::GapFromInstructionIndex(block->code_end());
3355109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          const LiveRange* current = result.cur_cover_;
3356109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          const LiveRange* successor = current->next();
3357109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          if (current->End() < block_end &&
3358109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch              (successor == nullptr || successor->spilled())) {
3359109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            // verify point 1: no register use. We can go to the end of the
3360109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            // range, since it's all within the block.
3361109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3362109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            bool uses_reg = false;
3363109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            for (const UsePosition* use = current->NextUsePosition(block_start);
3364109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                 use != nullptr; use = use->next()) {
3365109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch              if (use->operand()->IsAnyRegister()) {
3366109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                uses_reg = true;
3367109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                break;
3368109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch              }
3369109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            }
3370109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            if (!uses_reg) continue;
3371109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          }
3372109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          if (current->TopLevel()->IsSpilledOnlyInDeferredBlocks() &&
3373109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch              pred_block->IsDeferred()) {
3374109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            // The spill location should be defined in pred_block, so add
3375109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            // pred_block to the list of blocks requiring a spill operand.
3376109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            current->TopLevel()->GetListOfBlocksRequiringSpillOperands()->Add(
3377109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                pred_block->rpo_number().ToInt());
3378109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          }
3379109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        }
3380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int move_loc = ResolveControlFlow(block, cur_op, pred_block, pred_op);
3381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        USE(move_loc);
3382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK_IMPLIES(
3383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            result.cur_cover_->TopLevel()->IsSpilledOnlyInDeferredBlocks() &&
3384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                !(pred_op.IsAnyRegister() && cur_op.IsAnyRegister()),
3385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            code()->GetInstructionBlock(move_loc)->IsDeferred());
3386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      iterator.Advance();
3388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3390109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3391109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // At this stage, we collected blocks needing a spill operand from
3392109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // ConnectRanges and from ResolveControlFlow. Time to commit the spills for
3393109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // deferred blocks.
3394109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  for (TopLevelLiveRange* top : data()->live_ranges()) {
3395109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (top == nullptr || top->IsEmpty() ||
3396109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        !top->IsSpilledOnlyInDeferredBlocks())
3397109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      continue;
3398109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    CommitSpillsInDeferredBlocks(top, finder.ArrayFor(top->vreg()), local_zone);
3399109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
3400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint LiveRangeConnector::ResolveControlFlow(const InstructionBlock* block,
3404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           const InstructionOperand& cur_op,
3405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           const InstructionBlock* pred,
3406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           const InstructionOperand& pred_op) {
3407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!pred_op.Equals(cur_op));
3408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int gap_index;
3409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Instruction::GapPosition position;
3410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (block->PredecessorCount() == 1) {
3411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    gap_index = block->first_instruction_index();
3412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    position = Instruction::START;
3413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
3414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(pred->SuccessorCount() == 1);
3415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!code()
3416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                ->InstructionAt(pred->last_instruction_index())
3417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                ->HasReferenceMap());
3418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    gap_index = pred->last_instruction_index();
3419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    position = Instruction::END;
3420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  data()->AddGapMove(gap_index, position, pred_op, cur_op);
3422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return gap_index;
3423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRangeConnector::ConnectRanges(Zone* local_zone) {
3427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DelayedInsertionMap delayed_insertion_map(local_zone);
3428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (TopLevelLiveRange* top_range : data()->live_ranges()) {
3429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (top_range == nullptr) continue;
3430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool connect_spilled = top_range->IsSpilledOnlyInDeferredBlocks();
3431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* first_range = top_range;
3432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (LiveRange *second_range = first_range->next(); second_range != nullptr;
3433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         first_range = second_range, second_range = second_range->next()) {
3434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LifetimePosition pos = second_range->Start();
3435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Add gap move if the two live ranges touch and there is no block
3436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // boundary.
3437109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (second_range->spilled()) continue;
3438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (first_range->End() != pos) continue;
3439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (data()->IsBlockBoundary(pos) &&
3440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          !CanEagerlyResolveControlFlow(GetInstructionBlock(code(), pos))) {
3441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        continue;
3442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionOperand prev_operand = first_range->GetAssignedOperand();
3444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionOperand cur_operand = second_range->GetAssignedOperand();
3445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (prev_operand.Equals(cur_operand)) continue;
3446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bool delay_insertion = false;
3447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Instruction::GapPosition gap_pos;
3448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int gap_index = pos.ToInstructionIndex();
3449109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (connect_spilled && !prev_operand.IsAnyRegister() &&
3450109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          cur_operand.IsAnyRegister()) {
3451109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        const InstructionBlock* block = code()->GetInstructionBlock(gap_index);
3452109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        DCHECK(block->IsDeferred());
3453109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        // Performing a reload in this block, meaning the spill operand must
3454109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        // be defined here.
3455109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        top_range->GetListOfBlocksRequiringSpillOperands()->Add(
3456109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            block->rpo_number().ToInt());
3457109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
3458109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (pos.IsGapPosition()) {
3460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        gap_pos = pos.IsStart() ? Instruction::START : Instruction::END;
3461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
3462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (pos.IsStart()) {
3463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          delay_insertion = true;
3464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else {
3465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          gap_index++;
3466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3467014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        gap_pos = delay_insertion ? Instruction::END : Instruction::START;
3468014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3469109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // Reloads or spills for spilled in deferred blocks ranges must happen
3470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // only in deferred blocks.
3471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK_IMPLIES(
3472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          connect_spilled &&
3473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              !(prev_operand.IsAnyRegister() && cur_operand.IsAnyRegister()),
3474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          code()->GetInstructionBlock(gap_index)->IsDeferred());
3475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ParallelMove* move =
3477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          code()->InstructionAt(gap_index)->GetOrCreateParallelMove(
3478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              gap_pos, code_zone());
3479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!delay_insertion) {
3480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        move->AddMove(prev_operand, cur_operand);
3481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
3482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        delayed_insertion_map.insert(
3483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            std::make_pair(std::make_pair(move, prev_operand), cur_operand));
3484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (delayed_insertion_map.empty()) return;
3488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Insert all the moves which should occur after the stored move.
3489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ZoneVector<MoveOperands*> to_insert(local_zone);
3490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ZoneVector<MoveOperands*> to_eliminate(local_zone);
3491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  to_insert.reserve(4);
3492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  to_eliminate.reserve(4);
3493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ParallelMove* moves = delayed_insertion_map.begin()->first.first;
3494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (auto it = delayed_insertion_map.begin();; ++it) {
3495014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool done = it == delayed_insertion_map.end();
3496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (done || it->first.first != moves) {
3497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Commit the MoveOperands for current ParallelMove.
3498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (MoveOperands* move : to_eliminate) {
3499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        move->Eliminate();
3500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (MoveOperands* move : to_insert) {
3502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        moves->push_back(move);
3503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (done) break;
3505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Reset state.
3506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      to_eliminate.clear();
3507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      to_insert.clear();
3508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      moves = it->first.first;
3509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Gather all MoveOperands for a single ParallelMove.
3511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MoveOperands* move =
3512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        new (code_zone()) MoveOperands(it->first.second, it->second);
3513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MoveOperands* eliminate = moves->PrepareInsertAfter(move);
3514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    to_insert.push_back(move);
3515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (eliminate != nullptr) to_eliminate.push_back(eliminate);
3516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3520109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid LiveRangeConnector::CommitSpillsInDeferredBlocks(
3521109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    TopLevelLiveRange* range, LiveRangeBoundArray* array, Zone* temp_zone) {
3522109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DCHECK(range->IsSpilledOnlyInDeferredBlocks());
3523109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DCHECK(!range->spilled());
3524109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3525109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  InstructionSequence* code = data()->code();
3526109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  InstructionOperand spill_operand = range->GetSpillRangeOperand();
3527109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3528109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  TRACE("Live Range %d will be spilled only in deferred blocks.\n",
3529109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        range->vreg());
3530109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // If we have ranges that aren't spilled but require the operand on the stack,
3531109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // make sure we insert the spill.
3532109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  for (const LiveRange* child = range; child != nullptr;
3533109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch       child = child->next()) {
3534109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    for (const UsePosition* pos = child->first_pos(); pos != nullptr;
3535109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch         pos = pos->next()) {
3536109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (pos->type() != UsePositionType::kRequiresSlot && !child->spilled())
3537109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        continue;
3538109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      range->AddBlockRequiringSpillOperand(
3539109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          code->GetInstructionBlock(pos->pos().ToInstructionIndex())
3540109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch              ->rpo_number());
3541109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
3542109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
3543109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3544109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  ZoneQueue<int> worklist(temp_zone);
3545109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3546109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  for (BitVector::Iterator iterator(
3547109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch           range->GetListOfBlocksRequiringSpillOperands());
3548109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch       !iterator.Done(); iterator.Advance()) {
3549109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    worklist.push(iterator.Current());
3550109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
3551109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3552109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Seek the deferred blocks that dominate locations requiring spill operands,
3553109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // and spill there. We only need to spill at the start of such blocks.
3554109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  BitVector done_blocks(
3555109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      range->GetListOfBlocksRequiringSpillOperands()->length(), temp_zone);
3556109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  while (!worklist.empty()) {
3557109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    int block_id = worklist.front();
3558109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    worklist.pop();
3559109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (done_blocks.Contains(block_id)) continue;
3560109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    done_blocks.Add(block_id);
3561109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    const InstructionBlock* spill_block =
3562109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        code->InstructionBlockAt(RpoNumber::FromInt(block_id));
3563109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3564109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    for (const RpoNumber& pred : spill_block->predecessors()) {
3565109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      const InstructionBlock* pred_block = code->InstructionBlockAt(pred);
3566109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3567109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (pred_block->IsDeferred()) {
3568109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        worklist.push(pred_block->rpo_number().ToInt());
3569109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      } else {
3570109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        LifetimePosition pred_end =
3571109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            LifetimePosition::InstructionFromInstructionIndex(
3572109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                pred_block->last_instruction_index());
3573109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3574109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        LiveRangeBound* bound = array->Find(pred_end);
3575109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3576109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        InstructionOperand pred_op = bound->range_->GetAssignedOperand();
3577109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3578109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        data()->AddGapMove(spill_block->first_instruction_index(),
3579109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                           Instruction::GapPosition::START, pred_op,
3580109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                           spill_operand);
3581109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
3582109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
3583109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
3584109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
3585109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3586109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3587958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}  // namespace compiler
3588958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}  // namespace internal
3589958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}  // namespace v8
3590