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