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
22c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochstatic const int kFloatRepBit =
23c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    1 << static_cast<int>(MachineRepresentation::kFloat32);
24c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochstatic const int kSimd128RepBit =
25c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    1 << static_cast<int>(MachineRepresentation::kSimd128);
26c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
27014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid RemoveElement(ZoneVector<LiveRange*>* v, LiveRange* range) {
28014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  auto it = std::find(v->begin(), v->end(), range);
29014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(it != v->end());
30014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  v->erase(it);
31014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
32014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
33014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint GetRegisterCount(const RegisterConfiguration* cfg, RegisterKind kind) {
34bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return kind == FP_REGISTERS ? cfg->num_double_registers()
35bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                              : cfg->num_general_registers();
36014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
37014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
38014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
39014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint GetAllocatableRegisterCount(const RegisterConfiguration* cfg,
40014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                RegisterKind kind) {
41c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return kind == FP_REGISTERS ? cfg->num_allocatable_double_registers()
42bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                              : cfg->num_allocatable_general_registers();
43014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
44014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
45014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
46014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst int* GetAllocatableRegisterCodes(const RegisterConfiguration* cfg,
47014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       RegisterKind kind) {
48bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return kind == FP_REGISTERS ? cfg->allocatable_double_codes()
49bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                              : cfg->allocatable_general_codes();
50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
53014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst InstructionBlock* GetContainingLoop(const InstructionSequence* sequence,
54014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                          const InstructionBlock* block) {
55014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RpoNumber index = block->loop_header();
56014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!index.IsValid()) return nullptr;
57014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return sequence->InstructionBlockAt(index);
58014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
59014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
60014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
61014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst InstructionBlock* GetInstructionBlock(const InstructionSequence* code,
62014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            LifetimePosition pos) {
63014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return code->GetInstructionBlock(pos.ToInstructionIndex());
64014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
65014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
66014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
67014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochInstruction* GetLastInstruction(InstructionSequence* code,
68014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                const InstructionBlock* block) {
69014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return code->InstructionAt(block->last_instruction_index());
70b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
72014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// TODO(dcarney): fix frame to allow frame accesses to half size location.
73014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint GetByteWidth(MachineRepresentation rep) {
74014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (rep) {
75014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kBit:
76014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord8:
77014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord16:
78014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord32:
79f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kTaggedSigned:
80f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kTaggedPointer:
81014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kTagged:
82014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kFloat32:
83f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return kPointerSize;
84014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kWord64:
85014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kFloat64:
86f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return kDoubleSize;
87109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    case MachineRepresentation::kSimd128:
88f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      return kSimd128Size;
8962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kSimd1x4:
9062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kSimd1x8:
9162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    case MachineRepresentation::kSimd1x16:
9262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return kSimdMaskRegisters ? kPointerSize : kSimd128Size;
93014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case MachineRepresentation::kNone:
94014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
95014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
96014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UNREACHABLE();
97014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return 0;
98958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
99958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}  // namespace
101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
102109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochclass LiveRangeBound {
103109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch public:
104109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  explicit LiveRangeBound(LiveRange* range, bool skip)
105109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      : range_(range), start_(range->Start()), end_(range->End()), skip_(skip) {
106109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    DCHECK(!range->IsEmpty());
107109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
108109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
109109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  bool CanCover(LifetimePosition position) {
110109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return start_ <= position && position < end_;
111109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
112109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
113109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  LiveRange* const range_;
114109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  const LifetimePosition start_;
115109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  const LifetimePosition end_;
116109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  const bool skip_;
117109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
118109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch private:
119109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(LiveRangeBound);
120109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch};
121109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
122109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
123109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochstruct FindResult {
124109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  LiveRange* cur_cover_;
125109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  LiveRange* pred_cover_;
126109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch};
127109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
128109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
129109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochclass LiveRangeBoundArray {
130109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch public:
131109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  LiveRangeBoundArray() : length_(0), start_(nullptr) {}
132109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
133109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  bool ShouldInitialize() { return start_ == nullptr; }
134109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
135109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  void Initialize(Zone* zone, TopLevelLiveRange* range) {
136109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    length_ = range->GetChildCount();
137109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
138109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    start_ = zone->NewArray<LiveRangeBound>(length_);
139109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    LiveRangeBound* curr = start_;
140109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // Normally, spilled ranges do not need connecting moves, because the spill
141109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // location has been assigned at definition. For ranges spilled in deferred
142109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    // blocks, that is not the case, so we need to connect the spilled children.
143109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    for (LiveRange *i = range; i != nullptr; i = i->next(), ++curr) {
144109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      new (curr) LiveRangeBound(i, i->spilled());
145109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
146109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
147109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
148109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  LiveRangeBound* Find(const LifetimePosition position) const {
149109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    size_t left_index = 0;
150109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    size_t right_index = length_;
151109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    while (true) {
152109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      size_t current_index = left_index + (right_index - left_index) / 2;
153109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      DCHECK(right_index > current_index);
154109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      LiveRangeBound* bound = &start_[current_index];
155109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (bound->start_ <= position) {
156109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        if (position < bound->end_) return bound;
157109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        DCHECK(left_index < current_index);
158109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        left_index = current_index;
159109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      } else {
160109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        right_index = current_index;
161109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
162109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
163109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
164109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
165109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  LiveRangeBound* FindPred(const InstructionBlock* pred) {
166109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    LifetimePosition pred_end =
167109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        LifetimePosition::InstructionFromInstructionIndex(
168109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            pred->last_instruction_index());
169109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return Find(pred_end);
170109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
171109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
172109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  LiveRangeBound* FindSucc(const InstructionBlock* succ) {
173109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    LifetimePosition succ_start = LifetimePosition::GapFromInstructionIndex(
174109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        succ->first_instruction_index());
175109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return Find(succ_start);
176109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
177109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
178109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  bool FindConnectableSubranges(const InstructionBlock* block,
179109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                const InstructionBlock* pred,
180109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                                FindResult* result) const {
181109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    LifetimePosition pred_end =
182109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        LifetimePosition::InstructionFromInstructionIndex(
183109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            pred->last_instruction_index());
184109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    LiveRangeBound* bound = Find(pred_end);
185109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    result->pred_cover_ = bound->range_;
186109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    LifetimePosition cur_start = LifetimePosition::GapFromInstructionIndex(
187109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        block->first_instruction_index());
188109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
189109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (bound->CanCover(cur_start)) {
190109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // Both blocks are covered by the same range, so there is nothing to
191109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // connect.
192109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return false;
193109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
194109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    bound = Find(cur_start);
195109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (bound->skip_) {
196109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return false;
197109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
198109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    result->cur_cover_ = bound->range_;
199109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    DCHECK(result->pred_cover_ != nullptr && result->cur_cover_ != nullptr);
200109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return (result->cur_cover_ != result->pred_cover_);
201109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
202109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
203109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch private:
204109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  size_t length_;
205109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  LiveRangeBound* start_;
206109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
207109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(LiveRangeBoundArray);
208109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch};
209109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
210109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
211109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochclass LiveRangeFinder {
212109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch public:
213109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  explicit LiveRangeFinder(const RegisterAllocationData* data, Zone* zone)
214109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      : data_(data),
215109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        bounds_length_(static_cast<int>(data_->live_ranges().size())),
216109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        bounds_(zone->NewArray<LiveRangeBoundArray>(bounds_length_)),
217109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        zone_(zone) {
218109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    for (int i = 0; i < bounds_length_; ++i) {
219109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      new (&bounds_[i]) LiveRangeBoundArray();
220109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
221109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
222109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
223109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  LiveRangeBoundArray* ArrayFor(int operand_index) {
224109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    DCHECK(operand_index < bounds_length_);
225109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    TopLevelLiveRange* range = data_->live_ranges()[operand_index];
226109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    DCHECK(range != nullptr && !range->IsEmpty());
227109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    LiveRangeBoundArray* array = &bounds_[operand_index];
228109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (array->ShouldInitialize()) {
229109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      array->Initialize(zone_, range);
230109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
231109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return array;
232109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
233109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
234109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch private:
235109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  const RegisterAllocationData* const data_;
236109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  const int bounds_length_;
237109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  LiveRangeBoundArray* const bounds_;
238109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  Zone* const zone_;
239109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
240109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DISALLOW_COPY_AND_ASSIGN(LiveRangeFinder);
241109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch};
242109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
243109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
244109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochtypedef std::pair<ParallelMove*, InstructionOperand> DelayedInsertionMapKey;
245109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
246109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
247109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochstruct DelayedInsertionMapCompare {
248109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  bool operator()(const DelayedInsertionMapKey& a,
249109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                  const DelayedInsertionMapKey& b) const {
250109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (a.first == b.first) {
251109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      return a.second.Compare(b.second);
252109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
253109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    return a.first < b.first;
254109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
255109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch};
256109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
257109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
258109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochtypedef ZoneMap<DelayedInsertionMapKey, InstructionOperand,
259109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                DelayedInsertionMapCompare> DelayedInsertionMap;
260109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
261958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochUsePosition::UsePosition(LifetimePosition pos, InstructionOperand* operand,
263014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         void* hint, UsePositionHintType hint_type)
264014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : operand_(operand), hint_(hint), next_(nullptr), pos_(pos), flags_(0) {
265014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_IMPLIES(hint == nullptr, hint_type == UsePositionHintType::kNone);
266014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool register_beneficial = true;
267014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePositionType type = UsePositionType::kAny;
268958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (operand_ != nullptr && operand_->IsUnallocated()) {
269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    const UnallocatedOperand* unalloc = UnallocatedOperand::cast(operand_);
270014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (unalloc->HasRegisterPolicy()) {
271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      type = UsePositionType::kRequiresRegister;
272014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (unalloc->HasSlotPolicy()) {
273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      type = UsePositionType::kRequiresSlot;
274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      register_beneficial = false;
275014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
276014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      register_beneficial = !unalloc->HasAnyPolicy();
277014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
279014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  flags_ = TypeField::encode(type) | HintTypeField::encode(hint_type) |
280014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           RegisterBeneficialField::encode(register_beneficial) |
281014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           AssignedRegisterField::encode(kUnassignedRegister);
282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(pos_.IsValid());
283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool UsePosition::HasHint() const {
287014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int hint_register;
288014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return HintRegister(&hint_register);
289014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
291014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
292014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool UsePosition::HintRegister(int* register_code) const {
293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (hint_ == nullptr) return false;
294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (HintTypeField::decode(flags_)) {
295014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case UsePositionHintType::kNone:
296014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case UsePositionHintType::kUnresolved:
297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return false;
298014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case UsePositionHintType::kUsePos: {
299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UsePosition* use_pos = reinterpret_cast<UsePosition*>(hint_);
300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int assigned_register = AssignedRegisterField::decode(use_pos->flags_);
301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (assigned_register == kUnassignedRegister) return false;
302014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *register_code = assigned_register;
303014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return true;
304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
305014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case UsePositionHintType::kOperand: {
306014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionOperand* operand =
307014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          reinterpret_cast<InstructionOperand*>(hint_);
30813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      *register_code = LocationOperand::cast(operand)->register_code();
309014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return true;
310014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case UsePositionHintType::kPhi: {
312014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      RegisterAllocationData::PhiMapValue* phi =
313014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          reinterpret_cast<RegisterAllocationData::PhiMapValue*>(hint_);
314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int assigned_register = phi->assigned_register();
315014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (assigned_register == kUnassignedRegister) return false;
316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      *register_code = assigned_register;
317014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return true;
318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UNREACHABLE();
321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return false;
322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
325014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochUsePositionHintType UsePosition::HintTypeForOperand(
326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const InstructionOperand& op) {
327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  switch (op.kind()) {
328014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case InstructionOperand::CONSTANT:
329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case InstructionOperand::IMMEDIATE:
330014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case InstructionOperand::EXPLICIT:
331014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return UsePositionHintType::kNone;
332014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case InstructionOperand::UNALLOCATED:
333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      return UsePositionHintType::kUnresolved;
334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case InstructionOperand::ALLOCATED:
335bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      if (op.IsRegister() || op.IsFPRegister()) {
336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return UsePositionHintType::kOperand;
337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
338bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        DCHECK(op.IsStackSlot() || op.IsFPStackSlot());
339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        return UsePositionHintType::kNone;
340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
341014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    case InstructionOperand::INVALID:
342014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      break;
343014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UNREACHABLE();
345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return UsePositionHintType::kNone;
346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
348c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochvoid UsePosition::SetHint(UsePosition* use_pos) {
349c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  DCHECK_NOT_NULL(use_pos);
350c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  hint_ = use_pos;
351c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  flags_ = HintTypeField::update(flags_, UsePositionHintType::kUsePos);
352c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
354014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid UsePosition::ResolveHint(UsePosition* use_pos) {
355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_NOT_NULL(use_pos);
356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (HintTypeField::decode(flags_) != UsePositionHintType::kUnresolved) return;
357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  hint_ = use_pos;
358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  flags_ = HintTypeField::update(flags_, UsePositionHintType::kUsePos);
359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid UsePosition::set_type(UsePositionType type, bool register_beneficial) {
363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_IMPLIES(type == UsePositionType::kRequiresSlot, !register_beneficial);
364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_EQ(kUnassignedRegister, AssignedRegisterField::decode(flags_));
365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  flags_ = TypeField::encode(type) |
366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           RegisterBeneficialField::encode(register_beneficial) |
367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           HintTypeField::encode(HintTypeField::decode(flags_)) |
368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           AssignedRegisterField::encode(kUnassignedRegister);
369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
370958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
371958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochUseInterval* UseInterval::SplitAt(LifetimePosition pos, Zone* zone) {
373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(Contains(pos) && pos != start());
374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UseInterval* after = new (zone) UseInterval(pos, end_);
375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  after->next_ = next_;
376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  next_ = nullptr;
377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  end_ = pos;
378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return after;
379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LifetimePosition::Print() const {
383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  OFStream os(stdout);
384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  os << *this << std::endl;
385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstd::ostream& operator<<(std::ostream& os, const LifetimePosition pos) {
389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  os << '@' << pos.ToInstructionIndex();
390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (pos.IsGapPosition()) {
391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    os << 'g';
392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    os << 'i';
394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (pos.IsStart()) {
396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    os << 's';
397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    os << 'e';
399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return os;
401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLiveRange::LiveRange(int relative_id, MachineRepresentation rep,
404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                     TopLevelLiveRange* top_level)
405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : relative_id_(relative_id),
406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bits_(0),
407958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      last_interval_(nullptr),
408958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      first_interval_(nullptr),
409958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      first_pos_(nullptr),
410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      top_level_(top_level),
411958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      next_(nullptr),
412958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      current_interval_(nullptr),
413958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      last_processed_use_(nullptr),
414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      current_hint_position_(nullptr),
41513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      splitting_pointer_(nullptr) {
416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(AllocatedOperand::IsSupportedRepresentation(rep));
417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bits_ = AssignedRegisterField::encode(kUnassignedRegister) |
418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          RepresentationField::encode(rep);
419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRange::VerifyPositions() const {
423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Walk the positions, verifying that each is in an interval.
424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UseInterval* interval = first_interval_;
425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (UsePosition* pos = first_pos_; pos != nullptr; pos = pos->next()) {
426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CHECK(Start() <= pos->pos());
427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CHECK(pos->pos() <= End());
428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CHECK_NOT_NULL(interval);
429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    while (!interval->Contains(pos->pos()) && interval->end() != pos->pos()) {
430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      interval = interval->next();
431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      CHECK_NOT_NULL(interval);
432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRange::VerifyIntervals() const {
438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(first_interval()->start() == Start());
439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition last_end = first_interval()->end();
440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (UseInterval* interval = first_interval()->next(); interval != nullptr;
441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       interval = interval->next()) {
442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(last_end <= interval->start());
443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    last_end = interval->end();
444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(last_end == End());
446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRange::set_assigned_register(int reg) {
450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!HasRegisterAssigned() && !spilled());
451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bits_ = AssignedRegisterField::update(bits_, reg);
452958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
453958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
454958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRange::UnsetAssignedRegister() {
456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(HasRegisterAssigned() && !spilled());
457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bits_ = AssignedRegisterField::update(bits_, kUnassignedRegister);
458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRange::Spill() {
462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!spilled());
463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!TopLevel()->HasNoSpillType());
464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_spilled(true);
465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bits_ = AssignedRegisterField::update(bits_, kUnassignedRegister);
466958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
467958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
468958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
469014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochRegisterKind LiveRange::kind() const {
470bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  return IsFloatingPoint(representation()) ? FP_REGISTERS : GENERAL_REGISTERS;
471958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
472958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
473958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
474014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochUsePosition* LiveRange::FirstHintPosition(int* register_index) const {
475014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (UsePosition* pos = first_pos_; pos != nullptr; pos = pos->next()) {
476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (pos->HintRegister(register_index)) return pos;
477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return nullptr;
479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochUsePosition* LiveRange::NextUsePosition(LifetimePosition start) const {
483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UsePosition* use_pos = last_processed_use_;
484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (use_pos == nullptr || use_pos->pos() > start) {
485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    use_pos = first_pos();
486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (use_pos != nullptr && use_pos->pos() < start) {
488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    use_pos = use_pos->next();
489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  last_processed_use_ = use_pos;
491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return use_pos;
492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochUsePosition* LiveRange::NextUsePositionRegisterIsBeneficial(
496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition start) const {
497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UsePosition* pos = NextUsePosition(start);
498958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  while (pos != nullptr && !pos->RegisterIsBeneficial()) {
499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    pos = pos->next();
500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return pos;
502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
504c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen MurdochLifetimePosition LiveRange::NextLifetimePositionRegisterIsBeneficial(
505c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    const LifetimePosition& start) const {
506c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  UsePosition* next_use = NextUsePositionRegisterIsBeneficial(start);
507c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (next_use == nullptr) return End();
508c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return next_use->pos();
509c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochUsePosition* LiveRange::PreviousUsePositionRegisterIsBeneficial(
512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition start) const {
513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePosition* pos = first_pos();
514958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  UsePosition* prev = nullptr;
515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (pos != nullptr && pos->pos() < start) {
516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (pos->RegisterIsBeneficial()) prev = pos;
517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    pos = pos->next();
518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return prev;
520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
523014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochUsePosition* LiveRange::NextRegisterPosition(LifetimePosition start) const {
524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  UsePosition* pos = NextUsePosition(start);
525014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (pos != nullptr && pos->type() != UsePositionType::kRequiresRegister) {
526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    pos = pos->next();
527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return pos;
529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochUsePosition* LiveRange::NextSlotPosition(LifetimePosition start) const {
533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (UsePosition* pos = NextUsePosition(start); pos != nullptr;
534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       pos = pos->next()) {
535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (pos->type() != UsePositionType::kRequiresSlot) continue;
536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return pos;
537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return nullptr;
539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool LiveRange::CanBeSpilled(LifetimePosition pos) const {
543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // We cannot spill a live range that has a use requiring a register
544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // at the current or the immediate next position.
545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePosition* use_pos = NextRegisterPosition(pos);
546958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (use_pos == nullptr) return true;
547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return use_pos->pos() > pos.NextStart().End();
548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool LiveRange::IsTopLevel() const { return top_level_ == this; }
552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochInstructionOperand LiveRange::GetAssignedOperand() const {
555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (HasRegisterAssigned()) {
556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!spilled());
557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return AllocatedOperand(LocationOperand::REGISTER, representation(),
558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            assigned_register());
559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(spilled());
561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!HasRegisterAssigned());
562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (TopLevel()->HasSpillOperand()) {
563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand* op = TopLevel()->GetSpillOperand();
564b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(!op->IsUnallocated());
565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return *op;
566b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return TopLevel()->GetSpillRangeOperand();
568b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
569b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
571b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochUseInterval* LiveRange::FirstSearchIntervalForPosition(
572b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    LifetimePosition position) const {
573958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (current_interval_ == nullptr) return first_interval_;
574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (current_interval_->start() > position) {
575958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    current_interval_ = nullptr;
576b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return first_interval_;
577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return current_interval_;
579b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
580b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LiveRange::AdvanceLastProcessedMarker(
583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UseInterval* to_start_of, LifetimePosition but_not_past) const {
584958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (to_start_of == nullptr) return;
585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (to_start_of->start() > but_not_past) return;
586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition start = current_interval_ == nullptr
587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                               ? LifetimePosition::Invalid()
588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                               : current_interval_->start();
589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (to_start_of->start() > start) {
590b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    current_interval_ = to_start_of;
591b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
593b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
594b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLiveRange* LiveRange::SplitAt(LifetimePosition position, Zone* zone) {
596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int new_id = TopLevel()->GetNextChildId();
597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LiveRange* child = new (zone) LiveRange(new_id, representation(), TopLevel());
598c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // If we split, we do so because we're about to switch registers or move
599c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // to/from a slot, so there's no value in connecting hints.
600c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  DetachAt(position, child, zone, DoNotConnectHints);
601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  child->top_level_ = TopLevel();
603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  child->next_ = next_;
604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  next_ = child;
605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return child;
606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochUsePosition* LiveRange::DetachAt(LifetimePosition position, LiveRange* result,
609c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                 Zone* zone,
610c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                 HintConnectionOption connect_hints) {
611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(Start() < position);
612014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(End() > position);
613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(result->IsEmpty());
614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Find the last interval that ends before the position. If the
615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // position is contained in one of the intervals in the chain, we
616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // split that interval and use the first part.
617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UseInterval* current = FirstSearchIntervalForPosition(position);
618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // If the split position coincides with the beginning of a use interval
620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // we need to split use positons in a special way.
621b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  bool split_at_start = false;
622b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (current->start() == position) {
624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // When splitting at start we need to locate the previous use interval.
625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    current = first_interval_;
626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UseInterval* after = nullptr;
629958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  while (current != nullptr) {
630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (current->Contains(position)) {
631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      after = current->SplitAt(position, zone);
632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UseInterval* next = current->next();
635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (next->start() >= position) {
636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      split_at_start = (next->start() == position);
637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      after = next;
638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      current->set_next(nullptr);
639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      break;
640b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
641b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    current = next;
642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(nullptr != after);
644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Partition original use intervals to the two live ranges.
646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UseInterval* before = current;
647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->last_interval_ =
648b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      (last_interval_ == before)
649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          ? after            // Only interval in the range after split.
650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch          : last_interval_;  // Last interval of the original range.
651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->first_interval_ = after;
652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  last_interval_ = before;
653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Find the last use position before the split and the first use
655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // position after it.
656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePosition* use_after =
657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      splitting_pointer_ == nullptr || splitting_pointer_->pos() > position
658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          ? first_pos()
659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          : splitting_pointer_;
660958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  UsePosition* use_before = nullptr;
661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (split_at_start) {
662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // The split position coincides with the beginning of a use interval (the
663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // end of a lifetime hole). Use at this position should be attributed to
664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // the split child because split child owns use interval covering it.
665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    while (use_after != nullptr && use_after->pos() < position) {
666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      use_before = use_after;
667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      use_after = use_after->next();
668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    while (use_after != nullptr && use_after->pos() <= position) {
671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      use_before = use_after;
672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      use_after = use_after->next();
673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Partition original use positions to the two live ranges.
677958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (use_before != nullptr) {
678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    use_before->set_next(nullptr);
679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
680958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    first_pos_ = nullptr;
681b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  result->first_pos_ = use_after;
683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Discard cached iteration state. It might be pointing
685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // to the use that no longer belongs to this live range.
686958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  last_processed_use_ = nullptr;
687958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  current_interval_ = nullptr;
688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
689c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (connect_hints == ConnectHints && use_before != nullptr &&
690c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      use_after != nullptr) {
691c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    use_after->SetHint(use_before);
692c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VerifyChildStructure();
695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  result->VerifyChildStructure();
696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return use_before;
698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRange::UpdateParentForAllChildren(TopLevelLiveRange* new_top_level) {
702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LiveRange* child = this;
703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (; child != nullptr; child = child->next()) {
704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    child->top_level_ = new_top_level;
705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRange::ConvertUsesToOperand(const InstructionOperand& op,
710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     const InstructionOperand& spill_op) {
711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (UsePosition* pos = first_pos(); pos != nullptr; pos = pos->next()) {
712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(Start() <= pos->pos() && pos->pos() <= End());
713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!pos->HasOperand()) continue;
714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    switch (pos->type()) {
715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case UsePositionType::kRequiresSlot:
716bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        DCHECK(spill_op.IsStackSlot() || spill_op.IsFPStackSlot());
717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        InstructionOperand::ReplaceWith(pos->operand(), &spill_op);
718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case UsePositionType::kRequiresRegister:
720bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        DCHECK(op.IsRegister() || op.IsFPRegister());
721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Fall through.
722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case UsePositionType::kAny:
723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        InstructionOperand::ReplaceWith(pos->operand(), &op);
724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// This implements an ordering on live ranges so that they are ordered by their
731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// start positions.  This is needed for the correctness of the register
732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// allocation algorithm.  If two live ranges start at the same offset then there
733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// is a tie breaker based on where the value is first used.  This part of the
734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ordering is merely a heuristic.
735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool LiveRange::ShouldBeAllocatedBefore(const LiveRange* other) const {
736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LifetimePosition start = Start();
737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  LifetimePosition other_start = other->Start();
738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (start == other_start) {
739b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UsePosition* pos = first_pos();
740958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (pos == nullptr) return false;
741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    UsePosition* other_pos = other->first_pos();
742958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (other_pos == nullptr) return true;
743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return pos->pos() < other_pos->pos();
744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return start < other_start;
746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRange::SetUseHints(int register_index) {
750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (UsePosition* pos = first_pos(); pos != nullptr; pos = pos->next()) {
751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!pos->HasOperand()) continue;
752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    switch (pos->type()) {
753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case UsePositionType::kRequiresSlot:
754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case UsePositionType::kRequiresRegister:
756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      case UsePositionType::kAny:
757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        pos->set_assigned_register(register_index);
758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        break;
759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
760b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
761b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool LiveRange::CanCover(LifetimePosition position) const {
765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (IsEmpty()) return false;
766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return Start() <= position && position < End();
767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool LiveRange::Covers(LifetimePosition position) const {
771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  if (!CanCover(position)) return false;
772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UseInterval* start_search = FirstSearchIntervalForPosition(position);
773014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (UseInterval* interval = start_search; interval != nullptr;
774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       interval = interval->next()) {
775958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(interval->next() == nullptr ||
776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           interval->next()->start() >= interval->start());
777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AdvanceLastProcessedMarker(interval, position);
778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (interval->Contains(position)) return true;
779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (interval->start() > position) return false;
780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return false;
782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLifetimePosition LiveRange::FirstIntersection(LiveRange* other) const {
786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UseInterval* b = other->first_interval();
787958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (b == nullptr) return LifetimePosition::Invalid();
788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition advance_last_processed_up_to = b->start();
789014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UseInterval* a = FirstSearchIntervalForPosition(b->start());
790958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  while (a != nullptr && b != nullptr) {
791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (a->start() > other->End()) break;
792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (b->start() > End()) break;
793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition cur_intersection = a->Intersect(b);
794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (cur_intersection.IsValid()) {
795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return cur_intersection;
796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (a->start() < b->start()) {
798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      a = a->next();
799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (a == nullptr || a->start() > other->End()) break;
800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      AdvanceLastProcessedMarker(a, advance_last_processed_up_to);
801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      b = b->next();
803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return LifetimePosition::Invalid();
806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRange::Print(const RegisterConfiguration* config,
809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                      bool with_children) const {
810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  OFStream os(stdout);
811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  PrintableLiveRange wrapper;
812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  wrapper.register_configuration_ = config;
813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (const LiveRange* i = this; i != nullptr; i = i->next()) {
814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    wrapper.range_ = i;
815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    os << wrapper << std::endl;
816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!with_children) break;
817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRange::Print(bool with_children) const {
82213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  Print(RegisterConfiguration::Turbofan(), with_children);
823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstruct TopLevelLiveRange::SpillMoveInsertionList : ZoneObject {
827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SpillMoveInsertionList(int gap_index, InstructionOperand* operand,
828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         SpillMoveInsertionList* next)
829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      : gap_index(gap_index), operand(operand), next(next) {}
830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const int gap_index;
831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand* const operand;
832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SpillMoveInsertionList* const next;
833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch};
834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTopLevelLiveRange::TopLevelLiveRange(int vreg, MachineRepresentation rep)
837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : LiveRange(0, rep, this),
838014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      vreg_(vreg),
839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      last_child_id_(0),
840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      splintered_from_(nullptr),
841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      spill_operand_(nullptr),
842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      spill_move_insertion_locations_(nullptr),
843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      spilled_in_deferred_blocks_(false),
844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      spill_start_index_(kMaxInt),
845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      last_pos_(nullptr),
846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      splinter_(nullptr),
847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      has_preassigned_slot_(false) {
848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bits_ |= SpillTypeField::encode(SpillType::kNoSpillType);
849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if DEBUG
853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint TopLevelLiveRange::debug_virt_reg() const {
854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return IsSplinter() ? splintered_from()->vreg() : vreg();
855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif
857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::RecordSpillLocation(Zone* zone, int gap_index,
860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            InstructionOperand* operand) {
861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(HasNoSpillType());
862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  spill_move_insertion_locations_ = new (zone) SpillMoveInsertionList(
863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      gap_index, operand, spill_move_insertion_locations_);
864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::CommitSpillMoves(InstructionSequence* sequence,
867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                         const InstructionOperand& op,
868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                         bool might_be_duplicated) {
869109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DCHECK_IMPLIES(op.IsConstant(), GetSpillMoveInsertionLocations() == nullptr);
870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Zone* zone = sequence->zone();
871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
872109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  for (SpillMoveInsertionList* to_spill = GetSpillMoveInsertionLocations();
873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       to_spill != nullptr; to_spill = to_spill->next) {
874014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Instruction* instr = sequence->InstructionAt(to_spill->gap_index);
875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ParallelMove* move =
876014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        instr->GetOrCreateParallelMove(Instruction::START, zone);
877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Skip insertion if it's possible that the move exists already as a
878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // constraint move from a fixed output register to a slot.
879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (might_be_duplicated || has_preassigned_slot()) {
880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bool found = false;
881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (MoveOperands* move_op : *move) {
882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (move_op->IsEliminated()) continue;
883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (move_op->source().Equals(*to_spill->operand) &&
884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            move_op->destination().Equals(op)) {
885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          found = true;
886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          if (has_preassigned_slot()) move_op->Eliminate();
887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          break;
888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (found) continue;
891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!has_preassigned_slot()) {
893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      move->AddMove(*to_spill->operand, op);
894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::SetSpillOperand(InstructionOperand* operand) {
900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(HasNoSpillType());
901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!operand->IsUnallocated() && !operand->IsImmediate());
902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  set_spill_type(SpillType::kSpillOperand);
903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  spill_operand_ = operand;
904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
906b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::SetSpillRange(SpillRange* spill_range) {
908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!HasSpillOperand());
909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(spill_range);
910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  spill_range_ = spill_range;
911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochAllocatedOperand TopLevelLiveRange::GetSpillRangeOperand() const {
915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SpillRange* spill_range = GetSpillRange();
916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int index = spill_range->assigned_slot();
917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return AllocatedOperand(LocationOperand::STACK_SLOT, representation(), index);
918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::Splinter(LifetimePosition start, LifetimePosition end,
922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 Zone* zone) {
923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(start != Start() || end != End());
924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(start < end);
925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TopLevelLiveRange splinter_temp(-1, representation());
927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePosition* last_in_splinter = nullptr;
928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Live ranges defined in deferred blocks stay in deferred blocks, so we
929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // don't need to splinter them. That means that start should always be
930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // after the beginning of the range.
931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(start > Start());
932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (end >= End()) {
934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(start > Start());
935c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    DetachAt(start, &splinter_temp, zone, ConnectHints);
936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    next_ = nullptr;
937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(start < End() && Start() < end);
939014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
940014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const int kInvalidId = std::numeric_limits<int>::max();
941014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
942c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    UsePosition* last = DetachAt(start, &splinter_temp, zone, ConnectHints);
943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange end_part(kInvalidId, this->representation(), nullptr);
945c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // The last chunk exits the deferred region, and we don't want to connect
946c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // hints here, because the non-deferred region shouldn't be affected
947c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // by allocation decisions on the deferred path.
948c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    last_in_splinter =
949c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        splinter_temp.DetachAt(end, &end_part, zone, DoNotConnectHints);
950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    next_ = end_part.next_;
952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    last_interval_->set_next(end_part.first_interval_);
953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // The next splinter will happen either at or after the current interval.
954014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // We can optimize DetachAt by setting current_interval_ accordingly,
955014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // which will then be picked up by FirstSearchIntervalForPosition.
956014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    current_interval_ = last_interval_;
957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    last_interval_ = end_part.last_interval_;
958014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (first_pos_ == nullptr) {
960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      first_pos_ = end_part.first_pos_;
961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
962014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      splitting_pointer_ = last;
963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (last != nullptr) last->set_next(end_part.first_pos_);
964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (splinter()->IsEmpty()) {
968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    splinter()->first_interval_ = splinter_temp.first_interval_;
969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    splinter()->last_interval_ = splinter_temp.last_interval_;
970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    splinter()->last_interval_->set_next(splinter_temp.first_interval_);
972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    splinter()->last_interval_ = splinter_temp.last_interval_;
973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
974014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (splinter()->first_pos() == nullptr) {
975014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    splinter()->first_pos_ = splinter_temp.first_pos_;
976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    splinter()->last_pos_->set_next(splinter_temp.first_pos_);
978014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (last_in_splinter != nullptr) {
980014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    splinter()->last_pos_ = last_in_splinter;
981014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (splinter()->first_pos() != nullptr &&
983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        splinter()->last_pos_ == nullptr) {
984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      splinter()->last_pos_ = splinter()->first_pos();
985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (UsePosition* pos = splinter()->first_pos(); pos != nullptr;
986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           pos = pos->next()) {
987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        splinter()->last_pos_ = pos;
988014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
989014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if DEBUG
992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Verify();
993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  splinter()->Verify();
994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif
995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::SetSplinteredFrom(TopLevelLiveRange* splinter_parent) {
999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  splintered_from_ = splinter_parent;
1000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!HasSpillOperand() && splinter_parent->spill_range_ != nullptr) {
1001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SetSpillRange(splinter_parent->spill_range_);
1002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::UpdateSpillRangePostMerge(TopLevelLiveRange* merged) {
1007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(merged->TopLevel() == this);
1008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (HasNoSpillType() && merged->HasSpillRange()) {
1010014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    set_spill_type(merged->spill_type());
1011014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(GetSpillRange()->live_ranges().size() > 0);
1012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    merged->spill_range_ = nullptr;
1013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    merged->bits_ =
1014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        SpillTypeField::update(merged->bits_, SpillType::kNoSpillType);
1015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1018b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::Merge(TopLevelLiveRange* other, Zone* zone) {
1020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(Start() < other->Start());
1021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(other->splintered_from() == this);
1022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LiveRange* first = this;
1024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LiveRange* second = other;
1025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(first->Start() < second->Start());
1026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (first != nullptr && second != nullptr) {
1027014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(first != second);
1028014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Make sure the ranges are in order each time we iterate.
1029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (second->Start() < first->Start()) {
1030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LiveRange* tmp = second;
1031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      second = first;
1032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      first = tmp;
1033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      continue;
1034014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1035014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1036014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (first->End() <= second->Start()) {
1037014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (first->next() == nullptr ||
1038014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          first->next()->Start() > second->Start()) {
1039014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // First is in order before second.
1040014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        LiveRange* temp = first->next();
1041014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        first->next_ = second;
1042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        first = temp;
1043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // First is in order before its successor (or second), so advance first.
1045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        first = first->next();
1046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      continue;
1048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(first->Start() < second->Start());
1051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // If first and second intersect, split first.
1052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (first->Start() < second->End() && second->Start() < first->End()) {
1053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LiveRange* temp = first->SplitAt(second->Start(), zone);
1054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      CHECK(temp != first);
1055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      temp->set_spilled(first->spilled());
1056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!temp->spilled())
1057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        temp->set_assigned_register(first->assigned_register());
1058014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      first->next_ = second;
1060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      first = temp;
1061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      continue;
1062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(first->End() <= second->Start());
1064b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TopLevel()->UpdateParentForAllChildren(TopLevel());
1067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TopLevel()->UpdateSpillRangePostMerge(other);
1068f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  TopLevel()->set_has_slot_use(TopLevel()->has_slot_use() ||
1069f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch                               other->has_slot_use());
1070014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#if DEBUG
1072014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Verify();
1073014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif
1074014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1077014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::VerifyChildrenInOrder() const {
1078014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition last_end = End();
1079014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (const LiveRange* child = this->next(); child != nullptr;
1080014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       child = child->next()) {
1081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(last_end <= child->Start());
1082014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    last_end = child->End();
1083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1087014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::Verify() const {
1088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  VerifyChildrenInOrder();
1089014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (const LiveRange* child = this; child != nullptr; child = child->next()) {
1090014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    VerifyChildStructure();
1091014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1093014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1094014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1095014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::ShortenTo(LifetimePosition start) {
1096014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Shorten live range %d to [%d\n", vreg(), start.value());
1097014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(first_interval_ != nullptr);
1098014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(first_interval_->start() <= start);
1099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(start < first_interval_->end());
1100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  first_interval_->set_start(start);
1101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::EnsureInterval(LifetimePosition start,
1105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       LifetimePosition end, Zone* zone) {
1106014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Ensure live range %d in interval [%d %d[\n", vreg(), start.value(),
1107014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        end.value());
1108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition new_end = end;
1109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (first_interval_ != nullptr && first_interval_->start() <= end) {
1110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (first_interval_->end() > end) {
1111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      new_end = first_interval_->end();
1112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1113014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    first_interval_ = first_interval_->next();
1114014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1115014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1116014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UseInterval* new_interval = new (zone) UseInterval(start, new_end);
1117014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  new_interval->set_next(first_interval_);
1118014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  first_interval_ = new_interval;
1119014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (new_interval->next() == nullptr) {
1120014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    last_interval_ = new_interval;
1121014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1122014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1123014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1124014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::AddUseInterval(LifetimePosition start,
1126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       LifetimePosition end, Zone* zone) {
1127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Add to live range %d interval [%d %d[\n", vreg(), start.value(),
1128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        end.value());
1129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (first_interval_ == nullptr) {
1130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UseInterval* interval = new (zone) UseInterval(start, end);
1131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    first_interval_ = interval;
1132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    last_interval_ = interval;
1133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (end == first_interval_->start()) {
1135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      first_interval_->set_start(start);
1136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (end < first_interval_->start()) {
1137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UseInterval* interval = new (zone) UseInterval(start, end);
1138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      interval->set_next(first_interval_);
1139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      first_interval_ = interval;
1140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
1141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Order of instruction's processing (see ProcessInstructions) guarantees
1142f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // that each new use interval either precedes, intersects with or touches
1143f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      // the last added interval.
1144f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      DCHECK(start <= first_interval_->end());
1145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      first_interval_->set_start(Min(start, first_interval_->start()));
1146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      first_interval_->set_end(Max(end, first_interval_->end()));
1147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1149958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1151958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid TopLevelLiveRange::AddUsePosition(UsePosition* use_pos) {
1153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition pos = use_pos->pos();
1154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Add to live range %d use position %d\n", vreg(), pos.value());
1155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePosition* prev_hint = nullptr;
1156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePosition* prev = nullptr;
1157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePosition* current = first_pos_;
1158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (current != nullptr && current->pos() < pos) {
1159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    prev_hint = current->HasHint() ? current : prev_hint;
1160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    prev = current;
1161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    current = current->next();
1162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (prev == nullptr) {
1165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    use_pos->set_next(first_pos_);
1166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    first_pos_ = use_pos;
1167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    use_pos->set_next(prev->next());
1169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    prev->set_next(use_pos);
1170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (prev_hint == nullptr && use_pos->HasHint()) {
1173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    current_hint_position_ = use_pos;
1174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1175958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1176958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1177958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1178958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic bool AreUseIntervalsIntersecting(UseInterval* interval1,
1179958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                                        UseInterval* interval2) {
1180958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  while (interval1 != nullptr && interval2 != nullptr) {
1181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (interval1->start() < interval2->start()) {
1182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (interval1->end() > interval2->start()) {
1183958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        return true;
1184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
1185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      interval1 = interval1->next();
1186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {
1187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (interval2->end() > interval1->start()) {
1188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        return true;
1189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1190958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      interval2 = interval2->next();
1191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return false;
1194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochstd::ostream& operator<<(std::ostream& os,
1198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         const PrintableLiveRange& printable_range) {
1199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const LiveRange* range = printable_range.range_;
1200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  os << "Range: " << range->TopLevel()->vreg() << ":" << range->relative_id()
1201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch     << " ";
1202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (range->TopLevel()->is_phi()) os << "phi ";
1203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (range->TopLevel()->is_non_loop_phi()) os << "nlphi ";
1204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  os << "{" << std::endl;
1206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UseInterval* interval = range->first_interval();
1207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePosition* use_pos = range->first_pos();
1208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  PrintableInstructionOperand pio;
1209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  pio.register_configuration_ = printable_range.register_configuration_;
1210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (use_pos != nullptr) {
1211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (use_pos->HasOperand()) {
1212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      pio.op_ = *use_pos->operand();
1213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      os << pio << use_pos->pos() << " ";
1214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    use_pos = use_pos->next();
1216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  os << std::endl;
1218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1219014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (interval != nullptr) {
1220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    os << '[' << interval->start() << ", " << interval->end() << ')'
1221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       << std::endl;
1222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    interval = interval->next();
1223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  os << "}";
1225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return os;
1226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochSpillRange::SpillRange(TopLevelLiveRange* parent, Zone* zone)
1229014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : live_ranges_(zone),
1230014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      assigned_slot_(kUnassignedSlot),
1231f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      byte_width_(GetByteWidth(parent->representation())) {
1232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Spill ranges are created for top level, non-splintered ranges. This is so
1233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // that, when merging decisions are made, we consider the full extent of the
1234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // virtual register, and avoid clobbering it.
1235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!parent->IsSplinter());
1236958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  UseInterval* result = nullptr;
1237958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  UseInterval* node = nullptr;
1238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Copy the intervals for all ranges.
1239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (LiveRange* range = parent; range != nullptr; range = range->next()) {
1240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UseInterval* src = range->first_interval();
1241014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    while (src != nullptr) {
1242014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UseInterval* new_node = new (zone) UseInterval(src->start(), src->end());
1243014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (result == nullptr) {
1244014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        result = new_node;
1245014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
1246014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        node->set_next(new_node);
1247014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1248014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      node = new_node;
1249014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      src = src->next();
1250958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1251958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1252958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  use_interval_ = result;
1253014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  live_ranges().push_back(parent);
1254958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  end_position_ = node->end();
1255014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  parent->SetSpillRange(this);
1256014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1257014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1258958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool SpillRange::IsIntersectingWith(SpillRange* other) const {
1259958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (this->use_interval_ == nullptr || other->use_interval_ == nullptr ||
1260014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      this->End() <= other->use_interval_->start() ||
1261014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      other->End() <= this->use_interval_->start()) {
1262958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return false;
1263958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1264958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return AreUseIntervalsIntersecting(use_interval_, other->use_interval_);
1265958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1266958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1267958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1268958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool SpillRange::TryMerge(SpillRange* other) {
1269014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (HasSlot() || other->HasSlot()) return false;
1270f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  if (byte_width() != other->byte_width() || IsIntersectingWith(other))
1271014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return false;
1272958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition max = LifetimePosition::MaxPosition();
1274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (End() < other->End() && other->End() != max) {
1275958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    end_position_ = other->End();
1276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  other->end_position_ = max;
1278958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1279958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  MergeDisjointIntervals(other->use_interval_);
1280958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  other->use_interval_ = nullptr;
1281958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1282014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (TopLevelLiveRange* range : other->live_ranges()) {
1283958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(range->GetSpillRange() == other);
1284958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    range->SetSpillRange(this);
1285958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1286958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1287958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  live_ranges().insert(live_ranges().end(), other->live_ranges().begin(),
1288958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier                       other->live_ranges().end());
1289958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  other->live_ranges().clear();
1290958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1291958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  return true;
1292958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1293958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1294958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1295958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid SpillRange::MergeDisjointIntervals(UseInterval* other) {
1296958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  UseInterval* tail = nullptr;
1297014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UseInterval* current = use_interval_;
1298958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  while (other != nullptr) {
1299958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // Make sure the 'current' list starts first
1300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (current == nullptr || current->start() > other->start()) {
1301958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      std::swap(current, other);
1302958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1303958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // Check disjointness
1304014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(other == nullptr || current->end() <= other->start());
1305958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // Append the 'current' node to the result accumulator and move forward
1306958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (tail == nullptr) {
1307958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      use_interval_ = current;
1308958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    } else {
1309958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      tail->set_next(current);
1310958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
1311958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    tail = current;
1312958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    current = current->next();
1313958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1314958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  // Other list is empty => we are done
1315958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1316958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1317958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1318014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid SpillRange::Print() const {
1319014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  OFStream os(stdout);
1320014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  os << "{" << std::endl;
1321014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (TopLevelLiveRange* range : live_ranges()) {
1322014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    os << range->vreg() << " ";
1323958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1324014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  os << std::endl;
1325958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1326014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (UseInterval* i = interval(); i != nullptr; i = i->next()) {
1327014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    os << '[' << i->start() << ", " << i->end() << ')' << std::endl;
1328958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1329014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  os << "}" << std::endl;
1330958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1331958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1332958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1333014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochRegisterAllocationData::PhiMapValue::PhiMapValue(PhiInstruction* phi,
1334014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                 const InstructionBlock* block,
1335014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                 Zone* zone)
1336014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : phi_(phi),
1337014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      block_(block),
1338014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      incoming_operands_(zone),
1339014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      assigned_register_(kUnassignedRegister) {
1340014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  incoming_operands_.reserve(phi->operands().size());
1341958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1342958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1343958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1344014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid RegisterAllocationData::PhiMapValue::AddOperand(
1345014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand* operand) {
1346014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  incoming_operands_.push_back(operand);
1347958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1348958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1349958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid RegisterAllocationData::PhiMapValue::CommitAssignment(
1351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const InstructionOperand& assigned) {
1352014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (InstructionOperand* operand : incoming_operands_) {
1353014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand::ReplaceWith(operand, &assigned);
1354958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1355014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1356958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochRegisterAllocationData::RegisterAllocationData(
1358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const RegisterConfiguration* config, Zone* zone, Frame* frame,
1359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionSequence* code, const char* debug_name)
1360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : allocation_zone_(zone),
1361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      frame_(frame),
1362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      code_(code),
1363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      debug_name_(debug_name),
1364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      config_(config),
1365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      phi_map_(allocation_zone()),
1366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      live_in_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()),
1367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      live_out_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()),
1368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      live_ranges_(code->VirtualRegisterCount() * 2, nullptr,
1369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                   allocation_zone()),
1370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      fixed_live_ranges_(this->config()->num_general_registers(), nullptr,
1371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         allocation_zone()),
1372c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      fixed_float_live_ranges_(allocation_zone()),
1373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      fixed_double_live_ranges_(this->config()->num_double_registers(), nullptr,
1374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                allocation_zone()),
1375c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      fixed_simd128_live_ranges_(allocation_zone()),
1376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      spill_ranges_(code->VirtualRegisterCount(), nullptr, allocation_zone()),
1377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      delayed_references_(allocation_zone()),
1378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      assigned_registers_(nullptr),
1379014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      assigned_double_registers_(nullptr),
1380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      virtual_register_count_(code->VirtualRegisterCount()),
1381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      preassigned_slot_ranges_(zone) {
1382c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (!kSimpleFPAliasing) {
1383c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    fixed_float_live_ranges_.resize(this->config()->num_float_registers(),
1384c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                    nullptr);
1385c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    fixed_simd128_live_ranges_.resize(this->config()->num_simd128_registers(),
1386c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                      nullptr);
1387c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
1388c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
1389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assigned_registers_ = new (code_zone())
1390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      BitVector(this->config()->num_general_registers(), code_zone());
1391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  assigned_double_registers_ = new (code_zone())
1392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      BitVector(this->config()->num_double_registers(), code_zone());
1393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  this->frame()->SetAllocatedRegisters(assigned_registers_);
1394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  this->frame()->SetAllocatedDoubleRegisters(assigned_double_registers_);
1395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1396958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1397958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochMoveOperands* RegisterAllocationData::AddGapMove(
1399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int index, Instruction::GapPosition position,
1400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const InstructionOperand& from, const InstructionOperand& to) {
1401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Instruction* instr = code()->InstructionAt(index);
1402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ParallelMove* moves = instr->GetOrCreateParallelMove(position, code_zone());
1403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return moves->AddMove(from, to);
1404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochMachineRepresentation RegisterAllocationData::RepresentationFor(
1408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int virtual_register) {
1409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_LT(virtual_register, code()->VirtualRegisterCount());
1410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return code()->GetRepresentation(virtual_register);
1411014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1412014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTopLevelLiveRange* RegisterAllocationData::GetOrCreateLiveRangeFor(int index) {
1415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (index >= static_cast<int>(live_ranges().size())) {
1416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    live_ranges().resize(index + 1, nullptr);
1417958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TopLevelLiveRange* result = live_ranges()[index];
1419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (result == nullptr) {
1420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    result = NewLiveRange(index, RepresentationFor(index));
1421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    live_ranges()[index] = result;
1422958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return result;
1424958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
1425958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1426958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTopLevelLiveRange* RegisterAllocationData::NewLiveRange(
1428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int index, MachineRepresentation rep) {
1429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return new (allocation_zone()) TopLevelLiveRange(index, rep);
1430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint RegisterAllocationData::GetNextLiveRangeId() {
1434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int vreg = virtual_register_count_++;
1435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (vreg >= static_cast<int>(live_ranges().size())) {
1436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    live_ranges().resize(vreg + 1, nullptr);
1437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return vreg;
1439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTopLevelLiveRange* RegisterAllocationData::NextLiveRange(
1443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MachineRepresentation rep) {
1444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int vreg = GetNextLiveRangeId();
1445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TopLevelLiveRange* ret = NewLiveRange(vreg, rep);
1446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return ret;
1447014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochRegisterAllocationData::PhiMapValue* RegisterAllocationData::InitializePhiMap(
1451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const InstructionBlock* block, PhiInstruction* phi) {
1452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RegisterAllocationData::PhiMapValue* map_value = new (allocation_zone())
1453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      RegisterAllocationData::PhiMapValue(phi, block, allocation_zone());
1454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  auto res =
1455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      phi_map_.insert(std::make_pair(phi->virtual_register(), map_value));
1456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(res.second);
1457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  USE(res);
1458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return map_value;
1459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1462014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochRegisterAllocationData::PhiMapValue* RegisterAllocationData::GetPhiMapValueFor(
1463014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int virtual_register) {
1464014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  auto it = phi_map_.find(virtual_register);
1465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(it != phi_map_.end());
1466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return it->second;
1467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1470014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochRegisterAllocationData::PhiMapValue* RegisterAllocationData::GetPhiMapValueFor(
1471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TopLevelLiveRange* top_range) {
1472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return GetPhiMapValueFor(top_range->vreg());
1473014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1476014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool RegisterAllocationData::ExistsUseWithoutDefinition() {
1477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  bool found = false;
1478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BitVector::Iterator iterator(live_in_sets()[0]);
1479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (!iterator.Done()) {
1480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    found = true;
1481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int operand_index = iterator.Current();
1482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintF("Register allocator error: live v%d reached first block.\n",
1483014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           operand_index);
1484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* range = GetOrCreateLiveRangeFor(operand_index);
1485014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    PrintF("  (first use is at %d)\n", range->first_pos()->pos().value());
1486014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (debug_name() == nullptr) {
1487014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      PrintF("\n");
1488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else {
1489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      PrintF("  (function: %s)\n", debug_name());
1490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    iterator.Advance();
1492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return found;
1494014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1496014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1497014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// If a range is defined in a deferred block, we can expect all the range
1498014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// to only cover positions in deferred blocks. Otherwise, a block on the
1499014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// hot path would be dominated by a deferred block, meaning it is unreachable
1500014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// without passing through the deferred block, which is contradictory.
1501014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// In particular, when such a range contributes a result back on the hot
1502014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// path, it will be as one of the inputs of a phi. In that case, the value
1503014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// will be transferred via a move in the Gap::END's of the last instruction
1504014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch// of a deferred block.
1505014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool RegisterAllocationData::RangesDefinedInDeferredStayInDeferred() {
1506014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (const TopLevelLiveRange* range : live_ranges()) {
1507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range == nullptr || range->IsEmpty() ||
1508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        !code()
1509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             ->GetInstructionBlock(range->Start().ToInstructionIndex())
1510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             ->IsDeferred()) {
1511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      continue;
1512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (const UseInterval* i = range->first_interval(); i != nullptr;
1514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         i = i->next()) {
1515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int first = i->FirstGapIndex();
1516014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int last = i->LastGapIndex();
1517014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (int instr = first; instr <= last;) {
1518014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        const InstructionBlock* block = code()->GetInstructionBlock(instr);
1519014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (!block->IsDeferred()) return false;
1520014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        instr = block->last_instruction_index() + 1;
1521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1524014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return true;
1525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1527014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochSpillRange* RegisterAllocationData::AssignSpillRangeToLiveRange(
1528014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TopLevelLiveRange* range) {
1529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!range->HasSpillOperand());
1530014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1531014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SpillRange* spill_range = range->GetAllocatedSpillRange();
1532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (spill_range == nullptr) {
1533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!range->IsSplinter());
1534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    spill_range = new (allocation_zone()) SpillRange(range, allocation_zone());
1535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  range->set_spill_type(TopLevelLiveRange::SpillType::kSpillRange);
1537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int spill_range_index =
1539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      range->IsSplinter() ? range->splintered_from()->vreg() : range->vreg();
1540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  spill_ranges()[spill_range_index] = spill_range;
1542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return spill_range;
1544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1546b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochSpillRange* RegisterAllocationData::CreateSpillRangeForLiveRange(
1548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TopLevelLiveRange* range) {
1549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!range->HasSpillOperand());
1550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!range->IsSplinter());
1551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SpillRange* spill_range =
1552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      new (allocation_zone()) SpillRange(range, allocation_zone());
1553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return spill_range;
1554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
155613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochvoid RegisterAllocationData::MarkAllocated(MachineRepresentation rep,
155713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                           int index) {
155813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  switch (rep) {
155913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case MachineRepresentation::kFloat32:
1560f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kSimd128:
1561c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (kSimpleFPAliasing) {
1562c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        assigned_double_registers_->Add(index);
1563c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      } else {
1564c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        int alias_base_index = -1;
1565c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        int aliases = config()->GetAliases(
1566c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            rep, index, MachineRepresentation::kFloat64, &alias_base_index);
1567c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1));
1568c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        while (aliases--) {
1569c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          int aliased_reg = alias_base_index + aliases;
1570c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          assigned_double_registers_->Add(aliased_reg);
1571c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        }
1572c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      }
1573c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      break;
1574c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    case MachineRepresentation::kFloat64:
157513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      assigned_double_registers_->Add(index);
157613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
157713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    default:
157813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      DCHECK(!IsFloatingPoint(rep));
157913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      assigned_registers_->Add(index);
158013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
1581b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1582b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1583b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool RegisterAllocationData::IsBlockBoundary(LifetimePosition pos) const {
1585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return pos.IsFullStart() &&
1586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         code()->GetInstructionBlock(pos.ToInstructionIndex())->code_start() ==
1587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch             pos.ToInstructionIndex();
1588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1589b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochConstraintBuilder::ConstraintBuilder(RegisterAllocationData* data)
1592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : data_(data) {}
1593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochInstructionOperand* ConstraintBuilder::AllocateFixed(
1596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UnallocatedOperand* operand, int pos, bool is_tagged) {
1597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Allocating fixed reg for op %d\n", operand->virtual_register());
1598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(operand->HasFixedPolicy());
1599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand allocated;
1600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MachineRepresentation rep = InstructionSequence::DefaultRepresentation();
1601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int virtual_register = operand->virtual_register();
1602014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (virtual_register != InstructionOperand::kInvalidVirtualRegister) {
1603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    rep = data()->RepresentationFor(virtual_register);
1604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (operand->HasFixedSlotPolicy()) {
1606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    allocated = AllocatedOperand(AllocatedOperand::STACK_SLOT, rep,
1607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 operand->fixed_slot_index());
1608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (operand->HasFixedRegisterPolicy()) {
1609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!IsFloatingPoint(rep));
1610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    allocated = AllocatedOperand(AllocatedOperand::REGISTER, rep,
1611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 operand->fixed_register_index());
161213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  } else if (operand->HasFixedFPRegisterPolicy()) {
1613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(IsFloatingPoint(rep));
1614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK_NE(InstructionOperand::kInvalidVirtualRegister, virtual_register);
1615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    allocated = AllocatedOperand(AllocatedOperand::REGISTER, rep,
1616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 operand->fixed_register_index());
1617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UNREACHABLE();
1619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  InstructionOperand::ReplaceWith(operand, &allocated);
1621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (is_tagged) {
1622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TRACE("Fixed reg is tagged at %d\n", pos);
1623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Instruction* instr = code()->InstructionAt(pos);
1624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (instr->HasReferenceMap()) {
1625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      instr->reference_map()->RecordReference(*AllocatedOperand::cast(operand));
1626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return operand;
1629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid ConstraintBuilder::MeetRegisterConstraints() {
1633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (InstructionBlock* block : code()->instruction_blocks()) {
1634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MeetRegisterConstraints(block);
1635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid ConstraintBuilder::MeetRegisterConstraints(const InstructionBlock* block) {
1640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int start = block->first_instruction_index();
1641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int end = block->last_instruction_index();
1642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK_NE(-1, start);
1643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = start; i <= end; ++i) {
1644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MeetConstraintsBefore(i);
1645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (i != end) MeetConstraintsAfter(i);
1646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Meet register constraints for the instruction in the end.
1648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  MeetRegisterConstraintsForLastInstructionInBlock(block);
1649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid ConstraintBuilder::MeetRegisterConstraintsForLastInstructionInBlock(
1653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const InstructionBlock* block) {
1654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int end = block->last_instruction_index();
1655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Instruction* last_instruction = code()->InstructionAt(end);
1656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < last_instruction->OutputCount(); i++) {
1657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand* output_operand = last_instruction->OutputAt(i);
1658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!output_operand->IsConstant());
1659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UnallocatedOperand* output = UnallocatedOperand::cast(output_operand);
1660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int output_vreg = output->virtual_register();
1661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TopLevelLiveRange* range = data()->GetOrCreateLiveRangeFor(output_vreg);
1662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool assigned = false;
1663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (output->HasFixedPolicy()) {
1664014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      AllocateFixed(output, -1, false);
1665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // This value is produced on the stack, we never need to spill it.
1666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (output->IsStackSlot()) {
1667014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(LocationOperand::cast(output)->index() <
1668014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               data()->frame()->GetSpillSlotCount());
1669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->SetSpillOperand(LocationOperand::cast(output));
1670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->SetSpillStartIndex(end);
1671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        assigned = true;
1672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (const RpoNumber& succ : block->successors()) {
1675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        const InstructionBlock* successor = code()->InstructionBlockAt(succ);
1676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(successor->PredecessorCount() == 1);
1677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int gap_index = successor->first_instruction_index();
1678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Create an unconstrained operand for the same virtual register
1679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // and insert a gap move from the fixed output to the operand.
1680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UnallocatedOperand output_copy(UnallocatedOperand::ANY, output_vreg);
1681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        data()->AddGapMove(gap_index, Instruction::START, *output, output_copy);
1682b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!assigned) {
1686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (const RpoNumber& succ : block->successors()) {
1687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        const InstructionBlock* successor = code()->InstructionBlockAt(succ);
1688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(successor->PredecessorCount() == 1);
1689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int gap_index = successor->first_instruction_index();
1690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->RecordSpillLocation(allocation_zone(), gap_index, output);
1691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->SetSpillStartIndex(gap_index);
1692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid ConstraintBuilder::MeetConstraintsAfter(int instr_index) {
1699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Instruction* first = code()->InstructionAt(instr_index);
1700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Handle fixed temporaries.
1701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < first->TempCount(); i++) {
1702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UnallocatedOperand* temp = UnallocatedOperand::cast(first->TempAt(i));
1703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (temp->HasFixedPolicy()) AllocateFixed(temp, instr_index, false);
1704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Handle constant/fixed output operands.
1706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < first->OutputCount(); i++) {
1707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand* output = first->OutputAt(i);
1708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (output->IsConstant()) {
1709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int output_vreg = ConstantOperand::cast(output)->virtual_register();
1710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      TopLevelLiveRange* range = data()->GetOrCreateLiveRangeFor(output_vreg);
1711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      range->SetSpillStartIndex(instr_index + 1);
1712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      range->SetSpillOperand(output);
1713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      continue;
1714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UnallocatedOperand* first_output = UnallocatedOperand::cast(output);
1716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TopLevelLiveRange* range =
1717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        data()->GetOrCreateLiveRangeFor(first_output->virtual_register());
1718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool assigned = false;
1719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (first_output->HasFixedPolicy()) {
1720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int output_vreg = first_output->virtual_register();
1721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UnallocatedOperand output_copy(UnallocatedOperand::ANY, output_vreg);
1722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bool is_tagged = code()->IsReference(output_vreg);
1723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (first_output->HasSecondaryStorage()) {
1724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->MarkHasPreassignedSlot();
1725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        data()->preassigned_slot_ranges().push_back(
1726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            std::make_pair(range, first_output->GetSecondaryStorage()));
1727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      AllocateFixed(first_output, instr_index, is_tagged);
1729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // This value is produced on the stack, we never need to spill it.
1731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (first_output->IsStackSlot()) {
1732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(LocationOperand::cast(first_output)->index() <
1733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               data()->frame()->GetTotalFrameSlotCount());
1734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->SetSpillOperand(LocationOperand::cast(first_output));
1735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->SetSpillStartIndex(instr_index + 1);
1736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        assigned = true;
1737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      data()->AddGapMove(instr_index + 1, Instruction::START, *first_output,
1739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                         output_copy);
1740014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1741014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Make sure we add a gap move for spilling (if we have not done
1742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // so already).
1743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!assigned) {
1744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      range->RecordSpillLocation(allocation_zone(), instr_index + 1,
1745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                 first_output);
1746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      range->SetSpillStartIndex(instr_index + 1);
1747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid ConstraintBuilder::MeetConstraintsBefore(int instr_index) {
1753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Instruction* second = code()->InstructionAt(instr_index);
1754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Handle fixed input operands of second instruction.
1755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < second->InputCount(); i++) {
1756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand* input = second->InputAt(i);
1757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (input->IsImmediate() || input->IsExplicit()) {
1758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      continue;  // Ignore immediates and explicitly reserved registers.
1759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1760014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UnallocatedOperand* cur_input = UnallocatedOperand::cast(input);
1761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (cur_input->HasFixedPolicy()) {
1762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int input_vreg = cur_input->virtual_register();
1763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UnallocatedOperand input_copy(UnallocatedOperand::ANY, input_vreg);
1764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bool is_tagged = code()->IsReference(input_vreg);
1765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      AllocateFixed(cur_input, instr_index, is_tagged);
1766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      data()->AddGapMove(instr_index, Instruction::END, input_copy, *cur_input);
1767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Handle "output same as input" for second instruction.
1770014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < second->OutputCount(); i++) {
1771014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand* output = second->OutputAt(i);
1772014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!output->IsUnallocated()) continue;
1773014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UnallocatedOperand* second_output = UnallocatedOperand::cast(output);
1774014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!second_output->HasSameAsInputPolicy()) continue;
1775014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(i == 0);  // Only valid for first output.
1776014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UnallocatedOperand* cur_input =
1777014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UnallocatedOperand::cast(second->InputAt(0));
1778014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int output_vreg = second_output->virtual_register();
1779014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int input_vreg = cur_input->virtual_register();
1780014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UnallocatedOperand input_copy(UnallocatedOperand::ANY, input_vreg);
1781014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    cur_input->set_virtual_register(second_output->virtual_register());
1782014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MoveOperands* gap_move = data()->AddGapMove(instr_index, Instruction::END,
1783014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                input_copy, *cur_input);
1784014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (code()->IsReference(input_vreg) && !code()->IsReference(output_vreg)) {
1785014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (second->HasReferenceMap()) {
1786014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        RegisterAllocationData::DelayedReference delayed_reference = {
1787014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            second->reference_map(), &gap_move->source()};
1788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        data()->delayed_references().push_back(delayed_reference);
1789b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
1790014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (!code()->IsReference(input_vreg) &&
1791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch               code()->IsReference(output_vreg)) {
1792014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // The input is assumed to immediately have a tagged representation,
1793014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // before the pointer map can be used. I.e. the pointer map at the
1794014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // instruction will include the output operand (whose value at the
1795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // beginning of the instruction is equal to the input operand). If
1796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // this is not desired, then the pointer map at this instruction needs
1797014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // to be adjusted manually.
1798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
1799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1802b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid ConstraintBuilder::ResolvePhis() {
1804014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Process the blocks in reverse order.
1805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (InstructionBlock* block : base::Reversed(code()->instruction_blocks())) {
1806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ResolvePhis(block);
1807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid ConstraintBuilder::ResolvePhis(const InstructionBlock* block) {
1812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (PhiInstruction* phi : block->phis()) {
1813958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    int phi_vreg = phi->virtual_register();
1814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    RegisterAllocationData::PhiMapValue* map_value =
1815014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        data()->InitializePhiMap(block, phi);
1816014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand& output = phi->output();
1817014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Map the destination operands, so the commitment phase can find them.
1818014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (size_t i = 0; i < phi->operands().size(); ++i) {
1819014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionBlock* cur_block =
1820014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          code()->InstructionBlockAt(block->predecessors()[i]);
1821014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      UnallocatedOperand input(UnallocatedOperand::ANY, phi->operands()[i]);
1822014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      MoveOperands* move = data()->AddGapMove(
1823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          cur_block->last_instruction_index(), Instruction::END, input, output);
1824014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      map_value->AddOperand(&move->destination());
1825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(!code()
1826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  ->InstructionAt(cur_block->last_instruction_index())
1827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                  ->HasReferenceMap());
1828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TopLevelLiveRange* live_range = data()->GetOrCreateLiveRangeFor(phi_vreg);
1830958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    int gap_index = block->first_instruction_index();
1831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    live_range->RecordSpillLocation(allocation_zone(), gap_index, &output);
1832958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    live_range->SetSpillStartIndex(gap_index);
1833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // We use the phi-ness of some nodes in some later heuristics.
1834b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    live_range->set_is_phi(true);
1835958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    live_range->set_is_non_loop_phi(!block->IsLoopHeader());
1836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLiveRangeBuilder::LiveRangeBuilder(RegisterAllocationData* data,
1841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                   Zone* local_zone)
1842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : data_(data), phi_hints_(local_zone) {}
1843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochBitVector* LiveRangeBuilder::ComputeLiveOut(const InstructionBlock* block,
1846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            RegisterAllocationData* data) {
1847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t block_index = block->rpo_number().ToSize();
1848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BitVector* live_out = data->live_out_sets()[block_index];
1849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (live_out == nullptr) {
1850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Compute live out for the given block, except not including backward
1851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // successor edges.
1852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Zone* zone = data->allocation_zone();
1853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const InstructionSequence* code = data->code();
1854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    live_out = new (zone) BitVector(code->VirtualRegisterCount(), zone);
1856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Process all successor blocks.
1858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (const RpoNumber& succ : block->successors()) {
1859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Add values live on entry to the successor.
1860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (succ <= block->rpo_number()) continue;
1861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      BitVector* live_in = data->live_in_sets()[succ.ToSize()];
1862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (live_in != nullptr) live_out->Union(*live_in);
1863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
1864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // All phi input operands corresponding to this successor edge are live
1865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // out from this block.
1866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      const InstructionBlock* successor = code->InstructionBlockAt(succ);
1867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      size_t index = successor->PredecessorIndexOf(block->rpo_number());
1868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(index < successor->PredecessorCount());
1869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (PhiInstruction* phi : successor->phis()) {
1870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        live_out->Add(phi->operands()[index]);
1871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
1872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
1873014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    data->live_out_sets()[block_index] = live_out;
1874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return live_out;
1876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1877b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1878b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1879014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRangeBuilder::AddInitialIntervals(const InstructionBlock* block,
1880014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           BitVector* live_out) {
1881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Add an interval that includes the entire block to the live range for
1882014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // each live_out value.
1883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition start = LifetimePosition::GapFromInstructionIndex(
1884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      block->first_instruction_index());
1885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition end = LifetimePosition::InstructionFromInstructionIndex(
1886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             block->last_instruction_index())
1887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             .NextStart();
1888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BitVector::Iterator iterator(live_out);
1889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (!iterator.Done()) {
1890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int operand_index = iterator.Current();
1891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TopLevelLiveRange* range = data()->GetOrCreateLiveRangeFor(operand_index);
1892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    range->AddUseInterval(start, end, allocation_zone());
1893014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    iterator.Advance();
1894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
189713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdochint LiveRangeBuilder::FixedFPLiveRangeID(int index, MachineRepresentation rep) {
1898f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  int result = -index - 1;
189913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  switch (rep) {
1900f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch    case MachineRepresentation::kSimd128:
1901c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      result -= config()->num_float_registers();
1902c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // Fall through.
190313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case MachineRepresentation::kFloat32:
1904c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      result -= config()->num_double_registers();
1905c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // Fall through.
190613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    case MachineRepresentation::kFloat64:
1907f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      result -= config()->num_general_registers();
1908f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      break;
190913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    default:
1910f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      UNREACHABLE();
191113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      break;
191213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  }
1913f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch  return result;
1914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTopLevelLiveRange* LiveRangeBuilder::FixedLiveRangeFor(int index) {
1917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(index < config()->num_general_registers());
1918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TopLevelLiveRange* result = data()->fixed_live_ranges()[index];
1919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (result == nullptr) {
192013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    MachineRepresentation rep = InstructionSequence::DefaultRepresentation();
192113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    result = data()->NewLiveRange(FixedLiveRangeID(index), rep);
1922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(result->IsFixed());
1923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    result->set_assigned_register(index);
192413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    data()->MarkAllocated(rep, index);
1925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    data()->fixed_live_ranges()[index] = result;
1926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
1927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return result;
1928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
193013e2dadd00298019ed862f2b2fc5068bba730bcfBen MurdochTopLevelLiveRange* LiveRangeBuilder::FixedFPLiveRangeFor(
193113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    int index, MachineRepresentation rep) {
1932c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  int num_regs = config()->num_double_registers();
1933c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  ZoneVector<TopLevelLiveRange*>* live_ranges =
1934c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      &data()->fixed_double_live_ranges();
1935c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (!kSimpleFPAliasing) {
1936c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    switch (rep) {
1937c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      case MachineRepresentation::kFloat32:
1938c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        num_regs = config()->num_float_registers();
1939c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        live_ranges = &data()->fixed_float_live_ranges();
1940c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        break;
1941c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      case MachineRepresentation::kSimd128:
1942c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        num_regs = config()->num_simd128_registers();
1943c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        live_ranges = &data()->fixed_simd128_live_ranges();
1944c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        break;
1945c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      default:
1946c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        break;
1947c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    }
1948c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
1949c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
1950c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  DCHECK(index < num_regs);
1951c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  USE(num_regs);
1952c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  TopLevelLiveRange* result = (*live_ranges)[index];
1953c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (result == nullptr) {
1954c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    result = data()->NewLiveRange(FixedFPLiveRangeID(index, rep), rep);
1955c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    DCHECK(result->IsFixed());
1956c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    result->set_assigned_register(index);
1957c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    data()->MarkAllocated(rep, index);
1958c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    (*live_ranges)[index] = result;
1959014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
1960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return result;
1961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
1962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
1963014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochTopLevelLiveRange* LiveRangeBuilder::LiveRangeFor(InstructionOperand* operand) {
1964014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (operand->IsUnallocated()) {
1965014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return data()->GetOrCreateLiveRangeFor(
1966014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UnallocatedOperand::cast(operand)->virtual_register());
1967014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (operand->IsConstant()) {
1968014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return data()->GetOrCreateLiveRangeFor(
1969014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        ConstantOperand::cast(operand)->virtual_register());
1970014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (operand->IsRegister()) {
1971014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return FixedLiveRangeFor(
1972014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        LocationOperand::cast(operand)->GetRegister().code());
1973bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  } else if (operand->IsFPRegister()) {
197413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    LocationOperand* op = LocationOperand::cast(operand);
197513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    return FixedFPLiveRangeFor(op->register_code(), op->representation());
1976014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
1977014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return nullptr;
1978958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
1979014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1980958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1981958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1982014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochUsePosition* LiveRangeBuilder::NewUsePosition(LifetimePosition pos,
1983014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                              InstructionOperand* operand,
1984014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                              void* hint,
1985014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                              UsePositionHintType hint_type) {
1986014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return new (allocation_zone()) UsePosition(pos, operand, hint, hint_type);
1987014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
1988958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1989958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1990014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochUsePosition* LiveRangeBuilder::Define(LifetimePosition position,
1991014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                      InstructionOperand* operand, void* hint,
1992014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                      UsePositionHintType hint_type) {
1993014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TopLevelLiveRange* range = LiveRangeFor(operand);
1994014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (range == nullptr) return nullptr;
1995958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
1996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (range->IsEmpty() || range->Start() > position) {
1997014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Can happen if there is a definition without use.
1998014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    range->AddUseInterval(position, position.NextStart(), allocation_zone());
1999014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    range->AddUsePosition(NewUsePosition(position.NextStart()));
2000014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
2001014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    range->ShortenTo(position);
2002014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2003014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!operand->IsUnallocated()) return nullptr;
2004014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UnallocatedOperand* unalloc_operand = UnallocatedOperand::cast(operand);
2005014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePosition* use_pos =
2006014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      NewUsePosition(position, unalloc_operand, hint, hint_type);
2007014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  range->AddUsePosition(use_pos);
2008014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return use_pos;
2009014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2010958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2011958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2012014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochUsePosition* LiveRangeBuilder::Use(LifetimePosition block_start,
2013014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                   LifetimePosition position,
2014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                   InstructionOperand* operand, void* hint,
2015014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                   UsePositionHintType hint_type) {
2016014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TopLevelLiveRange* range = LiveRangeFor(operand);
2017014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (range == nullptr) return nullptr;
2018014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePosition* use_pos = nullptr;
2019014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (operand->IsUnallocated()) {
2020014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UnallocatedOperand* unalloc_operand = UnallocatedOperand::cast(operand);
2021014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    use_pos = NewUsePosition(position, unalloc_operand, hint, hint_type);
2022014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    range->AddUsePosition(use_pos);
2023014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2024014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  range->AddUseInterval(block_start, position, allocation_zone());
2025014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return use_pos;
2026014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2027958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2028958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2029014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRangeBuilder::ProcessInstructions(const InstructionBlock* block,
2030014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           BitVector* live) {
2031014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int block_start = block->first_instruction_index();
2032014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition block_start_position =
2033014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LifetimePosition::GapFromInstructionIndex(block_start);
2034c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  bool fixed_float_live_ranges = false;
2035c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  bool fixed_simd128_live_ranges = false;
2036c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (!kSimpleFPAliasing) {
2037c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    int mask = data()->code()->representation_mask();
2038c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    fixed_float_live_ranges = (mask & kFloatRepBit) != 0;
2039c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    fixed_simd128_live_ranges = (mask & kSimd128RepBit) != 0;
2040c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
2041958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2042014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int index = block->last_instruction_index(); index >= block_start;
2043014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       index--) {
2044014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition curr_position =
2045014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        LifetimePosition::InstructionFromInstructionIndex(index);
2046014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Instruction* instr = code()->InstructionAt(index);
2047014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(instr != nullptr);
2048014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(curr_position.IsInstructionPosition());
2049014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Process output, inputs, and temps of this instruction.
2050014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (size_t i = 0; i < instr->OutputCount(); i++) {
2051014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionOperand* output = instr->OutputAt(i);
2052014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (output->IsUnallocated()) {
2053014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Unsupported.
2054014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(!UnallocatedOperand::cast(output)->HasSlotPolicy());
2055014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int out_vreg = UnallocatedOperand::cast(output)->virtual_register();
2056014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        live->Remove(out_vreg);
2057014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else if (output->IsConstant()) {
2058014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int out_vreg = ConstantOperand::cast(output)->virtual_register();
2059014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        live->Remove(out_vreg);
2060014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2061014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (block->IsHandler() && index == block_start && output->IsAllocated() &&
2062014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          output->IsRegister() &&
2063014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          AllocatedOperand::cast(output)->GetRegister().is(
2064014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              v8::internal::kReturnRegister0)) {
2065014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // The register defined here is blocked from gap start - it is the
2066014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // exception value.
2067014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // TODO(mtrofin): should we explore an explicit opcode for
2068014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // the first instruction in the handler?
2069014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Define(LifetimePosition::GapFromInstructionIndex(index), output);
2070958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      } else {
2071014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        Define(curr_position, output);
2072958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
2073958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2074958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2075014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (instr->ClobbersRegisters()) {
2076014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (int i = 0; i < config()->num_allocatable_general_registers(); ++i) {
2077f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        // Create a UseInterval at this instruction for all fixed registers,
2078f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        // (including the instruction outputs). Adding another UseInterval here
2079f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        // is OK because AddUseInterval will just merge it with the existing
2080f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        // one at the end of the range.
2081014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int code = config()->GetAllocatableGeneralCode(i);
2082f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        TopLevelLiveRange* range = FixedLiveRangeFor(code);
2083f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        range->AddUseInterval(curr_position, curr_position.End(),
2084f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                              allocation_zone());
2085014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2086958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2087958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2088014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (instr->ClobbersDoubleRegisters()) {
2089c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      for (int i = 0; i < config()->num_allocatable_double_registers(); ++i) {
2090f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        // Add a UseInterval for all DoubleRegisters. See comment above for
2091f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        // general registers.
2092014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int code = config()->GetAllocatableDoubleCode(i);
2093f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        TopLevelLiveRange* range =
2094f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch            FixedFPLiveRangeFor(code, MachineRepresentation::kFloat64);
2095f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch        range->AddUseInterval(curr_position, curr_position.End(),
2096f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch                              allocation_zone());
209713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      }
2098c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // Clobber fixed float registers on archs with non-simple aliasing.
2099c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (!kSimpleFPAliasing) {
2100c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        if (fixed_float_live_ranges) {
2101c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          for (int i = 0; i < config()->num_allocatable_float_registers();
2102c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch               ++i) {
2103c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            // Add a UseInterval for all FloatRegisters. See comment above for
2104c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            // general registers.
2105c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            int code = config()->GetAllocatableFloatCode(i);
2106c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            TopLevelLiveRange* range =
2107c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                FixedFPLiveRangeFor(code, MachineRepresentation::kFloat32);
2108c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            range->AddUseInterval(curr_position, curr_position.End(),
2109c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                  allocation_zone());
2110c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          }
2111c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        }
2112c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        if (fixed_simd128_live_ranges) {
2113c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          for (int i = 0; i < config()->num_allocatable_simd128_registers();
2114c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch               ++i) {
2115c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            int code = config()->GetAllocatableSimd128Code(i);
2116c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            TopLevelLiveRange* range =
2117c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                FixedFPLiveRangeFor(code, MachineRepresentation::kSimd128);
2118c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            range->AddUseInterval(curr_position, curr_position.End(),
2119c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                  allocation_zone());
2120c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          }
2121c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        }
2122c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      }
2123958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2125014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (size_t i = 0; i < instr->InputCount(); i++) {
2126014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionOperand* input = instr->InputAt(i);
2127014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (input->IsImmediate() || input->IsExplicit()) {
2128014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        continue;  // Ignore immediates and explicitly reserved registers.
2129014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2130014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LifetimePosition use_pos;
2131014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (input->IsUnallocated() &&
2132014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          UnallocatedOperand::cast(input)->IsUsedAtStart()) {
2133014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        use_pos = curr_position;
2134014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
2135014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        use_pos = curr_position.End();
2136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2137958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2138014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (input->IsUnallocated()) {
2139014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UnallocatedOperand* unalloc = UnallocatedOperand::cast(input);
2140014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int vreg = unalloc->virtual_register();
2141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        live->Add(vreg);
2142014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (unalloc->HasSlotPolicy()) {
2143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          data()->GetOrCreateLiveRangeFor(vreg)->set_has_slot_use(true);
2144014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
2145014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2146014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Use(block_start_position, use_pos, input);
2147014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2149014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (size_t i = 0; i < instr->TempCount(); i++) {
2150014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionOperand* temp = instr->TempAt(i);
2151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Unsupported.
2152014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK_IMPLIES(temp->IsUnallocated(),
2153014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                     !UnallocatedOperand::cast(temp)->HasSlotPolicy());
2154014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (instr->ClobbersTemps()) {
2155014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (temp->IsRegister()) continue;
2156014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (temp->IsUnallocated()) {
2157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          UnallocatedOperand* temp_unalloc = UnallocatedOperand::cast(temp);
2158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          if (temp_unalloc->HasFixedPolicy()) {
2159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            continue;
2160014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
2161014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
2162014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2163014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Use(block_start_position, curr_position.End(), temp);
2164014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Define(curr_position, temp);
2165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2167014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Process the moves of the instruction's gaps, making their sources live.
2168014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const Instruction::GapPosition kPositions[] = {Instruction::END,
2169014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                   Instruction::START};
2170014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    curr_position = curr_position.PrevStart();
2171014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(curr_position.IsGapPosition());
2172014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (const Instruction::GapPosition& position : kPositions) {
2173014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ParallelMove* move = instr->GetParallelMove(position);
2174014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (move == nullptr) continue;
2175014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (position == Instruction::END) {
2176014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        curr_position = curr_position.End();
2177014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
2178014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        curr_position = curr_position.Start();
2179014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
2180014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (MoveOperands* cur : *move) {
2181014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        InstructionOperand& from = cur->source();
2182014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        InstructionOperand& to = cur->destination();
2183014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        void* hint = &to;
2184014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UsePositionHintType hint_type = UsePosition::HintTypeForOperand(to);
2185014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UsePosition* to_use = nullptr;
2186014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int phi_vreg = -1;
2187014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (to.IsUnallocated()) {
2188014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          int to_vreg = UnallocatedOperand::cast(to).virtual_register();
2189014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          TopLevelLiveRange* to_range =
2190014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              data()->GetOrCreateLiveRangeFor(to_vreg);
2191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          if (to_range->is_phi()) {
2192014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            phi_vreg = to_vreg;
2193014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            if (to_range->is_non_loop_phi()) {
2194014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              hint = to_range->current_hint_position();
2195014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              hint_type = hint == nullptr ? UsePositionHintType::kNone
2196014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                          : UsePositionHintType::kUsePos;
2197014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            } else {
2198014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              hint_type = UsePositionHintType::kPhi;
2199014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              hint = data()->GetPhiMapValueFor(to_vreg);
2200014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            }
2201014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          } else {
2202014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            if (live->Contains(to_vreg)) {
2203014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              to_use = Define(curr_position, &to, &from,
2204014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                              UsePosition::HintTypeForOperand(from));
2205014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              live->Remove(to_vreg);
2206014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            } else {
2207014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              cur->Eliminate();
2208014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              continue;
2209014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            }
2210014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
2211014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else {
2212014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          Define(curr_position, &to);
2213014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
2214014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UsePosition* from_use =
2215014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            Use(block_start_position, curr_position, &from, hint, hint_type);
2216014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Mark range live.
2217014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (from.IsUnallocated()) {
2218014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          live->Add(UnallocatedOperand::cast(from).virtual_register());
2219958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        }
2220014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Resolve use position hints just created.
2221014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (to_use != nullptr && from_use != nullptr) {
2222014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          to_use->ResolveHint(from_use);
2223014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          from_use->ResolveHint(to_use);
2224014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
2225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK_IMPLIES(to_use != nullptr, to_use->IsResolved());
2226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK_IMPLIES(from_use != nullptr, from_use->IsResolved());
2227014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Potentially resolve phi hint.
2228014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (phi_vreg != -1) ResolvePhiHint(&from, from_use);
2229958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier      }
2230958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    }
2231014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2232014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2233014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2234014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRangeBuilder::ProcessPhis(const InstructionBlock* block,
2235014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                   BitVector* live) {
2236014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (PhiInstruction* phi : block->phis()) {
2237014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // The live range interval already ends at the first instruction of the
2238014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // block.
2239014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int phi_vreg = phi->virtual_register();
2240014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    live->Remove(phi_vreg);
2241c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // Select a hint from a predecessor block that preceeds this block in the
2242c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // rpo order. In order of priority:
2243c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // - Avoid hints from deferred blocks.
2244c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // - Prefer hints from allocated (or explicit) operands.
2245c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // - Prefer hints from empty blocks (containing just parallel moves and a
2246c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    //   jump). In these cases, if we can elide the moves, the jump threader
2247c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    //   is likely to be able to elide the jump.
2248c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // The enforcement of hinting in rpo order is required because hint
2249c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // resolution that happens later in the compiler pipeline visits
2250c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // instructions in reverse rpo order, relying on the fact that phis are
2251c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // encountered before their hints.
2252c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    InstructionOperand* hint = nullptr;
2253c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    int hint_preference = 0;
2254c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
2255c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // The cost of hinting increases with the number of predecessors. At the
2256c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // same time, the typical benefit decreases, since this hinting only
2257c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // optimises the execution path through one predecessor. A limit of 2 is
2258c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // sufficient to hit the common if/else pattern.
2259c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    int predecessor_limit = 2;
2260c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
2261c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    for (RpoNumber predecessor : block->predecessors()) {
226213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      const InstructionBlock* predecessor_block =
2263c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          code()->InstructionBlockAt(predecessor);
2264c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      DCHECK_EQ(predecessor_block->rpo_number(), predecessor);
2265c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
2266c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // Only take hints from earlier rpo numbers.
2267c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (predecessor >= block->rpo_number()) continue;
2268c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
2269c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // Look up the predecessor instruction.
2270c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      const Instruction* predecessor_instr =
2271c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          GetLastInstruction(code(), predecessor_block);
2272c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      InstructionOperand* predecessor_hint = nullptr;
2273c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // Phis are assigned in the END position of the last instruction in each
2274c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // predecessor block.
2275c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      for (MoveOperands* move :
2276c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch           *predecessor_instr->GetParallelMove(Instruction::END)) {
2277c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        InstructionOperand& to = move->destination();
2278c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        if (to.IsUnallocated() &&
2279c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            UnallocatedOperand::cast(to).virtual_register() == phi_vreg) {
2280c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          predecessor_hint = &move->source();
2281c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          break;
2282c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        }
2283c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      }
2284c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      DCHECK_NOT_NULL(predecessor_hint);
2285c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
2286c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // For each predecessor, generate a score according to the priorities
2287c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // described above, and pick the best one. Flags in higher-order bits have
2288c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // a higher priority than those in lower-order bits.
2289c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      int predecessor_hint_preference = 0;
2290c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      const int kNotDeferredBlockPreference = (1 << 2);
2291c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      const int kMoveIsAllocatedPreference = (1 << 1);
2292c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      const int kBlockIsEmptyPreference = (1 << 0);
2293c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
2294c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // - Avoid hints from deferred blocks.
2295c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (!predecessor_block->IsDeferred()) {
2296c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        predecessor_hint_preference |= kNotDeferredBlockPreference;
22973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
22983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
2299c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // - Prefer hints from allocated (or explicit) operands.
2300c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      //
2301c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // Already-allocated or explicit operands are typically assigned using
2302c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // the parallel moves on the last instruction. For example:
2303c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      //
2304c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      //      gap (v101 = [x0|R|w32]) (v100 = v101)
2305c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      //      ArchJmp
2306c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      //    ...
2307c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      //    phi: v100 = v101 v102
2308c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      //
2309c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // We have already found the END move, so look for a matching START move
2310c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // from an allocated (or explicit) operand.
2311c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      //
2312c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // Note that we cannot simply look up data()->live_ranges()[vreg] here
2313c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // because the live ranges are still being built when this function is
2314c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // called.
2315c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // TODO(v8): Find a way to separate hinting from live range analysis in
2316c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // BuildLiveRanges so that we can use the O(1) live-range look-up.
2317c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      auto moves = predecessor_instr->GetParallelMove(Instruction::START);
2318c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (moves != nullptr) {
2319c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        for (MoveOperands* move : *moves) {
2320c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          InstructionOperand& to = move->destination();
2321c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          if (predecessor_hint->Equals(to)) {
2322c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            if (move->source().IsAllocated() || move->source().IsExplicit()) {
2323c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch              predecessor_hint_preference |= kMoveIsAllocatedPreference;
2324c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            }
2325c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            break;
2326c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          }
2327c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        }
2328c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      }
2329c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
2330c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      // - Prefer hints from empty blocks.
2331c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (predecessor_block->last_instruction_index() ==
2332c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          predecessor_block->first_instruction_index()) {
2333c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        predecessor_hint_preference |= kBlockIsEmptyPreference;
2334c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      }
2335c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
2336c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if ((hint == nullptr) ||
2337c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          (predecessor_hint_preference > hint_preference)) {
2338c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        // Take the hint from this predecessor.
2339c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        hint = predecessor_hint;
2340c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        hint_preference = predecessor_hint_preference;
2341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2342c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
2343c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (--predecessor_limit <= 0) break;
2344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2345c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    DCHECK_NOT_NULL(hint);
2346c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
2347014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition block_start = LifetimePosition::GapFromInstructionIndex(
2348014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        block->first_instruction_index());
2349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    UsePosition* use_pos = Define(block_start, &phi->output(), hint,
2350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  UsePosition::HintTypeForOperand(*hint));
2351014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MapPhiHint(hint, use_pos);
2352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2355b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2356014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRangeBuilder::ProcessLoopHeader(const InstructionBlock* block,
2357014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                         BitVector* live) {
2358014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(block->IsLoopHeader());
2359014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Add a live range stretching from the first loop instruction to the last
2360014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // for each value live on entry to the header.
2361014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  BitVector::Iterator iterator(live);
2362014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition start = LifetimePosition::GapFromInstructionIndex(
2363014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      block->first_instruction_index());
2364014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition end = LifetimePosition::GapFromInstructionIndex(
2365014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             code()->LastLoopInstructionIndex(block))
2366014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                             .NextFullStart();
2367014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (!iterator.Done()) {
2368014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int operand_index = iterator.Current();
2369014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TopLevelLiveRange* range = data()->GetOrCreateLiveRangeFor(operand_index);
2370014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    range->EnsureInterval(start, end, allocation_zone());
2371014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    iterator.Advance();
2372014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2373014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Insert all values into the live in sets of all blocks in the loop.
2374014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (int i = block->rpo_number().ToInt() + 1; i < block->loop_end().ToInt();
2375014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       ++i) {
2376014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    live_in_sets()[i]->Union(*live);
2377958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2378958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2379958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2380958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRangeBuilder::BuildLiveRanges() {
2382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Process the blocks in reverse order.
2383958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (int block_id = code()->InstructionBlockCount() - 1; block_id >= 0;
2384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch       --block_id) {
2385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionBlock* block =
2386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        code()->InstructionBlockAt(RpoNumber::FromInt(block_id));
2387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    BitVector* live = ComputeLiveOut(block, data());
2388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Initially consider all live_out values live for the entire block. We
2389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // will shorten these intervals if necessary.
2390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AddInitialIntervals(block, live);
2391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Process the instructions in reverse order, generating and killing
2392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // live values.
2393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    ProcessInstructions(block, live);
2394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // All phi output operands are killed by this block.
2395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    ProcessPhis(block, live);
2396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Now live is live_in for this block except not including values live
2397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // out on backward successor edges.
2398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (block->IsLoopHeader()) ProcessLoopHeader(block, live);
2399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    live_in_sets()[block_id] = live;
2400958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  }
2401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Postprocess the ranges.
2402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (TopLevelLiveRange* range : data()->live_ranges()) {
2403958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (range == nullptr) continue;
2404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Give slots to all ranges with a non fixed slot use.
2405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range->has_slot_use() && range->HasNoSpillType()) {
2406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      data()->AssignSpillRangeToLiveRange(range);
2407014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2408958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // TODO(bmeurer): This is a horrible hack to make sure that for constant
2409958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // live ranges, every use requires the constant to be in a register.
2410958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // Without this hack, all uses with "any" policy would get the constant
2411958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    // operand assigned.
2412958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (range->HasSpillOperand() && range->GetSpillOperand()->IsConstant()) {
2413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (UsePosition* pos = range->first_pos(); pos != nullptr;
2414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch           pos = pos->next()) {
2415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (pos->type() == UsePositionType::kRequiresSlot) continue;
2416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        UsePositionType new_type = UsePositionType::kAny;
2417958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier        // Can't mark phis as needing a register.
2418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (!pos->pos().IsGapPosition()) {
2419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          new_type = UsePositionType::kRequiresRegister;
2420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        }
2421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        pos->set_type(new_type, true);
2422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (auto preassigned : data()->preassigned_slot_ranges()) {
2426014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TopLevelLiveRange* range = preassigned.first;
2427014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int slot_id = preassigned.second;
2428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SpillRange* spill = range->HasSpillRange()
2429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            ? range->GetSpillRange()
2430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            : data()->AssignSpillRangeToLiveRange(range);
2431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    spill->set_assigned_slot(slot_id);
2432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#ifdef DEBUG
2434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Verify();
2435014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch#endif
2436958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}
2437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2438958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRangeBuilder::MapPhiHint(InstructionOperand* operand,
2440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  UsePosition* use_pos) {
2441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!use_pos->IsResolved());
2442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  auto res = phi_hints_.insert(std::make_pair(operand, use_pos));
2443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(res.second);
2444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  USE(res);
2445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRangeBuilder::ResolvePhiHint(InstructionOperand* operand,
2449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                      UsePosition* use_pos) {
2450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  auto it = phi_hints_.find(operand);
2451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (it == phi_hints_.end()) return;
2452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!it->second->IsResolved());
2453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  it->second->ResolveHint(use_pos);
2454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2456014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRangeBuilder::Verify() const {
2458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (auto& hint : phi_hints_) {
2459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    CHECK(hint.second->IsResolved());
2460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
24613b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  for (const TopLevelLiveRange* current : data()->live_ranges()) {
24623b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (current != nullptr && !current->IsEmpty()) {
24633b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // New LiveRanges should not be split.
24643b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      CHECK_NULL(current->next());
24653b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // General integrity check.
24663b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      current->Verify();
24673b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      const UseInterval* first = current->first_interval();
24683b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      if (first->next() == nullptr) continue;
24693b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
24703b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // Consecutive intervals should not end and start in the same block,
24713b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // otherwise the intervals should have been joined, because the
24723b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      // variable is live throughout that block.
24733b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      CHECK(NextIntervalStartsInDifferentBlocks(first));
24743b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
24753b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      for (const UseInterval* i = first->next(); i != nullptr; i = i->next()) {
24763b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // Except for the first interval, the other intevals must start at
24773b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // a block boundary, otherwise data wouldn't flow to them.
24783b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        CHECK(IntervalStartsAtBlockBoundary(i));
24793b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // The last instruction of the predecessors of the block the interval
24803b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        // starts must be covered by the range.
24813b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        CHECK(IntervalPredecessorsCoveredByRange(i, current));
24823b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        if (i->next() != nullptr) {
24833b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          // Check the consecutive intervals property, except for the last
24843b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          // interval, where it doesn't apply.
24853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch          CHECK(NextIntervalStartsInDifferentBlocks(i));
24863b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        }
24873b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      }
24883b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
2489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
24923b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochbool LiveRangeBuilder::IntervalStartsAtBlockBoundary(
24933b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    const UseInterval* interval) const {
24943b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  LifetimePosition start = interval->start();
24953b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  if (!start.IsFullStart()) return false;
24963b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  int instruction_index = start.ToInstructionIndex();
24973b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  const InstructionBlock* block =
24983b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      data()->code()->GetInstructionBlock(instruction_index);
24993b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  return block->first_instruction_index() == instruction_index;
25003b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
25013b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
25023b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochbool LiveRangeBuilder::IntervalPredecessorsCoveredByRange(
25033b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    const UseInterval* interval, const TopLevelLiveRange* range) const {
25043b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  LifetimePosition start = interval->start();
25053b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  int instruction_index = start.ToInstructionIndex();
25063b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  const InstructionBlock* block =
25073b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      data()->code()->GetInstructionBlock(instruction_index);
25083b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  for (RpoNumber pred_index : block->predecessors()) {
25093b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    const InstructionBlock* predecessor =
25103b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        data()->code()->InstructionBlockAt(pred_index);
25113b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    LifetimePosition last_pos = LifetimePosition::GapFromInstructionIndex(
25123b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        predecessor->last_instruction_index());
25133b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    last_pos = last_pos.NextStart().End();
25143b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (!range->Covers(last_pos)) return false;
25153b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  }
25163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  return true;
25173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
25183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch
25193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdochbool LiveRangeBuilder::NextIntervalStartsInDifferentBlocks(
25203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    const UseInterval* interval) const {
25213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  DCHECK_NOT_NULL(interval->next());
25223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  LifetimePosition end = interval->end();
25233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  LifetimePosition next_start = interval->next()->start();
25243b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // Since end is not covered, but the previous position is, move back a
25253b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  // position
25263b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  end = end.IsStart() ? end.PrevStart().End() : end.Start();
25273b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  int last_covered_index = end.ToInstructionIndex();
25283b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  const InstructionBlock* block =
25293b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      data()->code()->GetInstructionBlock(last_covered_index);
25303b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  const InstructionBlock* next_block =
25313b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      data()->code()->GetInstructionBlock(next_start.ToInstructionIndex());
25323b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch  return block->rpo_number() < next_block->rpo_number();
25333b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch}
2534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochRegisterAllocator::RegisterAllocator(RegisterAllocationData* data,
2536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                     RegisterKind kind)
2537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : data_(data),
2538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      mode_(kind),
2539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      num_registers_(GetRegisterCount(data->config(), kind)),
2540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      num_allocatable_registers_(
2541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          GetAllocatableRegisterCount(data->config(), kind)),
2542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      allocatable_register_codes_(
2543c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          GetAllocatableRegisterCodes(data->config(), kind)),
2544c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      check_fp_aliasing_(false) {
2545c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (!kSimpleFPAliasing && kind == FP_REGISTERS) {
2546c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    check_fp_aliasing_ = (data->code()->representation_mask() &
2547c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                          (kFloatRepBit | kSimd128RepBit)) != 0;
2548c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
2549c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
2550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2551014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLifetimePosition RegisterAllocator::GetSplitPositionForInstruction(
2552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const LiveRange* range, int instruction_index) {
2553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition ret = LifetimePosition::Invalid();
2554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ret = LifetimePosition::GapFromInstructionIndex(instruction_index);
2556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (range->Start() >= ret || ret >= range->End()) {
2557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return LifetimePosition::Invalid();
2558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return ret;
2560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2562f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdochvoid RegisterAllocator::SplitAndSpillRangesDefinedByMemoryOperand() {
2563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t initial_range_count = data()->live_ranges().size();
2564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < initial_range_count; ++i) {
2565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TopLevelLiveRange* range = data()->live_ranges()[i];
2566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!CanProcessRange(range)) continue;
2567f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch    if (range->HasNoSpillType() ||
2568f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        (range->HasSpillRange() && !range->has_slot_use())) {
2569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      continue;
2570b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition start = range->Start();
2572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TRACE("Live range %d:%d is defined by a spill operand.\n",
2573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          range->TopLevel()->vreg(), range->relative_id());
2574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition next_pos = start;
2575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (next_pos.IsGapPosition()) {
2576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      next_pos = next_pos.NextStart();
2577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
2578c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
2579c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // With splinters, we can be more strict and skip over positions
2580c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // not strictly needing registers.
2581c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    UsePosition* pos =
2582c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        range->IsSplinter()
2583c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            ? range->NextRegisterPosition(next_pos)
2584c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            : range->NextUsePositionRegisterIsBeneficial(next_pos);
2585014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // If the range already has a spill operand and it doesn't need a
2586014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // register immediately, split it and spill the first part of the range.
2587014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (pos == nullptr) {
2588014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Spill(range);
2589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (pos->pos() > range->Start().NextStart()) {
2590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Do not spill live range eagerly if use position that can benefit from
2591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // the register is too close to the start of live range.
2592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LifetimePosition split_pos = GetSplitPositionForInstruction(
2593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          range, pos->pos().ToInstructionIndex());
2594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // There is no place to split, so we can't split and spill.
2595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!split_pos.IsValid()) continue;
2596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      split_pos =
2598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          FindOptimalSplitPos(range->Start().NextFullStart(), split_pos);
2599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SplitRangeAt(range, split_pos);
2601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Spill(range);
2602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2603014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2606b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLiveRange* RegisterAllocator::SplitRangeAt(LiveRange* range,
2608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           LifetimePosition pos) {
2609014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!range->TopLevel()->IsFixed());
2610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Splitting live range %d:%d at %d\n", range->TopLevel()->vreg(),
2611014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->relative_id(), pos.value());
2612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2613014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (pos <= range->Start()) return range;
2614b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // We can't properly connect liveranges if splitting occurred at the end
2616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // a block.
2617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(pos.IsStart() || pos.IsGapPosition() ||
2618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         (GetInstructionBlock(code(), pos)->last_instruction_index() !=
2619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          pos.ToInstructionIndex()));
2620b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LiveRange* result = range->SplitAt(pos, allocation_zone());
2622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return result;
2623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLiveRange* RegisterAllocator::SplitBetween(LiveRange* range,
2627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           LifetimePosition start,
2628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           LifetimePosition end) {
2629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!range->TopLevel()->IsFixed());
2630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Splitting live range %d:%d in position between [%d, %d]\n",
2631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->TopLevel()->vreg(), range->relative_id(), start.value(),
2632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        end.value());
2633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition split_pos = FindOptimalSplitPos(start, end);
2635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(split_pos >= start);
2636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return SplitRangeAt(range, split_pos);
2637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLifetimePosition RegisterAllocator::FindOptimalSplitPos(LifetimePosition start,
2641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                        LifetimePosition end) {
2642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int start_instr = start.ToInstructionIndex();
2643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int end_instr = end.ToInstructionIndex();
2644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(start_instr <= end_instr);
2645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // We have no choice
2647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (start_instr == end_instr) return end;
2648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2649014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const InstructionBlock* start_block = GetInstructionBlock(code(), start);
2650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const InstructionBlock* end_block = GetInstructionBlock(code(), end);
2651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (end_block == start_block) {
2653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // The interval is split in the same basic block. Split at the latest
2654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // possible position.
2655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return end;
2656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const InstructionBlock* block = end_block;
2659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Find header of outermost loop.
2660109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  do {
2661109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    const InstructionBlock* loop = GetContainingLoop(code(), block);
2662109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (loop == nullptr ||
2663109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        loop->rpo_number().ToInt() <= start_block->rpo_number().ToInt()) {
2664109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // No more loops or loop starts before the lifetime start.
2665109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      break;
2666109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
2667109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    block = loop;
2668109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  } while (true);
2669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2670014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // We did not find any suitable outer loop. Split at the latest possible
2671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // position unless end_block is a loop header itself.
2672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (block == end_block && !end_block->IsLoopHeader()) return end;
2673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return LifetimePosition::GapFromInstructionIndex(
2675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      block->first_instruction_index());
2676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLifetimePosition RegisterAllocator::FindOptimalSpillingPos(
2680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* range, LifetimePosition pos) {
2681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const InstructionBlock* block = GetInstructionBlock(code(), pos.Start());
2682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const InstructionBlock* loop_header =
2683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      block->IsLoopHeader() ? block : GetContainingLoop(code(), block);
2684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (loop_header == nullptr) return pos;
2686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const UsePosition* prev_use =
2688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      range->PreviousUsePositionRegisterIsBeneficial(pos);
2689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  while (loop_header != nullptr) {
2691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // We are going to spill live range inside the loop.
2692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // If possible try to move spilling position backwards to loop header.
2693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // This will reduce number of memory moves on the back edge.
2694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition loop_start = LifetimePosition::GapFromInstructionIndex(
2695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        loop_header->first_instruction_index());
2696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range->Covers(loop_start)) {
2698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (prev_use == nullptr || prev_use->pos() < loop_start) {
2699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // No register beneficial use inside the loop before the pos.
2700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        pos = loop_start;
2701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Try hoisting out to an outer loop.
2705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    loop_header = GetContainingLoop(code(), loop_header);
2706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return pos;
2709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid RegisterAllocator::Spill(LiveRange* range) {
2713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!range->spilled());
2714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TopLevelLiveRange* first = range->TopLevel();
2715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Spilling live range %d:%d\n", first->vreg(), range->relative_id());
2716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (first->HasNoSpillType()) {
2718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    data()->AssignSpillRangeToLiveRange(first);
2719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  range->Spill();
2721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochconst char* RegisterAllocator::RegisterName(int register_code) const {
2724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (mode() == GENERAL_REGISTERS) {
2725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return data()->config()->GetGeneralRegisterName(register_code);
2726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else {
2727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return data()->config()->GetDoubleRegisterName(register_code);
2728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2730014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2731014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLinearScanAllocator::LinearScanAllocator(RegisterAllocationData* data,
2733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                         RegisterKind kind, Zone* local_zone)
2734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : RegisterAllocator(data, kind),
2735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      unhandled_live_ranges_(local_zone),
2736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      active_live_ranges_(local_zone),
2737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      inactive_live_ranges_(local_zone) {
2738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  unhandled_live_ranges().reserve(
2739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      static_cast<size_t>(code()->VirtualRegisterCount() * 2));
2740014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  active_live_ranges().reserve(8);
2741014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  inactive_live_ranges().reserve(8);
2742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // TryAllocateFreeReg and AllocateBlockedReg assume this
2743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // when allocating local arrays.
2744bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  DCHECK(RegisterConfiguration::kMaxFPRegisters >=
2745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         this->data()->config()->num_general_registers());
2746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
2747b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::AllocateRegisters() {
2750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(unhandled_live_ranges().empty());
2751958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(active_live_ranges().empty());
2752958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(inactive_live_ranges().empty());
2753b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2754f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch  SplitAndSpillRangesDefinedByMemoryOperand();
2755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
2756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (TopLevelLiveRange* range : data()->live_ranges()) {
2757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!CanProcessRange(range)) continue;
2758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (LiveRange* to_add = range; to_add != nullptr;
2759014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         to_add = to_add->next()) {
2760014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!to_add->spilled()) {
2761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        AddToUnhandledUnsorted(to_add);
2762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
2765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SortUnhandled();
2766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(UnhandledIsSorted());
2767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
276813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  if (mode() == GENERAL_REGISTERS) {
276913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    for (TopLevelLiveRange* current : data()->fixed_live_ranges()) {
277013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if (current != nullptr) AddToInactive(current);
277113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
277213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  } else {
277313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    for (TopLevelLiveRange* current : data()->fixed_double_live_ranges()) {
277413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if (current != nullptr) AddToInactive(current);
2775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2776c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    if (!kSimpleFPAliasing && check_fp_aliasing()) {
2777c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      for (TopLevelLiveRange* current : data()->fixed_float_live_ranges()) {
2778c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        if (current != nullptr) AddToInactive(current);
2779c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      }
2780c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      for (TopLevelLiveRange* current : data()->fixed_simd128_live_ranges()) {
2781c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        if (current != nullptr) AddToInactive(current);
2782c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      }
2783c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    }
2784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2786958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  while (!unhandled_live_ranges().empty()) {
2787b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(UnhandledIsSorted());
2788014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* current = unhandled_live_ranges().back();
2789958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    unhandled_live_ranges().pop_back();
2790b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(UnhandledIsSorted());
2791014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition position = current->Start();
2792b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG
2793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    allocation_finger_ = position;
2794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif
2795014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TRACE("Processing interval %d:%d start=%d\n", current->TopLevel()->vreg(),
2796014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          current->relative_id(), position.value());
2797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2798014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (current->IsTopLevel() && TryReuseSpillForPhi(current->TopLevel()))
2799014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      continue;
2800958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier
2801958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (size_t i = 0; i < active_live_ranges().size(); ++i) {
2802014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LiveRange* cur_active = active_live_ranges()[i];
2803014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (cur_active->End() <= position) {
2804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ActiveToHandled(cur_active);
2805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        --i;  // The live range was removed from the list of active live ranges.
2806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else if (!cur_active->Covers(position)) {
2807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        ActiveToInactive(cur_active);
2808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        --i;  // The live range was removed from the list of active live ranges.
2809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2812958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    for (size_t i = 0; i < inactive_live_ranges().size(); ++i) {
2813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LiveRange* cur_inactive = inactive_live_ranges()[i];
2814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (cur_inactive->End() <= position) {
2815b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        InactiveToHandled(cur_inactive);
2816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        --i;  // Live range was removed from the list of inactive live ranges.
2817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      } else if (cur_inactive->Covers(position)) {
2818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        InactiveToActive(cur_inactive);
2819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch        --i;  // Live range was removed from the list of inactive live ranges.
2820b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
2821b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
2822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2823014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!current->HasRegisterAssigned() && !current->spilled());
2824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2825c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    ProcessCurrentRange(current);
2826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2829c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochbool LinearScanAllocator::TrySplitAndSpillSplinter(LiveRange* range) {
2830c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  DCHECK(range->TopLevel()->IsSplinter());
2831c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // If we can spill the whole range, great. Otherwise, split above the
2832c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  // first use needing a register and spill the top part.
2833c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  const UsePosition* next_reg = range->NextRegisterPosition(range->Start());
2834c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (next_reg == nullptr) {
2835c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    Spill(range);
2836c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return true;
2837c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  } else if (range->FirstHintPosition() == nullptr) {
2838c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // If there was no hint, but we have a use position requiring a
2839c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    // register, apply the hot path heuristics.
2840c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return false;
2841c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  } else if (next_reg->pos().PrevStart() > range->Start()) {
2842c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    LiveRange* tail = SplitRangeAt(range, next_reg->pos().PrevStart());
2843c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    AddToUnhandledSorted(tail);
2844c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    Spill(range);
2845c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    return true;
2846c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
2847c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return false;
2848c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
2849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::SetLiveRangeAssignedRegister(LiveRange* range,
2851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                                       int reg) {
285213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  data()->MarkAllocated(range->representation(), reg);
2853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  range->set_assigned_register(reg);
2854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  range->SetUseHints(reg);
2855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (range->IsTopLevel() && range->TopLevel()->is_phi()) {
2856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    data()->GetPhiMapValueFor(range->TopLevel())->set_assigned_register(reg);
2857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2861014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::AddToActive(LiveRange* range) {
2862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Add live range %d:%d to active\n", range->TopLevel()->vreg(),
2863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->relative_id());
2864958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  active_live_ranges().push_back(range);
2865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::AddToInactive(LiveRange* range) {
2869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Add live range %d:%d to inactive\n", range->TopLevel()->vreg(),
2870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->relative_id());
2871958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  inactive_live_ranges().push_back(range);
2872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2875014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::AddToUnhandledSorted(LiveRange* range) {
2876958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (range == nullptr || range->IsEmpty()) return;
2877014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!range->HasRegisterAssigned() && !range->spilled());
2878014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(allocation_finger_ <= range->Start());
2879958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (int i = static_cast<int>(unhandled_live_ranges().size() - 1); i >= 0;
2880958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier       --i) {
2881014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* cur_range = unhandled_live_ranges().at(i);
2882958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    if (!range->ShouldBeAllocatedBefore(cur_range)) continue;
2883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TRACE("Add live range %d:%d to unhandled at %d\n",
2884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          range->TopLevel()->vreg(), range->relative_id(), i + 1);
2885958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    auto it = unhandled_live_ranges().begin() + (i + 1);
2886958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    unhandled_live_ranges().insert(it, range);
2887958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    DCHECK(UnhandledIsSorted());
2888958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier    return;
2889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Add live range %d:%d to unhandled at start\n",
2891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->TopLevel()->vreg(), range->relative_id());
2892958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  unhandled_live_ranges().insert(unhandled_live_ranges().begin(), range);
2893b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(UnhandledIsSorted());
2894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::AddToUnhandledUnsorted(LiveRange* range) {
2898958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (range == nullptr || range->IsEmpty()) return;
2899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!range->HasRegisterAssigned() && !range->spilled());
2900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Add live range %d:%d to unhandled unsorted at end\n",
2901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->TopLevel()->vreg(), range->relative_id());
2902958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  unhandled_live_ranges().push_back(range);
2903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2906958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic bool UnhandledSortHelper(LiveRange* a, LiveRange* b) {
2907958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  DCHECK(!a->ShouldBeAllocatedBefore(b) || !b->ShouldBeAllocatedBefore(a));
2908958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (a->ShouldBeAllocatedBefore(b)) return false;
2909958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (b->ShouldBeAllocatedBefore(a)) return true;
2910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return a->TopLevel()->vreg() < b->TopLevel()->vreg();
2911b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Sort the unhandled live ranges so that the ranges to be processed first are
2915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// at the end of the array list.  This is convenient for the register allocation
2916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// algorithm because it is efficient to remove elements from the end.
2917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::SortUnhandled() {
2918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Sort unhandled\n");
2919958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  std::sort(unhandled_live_ranges().begin(), unhandled_live_ranges().end(),
2920958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier            &UnhandledSortHelper);
2921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool LinearScanAllocator::UnhandledIsSorted() {
2925958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  size_t len = unhandled_live_ranges().size();
2926958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (size_t i = 1; i < len; i++) {
2927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* a = unhandled_live_ranges().at(i - 1);
2928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* b = unhandled_live_ranges().at(i);
2929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (a->Start() < b->Start()) return false;
2930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return true;
2932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::ActiveToHandled(LiveRange* range) {
2936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RemoveElement(&active_live_ranges(), range);
2937014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Moving live range %d:%d from active to handled\n",
2938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->TopLevel()->vreg(), range->relative_id());
2939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::ActiveToInactive(LiveRange* range) {
2943014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RemoveElement(&active_live_ranges(), range);
2944014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  inactive_live_ranges().push_back(range);
2945014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Moving live range %d:%d from active to inactive\n",
2946014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->TopLevel()->vreg(), range->relative_id());
2947b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2948b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2949b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2950014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::InactiveToHandled(LiveRange* range) {
2951014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RemoveElement(&inactive_live_ranges(), range);
2952014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Moving live range %d:%d from inactive to handled\n",
2953014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->TopLevel()->vreg(), range->relative_id());
2954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2957014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::InactiveToActive(LiveRange* range) {
2958958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  RemoveElement(&inactive_live_ranges(), range);
2959958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  active_live_ranges().push_back(range);
2960014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Moving live range %d:%d from inactive to active\n",
2961014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->TopLevel()->vreg(), range->relative_id());
2962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
2963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2964c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochvoid LinearScanAllocator::GetFPRegisterSet(MachineRepresentation rep,
2965c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                           int* num_regs, int* num_codes,
2966c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                           const int** codes) const {
2967c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  DCHECK(!kSimpleFPAliasing);
2968c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (rep == MachineRepresentation::kFloat32) {
2969c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    *num_regs = data()->config()->num_float_registers();
2970c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    *num_codes = data()->config()->num_allocatable_float_registers();
2971c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    *codes = data()->config()->allocatable_float_codes();
2972c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  } else if (rep == MachineRepresentation::kSimd128) {
2973c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    *num_regs = data()->config()->num_simd128_registers();
2974c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    *num_codes = data()->config()->num_allocatable_simd128_registers();
2975c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    *codes = data()->config()->allocatable_simd128_codes();
2976c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  } else {
2977c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    UNREACHABLE();
2978c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
2979c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
2980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2981c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochvoid LinearScanAllocator::FindFreeRegistersForRange(
2982c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    LiveRange* range, Vector<LifetimePosition> positions) {
298313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  int num_regs = num_registers();
298413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  int num_codes = num_allocatable_registers();
298513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  const int* codes = allocatable_register_codes();
2986c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  MachineRepresentation rep = range->representation();
2987c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (!kSimpleFPAliasing && (rep == MachineRepresentation::kFloat32 ||
2988c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                             rep == MachineRepresentation::kSimd128))
2989c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    GetFPRegisterSet(rep, &num_regs, &num_codes, &codes);
2990c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  DCHECK_GE(positions.length(), num_regs);
2991f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch
299262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  for (int i = 0; i < num_regs; ++i) {
2993c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    positions[i] = LifetimePosition::MaxPosition();
2994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
2995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
2996014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (LiveRange* cur_active : active_live_ranges()) {
299713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    int cur_reg = cur_active->assigned_register();
2998c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    if (kSimpleFPAliasing || !check_fp_aliasing()) {
2999c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      positions[cur_reg] = LifetimePosition::GapFromInstructionIndex(0);
3000c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      TRACE("Register %s is free until pos %d (1)\n", RegisterName(cur_reg),
3001c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            LifetimePosition::GapFromInstructionIndex(0).value());
3002c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    } else {
3003c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      int alias_base_index = -1;
3004c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      int aliases = data()->config()->GetAliases(
3005c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          cur_active->representation(), cur_reg, rep, &alias_base_index);
3006c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1));
3007c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      while (aliases--) {
3008c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        int aliased_reg = alias_base_index + aliases;
3009c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        positions[aliased_reg] = LifetimePosition::GapFromInstructionIndex(0);
3010c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      }
3011c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    }
3012b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3014014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (LiveRange* cur_inactive : inactive_live_ranges()) {
3015c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    DCHECK(cur_inactive->End() > range->Start());
301662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    int cur_reg = cur_inactive->assigned_register();
301762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // No need to carry out intersections, when this register won't be
301862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // interesting to this range anyway.
301962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // TODO(mtrofin): extend to aliased ranges, too.
302062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if ((kSimpleFPAliasing || !check_fp_aliasing()) &&
302162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        positions[cur_reg] < range->Start()) {
302262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      continue;
302362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
302462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
3025c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    LifetimePosition next_intersection = cur_inactive->FirstIntersection(range);
3026b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    if (!next_intersection.IsValid()) continue;
3027c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    if (kSimpleFPAliasing || !check_fp_aliasing()) {
3028c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      positions[cur_reg] = Min(positions[cur_reg], next_intersection);
3029c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      TRACE("Register %s is free until pos %d (2)\n", RegisterName(cur_reg),
3030c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            Min(positions[cur_reg], next_intersection).value());
3031c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    } else {
3032c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      int alias_base_index = -1;
3033c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      int aliases = data()->config()->GetAliases(
3034c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          cur_inactive->representation(), cur_reg, rep, &alias_base_index);
3035c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1));
3036c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      while (aliases--) {
3037c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        int aliased_reg = alias_base_index + aliases;
3038c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        positions[aliased_reg] = Min(positions[aliased_reg], next_intersection);
3039c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      }
3040c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    }
3041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3042c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
3043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3044c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// High-level register allocation summary:
3045c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch//
3046c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// For regular, or hot (i.e. not splinter) ranges, we attempt to first
3047c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// allocate first the preferred (hint) register. If that is not possible,
3048c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// we find a register that's free, and allocate that. If that's not possible,
3049c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// we search for a register to steal from a range that was allocated. The
3050c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// goal is to optimize for throughput by avoiding register-to-memory
3051c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// moves, which are expensive.
3052c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch//
3053c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// For splinters, the goal is to minimize the number of moves. First we try
3054c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// to allocate the preferred register (more discussion follows). Failing that,
3055c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// we bail out and spill as far as we can, unless the first use is at start,
3056c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// case in which we apply the same behavior as we do for regular ranges.
3057c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// If there is no hint, we apply the hot-path behavior.
3058c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch//
3059c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// For the splinter, the hint register may come from:
3060c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch//
3061c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// - the hot path (we set it at splintering time with SetHint). In this case, if
3062c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// we cannot offer the hint register, spilling is better because it's at most
3063c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// 1 move, while trying to find and offer another register is at least 1 move.
3064c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch//
3065c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// - a constraint. If we cannot offer that register, it's because  there is some
3066c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// interference. So offering the hint register up to the interference would
3067c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// result
3068c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// in a move at the interference, plus a move to satisfy the constraint. This is
3069c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// also the number of moves if we spill, with the potential of the range being
3070c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// already spilled and thus saving a move (the spill).
3071c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// Note that this can only be an input constraint, if it were an output one,
3072c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// the range wouldn't be a splinter because it means it'd be defined in a
3073c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// deferred
3074c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// block, and we don't mark those as splinters (they live in deferred blocks
3075c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// only).
3076c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch//
3077c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch// - a phi. The same analysis as in the case of the input constraint applies.
3078c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch//
3079c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochvoid LinearScanAllocator::ProcessCurrentRange(LiveRange* current) {
3080c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  LifetimePosition free_until_pos_buff[RegisterConfiguration::kMaxFPRegisters];
3081c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  Vector<LifetimePosition> free_until_pos(
3082c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      free_until_pos_buff, RegisterConfiguration::kMaxFPRegisters);
3083c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  FindFreeRegistersForRange(current, free_until_pos);
3084c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (!TryAllocatePreferredReg(current, free_until_pos)) {
3085c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    if (current->TopLevel()->IsSplinter()) {
3086c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (TrySplitAndSpillSplinter(current)) return;
3087c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    }
3088c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    if (!TryAllocateFreeReg(current, free_until_pos)) {
3089c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      AllocateBlockedReg(current);
3090c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    }
3091c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
3092c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (current->HasRegisterAssigned()) {
3093c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    AddToActive(current);
3094c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  }
3095c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
3096c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
3097c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochbool LinearScanAllocator::TryAllocatePreferredReg(
3098c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    LiveRange* current, const Vector<LifetimePosition>& free_until_pos) {
3099014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int hint_register;
3100014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (current->FirstHintPosition(&hint_register) != nullptr) {
3101014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TRACE(
3102014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        "Found reg hint %s (free until [%d) for live range %d:%d (end %d[).\n",
3103014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        RegisterName(hint_register), free_until_pos[hint_register].value(),
3104014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        current->TopLevel()->vreg(), current->relative_id(),
3105014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        current->End().value());
3106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // The desired register is free until the end of the current live range.
3108014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (free_until_pos[hint_register] >= current->End()) {
3109014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      TRACE("Assigning preferred reg %s to live range %d:%d\n",
3110014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            RegisterName(hint_register), current->TopLevel()->vreg(),
3111014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            current->relative_id());
3112014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SetLiveRangeAssignedRegister(current, hint_register);
3113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      return true;
3114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3116c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  return false;
3117c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch}
3118c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
3119c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdochbool LinearScanAllocator::TryAllocateFreeReg(
3120c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    LiveRange* current, const Vector<LifetimePosition>& free_until_pos) {
3121c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  int num_regs = 0;  // used only for the call to GetFPRegisterSet.
3122c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  int num_codes = num_allocatable_registers();
3123c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  const int* codes = allocatable_register_codes();
3124c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  MachineRepresentation rep = current->representation();
3125c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (!kSimpleFPAliasing && (rep == MachineRepresentation::kFloat32 ||
312662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                             rep == MachineRepresentation::kSimd128)) {
3127c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    GetFPRegisterSet(rep, &num_regs, &num_codes, &codes);
312862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  }
3129c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch
3130c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  DCHECK_GE(free_until_pos.length(), num_codes);
3131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Find the register which stays free for the longest time.
313313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  int reg = codes[0];
313413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  for (int i = 1; i < num_codes; ++i) {
313513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    int code = codes[i];
3136014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (free_until_pos[code] > free_until_pos[reg]) {
3137014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      reg = code;
3138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3141014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition pos = free_until_pos[reg];
3142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3143014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (pos <= current->Start()) {
3144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // All registers are blocked.
3145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return false;
3146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3148014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (pos < current->End()) {
3149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Register reg is available at the range start but becomes blocked before
3150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // the range end. Split current at position where it becomes blocked.
3151014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* tail = SplitRangeAt(current, pos);
3152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AddToUnhandledSorted(tail);
3153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
315513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  // Register reg is available at the range start and is free until the range
315613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  // end.
3157014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(pos >= current->End());
3158014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Assigning free reg %s to live range %d:%d\n", RegisterName(reg),
3159014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        current->TopLevel()->vreg(), current->relative_id());
3160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SetLiveRangeAssignedRegister(current, reg);
3161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  return true;
3163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3165014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::AllocateBlockedReg(LiveRange* current) {
3166014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePosition* register_use = current->NextRegisterPosition(current->Start());
3167958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  if (register_use == nullptr) {
3168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // There is no use in the current live range that requires a register.
3169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // We can just spill it.
3170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Spill(current);
3171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    return;
3172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
317413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  int num_regs = num_registers();
317513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  int num_codes = num_allocatable_registers();
317613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  const int* codes = allocatable_register_codes();
3177c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  MachineRepresentation rep = current->representation();
3178c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch  if (!kSimpleFPAliasing && (rep == MachineRepresentation::kFloat32 ||
3179c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                             rep == MachineRepresentation::kSimd128))
3180c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    GetFPRegisterSet(rep, &num_regs, &num_codes, &codes);
318113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
318262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // use_pos keeps track of positions a register/alias is used at.
318362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // block_pos keeps track of positions where a register/alias is blocked
318462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // from.
3185bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  LifetimePosition use_pos[RegisterConfiguration::kMaxFPRegisters];
3186bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  LifetimePosition block_pos[RegisterConfiguration::kMaxFPRegisters];
318713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  for (int i = 0; i < num_regs; i++) {
3188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    use_pos[i] = block_pos[i] = LifetimePosition::MaxPosition();
3189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3191014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (LiveRange* range : active_live_ranges()) {
3192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int cur_reg = range->assigned_register();
319313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    bool is_fixed_or_cant_spill =
319413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        range->TopLevel()->IsFixed() || !range->CanBeSpilled(current->Start());
3195c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    if (kSimpleFPAliasing || !check_fp_aliasing()) {
3196c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (is_fixed_or_cant_spill) {
3197c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        block_pos[cur_reg] = use_pos[cur_reg] =
3198c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            LifetimePosition::GapFromInstructionIndex(0);
3199f91f0611dbaf29ca0f1d4aecb357ce243a19d2faBen Murdoch      } else {
320062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        DCHECK_NE(LifetimePosition::GapFromInstructionIndex(0),
320162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                  block_pos[cur_reg]);
3202c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        use_pos[cur_reg] =
3203c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch            range->NextLifetimePositionRegisterIsBeneficial(current->Start());
3204c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      }
3205c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    } else {
3206c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      int alias_base_index = -1;
3207c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      int aliases = data()->config()->GetAliases(
3208c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          range->representation(), cur_reg, rep, &alias_base_index);
3209c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1));
3210c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      while (aliases--) {
3211c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        int aliased_reg = alias_base_index + aliases;
3212c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        if (is_fixed_or_cant_spill) {
3213c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          block_pos[aliased_reg] = use_pos[aliased_reg] =
3214c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch              LifetimePosition::GapFromInstructionIndex(0);
3215c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        } else {
3216c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          use_pos[aliased_reg] =
321762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch              Min(block_pos[aliased_reg],
321862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                  range->NextLifetimePositionRegisterIsBeneficial(
321962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch                      current->Start()));
3220c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        }
3221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
3222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3225014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (LiveRange* range : inactive_live_ranges()) {
3226014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(range->End() > current->Start());
3227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    int cur_reg = range->assigned_register();
322813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    bool is_fixed = range->TopLevel()->IsFixed();
322962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
323062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // Don't perform costly intersections if they are guaranteed to not update
323162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // block_pos or use_pos.
323262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // TODO(mtrofin): extend to aliased ranges, too.
323362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if ((kSimpleFPAliasing || !check_fp_aliasing())) {
323462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      if (is_fixed) {
323562ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        if (block_pos[cur_reg] < range->Start()) continue;
323662ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      } else {
323762ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch        if (use_pos[cur_reg] < range->Start()) continue;
323862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      }
323962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    }
324062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
324162ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    LifetimePosition next_intersection = range->FirstIntersection(current);
324262ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    if (!next_intersection.IsValid()) continue;
324362ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch
3244c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    if (kSimpleFPAliasing || !check_fp_aliasing()) {
3245c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (is_fixed) {
3246c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        block_pos[cur_reg] = Min(block_pos[cur_reg], next_intersection);
3247c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        use_pos[cur_reg] = Min(block_pos[cur_reg], use_pos[cur_reg]);
3248c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      } else {
3249c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        use_pos[cur_reg] = Min(use_pos[cur_reg], next_intersection);
3250c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      }
3251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    } else {
3252c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      int alias_base_index = -1;
3253c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      int aliases = data()->config()->GetAliases(
3254c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          range->representation(), cur_reg, rep, &alias_base_index);
3255c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      DCHECK(aliases > 0 || (aliases == 0 && alias_base_index == -1));
3256c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      while (aliases--) {
3257c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        int aliased_reg = alias_base_index + aliases;
3258c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        if (is_fixed) {
3259c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          block_pos[aliased_reg] =
3260c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch              Min(block_pos[aliased_reg], next_intersection);
3261c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          use_pos[aliased_reg] =
3262c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch              Min(block_pos[aliased_reg], use_pos[aliased_reg]);
3263c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        } else {
3264c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch          use_pos[aliased_reg] = Min(use_pos[aliased_reg], next_intersection);
3265c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        }
3266c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      }
3267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
327013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  int reg = codes[0];
327113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch  for (int i = 1; i < num_codes; ++i) {
327213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    int code = codes[i];
3273014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (use_pos[code] > use_pos[reg]) {
3274014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      reg = code;
3275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
327862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  if (use_pos[reg] < register_use->pos()) {
327962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // If there is a gap position before the next register use, we can
328062ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch    // spill until there. The gap position will then fit the fill move.
3281bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (LifetimePosition::ExistsGapPositionBetween(current->Start(),
3282bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                                                   register_use->pos())) {
3283bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      SpillBetween(current, current->Start(), register_use->pos());
328462ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch      return;
3285bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    }
3286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
328862ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // We couldn't spill until the next register use. Split before the register
328962ed631aa0ff23db68a47fd423efa9c019ff2c9eBen Murdoch  // is blocked, if applicable.
3290014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (block_pos[reg] < current->End()) {
3291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Register becomes blocked before the current range end. Split before that
3292b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // position.
3293014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* tail =
3294014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        SplitBetween(current, current->Start(), block_pos[reg].Start());
3295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AddToUnhandledSorted(tail);
3296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // Register reg is not blocked for the whole range.
3299014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(block_pos[reg] >= current->End());
3300014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  TRACE("Assigning blocked reg %s to live range %d:%d\n", RegisterName(reg),
3301014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        current->TopLevel()->vreg(), current->relative_id());
3302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SetLiveRangeAssignedRegister(current, reg);
3303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // This register was not free. Thus we need to find and spill
3305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // parts of active and inactive live regions that use the same register
3306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  // at the same lifetime positions as current.
3307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SplitAndSpillIntersecting(current);
3308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3311014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::SplitAndSpillIntersecting(LiveRange* current) {
3312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  DCHECK(current->HasRegisterAssigned());
3313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  int reg = current->assigned_register();
3314014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition split_pos = current->Start();
3315958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (size_t i = 0; i < active_live_ranges().size(); ++i) {
3316014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* range = active_live_ranges()[i];
3317c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    if (kSimpleFPAliasing || !check_fp_aliasing()) {
3318c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (range->assigned_register() != reg) continue;
3319c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    } else {
3320c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (!data()->config()->AreAliases(current->representation(), reg,
3321c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                        range->representation(),
3322c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                        range->assigned_register())) {
3323c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        continue;
3324c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      }
3325c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    }
332613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
332713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    UsePosition* next_pos = range->NextRegisterPosition(current->Start());
332813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    LifetimePosition spill_pos = FindOptimalSpillingPos(range, split_pos);
332913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (next_pos == nullptr) {
333013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      SpillAfter(range, spill_pos);
333113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    } else {
333213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      // When spilling between spill_pos and next_pos ensure that the range
333313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      // remains spilled at least until the start of the current live range.
333413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      // This guarantees that we will not introduce new unhandled ranges that
333513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      // start before the current range as this violates allocation invariants
333613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      // and will lead to an inconsistent state of active and inactive
333713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      // live-ranges: ranges are allocated in order of their start positions,
333813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      // ranges are retired from active/inactive when the start of the
333913e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      // current live-range is larger than their end.
334013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      DCHECK(LifetimePosition::ExistsGapPositionBetween(current->Start(),
334113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch                                                        next_pos->pos()));
334213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      SpillBetweenUntil(range, spill_pos, current->Start(), next_pos->pos());
334313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    }
334413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    ActiveToHandled(range);
334513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    --i;
3346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3348958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier  for (size_t i = 0; i < inactive_live_ranges().size(); ++i) {
3349014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* range = inactive_live_ranges()[i];
3350014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(range->End() > current->Start());
335113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (range->TopLevel()->IsFixed()) continue;
3352c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    if (kSimpleFPAliasing || !check_fp_aliasing()) {
3353c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (range->assigned_register() != reg) continue;
3354c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    } else {
3355c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch      if (!data()->config()->AreAliases(current->representation(), reg,
3356c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                        range->representation(),
3357c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch                                        range->assigned_register()))
3358c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch        continue;
3359c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    }
336013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch
336113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    LifetimePosition next_intersection = range->FirstIntersection(current);
336213e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch    if (next_intersection.IsValid()) {
336313e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      UsePosition* next_pos = range->NextRegisterPosition(current->Start());
336413e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      if (next_pos == nullptr) {
336513e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        SpillAfter(range, split_pos);
336613e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      } else {
336713e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        next_intersection = Min(next_intersection, next_pos->pos());
336813e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch        SpillBetween(range, split_pos, next_intersection);
3369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch      }
337013e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      InactiveToHandled(range);
337113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      --i;
3372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3377014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool LinearScanAllocator::TryReuseSpillForPhi(TopLevelLiveRange* range) {
3378014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (!range->is_phi()) return false;
3379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3380014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!range->HasSpillOperand());
3381014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  RegisterAllocationData::PhiMapValue* phi_map_value =
3382014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      data()->GetPhiMapValueFor(range);
3383014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const PhiInstruction* phi = phi_map_value->phi();
3384014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const InstructionBlock* block = phi_map_value->block();
3385014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Count the number of spilled operands.
3386014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t spilled_count = 0;
3387014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LiveRange* first_op = nullptr;
3388014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < phi->operands().size(); i++) {
3389014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int op = phi->operands()[i];
3390014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* op_range = data()->GetOrCreateLiveRangeFor(op);
3391014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!op_range->TopLevel()->HasSpillRange()) continue;
3392014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const InstructionBlock* pred =
3393014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        code()->InstructionBlockAt(block->predecessors()[i]);
3394014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition pred_end =
3395014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        LifetimePosition::InstructionFromInstructionIndex(
3396014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            pred->last_instruction_index());
3397014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    while (op_range != nullptr && !op_range->CanCover(pred_end)) {
3398014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      op_range = op_range->next();
3399014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3400014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (op_range != nullptr && op_range->spilled()) {
3401014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      spilled_count++;
3402014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (first_op == nullptr) {
3403014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        first_op = op_range->TopLevel();
3404014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3405014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3406014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3408014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Only continue if more than half of the operands are spilled.
3409014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (spilled_count * 2 <= phi->operands().size()) {
3410014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return false;
3411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3413014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Try to merge the spilled operands and count the number of merged spilled
3414014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // operands.
3415014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(first_op != nullptr);
3416014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  SpillRange* first_op_spill = first_op->TopLevel()->GetSpillRange();
3417014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  size_t num_merged = 1;
3418014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 1; i < phi->operands().size(); i++) {
3419014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int op = phi->operands()[i];
3420014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    TopLevelLiveRange* op_range = data()->live_ranges()[op];
3421014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!op_range->HasSpillRange()) continue;
3422014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SpillRange* op_spill = op_range->GetSpillRange();
3423014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (op_spill == first_op_spill || first_op_spill->TryMerge(op_spill)) {
3424014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      num_merged++;
3425014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3428014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Only continue if enough operands could be merged to the
3429014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // same spill slot.
3430014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (num_merged * 2 <= phi->operands().size() ||
3431014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      AreUseIntervalsIntersecting(first_op_spill->interval(),
3432014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                  range->first_interval())) {
3433014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return false;
3434014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3436014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // If the range does not need register soon, spill it to the merged
3437014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // spill range.
3438014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LifetimePosition next_pos = range->Start();
3439014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (next_pos.IsGapPosition()) next_pos = next_pos.NextStart();
3440014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  UsePosition* pos = range->NextUsePositionRegisterIsBeneficial(next_pos);
3441014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (pos == nullptr) {
3442014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SpillRange* spill_range =
3443014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->TopLevel()->HasSpillRange()
3444014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            ? range->TopLevel()->GetSpillRange()
3445014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            : data()->AssignSpillRangeToLiveRange(range->TopLevel());
3446014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool merged = first_op_spill->TryMerge(spill_range);
3447bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (!merged) return false;
3448014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    Spill(range);
3449014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return true;
3450014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  } else if (pos->pos() > range->Start().NextStart()) {
3451014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SpillRange* spill_range =
3452014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->TopLevel()->HasSpillRange()
3453014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            ? range->TopLevel()->GetSpillRange()
3454014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            : data()->AssignSpillRangeToLiveRange(range->TopLevel());
3455014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool merged = first_op_spill->TryMerge(spill_range);
3456bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch    if (!merged) return false;
3457014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SpillBetween(range, range->Start(), pos->pos());
3458014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(UnhandledIsSorted());
3459014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    return true;
3460014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3461014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return false;
3462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3465014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::SpillAfter(LiveRange* range, LifetimePosition pos) {
3466014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LiveRange* second_part = SplitRangeAt(range, pos);
3467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  Spill(second_part);
3468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3470b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3471014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::SpillBetween(LiveRange* range, LifetimePosition start,
3472014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                       LifetimePosition end) {
3473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  SpillBetweenUntil(range, start, start, end);
3474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3477014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LinearScanAllocator::SpillBetweenUntil(LiveRange* range,
3478014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            LifetimePosition start,
3479014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            LifetimePosition until,
3480014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                            LifetimePosition end) {
3481014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  CHECK(start < end);
3482014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LiveRange* second_part = SplitRangeAt(range, start);
3483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3484014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (second_part->Start() < end) {
3485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // The split result intersects with [start, end[.
3486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Split it at position between ]start+1, end[, spill the middle part
3487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // and put the rest to unhandled.
3488014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LifetimePosition third_part_end = end.PrevStart().End();
3489014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (data()->IsBlockBoundary(end.Start())) {
3490014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      third_part_end = end.Start();
3491014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3492014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* third_part = SplitBetween(
3493014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        second_part, Max(second_part->Start().End(), until), third_part_end);
3494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    DCHECK(third_part != second_part);
3496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    Spill(second_part);
3498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AddToUnhandledSorted(third_part);
3499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
3500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // The split result does not intersect with [start, end[.
3501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    // Nothing to spill. Just put it to unhandled as whole.
3502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    AddToUnhandledSorted(second_part);
3503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3507014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochSpillSlotLocator::SpillSlotLocator(RegisterAllocationData* data)
3508014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : data_(data) {}
3509014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3510014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3511014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid SpillSlotLocator::LocateSpillSlots() {
3512014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const InstructionSequence* code = data()->code();
3513014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (TopLevelLiveRange* range : data()->live_ranges()) {
3514014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range == nullptr || range->IsEmpty()) continue;
3515014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // We care only about ranges which spill in the frame.
35163b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    if (!range->HasSpillRange() || range->IsSpilledOnlyInDeferredBlocks()) {
35173b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      continue;
35183b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    }
35193b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    TopLevelLiveRange::SpillMoveInsertionList* spills =
35203b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch        range->GetSpillMoveInsertionLocations();
35213b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    DCHECK_NOT_NULL(spills);
35223b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    for (; spills != nullptr; spills = spills->next) {
35233b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch      code->GetInstructionBlock(spills->gap_index)->mark_needs_frame();
3524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch    }
3525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3529014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochOperandAssigner::OperandAssigner(RegisterAllocationData* data) : data_(data) {}
3530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3532014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid OperandAssigner::AssignSpillSlots() {
3533014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ZoneVector<SpillRange*>& spill_ranges = data()->spill_ranges();
3534014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Merge disjoint spill ranges
3535014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (size_t i = 0; i < spill_ranges.size(); ++i) {
3536014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    SpillRange* range = spill_ranges[i];
3537014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range == nullptr) continue;
3538014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range->IsEmpty()) continue;
3539014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (size_t j = i + 1; j < spill_ranges.size(); ++j) {
3540014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      SpillRange* other = spill_ranges[j];
3541014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (other != nullptr && !other->IsEmpty()) {
3542014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        range->TryMerge(other);
3543014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3544014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3545014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3546014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Allocate slots for the merged spill ranges.
3547014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (SpillRange* range : spill_ranges) {
3548014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range == nullptr || range->IsEmpty()) continue;
3549014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Allocate a new operand referring to the spill slot.
3550014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!range->HasSlot()) {
355113e2dadd00298019ed862f2b2fc5068bba730bcfBen Murdoch      int index = data()->frame()->AllocateSpillSlot(range->byte_width());
3552014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      range->set_assigned_slot(index);
3553014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3554014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3555014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3556014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3557014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3558014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid OperandAssigner::CommitAssignment() {
3559014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (TopLevelLiveRange* top_range : data()->live_ranges()) {
3560014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (top_range == nullptr || top_range->IsEmpty()) continue;
3561014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand spill_operand;
3562014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (top_range->HasSpillOperand()) {
3563014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      spill_operand = *top_range->TopLevel()->GetSpillOperand();
3564014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    } else if (top_range->TopLevel()->HasSpillRange()) {
3565014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      spill_operand = top_range->TopLevel()->GetSpillRangeOperand();
3566014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3567014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (top_range->is_phi()) {
3568014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      data()->GetPhiMapValueFor(top_range)->CommitAssignment(
3569014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          top_range->GetAssignedOperand());
3570014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3571014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (LiveRange* range = top_range; range != nullptr;
3572014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         range = range->next()) {
3573014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionOperand assigned = range->GetAssignedOperand();
3574014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      range->ConvertUsesToOperand(assigned, spill_operand);
3575014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3576014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3577014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!spill_operand.IsInvalid()) {
3578014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // If this top level range has a child spilled in a deferred block, we use
3579014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // the range and control flow connection mechanism instead of spilling at
3580014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // definition. Refer to the ConnectLiveRanges and ResolveControlFlow
3581014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // phases. Normally, when we spill at definition, we do not insert a
3582014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // connecting move when a successor child range is spilled - because the
3583014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // spilled range picks up its value from the slot which was assigned at
3584014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // definition. For ranges that are determined to spill only in deferred
3585109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // blocks, we let ConnectLiveRanges and ResolveControlFlow find the blocks
3586109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // where a spill operand is expected, and then finalize by inserting the
3587109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // spills in the deferred blocks dominators.
3588109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (!top_range->IsSpilledOnlyInDeferredBlocks()) {
3589014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // Spill at definition if the range isn't spilled only in deferred
3590014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        // blocks.
3591014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        top_range->CommitSpillMoves(
3592014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            data()->code(), spill_operand,
3593014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            top_range->has_slot_use() || top_range->spilled());
3594014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3595014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3596014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3597014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3598014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3599014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3600014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochReferenceMapPopulator::ReferenceMapPopulator(RegisterAllocationData* data)
3601014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : data_(data) {}
3602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3603b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3604014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool ReferenceMapPopulator::SafePointsAreInOrder() const {
3605014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int safe_point = 0;
3606014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (ReferenceMap* map : *data()->code()->reference_maps()) {
3607014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (safe_point > map->instruction_position()) return false;
3608014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    safe_point = map->instruction_position();
3609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3610014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return true;
3611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3613b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3614014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid ReferenceMapPopulator::PopulateReferenceMaps() {
3615014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(SafePointsAreInOrder());
3616014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Map all delayed references.
3617014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (RegisterAllocationData::DelayedReference& delayed_reference :
3618014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch       data()->delayed_references()) {
3619014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    delayed_reference.map->RecordReference(
3620014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        AllocatedOperand::cast(*delayed_reference.operand));
3621014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3622014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Iterate over all safe point positions and record a pointer
3623014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // for all spilled live ranges at this point.
3624014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int last_range_start = 0;
3625014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  const ReferenceMapDeque* reference_maps = data()->code()->reference_maps();
3626014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ReferenceMapDeque::const_iterator first_it = reference_maps->begin();
3627014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (TopLevelLiveRange* range : data()->live_ranges()) {
3628014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range == nullptr) continue;
3629014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Skip non-reference values.
3630014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (!data()->IsReference(range)) continue;
3631014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Skip empty live ranges.
3632014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range->IsEmpty()) continue;
3633014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (range->has_preassigned_slot()) continue;
3634014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3635014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Find the extent of the range and its children.
3636014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int start = range->Start().ToInstructionIndex();
3637014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    int end = 0;
3638014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (LiveRange* cur = range; cur != nullptr; cur = cur->next()) {
3639014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LifetimePosition this_end = cur->End();
3640014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (this_end.ToInstructionIndex() > end)
3641014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        end = this_end.ToInstructionIndex();
3642014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(cur->Start().ToInstructionIndex() >= start);
3643014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3644014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3645014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Most of the ranges are in order, but not all.  Keep an eye on when they
3646014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // step backwards and reset the first_it so we don't miss any safe points.
3647014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (start < last_range_start) first_it = reference_maps->begin();
3648014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    last_range_start = start;
3649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3650014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Step across all the safe points that are before the start of this range,
3651014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // recording how far we step in order to save doing this for the next range.
3652014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (; first_it != reference_maps->end(); ++first_it) {
3653014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ReferenceMap* map = *first_it;
3654014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (map->instruction_position() >= start) break;
3655014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3656014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3657014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    InstructionOperand spill_operand;
3658014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (((range->HasSpillOperand() &&
3659014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          !range->GetSpillOperand()->IsConstant()) ||
3660014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         range->HasSpillRange())) {
3661014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (range->HasSpillOperand()) {
3662014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        spill_operand = *range->GetSpillOperand();
3663014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
3664014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        spill_operand = range->GetSpillRangeOperand();
3665014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3666014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(spill_operand.IsStackSlot());
3667f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch      DCHECK(CanBeTaggedPointer(
3668f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch          AllocatedOperand::cast(spill_operand).representation()));
3669014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3671014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* cur = range;
3672014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Step through the safe points to see whether they are in the range.
3673014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (auto it = first_it; it != reference_maps->end(); ++it) {
3674014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ReferenceMap* map = *it;
3675014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int safe_point = map->instruction_position();
3676014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3677014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // The safe points are sorted so we can stop searching here.
3678014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (safe_point - 1 > end) break;
3679014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3680014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Advance to the next active range that covers the current
3681014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // safe point position.
3682014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LifetimePosition safe_point_pos =
3683014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          LifetimePosition::InstructionFromInstructionIndex(safe_point);
3684014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3685014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Search for the child range (cur) that covers safe_point_pos. If we
3686014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // don't find it before the children pass safe_point_pos, keep cur at
3687014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // the last child, because the next safe_point_pos may be covered by cur.
3688014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // This may happen if cur has more than one interval, and the current
3689014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // safe_point_pos is in between intervals.
3690014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // For that reason, cur may be at most the last child.
3691014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK_NOT_NULL(cur);
3692014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK(safe_point_pos >= cur->Start() || range == cur);
3693014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bool found = false;
3694014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      while (!found) {
3695014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (cur->Covers(safe_point_pos)) {
3696014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          found = true;
3697014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else {
3698014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          LiveRange* next = cur->next();
3699014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          if (next == nullptr || next->Start() > safe_point_pos) {
3700014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            break;
3701014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          }
3702014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          cur = next;
3703014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3704014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3705014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3706014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!found) {
3707014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        continue;
3708014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3709014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3710014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Check if the live range is spilled and the safe point is after
3711014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // the spill position.
3712014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int spill_index = range->IsSpilledOnlyInDeferredBlocks()
3713014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            ? cur->Start().ToInstructionIndex()
3714014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                            : range->spill_start_index();
3715014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3716014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!spill_operand.IsInvalid() && safe_point >= spill_index) {
3717014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        TRACE("Pointer for range %d (spilled at %d) at safe point %d\n",
3718014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              range->vreg(), spill_index, safe_point);
3719014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        map->RecordReference(AllocatedOperand::cast(spill_operand));
3720014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3721014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3722014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!cur->spilled()) {
3723014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        TRACE(
3724014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            "Pointer in register for range %d:%d (start at %d) "
3725014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            "at safe point %d\n",
3726014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            range->vreg(), cur->relative_id(), cur->Start().value(),
3727014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            safe_point);
3728014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        InstructionOperand operand = cur->GetAssignedOperand();
3729014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK(!operand.IsStackSlot());
3730f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch        DCHECK(CanBeTaggedPointer(
3731f3b273f5e6ffd2f6ba1c18a27a17db41dfb113c3Ben Murdoch            AllocatedOperand::cast(operand).representation()));
3732014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        map->RecordReference(AllocatedOperand::cast(operand));
3733014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3734014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3735014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3736014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3737014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3738014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3739014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben MurdochLiveRangeConnector::LiveRangeConnector(RegisterAllocationData* data)
3740014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    : data_(data) {}
3741014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3742014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3743014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochbool LiveRangeConnector::CanEagerlyResolveControlFlow(
3744014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    const InstructionBlock* block) const {
3745014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (block->PredecessorCount() != 1) return false;
3746014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return block->predecessors()[0].IsNext(block->rpo_number());
3747014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3748014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3749014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3750014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRangeConnector::ResolveControlFlow(Zone* local_zone) {
3751014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Lazily linearize live ranges in memory for fast lookup.
3752014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  LiveRangeFinder finder(data(), local_zone);
3753014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ZoneVector<BitVector*>& live_in_sets = data()->live_in_sets();
3754014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (const InstructionBlock* block : code()->instruction_blocks()) {
3755014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (CanEagerlyResolveControlFlow(block)) continue;
3756014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    BitVector* live = live_in_sets[block->rpo_number().ToInt()];
3757014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    BitVector::Iterator iterator(live);
3758014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    while (!iterator.Done()) {
3759bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      int vreg = iterator.Current();
3760bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch      LiveRangeBoundArray* array = finder.ArrayFor(vreg);
3761014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (const RpoNumber& pred : block->predecessors()) {
3762014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        FindResult result;
3763014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        const InstructionBlock* pred_block = code()->InstructionBlockAt(pred);
3764014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (!array->FindConnectableSubranges(block, pred_block, &result)) {
3765014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          continue;
3766014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3767014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        InstructionOperand pred_op = result.pred_cover_->GetAssignedOperand();
3768014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        InstructionOperand cur_op = result.cur_cover_->GetAssignedOperand();
3769014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (pred_op.Equals(cur_op)) continue;
3770109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        if (!pred_op.IsAnyRegister() && cur_op.IsAnyRegister()) {
3771109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          // We're doing a reload.
3772109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          // We don't need to, if:
3773109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          // 1) there's no register use in this block, and
3774109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          // 2) the range ends before the block does, and
3775109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          // 3) we don't have a successor, or the successor is spilled.
3776109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          LifetimePosition block_start =
3777109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch              LifetimePosition::GapFromInstructionIndex(block->code_start());
3778109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          LifetimePosition block_end =
3779109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch              LifetimePosition::GapFromInstructionIndex(block->code_end());
3780109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          const LiveRange* current = result.cur_cover_;
3781109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          const LiveRange* successor = current->next();
3782109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          if (current->End() < block_end &&
3783109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch              (successor == nullptr || successor->spilled())) {
3784109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            // verify point 1: no register use. We can go to the end of the
3785109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            // range, since it's all within the block.
3786109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3787109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            bool uses_reg = false;
3788109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            for (const UsePosition* use = current->NextUsePosition(block_start);
3789109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                 use != nullptr; use = use->next()) {
3790109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch              if (use->operand()->IsAnyRegister()) {
3791109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                uses_reg = true;
3792109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                break;
3793109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch              }
3794109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            }
3795109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            if (!uses_reg) continue;
3796109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          }
3797109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          if (current->TopLevel()->IsSpilledOnlyInDeferredBlocks() &&
3798109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch              pred_block->IsDeferred()) {
3799109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            // The spill location should be defined in pred_block, so add
3800109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            // pred_block to the list of blocks requiring a spill operand.
3801109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            current->TopLevel()->GetListOfBlocksRequiringSpillOperands()->Add(
3802109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                pred_block->rpo_number().ToInt());
3803109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          }
3804109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        }
3805014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        int move_loc = ResolveControlFlow(block, cur_op, pred_block, pred_op);
3806014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        USE(move_loc);
3807014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        DCHECK_IMPLIES(
3808014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            result.cur_cover_->TopLevel()->IsSpilledOnlyInDeferredBlocks() &&
3809014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                !(pred_op.IsAnyRegister() && cur_op.IsAnyRegister()),
3810014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            code()->GetInstructionBlock(move_loc)->IsDeferred());
3811014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3812014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      iterator.Advance();
3813014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3814014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3815109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3816109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // At this stage, we collected blocks needing a spill operand from
3817109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // ConnectRanges and from ResolveControlFlow. Time to commit the spills for
3818109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // deferred blocks.
3819109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  for (TopLevelLiveRange* top : data()->live_ranges()) {
3820109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (top == nullptr || top->IsEmpty() ||
3821109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        !top->IsSpilledOnlyInDeferredBlocks())
3822109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      continue;
3823109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    CommitSpillsInDeferredBlocks(top, finder.ArrayFor(top->vreg()), local_zone);
3824109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
3825014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3826014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3827014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3828014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochint LiveRangeConnector::ResolveControlFlow(const InstructionBlock* block,
3829014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           const InstructionOperand& cur_op,
3830014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           const InstructionBlock* pred,
3831014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                                           const InstructionOperand& pred_op) {
3832014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DCHECK(!pred_op.Equals(cur_op));
3833014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  int gap_index;
3834014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  Instruction::GapPosition position;
3835014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (block->PredecessorCount() == 1) {
3836014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    gap_index = block->first_instruction_index();
3837014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    position = Instruction::START;
3838b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  } else {
3839014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(pred->SuccessorCount() == 1);
3840014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    DCHECK(!code()
3841014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                ->InstructionAt(pred->last_instruction_index())
3842014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch                ->HasReferenceMap());
3843014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    gap_index = pred->last_instruction_index();
3844014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    position = Instruction::END;
3845014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3846014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  data()->AddGapMove(gap_index, position, pred_op, cur_op);
3847014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  return gap_index;
3848014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch}
3849014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3850014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdochvoid LiveRangeConnector::ConnectRanges(Zone* local_zone) {
3851014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  DelayedInsertionMap delayed_insertion_map(local_zone);
3852014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (TopLevelLiveRange* top_range : data()->live_ranges()) {
3853014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (top_range == nullptr) continue;
3854014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool connect_spilled = top_range->IsSpilledOnlyInDeferredBlocks();
3855014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    LiveRange* first_range = top_range;
3856014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    for (LiveRange *second_range = first_range->next(); second_range != nullptr;
3857014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch         first_range = second_range, second_range = second_range->next()) {
3858014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      LifetimePosition pos = second_range->Start();
3859014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Add gap move if the two live ranges touch and there is no block
3860014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // boundary.
3861109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (second_range->spilled()) continue;
3862014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (first_range->End() != pos) continue;
3863014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (data()->IsBlockBoundary(pos) &&
3864014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          !CanEagerlyResolveControlFlow(GetInstructionBlock(code(), pos))) {
3865014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        continue;
3866014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3867014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionOperand prev_operand = first_range->GetAssignedOperand();
3868014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      InstructionOperand cur_operand = second_range->GetAssignedOperand();
3869014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (prev_operand.Equals(cur_operand)) continue;
3870014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      bool delay_insertion = false;
3871014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      Instruction::GapPosition gap_pos;
3872014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      int gap_index = pos.ToInstructionIndex();
3873109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (connect_spilled && !prev_operand.IsAnyRegister() &&
3874109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          cur_operand.IsAnyRegister()) {
3875109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        const InstructionBlock* block = code()->GetInstructionBlock(gap_index);
3876109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        DCHECK(block->IsDeferred());
3877109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        // Performing a reload in this block, meaning the spill operand must
3878109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        // be defined here.
3879109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        top_range->GetListOfBlocksRequiringSpillOperands()->Add(
3880109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            block->rpo_number().ToInt());
3881109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
3882109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3883014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (pos.IsGapPosition()) {
3884014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        gap_pos = pos.IsStart() ? Instruction::START : Instruction::END;
3885014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
3886014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        if (pos.IsStart()) {
3887014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          delay_insertion = true;
3888014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        } else {
3889014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          gap_index++;
3890014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        }
3891014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        gap_pos = delay_insertion ? Instruction::END : Instruction::START;
3892014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3893109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      // Reloads or spills for spilled in deferred blocks ranges must happen
3894014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // only in deferred blocks.
3895014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      DCHECK_IMPLIES(
3896014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          connect_spilled &&
3897014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              !(prev_operand.IsAnyRegister() && cur_operand.IsAnyRegister()),
3898014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          code()->GetInstructionBlock(gap_index)->IsDeferred());
3899014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3900014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      ParallelMove* move =
3901014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch          code()->InstructionAt(gap_index)->GetOrCreateParallelMove(
3902014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch              gap_pos, code_zone());
3903014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (!delay_insertion) {
3904014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        move->AddMove(prev_operand, cur_operand);
3905014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      } else {
3906014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        delayed_insertion_map.insert(
3907014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch            std::make_pair(std::make_pair(move, prev_operand), cur_operand));
3908014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3909014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3910014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  }
3911014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  if (delayed_insertion_map.empty()) return;
3912014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  // Insert all the moves which should occur after the stored move.
3913014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ZoneVector<MoveOperands*> to_insert(local_zone);
3914014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ZoneVector<MoveOperands*> to_eliminate(local_zone);
3915014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  to_insert.reserve(4);
3916014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  to_eliminate.reserve(4);
3917014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  ParallelMove* moves = delayed_insertion_map.begin()->first.first;
3918014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch  for (auto it = delayed_insertion_map.begin();; ++it) {
3919014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    bool done = it == delayed_insertion_map.end();
3920014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    if (done || it->first.first != moves) {
3921014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Commit the MoveOperands for current ParallelMove.
3922014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (MoveOperands* move : to_eliminate) {
3923014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        move->Eliminate();
3924014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3925014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      for (MoveOperands* move : to_insert) {
3926014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        moves->push_back(move);
3927014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      }
3928014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      if (done) break;
3929014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      // Reset state.
3930014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      to_eliminate.clear();
3931014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      to_insert.clear();
3932014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch      moves = it->first.first;
3933014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    }
3934014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    // Gather all MoveOperands for a single ParallelMove.
3935014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    MoveOperands* move =
3936014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch        new (code_zone()) MoveOperands(it->first.second, it->second);
3937c8c1d9e03f4babd16833b0f8ccf6aab5fa6e8c7aBen Murdoch    moves->PrepareInsertAfter(move, &to_eliminate);
3938014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch    to_insert.push_back(move);
3939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch  }
3940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch}
3941b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch
3942014dc512cdd3e367bee49a713fdc5ed92584a3e5Ben Murdoch
3943109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdochvoid LiveRangeConnector::CommitSpillsInDeferredBlocks(
3944109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    TopLevelLiveRange* range, LiveRangeBoundArray* array, Zone* temp_zone) {
3945109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DCHECK(range->IsSpilledOnlyInDeferredBlocks());
3946109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  DCHECK(!range->spilled());
3947109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3948109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  InstructionSequence* code = data()->code();
3949109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  InstructionOperand spill_operand = range->GetSpillRangeOperand();
3950109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3951109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  TRACE("Live Range %d will be spilled only in deferred blocks.\n",
3952109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        range->vreg());
3953109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // If we have ranges that aren't spilled but require the operand on the stack,
3954109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // make sure we insert the spill.
3955109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  for (const LiveRange* child = range; child != nullptr;
3956109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch       child = child->next()) {
3957109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    for (const UsePosition* pos = child->first_pos(); pos != nullptr;
3958109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch         pos = pos->next()) {
3959109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (pos->type() != UsePositionType::kRequiresSlot && !child->spilled())
3960109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        continue;
3961109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      range->AddBlockRequiringSpillOperand(
3962109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch          code->GetInstructionBlock(pos->pos().ToInstructionIndex())
3963109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch              ->rpo_number());
3964109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
3965109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
3966109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3967109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  ZoneQueue<int> worklist(temp_zone);
3968109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3969109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  for (BitVector::Iterator iterator(
3970109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch           range->GetListOfBlocksRequiringSpillOperands());
3971109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch       !iterator.Done(); iterator.Advance()) {
3972109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    worklist.push(iterator.Current());
3973109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
3974109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3975bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch  ZoneSet<std::pair<RpoNumber, int>> done_moves(temp_zone);
3976109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // Seek the deferred blocks that dominate locations requiring spill operands,
3977109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  // and spill there. We only need to spill at the start of such blocks.
3978109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  BitVector done_blocks(
3979109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      range->GetListOfBlocksRequiringSpillOperands()->length(), temp_zone);
3980109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  while (!worklist.empty()) {
3981109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    int block_id = worklist.front();
3982109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    worklist.pop();
3983109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    if (done_blocks.Contains(block_id)) continue;
3984109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    done_blocks.Add(block_id);
39853b9bc31999c9787eb726ecdbfd5796bfdec32a18Ben Murdoch    InstructionBlock* spill_block =
3986109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        code->InstructionBlockAt(RpoNumber::FromInt(block_id));
3987109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3988109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    for (const RpoNumber& pred : spill_block->predecessors()) {
3989109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      const InstructionBlock* pred_block = code->InstructionBlockAt(pred);
3990109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3991109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      if (pred_block->IsDeferred()) {
3992109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        worklist.push(pred_block->rpo_number().ToInt());
3993109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      } else {
3994109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        LifetimePosition pred_end =
3995109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch            LifetimePosition::InstructionFromInstructionIndex(
3996109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch                pred_block->last_instruction_index());
3997109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
3998109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        LiveRangeBound* bound = array->Find(pred_end);
3999109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
4000109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch        InstructionOperand pred_op = bound->range_->GetAssignedOperand();
4001109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
4002bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        RpoNumber spill_block_number = spill_block->rpo_number();
4003bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        if (done_moves.find(std::make_pair(
4004bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                spill_block_number, range->vreg())) == done_moves.end()) {
4005bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          data()->AddGapMove(spill_block->first_instruction_index(),
4006bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                             Instruction::GapPosition::START, pred_op,
4007bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch                             spill_operand);
4008bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          done_moves.insert(std::make_pair(spill_block_number, range->vreg()));
4009bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch          spill_block->mark_needs_frame();
4010bcf72ee8e3b26f1d0726869c7ddb3921c68b09a8Ben Murdoch        }
4011109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch      }
4012109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch    }
4013109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch  }
4014109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch}
4015109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
4016109988c7ccb6f3fd1a58574fa3dfb88beaef6632Ben Murdoch
4017958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}  // namespace compiler
4018958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}  // namespace internal
4019958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}  // namespace v8
4020