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