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