register-allocator.cc revision 958fae7ec3f466955f8e5b50fa5b8d38b9e91675
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 5b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/compiler/linkage.h" 6958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier#include "src/compiler/register-allocator.h" 7b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#include "src/string-stream.h" 8b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 9b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace v8 { 10b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace internal { 11b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochnamespace compiler { 12b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 13b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic inline LifetimePosition Min(LifetimePosition a, LifetimePosition b) { 14b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return a.Value() < b.Value() ? a : b; 15b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 16b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 17b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 18b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochstatic inline LifetimePosition Max(LifetimePosition a, LifetimePosition b) { 19b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return a.Value() > b.Value() ? a : b; 20b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 21b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 22b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 23958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic void TraceAlloc(const char* msg, ...) { 24958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (FLAG_trace_alloc) { 25958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier va_list arguments; 26958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier va_start(arguments, msg); 27958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier base::OS::VPrint(msg, arguments); 28958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier va_end(arguments); 29958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 30958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 31958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 32958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 33958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic void RemoveElement(ZoneVector<LiveRange*>* v, LiveRange* range) { 34958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto it = std::find(v->begin(), v->end(), range); 35958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(it != v->end()); 36958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier v->erase(it); 37958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 38958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 39958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 40b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochUsePosition::UsePosition(LifetimePosition pos, InstructionOperand* operand, 41b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperand* hint) 42b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : operand_(operand), 43b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch hint_(hint), 44b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pos_(pos), 45958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier next_(nullptr), 46b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch requires_reg_(false), 47b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch register_beneficial_(true) { 48958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (operand_ != nullptr && operand_->IsUnallocated()) { 49b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch const UnallocatedOperand* unalloc = UnallocatedOperand::cast(operand_); 50b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch requires_reg_ = unalloc->HasRegisterPolicy(); 51b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch register_beneficial_ = !unalloc->HasAnyPolicy(); 52b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 53b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(pos_.IsValid()); 54b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 55b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 56b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 57b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool UsePosition::HasHint() const { 58958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return hint_ != nullptr && !hint_->IsUnallocated(); 59b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 60b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 61b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 62b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool UsePosition::RequiresRegister() const { return requires_reg_; } 63b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 64b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 65b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool UsePosition::RegisterIsBeneficial() const { return register_beneficial_; } 66b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 67b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 68b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid UseInterval::SplitAt(LifetimePosition pos, Zone* zone) { 69b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(Contains(pos) && pos.Value() != start().Value()); 70958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto after = new (zone) UseInterval(pos, end_); 71b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch after->next_ = next_; 72b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_ = after; 73b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch end_ = pos; 74b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 75b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 76b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 77958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstruct LiveRange::SpillAtDefinitionList : ZoneObject { 78958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SpillAtDefinitionList(int gap_index, InstructionOperand* operand, 79958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SpillAtDefinitionList* next) 80958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier : gap_index(gap_index), operand(operand), next(next) {} 81958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const int gap_index; 82958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier InstructionOperand* const operand; 83958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SpillAtDefinitionList* const next; 84958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}; 85958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 86958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 87b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 88b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 89b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 90b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LiveRange::Verify() const { 91b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UsePosition* cur = first_pos_; 92958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (cur != nullptr) { 93b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(Start().Value() <= cur->pos().Value() && 94b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cur->pos().Value() <= End().Value()); 95b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cur = cur->next(); 96b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 97b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 98b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 99b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool LiveRange::HasOverlap(UseInterval* target) const { 101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UseInterval* current_interval = first_interval_; 102958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (current_interval != nullptr) { 103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Intervals overlap if the start of one is contained in the other. 104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current_interval->Contains(target->start()) || 105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch target->Contains(current_interval->start())) { 106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_interval = current_interval->next(); 109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 113b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLiveRange::LiveRange(int id, Zone* zone) 118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : id_(id), 119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch spilled_(false), 120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch is_phi_(false), 121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch is_non_loop_phi_(false), 122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch kind_(UNALLOCATED_REGISTERS), 123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assigned_register_(kInvalidAssignment), 124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier last_interval_(nullptr), 125958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier first_interval_(nullptr), 126958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier first_pos_(nullptr), 127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier parent_(nullptr), 128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier next_(nullptr), 129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier current_interval_(nullptr), 130958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier last_processed_use_(nullptr), 131958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier current_hint_operand_(nullptr), 132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier spill_start_index_(kMaxInt), 133958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier spill_type_(SpillType::kNoSpillType), 134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier spill_operand_(nullptr), 135958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier spills_at_definition_(nullptr) {} 136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LiveRange::set_assigned_register(int reg, Zone* zone) { 139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasRegisterAssigned() && !IsSpilled()); 140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assigned_register_ = reg; 141958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // TODO(dcarney): stop aliasing hint operands. 142958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ConvertUsesToOperand(CreateAssignedOperand(zone)); 143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 146958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid LiveRange::MakeSpilled() { 147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!IsSpilled()); 148958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!TopLevel()->HasNoSpillType()); 149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch spilled_ = true; 150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assigned_register_ = kInvalidAssignment; 151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 154958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid LiveRange::SpillAtDefinition(Zone* zone, int gap_index, 155958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier InstructionOperand* operand) { 156958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(HasNoSpillType()); 157958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier spills_at_definition_ = new (zone) 158958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SpillAtDefinitionList(gap_index, operand, spills_at_definition_); 159958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 160958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 161958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 162958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid LiveRange::CommitSpillsAtDefinition(InstructionSequence* sequence, 163958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier InstructionOperand* op) { 164958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto to_spill = TopLevel()->spills_at_definition_; 165958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (to_spill == nullptr) return; 166958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto zone = sequence->zone(); 167958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (; to_spill != nullptr; to_spill = to_spill->next) { 168958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto gap = sequence->GapAt(to_spill->gap_index); 169958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto move = gap->GetOrCreateParallelMove(GapInstruction::START, zone); 170958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier move->AddMove(to_spill->operand, op, zone); 171958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 172958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier TopLevel()->spills_at_definition_ = nullptr; 173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LiveRange::SetSpillOperand(InstructionOperand* operand) { 177958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(HasNoSpillType()); 178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!operand->IsUnallocated()); 179958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier spill_type_ = SpillType::kSpillOperand; 180958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier spill_operand_ = operand; 181958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 182958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 183958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 184958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid LiveRange::SetSpillRange(SpillRange* spill_range) { 185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(HasNoSpillType() || HasSpillRange()); 186958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK_NE(spill_range, nullptr); 187958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier spill_type_ = SpillType::kSpillRange; 188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier spill_range_ = spill_range; 189958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 190958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 191958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 192958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid LiveRange::CommitSpillOperand(InstructionOperand* operand) { 193958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(HasSpillRange()); 194958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!operand->IsUnallocated()); 195958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!IsChild()); 196958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier spill_type_ = SpillType::kSpillOperand; 197958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier spill_operand_ = operand; 198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochUsePosition* LiveRange::NextUsePosition(LifetimePosition start) { 202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UsePosition* use_pos = last_processed_use_; 203958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (use_pos == nullptr) use_pos = first_pos(); 204958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (use_pos != nullptr && use_pos->pos().Value() < start.Value()) { 205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch use_pos = use_pos->next(); 206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch last_processed_use_ = use_pos; 208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return use_pos; 209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochUsePosition* LiveRange::NextUsePositionRegisterIsBeneficial( 213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LifetimePosition start) { 214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UsePosition* pos = NextUsePosition(start); 215958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (pos != nullptr && !pos->RegisterIsBeneficial()) { 216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pos = pos->next(); 217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return pos; 219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochUsePosition* LiveRange::PreviousUsePositionRegisterIsBeneficial( 223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LifetimePosition start) { 224958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto pos = first_pos(); 225958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UsePosition* prev = nullptr; 226958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (pos != nullptr && pos->pos().Value() < start.Value()) { 227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (pos->RegisterIsBeneficial()) prev = pos; 228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pos = pos->next(); 229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return prev; 231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochUsePosition* LiveRange::NextRegisterPosition(LifetimePosition start) { 235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UsePosition* pos = NextUsePosition(start); 236958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (pos != nullptr && !pos->RequiresRegister()) { 237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pos = pos->next(); 238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return pos; 240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool LiveRange::CanBeSpilled(LifetimePosition pos) { 244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We cannot spill a live range that has a use requiring a register 245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // at the current or the immediate next position. 246958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto use_pos = NextRegisterPosition(pos); 247958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (use_pos == nullptr) return true; 248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return use_pos->pos().Value() > 249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pos.NextInstruction().InstructionEnd().Value(); 250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 253958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierInstructionOperand* LiveRange::CreateAssignedOperand(Zone* zone) const { 254958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier InstructionOperand* op = nullptr; 255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (HasRegisterAssigned()) { 256b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!IsSpilled()); 257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch switch (Kind()) { 258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case GENERAL_REGISTERS: 259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch op = RegisterOperand::Create(assigned_register(), zone); 260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch case DOUBLE_REGISTERS: 262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch op = DoubleRegisterOperand::Create(assigned_register(), zone); 263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch default: 265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 267958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 268958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(IsSpilled()); 269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!HasRegisterAssigned()); 270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch op = TopLevel()->GetSpillOperand(); 271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!op->IsUnallocated()); 272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return op; 274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochUseInterval* LiveRange::FirstSearchIntervalForPosition( 278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LifetimePosition position) const { 279958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (current_interval_ == nullptr) return first_interval_; 280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current_interval_->start().Value() > position.Value()) { 281958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier current_interval_ = nullptr; 282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return first_interval_; 283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return current_interval_; 285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LiveRange::AdvanceLastProcessedMarker( 289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UseInterval* to_start_of, LifetimePosition but_not_past) const { 290958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (to_start_of == nullptr) return; 291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (to_start_of->start().Value() > but_not_past.Value()) return; 292958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto start = current_interval_ == nullptr ? LifetimePosition::Invalid() 293958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier : current_interval_->start(); 294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (to_start_of->start().Value() > start.Value()) { 295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_interval_ = to_start_of; 296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 298b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LiveRange::SplitAt(LifetimePosition position, LiveRange* result, 301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Zone* zone) { 302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(Start().Value() < position.Value()); 303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(result->IsEmpty()); 304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Find the last interval that ends before the position. If the 305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // position is contained in one of the intervals in the chain, we 306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // split that interval and use the first part. 307958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto current = FirstSearchIntervalForPosition(position); 308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the split position coincides with the beginning of a use interval 310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // we need to split use positons in a special way. 311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool split_at_start = false; 312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current->start().Value() == position.Value()) { 314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // When splitting at start we need to locate the previous use interval. 315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current = first_interval_; 316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 318958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (current != nullptr) { 319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current->Contains(position)) { 320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current->SplitAt(position, zone); 321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 323958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto next = current->next(); 324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (next->start().Value() >= position.Value()) { 325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch split_at_start = (next->start().Value() == position.Value()); 326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch break; 327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current = next; 329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Partition original use intervals to the two live ranges. 332958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto before = current; 333958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto after = before->next(); 334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->last_interval_ = 335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (last_interval_ == before) 336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ? after // Only interval in the range after split. 337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : last_interval_; // Last interval of the original range. 338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->first_interval_ = after; 339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch last_interval_ = before; 340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Find the last use position before the split and the first use 342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // position after it. 343958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto use_after = first_pos_; 344958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UsePosition* use_before = nullptr; 345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (split_at_start) { 346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The split position coincides with the beginning of a use interval (the 347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // end of a lifetime hole). Use at this position should be attributed to 348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the split child because split child owns use interval covering it. 349958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (use_after != nullptr && 350958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier use_after->pos().Value() < position.Value()) { 351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch use_before = use_after; 352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch use_after = use_after->next(); 353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 355958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (use_after != nullptr && 356958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier use_after->pos().Value() <= position.Value()) { 357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch use_before = use_after; 358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch use_after = use_after->next(); 359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 362b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Partition original use positions to the two live ranges. 363958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (use_before != nullptr) { 364958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier use_before->next_ = nullptr; 365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 366958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier first_pos_ = nullptr; 367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->first_pos_ = use_after; 369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Discard cached iteration state. It might be pointing 371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to the use that no longer belongs to this live range. 372958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier last_processed_use_ = nullptr; 373958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier current_interval_ = nullptr; 374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Link the new live range in the chain before any of the other 376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ranges linked from the range before the split. 377958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier result->parent_ = (parent_ == nullptr) ? this : parent_; 378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->kind_ = result->parent_->kind_; 379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->next_ = next_; 380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_ = result; 381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Verify(); 384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->Verify(); 385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// This implements an ordering on live ranges so that they are ordered by their 390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// start positions. This is needed for the correctness of the register 391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// allocation algorithm. If two live ranges start at the same offset then there 392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// is a tie breaker based on where the value is first used. This part of the 393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// ordering is merely a heuristic. 394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool LiveRange::ShouldBeAllocatedBefore(const LiveRange* other) const { 395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LifetimePosition start = Start(); 396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LifetimePosition other_start = other->Start(); 397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (start.Value() == other_start.Value()) { 398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UsePosition* pos = first_pos(); 399958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (pos == nullptr) return false; 400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UsePosition* other_pos = other->first_pos(); 401958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (other_pos == nullptr) return true; 402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return pos->pos().Value() < other_pos->pos().Value(); 403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return start.Value() < other_start.Value(); 405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LiveRange::ShortenTo(LifetimePosition start) { 409958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier TraceAlloc("Shorten live range %d to [%d\n", id_, start.Value()); 410958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(first_interval_ != nullptr); 411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(first_interval_->start().Value() <= start.Value()); 412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(start.Value() < first_interval_->end().Value()); 413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch first_interval_->set_start(start); 414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LiveRange::EnsureInterval(LifetimePosition start, LifetimePosition end, 418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Zone* zone) { 419958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier TraceAlloc("Ensure live range %d in interval [%d %d[\n", id_, start.Value(), 420958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier end.Value()); 421958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto new_end = end; 422958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (first_interval_ != nullptr && 423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch first_interval_->start().Value() <= end.Value()) { 424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (first_interval_->end().Value() > end.Value()) { 425b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_end = first_interval_->end(); 426b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch first_interval_ = first_interval_->next(); 428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 430958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto new_interval = new (zone) UseInterval(start, new_end); 431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new_interval->next_ = first_interval_; 432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch first_interval_ = new_interval; 433958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (new_interval->next() == nullptr) { 434b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch last_interval_ = new_interval; 435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 437b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 438b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 439b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LiveRange::AddUseInterval(LifetimePosition start, LifetimePosition end, 440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Zone* zone) { 441958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier TraceAlloc("Add to live range %d interval [%d %d[\n", id_, start.Value(), 442958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier end.Value()); 443958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (first_interval_ == nullptr) { 444958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto interval = new (zone) UseInterval(start, end); 445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch first_interval_ = interval; 446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch last_interval_ = interval; 447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (end.Value() == first_interval_->start().Value()) { 449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch first_interval_->set_start(start); 450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (end.Value() < first_interval_->start().Value()) { 451958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto interval = new (zone) UseInterval(start, end); 452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch interval->set_next(first_interval_); 453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch first_interval_ = interval; 454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Order of instruction's processing (see ProcessInstructions) guarantees 456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // that each new use interval either precedes or intersects with 457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // last added interval. 458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(start.Value() < first_interval_->end().Value()); 459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch first_interval_->start_ = Min(start, first_interval_->start_); 460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch first_interval_->end_ = Max(end, first_interval_->end_); 461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid LiveRange::AddUsePosition(LifetimePosition pos, 467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperand* operand, 468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperand* hint, Zone* zone) { 469958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier TraceAlloc("Add to live range %d use position %d\n", id_, pos.Value()); 470958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto use_pos = new (zone) UsePosition(pos, operand, hint); 471958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UsePosition* prev_hint = nullptr; 472958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UsePosition* prev = nullptr; 473958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto current = first_pos_; 474958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (current != nullptr && current->pos().Value() < pos.Value()) { 475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch prev_hint = current->HasHint() ? current : prev_hint; 476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch prev = current; 477b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current = current->next(); 478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 480958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (prev == nullptr) { 481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch use_pos->set_next(first_pos_); 482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch first_pos_ = use_pos; 483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch use_pos->next_ = prev->next_; 485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch prev->next_ = use_pos; 486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 488958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (prev_hint == nullptr && use_pos->HasHint()) { 489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current_hint_operand_ = hint; 490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 494958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid LiveRange::ConvertUsesToOperand(InstructionOperand* op) { 495958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto use_pos = first_pos(); 496958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (use_pos != nullptr) { 497b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(Start().Value() <= use_pos->pos().Value() && 498b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch use_pos->pos().Value() <= End().Value()); 499b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 500b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (use_pos->HasOperand()) { 501b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(op->IsRegister() || op->IsDoubleRegister() || 502b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !use_pos->RequiresRegister()); 503b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch use_pos->operand()->ConvertTo(op->kind(), op->index()); 504b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 505b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch use_pos = use_pos->next(); 506b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 507b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 508b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 509b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 510b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool LiveRange::CanCover(LifetimePosition position) const { 511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsEmpty()) return false; 512b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return Start().Value() <= position.Value() && 513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch position.Value() < End().Value(); 514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 515b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool LiveRange::Covers(LifetimePosition position) { 518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!CanCover(position)) return false; 519958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto start_search = FirstSearchIntervalForPosition(position); 520958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto interval = start_search; interval != nullptr; 521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch interval = interval->next()) { 522958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(interval->next() == nullptr || 523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch interval->next()->start().Value() >= interval->start().Value()); 524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AdvanceLastProcessedMarker(interval, position); 525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (interval->Contains(position)) return true; 526b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (interval->start().Value() > position.Value()) return false; 527b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLifetimePosition LiveRange::FirstIntersection(LiveRange* other) { 533958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto b = other->first_interval(); 534958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (b == nullptr) return LifetimePosition::Invalid(); 535958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto advance_last_processed_up_to = b->start(); 536958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto a = FirstSearchIntervalForPosition(b->start()); 537958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (a != nullptr && b != nullptr) { 538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (a->start().Value() > other->End().Value()) break; 539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (b->start().Value() > End().Value()) break; 540958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto cur_intersection = a->Intersect(b); 541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (cur_intersection.IsValid()) { 542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return cur_intersection; 543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (a->start().Value() < b->start().Value()) { 545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch a = a->next(); 546958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (a == nullptr || a->start().Value() > other->End().Value()) break; 547b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AdvanceLastProcessedMarker(a, advance_last_processed_up_to); 548b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 549b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch b = b->next(); 550b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 551b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 552b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return LifetimePosition::Invalid(); 553b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 554b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 555b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 556958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierRegisterAllocator::RegisterAllocator(const RegisterConfiguration* config, 557958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Zone* zone, Frame* frame, 558958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier InstructionSequence* code, 559958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const char* debug_name) 560958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier : local_zone_(zone), 561958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier frame_(frame), 562b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code_(code), 563958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier debug_name_(debug_name), 564958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier config_(config), 565958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier phi_map_(PhiMap::key_compare(), PhiMap::allocator_type(local_zone())), 566958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier live_in_sets_(code->InstructionBlockCount(), nullptr, local_zone()), 567958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier live_ranges_(code->VirtualRegisterCount() * 2, nullptr, local_zone()), 568958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier fixed_live_ranges_(this->config()->num_general_registers(), nullptr, 569958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier local_zone()), 570958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier fixed_double_live_ranges_(this->config()->num_double_registers(), nullptr, 571958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier local_zone()), 572958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier unhandled_live_ranges_(local_zone()), 573958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier active_live_ranges_(local_zone()), 574958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inactive_live_ranges_(local_zone()), 575958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reusable_slots_(local_zone()), 576958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier spill_ranges_(local_zone()), 577b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mode_(UNALLOCATED_REGISTERS), 578b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch num_registers_(-1), 579958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier allocation_ok_(true) { 580958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(this->config()->num_general_registers() <= 581958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RegisterConfiguration::kMaxGeneralRegisters); 582958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(this->config()->num_double_registers() <= 583958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RegisterConfiguration::kMaxDoubleRegisters); 584958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // TryAllocateFreeReg and AllocateBlockedReg assume this 585958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // when allocating local arrays. 586958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(RegisterConfiguration::kMaxDoubleRegisters >= 587958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier this->config()->num_general_registers()); 588958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier unhandled_live_ranges().reserve( 589958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier static_cast<size_t>(code->VirtualRegisterCount() * 2)); 590958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier active_live_ranges().reserve(8); 591958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inactive_live_ranges().reserve(8); 592958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reusable_slots().reserve(8); 593958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier spill_ranges().reserve(8); 594958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier assigned_registers_ = 595958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier new (code_zone()) BitVector(config->num_general_registers(), code_zone()); 596958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier assigned_double_registers_ = new (code_zone()) 597958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier BitVector(config->num_aliased_double_registers(), code_zone()); 598958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier frame->SetAllocatedRegisters(assigned_registers_); 599958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier frame->SetAllocatedDoubleRegisters(assigned_double_registers_); 600b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 601b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 602b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 603958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierBitVector* RegisterAllocator::ComputeLiveOut(const InstructionBlock* block) { 604b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Compute live out for the given block, except not including backward 605b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // successor edges. 606958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto live_out = new (local_zone()) 607958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier BitVector(code()->VirtualRegisterCount(), local_zone()); 608b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 609b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Process all successor blocks. 610958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto succ : block->successors()) { 611b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Add values live on entry to the successor. Note the successor's 612b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // live_in will not be computed yet for backwards edges. 613958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto live_in = live_in_sets_[succ.ToSize()]; 614958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (live_in != nullptr) live_out->Union(*live_in); 615b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 616b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // All phi input operands corresponding to this successor edge are live 617b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // out from this block. 618958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto successor = code()->InstructionBlockAt(succ); 619958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier size_t index = successor->PredecessorIndexOf(block->rpo_number()); 620958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(index < successor->PredecessorCount()); 621958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto phi : successor->phis()) { 622958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier live_out->Add(phi->operands()[index]); 623b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 624b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 625b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return live_out; 626b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 627b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 628b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 629958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid RegisterAllocator::AddInitialIntervals(const InstructionBlock* block, 630b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BitVector* live_out) { 631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Add an interval that includes the entire block to the live range for 632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // each live_out value. 633958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto start = 634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LifetimePosition::FromInstructionIndex(block->first_instruction_index()); 635958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto end = LifetimePosition::FromInstructionIndex( 636958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier block->last_instruction_index()).NextInstruction(); 637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BitVector::Iterator iterator(live_out); 638b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (!iterator.Done()) { 639b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int operand_index = iterator.Current(); 640958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto range = LiveRangeFor(operand_index); 641958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier range->AddUseInterval(start, end, local_zone()); 642b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch iterator.Advance(); 643b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 644b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 645b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 646b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 647b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint RegisterAllocator::FixedDoubleLiveRangeID(int index) { 648958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return -index - 1 - config()->num_general_registers(); 649b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 650b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 651b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 652b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochInstructionOperand* RegisterAllocator::AllocateFixed( 653b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UnallocatedOperand* operand, int pos, bool is_tagged) { 654b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceAlloc("Allocating fixed reg for op %d\n", operand->virtual_register()); 655b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(operand->HasFixedPolicy()); 656b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (operand->HasFixedSlotPolicy()) { 657b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch operand->ConvertTo(InstructionOperand::STACK_SLOT, 658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch operand->fixed_slot_index()); 659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (operand->HasFixedRegisterPolicy()) { 660b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int reg_index = operand->fixed_register_index(); 661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch operand->ConvertTo(InstructionOperand::REGISTER, reg_index); 662b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (operand->HasFixedDoubleRegisterPolicy()) { 663b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int reg_index = operand->fixed_register_index(); 664b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch operand->ConvertTo(InstructionOperand::DOUBLE_REGISTER, reg_index); 665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UNREACHABLE(); 667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (is_tagged) { 669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceAlloc("Fixed reg is tagged at %d\n", pos); 670958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto instr = InstructionAt(pos); 671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr->HasPointerMap()) { 672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr->pointer_map()->RecordPointer(operand, code_zone()); 673b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return operand; 676b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 677b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 678b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 679b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLiveRange* RegisterAllocator::FixedLiveRangeFor(int index) { 680958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(index < config()->num_general_registers()); 681958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto result = fixed_live_ranges()[index]; 682958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (result == nullptr) { 683b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(titzer): add a utility method to allocate a new LiveRange: 684b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The LiveRange object itself can go in this zone, but the 685b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // InstructionOperand needs 686b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to go in the code zone, since it may survive register allocation. 687958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier result = new (local_zone()) LiveRange(FixedLiveRangeID(index), code_zone()); 688b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(result->IsFixed()); 689b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->kind_ = GENERAL_REGISTERS; 690b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetLiveRangeAssignedRegister(result, index); 691958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier fixed_live_ranges()[index] = result; 692b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 694b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 695b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 696b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 697b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLiveRange* RegisterAllocator::FixedDoubleLiveRangeFor(int index) { 698958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(index < config()->num_aliased_double_registers()); 699958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto result = fixed_double_live_ranges()[index]; 700958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (result == nullptr) { 701958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier result = new (local_zone()) 702958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LiveRange(FixedDoubleLiveRangeID(index), code_zone()); 703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(result->IsFixed()); 704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch result->kind_ = DOUBLE_REGISTERS; 705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetLiveRangeAssignedRegister(result, index); 706958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier fixed_double_live_ranges()[index] = result; 707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 709b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 711b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 712b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLiveRange* RegisterAllocator::LiveRangeFor(int index) { 713958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (index >= static_cast<int>(live_ranges().size())) { 714958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier live_ranges().resize(index + 1, nullptr); 715b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 716958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto result = live_ranges()[index]; 717958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (result == nullptr) { 718958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier result = new (local_zone()) LiveRange(index, code_zone()); 719958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier live_ranges()[index] = result; 720b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 721b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 725958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierGapInstruction* RegisterAllocator::GetLastGap(const InstructionBlock* block) { 726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int last_instruction = block->last_instruction_index(); 727b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return code()->GapAt(last_instruction - 1); 728b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 729b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 730b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 731b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLiveRange* RegisterAllocator::LiveRangeFor(InstructionOperand* operand) { 732b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (operand->IsUnallocated()) { 733b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return LiveRangeFor(UnallocatedOperand::cast(operand)->virtual_register()); 734b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (operand->IsRegister()) { 735b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return FixedLiveRangeFor(operand->index()); 736b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (operand->IsDoubleRegister()) { 737b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return FixedDoubleLiveRangeFor(operand->index()); 738b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 739958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return nullptr; 740b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 741b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 742b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::Define(LifetimePosition position, 745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperand* operand, 746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperand* hint) { 747958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto range = LiveRangeFor(operand); 748958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (range == nullptr) return; 749b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 750b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (range->IsEmpty() || range->Start().Value() > position.Value()) { 751b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Can happen if there is a definition without use. 752958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier range->AddUseInterval(position, position.NextInstruction(), local_zone()); 753958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier range->AddUsePosition(position.NextInstruction(), nullptr, nullptr, 754958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier local_zone()); 755b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 756b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch range->ShortenTo(position); 757b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 758b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 759b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (operand->IsUnallocated()) { 760958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto unalloc_operand = UnallocatedOperand::cast(operand); 761958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier range->AddUsePosition(position, unalloc_operand, hint, local_zone()); 762b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 763b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 765b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::Use(LifetimePosition block_start, 767b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LifetimePosition position, 768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperand* operand, 769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperand* hint) { 770958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto range = LiveRangeFor(operand); 771958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (range == nullptr) return; 772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (operand->IsUnallocated()) { 773b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UnallocatedOperand* unalloc_operand = UnallocatedOperand::cast(operand); 774958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier range->AddUsePosition(position, unalloc_operand, hint, local_zone()); 775958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 776958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier range->AddUseInterval(block_start, position, local_zone()); 777958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 778958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 779958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 780958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid RegisterAllocator::AddGapMove(int index, 781958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier GapInstruction::InnerPosition position, 782958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier InstructionOperand* from, 783958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier InstructionOperand* to) { 784958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto gap = code()->GapAt(index); 785958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto move = gap->GetOrCreateParallelMove(position, code_zone()); 786958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier move->AddMove(from, to, code_zone()); 787958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 788958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 789958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 790958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic bool AreUseIntervalsIntersecting(UseInterval* interval1, 791958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UseInterval* interval2) { 792958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (interval1 != nullptr && interval2 != nullptr) { 793958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (interval1->start().Value() < interval2->start().Value()) { 794958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (interval1->end().Value() > interval2->start().Value()) { 795958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return true; 796958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 797958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier interval1 = interval1->next(); 798958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 799958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (interval2->end().Value() > interval1->start().Value()) { 800958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return true; 801b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 802958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier interval2 = interval2->next(); 803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 805958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return false; 806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 809958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierSpillRange::SpillRange(LiveRange* range, Zone* zone) : live_ranges_(zone) { 810958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto src = range->first_interval(); 811958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UseInterval* result = nullptr; 812958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UseInterval* node = nullptr; 813958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Copy the nodes 814958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (src != nullptr) { 815958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto new_node = new (zone) UseInterval(src->start(), src->end()); 816958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (result == nullptr) { 817958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier result = new_node; 818958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 819958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier node->set_next(new_node); 820958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 821958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier node = new_node; 822958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier src = src->next(); 823958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 824958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier use_interval_ = result; 825958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier live_ranges().push_back(range); 826958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier end_position_ = node->end(); 827958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!range->HasSpillRange()); 828958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier range->SetSpillRange(this); 829958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 830958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 831958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 832958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool SpillRange::IsIntersectingWith(SpillRange* other) const { 833958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (this->use_interval_ == nullptr || other->use_interval_ == nullptr || 834958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier this->End().Value() <= other->use_interval_->start().Value() || 835958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier other->End().Value() <= this->use_interval_->start().Value()) { 836958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return false; 837958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 838958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return AreUseIntervalsIntersecting(use_interval_, other->use_interval_); 839958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 840958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 841958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 842958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool SpillRange::TryMerge(SpillRange* other) { 843958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (Kind() != other->Kind() || IsIntersectingWith(other)) return false; 844958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 845958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto max = LifetimePosition::MaxPosition(); 846958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (End().Value() < other->End().Value() && 847958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier other->End().Value() != max.Value()) { 848958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier end_position_ = other->End(); 849958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 850958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier other->end_position_ = max; 851958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 852958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier MergeDisjointIntervals(other->use_interval_); 853958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier other->use_interval_ = nullptr; 854958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 855958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto range : other->live_ranges()) { 856958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(range->GetSpillRange() == other); 857958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier range->SetSpillRange(this); 858958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 859958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 860958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier live_ranges().insert(live_ranges().end(), other->live_ranges().begin(), 861958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier other->live_ranges().end()); 862958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier other->live_ranges().clear(); 863958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 864958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return true; 865958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 866958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 867958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 868958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid SpillRange::SetOperand(InstructionOperand* op) { 869958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto range : live_ranges()) { 870958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(range->GetSpillRange() == this); 871958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier range->CommitSpillOperand(op); 872958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 873958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 874958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 875958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 876958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid SpillRange::MergeDisjointIntervals(UseInterval* other) { 877958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UseInterval* tail = nullptr; 878958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto current = use_interval_; 879958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (other != nullptr) { 880958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Make sure the 'current' list starts first 881958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (current == nullptr || 882958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier current->start().Value() > other->start().Value()) { 883958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier std::swap(current, other); 884958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 885958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Check disjointness 886958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(other == nullptr || 887958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier current->end().Value() <= other->start().Value()); 888958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Append the 'current' node to the result accumulator and move forward 889958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (tail == nullptr) { 890958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier use_interval_ = current; 891958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 892958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier tail->set_next(current); 893958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 894958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier tail = current; 895958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier current = current->next(); 896958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 897958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Other list is empty => we are done 898958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 899958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 900958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 901958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid RegisterAllocator::ReuseSpillSlots() { 902958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(FLAG_turbo_reuse_spill_slots); 903958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 904958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Merge disjoint spill ranges 905958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (size_t i = 0; i < spill_ranges().size(); i++) { 906958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto range = spill_ranges()[i]; 907958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (range->IsEmpty()) continue; 908958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (size_t j = i + 1; j < spill_ranges().size(); j++) { 909958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto other = spill_ranges()[j]; 910958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!other->IsEmpty()) { 911958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier range->TryMerge(other); 912958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 913958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 914958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 915958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 916958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Allocate slots for the merged spill ranges. 917958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto range : spill_ranges()) { 918958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (range->IsEmpty()) continue; 919958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Allocate a new operand referring to the spill slot. 920958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto kind = range->Kind(); 921958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int index = frame()->AllocateSpillSlot(kind == DOUBLE_REGISTERS); 922958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto op_kind = kind == DOUBLE_REGISTERS 923958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ? InstructionOperand::DOUBLE_STACK_SLOT 924958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier : InstructionOperand::STACK_SLOT; 925958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto op = new (code_zone()) InstructionOperand(op_kind, index); 926958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier range->SetOperand(op); 927958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 928958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 929958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 930958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 931958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid RegisterAllocator::CommitAssignment() { 932958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto range : live_ranges()) { 933958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (range == nullptr || range->IsEmpty()) continue; 934958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Register assignments were committed in set_assigned_register. 935958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (range->HasRegisterAssigned()) continue; 936958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto assigned = range->CreateAssignedOperand(code_zone()); 937958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier range->ConvertUsesToOperand(assigned); 938958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (range->IsSpilled()) { 939958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier range->CommitSpillsAtDefinition(code(), assigned); 940958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 941958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 942958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 943958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 944958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 945958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily BernierSpillRange* RegisterAllocator::AssignSpillRangeToLiveRange(LiveRange* range) { 946958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(FLAG_turbo_reuse_spill_slots); 947958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto spill_range = new (local_zone()) SpillRange(range, local_zone()); 948958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier spill_ranges().push_back(spill_range); 949958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return spill_range; 950958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 951958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 952958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 953958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool RegisterAllocator::TryReuseSpillForPhi(LiveRange* range) { 954958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(FLAG_turbo_reuse_spill_slots); 955958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (range->IsChild() || !range->is_phi()) return false; 956958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(range->HasNoSpillType()); 957958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 958958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto lookup = phi_map_.find(range->id()); 959958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(lookup != phi_map_.end()); 960958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto phi = lookup->second.phi; 961958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto block = lookup->second.block; 962958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Count the number of spilled operands. 963958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier size_t spilled_count = 0; 964958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LiveRange* first_op = nullptr; 965958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (size_t i = 0; i < phi->operands().size(); i++) { 966958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int op = phi->operands()[i]; 967958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LiveRange* op_range = LiveRangeFor(op); 968958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (op_range->GetSpillRange() == nullptr) continue; 969958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto pred = code()->InstructionBlockAt(block->predecessors()[i]); 970958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto pred_end = 971958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LifetimePosition::FromInstructionIndex(pred->last_instruction_index()); 972958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (op_range != nullptr && !op_range->CanCover(pred_end)) { 973958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier op_range = op_range->next(); 974958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 975958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (op_range != nullptr && op_range->IsSpilled()) { 976958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier spilled_count++; 977958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (first_op == nullptr) { 978958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier first_op = op_range->TopLevel(); 979958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 980958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 981958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 982958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 983958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Only continue if more than half of the operands are spilled. 984958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (spilled_count * 2 <= phi->operands().size()) { 985958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return false; 986958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 987958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 988958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Try to merge the spilled operands and count the number of merged spilled 989958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // operands. 990958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(first_op != nullptr); 991958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto first_op_spill = first_op->GetSpillRange(); 992958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier size_t num_merged = 1; 993958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (size_t i = 1; i < phi->operands().size(); i++) { 994958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int op = phi->operands()[i]; 995958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto op_range = LiveRangeFor(op); 996958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto op_spill = op_range->GetSpillRange(); 997958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (op_spill != nullptr && 998958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier (op_spill == first_op_spill || first_op_spill->TryMerge(op_spill))) { 999958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier num_merged++; 1000958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1001958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1002958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1003958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Only continue if enough operands could be merged to the 1004958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // same spill slot. 1005958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (num_merged * 2 <= phi->operands().size() || 1006958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier AreUseIntervalsIntersecting(first_op_spill->interval(), 1007958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier range->first_interval())) { 1008958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return false; 1009958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1010958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1011958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // If the range does not need register soon, spill it to the merged 1012958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // spill range. 1013958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto next_pos = range->Start(); 1014958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (code()->IsGapAt(next_pos.InstructionIndex())) { 1015958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier next_pos = next_pos.NextInstruction(); 1016958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1017958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto pos = range->NextUsePositionRegisterIsBeneficial(next_pos); 1018958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (pos == nullptr) { 1019958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto spill_range = AssignSpillRangeToLiveRange(range->TopLevel()); 1020958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK(first_op_spill->TryMerge(spill_range)); 1021958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Spill(range); 1022958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return true; 1023958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else if (pos->pos().Value() > range->Start().NextInstruction().Value()) { 1024958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto spill_range = AssignSpillRangeToLiveRange(range->TopLevel()); 1025958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CHECK(first_op_spill->TryMerge(spill_range)); 1026958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier SpillBetween(range, range->Start(), pos->pos()); 1027958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!AllocationOk()) return false; 1028958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(UnhandledIsSorted()); 1029958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return true; 1030958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1031958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return false; 1032958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1033958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1034958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1035958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid RegisterAllocator::MeetRegisterConstraints(const InstructionBlock* block) { 1036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int start = block->first_instruction_index(); 1037b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int end = block->last_instruction_index(); 1038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK_NE(-1, start); 1039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = start; i <= end; ++i) { 1040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (code()->IsGapAt(i)) { 1041958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Instruction* instr = nullptr; 1042958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Instruction* prev_instr = nullptr; 1043b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (i < end) instr = InstructionAt(i + 1); 1044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (i > start) prev_instr = InstructionAt(i - 1); 1045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MeetConstraintsBetween(prev_instr, instr, i); 1046b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!AllocationOk()) return; 1047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1050b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Meet register constraints for the instruction in the end. 1051b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!code()->IsGapAt(end)) { 1052b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch MeetRegisterConstraintsForLastInstructionInBlock(block); 1053b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1054b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::MeetRegisterConstraintsForLastInstructionInBlock( 1058958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const InstructionBlock* block) { 1059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int end = block->last_instruction_index(); 1060958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto last_instruction = InstructionAt(end); 1061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (size_t i = 0; i < last_instruction->OutputCount(); i++) { 1062958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto output_operand = last_instruction->OutputAt(i); 1063b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!output_operand->IsConstant()); 1064958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto output = UnallocatedOperand::cast(output_operand); 1065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int output_vreg = output->virtual_register(); 1066958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto range = LiveRangeFor(output_vreg); 1067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool assigned = false; 1068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (output->HasFixedPolicy()) { 1069b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocateFixed(output, -1, false); 1070b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This value is produced on the stack, we never need to spill it. 1071b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (output->IsStackSlot()) { 1072958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(output->index() < 0); 1073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch range->SetSpillOperand(output); 1074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch range->SetSpillStartIndex(end); 1075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assigned = true; 1076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1078958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto succ : block->successors()) { 1079958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const InstructionBlock* successor = code()->InstructionBlockAt(succ); 1080958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(successor->PredecessorCount() == 1); 1081958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int gap_index = successor->first_instruction_index() + 1; 1082b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(code()->IsGapAt(gap_index)); 1083b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1084b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Create an unconstrained operand for the same virtual register 1085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // and insert a gap move from the fixed output to the operand. 1086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UnallocatedOperand* output_copy = 1087b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch new (code_zone()) UnallocatedOperand(UnallocatedOperand::ANY); 1088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch output_copy->set_virtual_register(output_vreg); 1089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1090958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier AddGapMove(gap_index, GapInstruction::START, output, output_copy); 1091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1093b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1094b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!assigned) { 1095958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto succ : block->successors()) { 1096958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const InstructionBlock* successor = code()->InstructionBlockAt(succ); 1097958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(successor->PredecessorCount() == 1); 1098958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int gap_index = successor->first_instruction_index() + 1; 1099958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier range->SpillAtDefinition(local_zone(), gap_index, output); 1100b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch range->SetSpillStartIndex(gap_index); 1101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1106b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::MeetConstraintsBetween(Instruction* first, 1108b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instruction* second, 1109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int gap_index) { 1110958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (first != nullptr) { 1111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Handle fixed temporaries. 1112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (size_t i = 0; i < first->TempCount(); i++) { 1113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto temp = UnallocatedOperand::cast(first->TempAt(i)); 1114b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (temp->HasFixedPolicy()) { 1115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocateFixed(temp, gap_index - 1, false); 1116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Handle constant/fixed output operands. 1120b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (size_t i = 0; i < first->OutputCount(); i++) { 1121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperand* output = first->OutputAt(i); 1122b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (output->IsConstant()) { 1123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int output_vreg = output->index(); 1124958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto range = LiveRangeFor(output_vreg); 1125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch range->SetSpillStartIndex(gap_index - 1); 1126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch range->SetSpillOperand(output); 1127b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto first_output = UnallocatedOperand::cast(output); 1129958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto range = LiveRangeFor(first_output->virtual_register()); 1130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool assigned = false; 1131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (first_output->HasFixedPolicy()) { 1132958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto output_copy = first_output->CopyUnconstrained(code_zone()); 1133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_tagged = HasTaggedValue(first_output->virtual_register()); 1134b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocateFixed(first_output, gap_index, is_tagged); 1135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This value is produced on the stack, we never need to spill it. 1137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (first_output->IsStackSlot()) { 1138958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(first_output->index() < 0); 1139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch range->SetSpillOperand(first_output); 1140b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch range->SetSpillStartIndex(gap_index - 1); 1141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assigned = true; 1142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1143958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier AddGapMove(gap_index, GapInstruction::START, first_output, 1144958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier output_copy); 1145b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1147b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Make sure we add a gap move for spilling (if we have not done 1148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // so already). 1149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!assigned) { 1150958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier range->SpillAtDefinition(local_zone(), gap_index, first_output); 1151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch range->SetSpillStartIndex(gap_index); 1152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1153b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1154b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1157958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (second != nullptr) { 1158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Handle fixed input operands of second instruction. 1159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (size_t i = 0; i < second->InputCount(); i++) { 1160958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto input = second->InputAt(i); 1161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (input->IsImmediate()) continue; // Ignore immediates. 1162958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto cur_input = UnallocatedOperand::cast(input); 1163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (cur_input->HasFixedPolicy()) { 1164958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto input_copy = cur_input->CopyUnconstrained(code_zone()); 1165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool is_tagged = HasTaggedValue(cur_input->virtual_register()); 1166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocateFixed(cur_input, gap_index + 1, is_tagged); 1167958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier AddGapMove(gap_index, GapInstruction::END, input_copy, cur_input); 1168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Handle "output same as input" for second instruction. 1172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (size_t i = 0; i < second->OutputCount(); i++) { 1173958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto output = second->OutputAt(i); 1174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!output->IsUnallocated()) continue; 1175958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto second_output = UnallocatedOperand::cast(output); 1176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (second_output->HasSameAsInputPolicy()) { 1177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(i == 0); // Only valid for first output. 1178b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UnallocatedOperand* cur_input = 1179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UnallocatedOperand::cast(second->InputAt(0)); 1180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int output_vreg = second_output->virtual_register(); 1181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int input_vreg = cur_input->virtual_register(); 1182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1183958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto input_copy = cur_input->CopyUnconstrained(code_zone()); 1184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cur_input->set_virtual_register(second_output->virtual_register()); 1185958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier AddGapMove(gap_index, GapInstruction::END, input_copy, cur_input); 1186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (HasTaggedValue(input_vreg) && !HasTaggedValue(output_vreg)) { 1188b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int index = gap_index + 1; 1189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Instruction* instr = InstructionAt(index); 1190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr->HasPointerMap()) { 1191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch instr->pointer_map()->RecordPointer(input_copy, code_zone()); 1192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (!HasTaggedValue(input_vreg) && HasTaggedValue(output_vreg)) { 1194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The input is assumed to immediately have a tagged representation, 1195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // before the pointer map can be used. I.e. the pointer map at the 1196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // instruction will include the output operand (whose value at the 1197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // beginning of the instruction is equal to the input operand). If 1198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // this is not desired, then the pointer map at this instruction needs 1199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // to be adjusted manually. 1200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1205b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1206b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool RegisterAllocator::IsOutputRegisterOf(Instruction* instr, int index) { 1208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (size_t i = 0; i < instr->OutputCount(); i++) { 1209958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto output = instr->OutputAt(i); 1210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (output->IsRegister() && output->index() == index) return true; 1211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 1213b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1214b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool RegisterAllocator::IsOutputDoubleRegisterOf(Instruction* instr, 1217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int index) { 1218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (size_t i = 0; i < instr->OutputCount(); i++) { 1219958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto output = instr->OutputAt(i); 1220b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (output->IsDoubleRegister() && output->index() == index) return true; 1221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 1223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1226958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid RegisterAllocator::ProcessInstructions(const InstructionBlock* block, 1227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BitVector* live) { 1228b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int block_start = block->first_instruction_index(); 1229958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto block_start_position = 1230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LifetimePosition::FromInstructionIndex(block_start); 1231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int index = block->last_instruction_index(); index >= block_start; 1233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch index--) { 1234958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto curr_position = LifetimePosition::FromInstructionIndex(index); 1235958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto instr = InstructionAt(index); 1236958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(instr != nullptr); 1237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr->IsGapMoves()) { 1238b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Process the moves of the gap instruction, making their sources live. 1239958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto gap = code()->GapAt(index); 1240958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const GapInstruction::InnerPosition kPositions[] = { 1241958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier GapInstruction::END, GapInstruction::START}; 1242958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto position : kPositions) { 1243958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto move = gap->GetParallelMove(position); 1244958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (move == nullptr) continue; 1245958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (position == GapInstruction::END) { 1246958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier curr_position = curr_position.InstructionEnd(); 1247958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 1248958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier curr_position = curr_position.InstructionStart(); 1249958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1250958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto move_ops = move->move_operands(); 1251958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto cur = move_ops->begin(); cur != move_ops->end(); ++cur) { 1252958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto from = cur->source(); 1253958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto to = cur->destination(); 1254958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto hint = to; 1255958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (to->IsUnallocated()) { 1256958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int to_vreg = UnallocatedOperand::cast(to)->virtual_register(); 1257958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto to_range = LiveRangeFor(to_vreg); 1258958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (to_range->is_phi()) { 1259958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!FLAG_turbo_delay_ssa_decon); 1260958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (to_range->is_non_loop_phi()) { 1261958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier hint = to_range->current_hint_operand(); 1262958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1264958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (live->Contains(to_vreg)) { 1265958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Define(curr_position, to, from); 1266958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier live->Remove(to_vreg); 1267958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 1268958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier cur->Eliminate(); 1269958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier continue; 1270958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1272958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 1273958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Define(curr_position, to, from); 1274958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1275958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Use(block_start_position, curr_position, from, hint); 1276958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (from->IsUnallocated()) { 1277958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier live->Add(UnallocatedOperand::cast(from)->virtual_register()); 1278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Process output, inputs, and temps of this non-gap instruction. 1283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (size_t i = 0; i < instr->OutputCount(); i++) { 1284958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto output = instr->OutputAt(i); 1285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (output->IsUnallocated()) { 1286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int out_vreg = UnallocatedOperand::cast(output)->virtual_register(); 1287b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch live->Remove(out_vreg); 1288b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (output->IsConstant()) { 1289b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int out_vreg = output->index(); 1290b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch live->Remove(out_vreg); 1291b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1292958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Define(curr_position, output, nullptr); 1293b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1294b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr->ClobbersRegisters()) { 1296958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int i = 0; i < config()->num_general_registers(); ++i) { 1297b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!IsOutputRegisterOf(instr, i)) { 1298958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto range = FixedLiveRangeFor(i); 1299b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch range->AddUseInterval(curr_position, curr_position.InstructionEnd(), 1300958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier local_zone()); 1301b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1303b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1305b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr->ClobbersDoubleRegisters()) { 1306958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int i = 0; i < config()->num_aliased_double_registers(); ++i) { 1307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!IsOutputDoubleRegisterOf(instr, i)) { 1308958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto range = FixedDoubleLiveRangeFor(i); 1309b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch range->AddUseInterval(curr_position, curr_position.InstructionEnd(), 1310958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier local_zone()); 1311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1313b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (size_t i = 0; i < instr->InputCount(); i++) { 1316958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto input = instr->InputAt(i); 1317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (input->IsImmediate()) continue; // Ignore immediates. 1318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LifetimePosition use_pos; 1319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (input->IsUnallocated() && 1320b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UnallocatedOperand::cast(input)->IsUsedAtStart()) { 1321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch use_pos = curr_position; 1322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch use_pos = curr_position.InstructionEnd(); 1324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1326958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Use(block_start_position, use_pos, input, nullptr); 1327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (input->IsUnallocated()) { 1328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch live->Add(UnallocatedOperand::cast(input)->virtual_register()); 1329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1330b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1331b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1332b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (size_t i = 0; i < instr->TempCount(); i++) { 1333958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto temp = instr->TempAt(i); 1334b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (instr->ClobbersTemps()) { 1335b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (temp->IsRegister()) continue; 1336b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (temp->IsUnallocated()) { 1337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UnallocatedOperand* temp_unalloc = UnallocatedOperand::cast(temp); 1338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (temp_unalloc->HasFixedPolicy()) { 1339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch continue; 1340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1343958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Use(block_start_position, curr_position.InstructionEnd(), temp, 1344958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier nullptr); 1345958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Define(curr_position, temp, nullptr); 1346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1352958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid RegisterAllocator::ResolvePhis(const InstructionBlock* block) { 1353958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto phi : block->phis()) { 1354958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (FLAG_turbo_reuse_spill_slots) { 1355958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto res = phi_map_.insert( 1356958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier std::make_pair(phi->virtual_register(), PhiMapValue(phi, block))); 1357958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(res.second); 1358958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier USE(res); 1359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1360958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto output = phi->output(); 1361958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int phi_vreg = phi->virtual_register(); 1362958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!FLAG_turbo_delay_ssa_decon) { 1363958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (size_t i = 0; i < phi->operands().size(); ++i) { 1364958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier InstructionBlock* cur_block = 1365958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier code()->InstructionBlockAt(block->predecessors()[i]); 1366958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier AddGapMove(cur_block->last_instruction_index() - 1, GapInstruction::END, 1367958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier phi->inputs()[i], output); 1368958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!InstructionAt(cur_block->last_instruction_index()) 1369958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ->HasPointerMap()); 1370958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1371958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1372958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto live_range = LiveRangeFor(phi_vreg); 1373958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int gap_index = block->first_instruction_index(); 1374958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier live_range->SpillAtDefinition(local_zone(), gap_index, output); 1375958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier live_range->SetSpillStartIndex(gap_index); 1376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We use the phi-ness of some nodes in some later heuristics. 1377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch live_range->set_is_phi(true); 1378958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier live_range->set_is_non_loop_phi(!block->IsLoopHeader()); 1379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::MeetRegisterConstraints() { 1384958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto block : code()->instruction_blocks()) { 1385958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier MeetRegisterConstraints(block); 1386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::ResolvePhis() { 1391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Process the blocks in reverse order. 1392958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto i = code()->instruction_blocks().rbegin(); 1393958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier i != code()->instruction_blocks().rend(); ++i) { 1394958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ResolvePhis(*i); 1395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1396b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1397b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1398b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochParallelMove* RegisterAllocator::GetConnectingParallelMove( 1400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LifetimePosition pos) { 1401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int index = pos.InstructionIndex(); 1402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (code()->IsGapAt(index)) { 1403958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto gap = code()->GapAt(index); 1404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return gap->GetOrCreateParallelMove( 1405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pos.IsInstructionStart() ? GapInstruction::START : GapInstruction::END, 1406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code_zone()); 1407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int gap_pos = pos.IsInstructionStart() ? (index - 1) : (index + 1); 1409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return code()->GapAt(gap_pos)->GetOrCreateParallelMove( 1410b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch (gap_pos < index) ? GapInstruction::AFTER : GapInstruction::BEFORE, 1411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch code_zone()); 1412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1415958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierconst InstructionBlock* RegisterAllocator::GetInstructionBlock( 1416958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LifetimePosition pos) { 1417958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return code()->GetInstructionBlock(pos.InstructionIndex()); 1418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::ConnectRanges() { 1422958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto first_range : live_ranges()) { 1423958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (first_range == nullptr || first_range->IsChild()) continue; 1424958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto second_range = first_range->next(); 1425958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (second_range != nullptr) { 1426958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto pos = second_range->Start(); 1427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!second_range->IsSpilled()) { 1428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Add gap move if the two live ranges touch and there is no block 1429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // boundary. 1430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (first_range->End().Value() == pos.Value()) { 1431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool should_insert = true; 1432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (IsBlockBoundary(pos)) { 1433958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier should_insert = 1434958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier CanEagerlyResolveControlFlow(GetInstructionBlock(pos)); 1435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (should_insert) { 1437958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto move = GetConnectingParallelMove(pos); 1438958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto prev_operand = first_range->CreateAssignedOperand(code_zone()); 1439958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto cur_operand = second_range->CreateAssignedOperand(code_zone()); 1440b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch move->AddMove(prev_operand, cur_operand, code_zone()); 1441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch first_range = second_range; 1445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch second_range = second_range->next(); 1446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1451958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool RegisterAllocator::CanEagerlyResolveControlFlow( 1452958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const InstructionBlock* block) const { 1453b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (block->PredecessorCount() != 1) return false; 1454958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return block->predecessors()[0].IsNext(block->rpo_number()); 1455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1458958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniernamespace { 1459958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1460958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass LiveRangeBound { 1461958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: 1462958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier explicit LiveRangeBound(const LiveRange* range) 1463958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier : range_(range), start_(range->Start()), end_(range->End()) { 1464958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!range->IsEmpty()); 1465958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1466958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1467958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool CanCover(LifetimePosition position) { 1468958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return start_.Value() <= position.Value() && 1469958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier position.Value() < end_.Value(); 1470958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1471958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1472958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const LiveRange* const range_; 1473958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const LifetimePosition start_; 1474958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const LifetimePosition end_; 1475958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1476958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private: 1477958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DISALLOW_COPY_AND_ASSIGN(LiveRangeBound); 1478958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}; 1479958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1480958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1481958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstruct FindResult { 1482958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const LiveRange* cur_cover_; 1483958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const LiveRange* pred_cover_; 1484958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}; 1485958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1486958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1487958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass LiveRangeBoundArray { 1488958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: 1489958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LiveRangeBoundArray() : length_(0), start_(nullptr) {} 1490958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1491958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool ShouldInitialize() { return start_ == nullptr; } 1492958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1493958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void Initialize(Zone* zone, const LiveRange* const range) { 1494958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier size_t length = 0; 1495958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto i = range; i != nullptr; i = i->next()) length++; 1496958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier start_ = zone->NewArray<LiveRangeBound>(static_cast<int>(length)); 1497958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier length_ = length; 1498958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto curr = start_; 1499958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto i = range; i != nullptr; i = i->next(), ++curr) { 1500958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier new (curr) LiveRangeBound(i); 1501958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1502958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1503958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1504958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LiveRangeBound* Find(const LifetimePosition position) const { 1505958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier size_t left_index = 0; 1506958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier size_t right_index = length_; 1507958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (true) { 1508958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier size_t current_index = left_index + (right_index - left_index) / 2; 1509958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(right_index > current_index); 1510958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto bound = &start_[current_index]; 1511958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (bound->start_.Value() <= position.Value()) { 1512958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (position.Value() < bound->end_.Value()) return bound; 1513958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(left_index < current_index); 1514958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier left_index = current_index; 1515958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 1516958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier right_index = current_index; 1517958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1518958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1519958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1520958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1521958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LiveRangeBound* FindPred(const InstructionBlock* pred) { 1522958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto pred_end = 1523958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LifetimePosition::FromInstructionIndex(pred->last_instruction_index()); 1524958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Find(pred_end); 1525958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1526958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1527958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LiveRangeBound* FindSucc(const InstructionBlock* succ) { 1528958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto succ_start = 1529958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LifetimePosition::FromInstructionIndex(succ->first_instruction_index()); 1530958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return Find(succ_start); 1531958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1532958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1533958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier void Find(const InstructionBlock* block, const InstructionBlock* pred, 1534958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FindResult* result) const { 1535958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto pred_end = 1536958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LifetimePosition::FromInstructionIndex(pred->last_instruction_index()); 1537958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto bound = Find(pred_end); 1538958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier result->pred_cover_ = bound->range_; 1539958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto cur_start = LifetimePosition::FromInstructionIndex( 1540958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier block->first_instruction_index()); 1541958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Common case. 1542958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (bound->CanCover(cur_start)) { 1543958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier result->cur_cover_ = bound->range_; 1544958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 1545958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1546958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier result->cur_cover_ = Find(cur_start)->range_; 1547958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(result->pred_cover_ != nullptr && result->cur_cover_ != nullptr); 1548958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1549958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1550958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private: 1551958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier size_t length_; 1552958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LiveRangeBound* start_; 1553958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1554958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DISALLOW_COPY_AND_ASSIGN(LiveRangeBoundArray); 1555958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}; 1556958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1557958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1558958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierclass LiveRangeFinder { 1559958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier public: 1560958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier explicit LiveRangeFinder(const RegisterAllocator& allocator) 1561958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier : allocator_(allocator), 1562958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bounds_length_(static_cast<int>(allocator.live_ranges().size())), 1563958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bounds_(allocator.local_zone()->NewArray<LiveRangeBoundArray>( 1564958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bounds_length_)) { 1565958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int i = 0; i < bounds_length_; ++i) { 1566958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier new (&bounds_[i]) LiveRangeBoundArray(); 1567958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1568958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1569958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1570958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LiveRangeBoundArray* ArrayFor(int operand_index) { 1571958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(operand_index < bounds_length_); 1572958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto range = allocator_.live_ranges()[operand_index]; 1573958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(range != nullptr && !range->IsEmpty()); 1574958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto array = &bounds_[operand_index]; 1575958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (array->ShouldInitialize()) { 1576958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier array->Initialize(allocator_.local_zone(), range); 1577958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1578958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return array; 1579958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1580958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1581958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier private: 1582958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const RegisterAllocator& allocator_; 1583958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const int bounds_length_; 1584958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LiveRangeBoundArray* const bounds_; 1585958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1586958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DISALLOW_COPY_AND_ASSIGN(LiveRangeFinder); 1587958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier}; 1588958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1589958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} // namespace 1590958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1591958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1592b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::ResolveControlFlow() { 1593958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Lazily linearize live ranges in memory for fast lookup. 1594958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LiveRangeFinder finder(*this); 1595958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto block : code()->instruction_blocks()) { 1596b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (CanEagerlyResolveControlFlow(block)) continue; 1597958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (FLAG_turbo_delay_ssa_decon) { 1598958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // resolve phis 1599958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto phi : block->phis()) { 1600958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto* block_bound = 1601958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier finder.ArrayFor(phi->virtual_register())->FindSucc(block); 1602958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto phi_output = 1603958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier block_bound->range_->CreateAssignedOperand(code_zone()); 1604958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier phi->output()->ConvertTo(phi_output->kind(), phi_output->index()); 1605958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier size_t pred_index = 0; 1606958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto pred : block->predecessors()) { 1607958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const InstructionBlock* pred_block = code()->InstructionBlockAt(pred); 1608958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto* pred_bound = finder.ArrayFor(phi->operands()[pred_index]) 1609958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ->FindPred(pred_block); 1610958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto pred_op = pred_bound->range_->CreateAssignedOperand(code_zone()); 1611958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier phi->inputs()[pred_index] = pred_op; 1612958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ResolveControlFlow(block, phi_output, pred_block, pred_op); 1613958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier pred_index++; 1614958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1615958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1616958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1617958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto live = live_in_sets_[block->rpo_number().ToInt()]; 1618b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BitVector::Iterator iterator(live); 1619b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (!iterator.Done()) { 1620958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto* array = finder.ArrayFor(iterator.Current()); 1621958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto pred : block->predecessors()) { 1622958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier FindResult result; 1623958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const auto* pred_block = code()->InstructionBlockAt(pred); 1624958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier array->Find(block, pred_block, &result); 1625958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (result.cur_cover_ == result.pred_cover_ || 1626958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier result.cur_cover_->IsSpilled()) 1627958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier continue; 1628958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto pred_op = result.pred_cover_->CreateAssignedOperand(code_zone()); 1629958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto cur_op = result.cur_cover_->CreateAssignedOperand(code_zone()); 1630958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ResolveControlFlow(block, cur_op, pred_block, pred_op); 1631b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1632b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch iterator.Advance(); 1633b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1634b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1635b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1636b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1637b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1638958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Berniervoid RegisterAllocator::ResolveControlFlow(const InstructionBlock* block, 1639958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier InstructionOperand* cur_op, 1640958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const InstructionBlock* pred, 1641958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier InstructionOperand* pred_op) { 1642958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (pred_op->Equals(cur_op)) return; 1643958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int gap_index; 1644958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier GapInstruction::InnerPosition position; 1645958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (block->PredecessorCount() == 1) { 1646958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier gap_index = block->first_instruction_index(); 1647958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier position = GapInstruction::START; 1648958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 1649958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(pred->SuccessorCount() == 1); 1650958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!InstructionAt(pred->last_instruction_index())->HasPointerMap()); 1651958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier gap_index = pred->last_instruction_index() - 1; 1652958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier position = GapInstruction::END; 1653958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1654958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier AddGapMove(gap_index, position, pred_op, cur_op); 1655958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1656958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1657958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1658b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::BuildLiveRanges() { 1659b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Process the blocks in reverse order. 1660958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int block_id = code()->InstructionBlockCount() - 1; block_id >= 0; 1661b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch --block_id) { 1662958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto block = 1663958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier code()->InstructionBlockAt(BasicBlock::RpoNumber::FromInt(block_id)); 1664958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto live = ComputeLiveOut(block); 1665b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Initially consider all live_out values live for the entire block. We 1666b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // will shorten these intervals if necessary. 1667b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddInitialIntervals(block, live); 1668b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1669b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Process the instructions in reverse order, generating and killing 1670b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // live values. 1671b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ProcessInstructions(block, live); 1672b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // All phi output operands are killed by this block. 1673958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto phi : block->phis()) { 1674b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The live range interval already ends at the first instruction of the 1675b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // block. 1676958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int phi_vreg = phi->virtual_register(); 1677958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier live->Remove(phi_vreg); 1678958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!FLAG_turbo_delay_ssa_decon) { 1679958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier InstructionOperand* hint = nullptr; 1680958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier InstructionOperand* phi_operand = nullptr; 1681958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto gap = 1682958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier GetLastGap(code()->InstructionBlockAt(block->predecessors()[0])); 1683958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto move = 1684958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier gap->GetOrCreateParallelMove(GapInstruction::END, code_zone()); 1685958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int j = 0; j < move->move_operands()->length(); ++j) { 1686958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto to = move->move_operands()->at(j).destination(); 1687958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (to->IsUnallocated() && 1688958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier UnallocatedOperand::cast(to)->virtual_register() == phi_vreg) { 1689958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier hint = move->move_operands()->at(j).source(); 1690958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier phi_operand = to; 1691958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier break; 1692958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1693b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1694958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(hint != nullptr); 1695958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto block_start = LifetimePosition::FromInstructionIndex( 1696958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier block->first_instruction_index()); 1697958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier Define(block_start, phi_operand, hint); 1698b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1699b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1700b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1701b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Now live is live_in for this block except not including values live 1702b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // out on backward successor edges. 1703b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch live_in_sets_[block_id] = live; 1704b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1705b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (block->IsLoopHeader()) { 1706b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Add a live range stretching from the first loop instruction to the last 1707b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // for each value live on entry to the header. 1708b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch BitVector::Iterator iterator(live); 1709958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto start = LifetimePosition::FromInstructionIndex( 1710b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block->first_instruction_index()); 1711958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto end = LifetimePosition::FromInstructionIndex( 1712958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier code()->LastLoopInstructionIndex(block)).NextInstruction(); 1713b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch while (!iterator.Done()) { 1714b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int operand_index = iterator.Current(); 1715958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto range = LiveRangeFor(operand_index); 1716958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier range->EnsureInterval(start, end, local_zone()); 1717b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch iterator.Advance(); 1718b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1719b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Insert all values into the live in sets of all blocks in the loop. 1720958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int i = block->rpo_number().ToInt() + 1; 1721958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier i < block->loop_end().ToInt(); ++i) { 1722b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch live_in_sets_[i]->Union(*live); 1723b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1724b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1725958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1726b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1727958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto range : live_ranges()) { 1728958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (range == nullptr) continue; 1729958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier range->kind_ = RequiredRegisterKind(range->id()); 1730958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // TODO(bmeurer): This is a horrible hack to make sure that for constant 1731958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // live ranges, every use requires the constant to be in a register. 1732958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Without this hack, all uses with "any" policy would get the constant 1733958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // operand assigned. 1734958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (range->HasSpillOperand() && range->GetSpillOperand()->IsConstant()) { 1735958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto pos = range->first_pos(); pos != nullptr; pos = pos->next_) { 1736958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier pos->register_beneficial_ = true; 1737958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // TODO(dcarney): should the else case assert requires_reg_ == false? 1738958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Can't mark phis as needing a register. 1739958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!code() 1740958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ->InstructionAt(pos->pos().InstructionIndex()) 1741958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ->IsGapMoves()) { 1742958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier pos->requires_reg_ = true; 1743b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1744b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1745b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1746b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1747958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 1748b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1749958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1750958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierbool RegisterAllocator::ExistsUseWithoutDefinition() { 1751958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier bool found = false; 1752958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier BitVector::Iterator iterator(live_in_sets_[0]); 1753958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (!iterator.Done()) { 1754958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier found = true; 1755958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int operand_index = iterator.Current(); 1756958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("Register allocator error: live v%d reached first block.\n", 1757958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier operand_index); 1758958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LiveRange* range = LiveRangeFor(operand_index); 1759958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" (first use is at %d)\n", range->first_pos()->pos().Value()); 1760958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (debug_name() == nullptr) { 1761958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF("\n"); 1762958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 1763958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier PrintF(" (function: %s)\n", debug_name()); 1764b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1765958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier iterator.Advance(); 1766b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1767958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return found; 1768b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1769b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1770b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1771b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool RegisterAllocator::SafePointsAreInOrder() const { 1772b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int safe_point = 0; 1773958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto map : *code()->pointer_maps()) { 1774b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (safe_point > map->instruction_position()) return false; 1775b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch safe_point = map->instruction_position(); 1776b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1777b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 1778b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1779b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1780b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1781b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::PopulatePointerMaps() { 1782b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(SafePointsAreInOrder()); 1783b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1784b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Iterate over all safe point positions and record a pointer 1785b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // for all spilled live ranges at this point. 1786b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int last_range_start = 0; 1787958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto pointer_maps = code()->pointer_maps(); 1788b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch PointerMapDeque::const_iterator first_it = pointer_maps->begin(); 1789958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (LiveRange* range : live_ranges()) { 1790958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (range == nullptr) continue; 1791b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Iterate over the first parts of multi-part live ranges. 1792958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (range->IsChild()) continue; 1793b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Skip non-reference values. 1794b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!HasTaggedValue(range->id())) continue; 1795b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Skip empty live ranges. 1796b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (range->IsEmpty()) continue; 1797b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1798b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Find the extent of the range and its children. 1799b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int start = range->Start().InstructionIndex(); 1800b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int end = 0; 1801958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto cur = range; cur != nullptr; cur = cur->next()) { 1802958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto this_end = cur->End(); 1803b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (this_end.InstructionIndex() > end) end = this_end.InstructionIndex(); 1804b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(cur->Start().InstructionIndex() >= start); 1805b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1806b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1807b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Most of the ranges are in order, but not all. Keep an eye on when they 1808b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // step backwards and reset the first_it so we don't miss any safe points. 1809b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (start < last_range_start) first_it = pointer_maps->begin(); 1810b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch last_range_start = start; 1811b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1812b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Step across all the safe points that are before the start of this range, 1813b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // recording how far we step in order to save doing this for the next range. 1814b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (; first_it != pointer_maps->end(); ++first_it) { 1815958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto map = *first_it; 1816b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (map->instruction_position() >= start) break; 1817b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1818b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1819b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Step through the safe points to see whether they are in the range. 1820958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto it = first_it; it != pointer_maps->end(); ++it) { 1821958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto map = *it; 1822b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int safe_point = map->instruction_position(); 1823b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1824b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The safe points are sorted so we can stop searching here. 1825b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (safe_point - 1 > end) break; 1826b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1827b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Advance to the next active range that covers the current 1828b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // safe point position. 1829958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto safe_point_pos = LifetimePosition::FromInstructionIndex(safe_point); 1830958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto cur = range; 1831958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (cur != nullptr && !cur->Covers(safe_point_pos)) { 1832b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cur = cur->next(); 1833b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1834958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (cur == nullptr) continue; 1835b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1836b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check if the live range is spilled and the safe point is after 1837b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the spill position. 1838958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (range->HasSpillOperand() && 1839b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch safe_point >= range->spill_start_index() && 1840b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !range->GetSpillOperand()->IsConstant()) { 1841b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceAlloc("Pointer for range %d (spilled at %d) at safe point %d\n", 1842b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch range->id(), range->spill_start_index(), safe_point); 1843b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->RecordPointer(range->GetSpillOperand(), code_zone()); 1844b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1845b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1846b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!cur->IsSpilled()) { 1847b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceAlloc( 1848b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "Pointer in register for range %d (start at %d) " 1849b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "at safe point %d\n", 1850b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch cur->id(), cur->Start().Value(), safe_point); 1851b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionOperand* operand = cur->CreateAssignedOperand(code_zone()); 1852b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!operand->IsStackSlot()); 1853b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch map->RecordPointer(operand, code_zone()); 1854b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1855b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1856b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1857b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1858b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1859b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1860b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::AllocateGeneralRegisters() { 1861958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier num_registers_ = config()->num_general_registers(); 1862b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mode_ = GENERAL_REGISTERS; 1863b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocateRegisters(); 1864b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1865b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1866b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1867b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::AllocateDoubleRegisters() { 1868958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier num_registers_ = config()->num_aliased_double_registers(); 1869b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch mode_ = DOUBLE_REGISTERS; 1870b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AllocateRegisters(); 1871b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1872b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1873b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1874b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::AllocateRegisters() { 1875958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(unhandled_live_ranges().empty()); 1876b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1877958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto range : live_ranges()) { 1878958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (range == nullptr) continue; 1879958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (range->Kind() == mode_) { 1880958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier AddToUnhandledUnsorted(range); 1881b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1882b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1883b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SortUnhandled(); 1884b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(UnhandledIsSorted()); 1885b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1886958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(reusable_slots().empty()); 1887958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(active_live_ranges().empty()); 1888958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(inactive_live_ranges().empty()); 1889b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1890b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mode_ == DOUBLE_REGISTERS) { 1891958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int i = 0; i < config()->num_aliased_double_registers(); ++i) { 1892958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto current = fixed_double_live_ranges()[i]; 1893958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (current != nullptr) { 1894b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddToInactive(current); 1895b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1896b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1897b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1898b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(mode_ == GENERAL_REGISTERS); 1899958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto current : fixed_live_ranges()) { 1900958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (current != nullptr) { 1901b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddToInactive(current); 1902b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1903b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1904b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1905b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1906958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (!unhandled_live_ranges().empty()) { 1907b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(UnhandledIsSorted()); 1908958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto current = unhandled_live_ranges().back(); 1909958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier unhandled_live_ranges().pop_back(); 1910b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(UnhandledIsSorted()); 1911958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto position = current->Start(); 1912b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 1913b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch allocation_finger_ = position; 1914b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 1915b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceAlloc("Processing interval %d start=%d\n", current->id(), 1916b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch position.Value()); 1917b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1918958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!current->HasNoSpillType()) { 1919b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceAlloc("Live range %d already has a spill operand\n", current->id()); 1920958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto next_pos = position; 1921b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (code()->IsGapAt(next_pos.InstructionIndex())) { 1922b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_pos = next_pos.NextInstruction(); 1923b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1924958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto pos = current->NextUsePositionRegisterIsBeneficial(next_pos); 1925b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If the range already has a spill operand and it doesn't need a 1926b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // register immediately, split it and spill the first part of the range. 1927958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (pos == nullptr) { 1928b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Spill(current); 1929b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch continue; 1930b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (pos->pos().Value() > 1931b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current->Start().NextInstruction().Value()) { 1932b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Do not spill live range eagerly if use position that can benefit from 1933b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the register is too close to the start of live range. 1934b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SpillBetween(current, current->Start(), pos->pos()); 1935b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!AllocationOk()) return; 1936b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(UnhandledIsSorted()); 1937b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch continue; 1938b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1939b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1940b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1941958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (FLAG_turbo_reuse_spill_slots) { 1942958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (TryReuseSpillForPhi(current)) { 1943958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier continue; 1944958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1945958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!AllocationOk()) return; 1946958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } 1947958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 1948958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (size_t i = 0; i < active_live_ranges().size(); ++i) { 1949958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto cur_active = active_live_ranges()[i]; 1950b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (cur_active->End().Value() <= position.Value()) { 1951b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ActiveToHandled(cur_active); 1952b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch --i; // The live range was removed from the list of active live ranges. 1953b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (!cur_active->Covers(position)) { 1954b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ActiveToInactive(cur_active); 1955b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch --i; // The live range was removed from the list of active live ranges. 1956b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1957b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1958b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1959958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (size_t i = 0; i < inactive_live_ranges().size(); ++i) { 1960958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto cur_inactive = inactive_live_ranges()[i]; 1961b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (cur_inactive->End().Value() <= position.Value()) { 1962b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InactiveToHandled(cur_inactive); 1963b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch --i; // Live range was removed from the list of inactive live ranges. 1964b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else if (cur_inactive->Covers(position)) { 1965b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InactiveToActive(cur_inactive); 1966b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch --i; // Live range was removed from the list of inactive live ranges. 1967b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1968b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1969b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1970b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!current->HasRegisterAssigned() && !current->IsSpilled()); 1971b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1972b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch bool result = TryAllocateFreeReg(current); 1973b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!AllocationOk()) return; 1974b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1975b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!result) AllocateBlockedReg(current); 1976b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!AllocationOk()) return; 1977b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1978b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (current->HasRegisterAssigned()) { 1979b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddToActive(current); 1980b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1981b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1982b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1983958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reusable_slots().clear(); 1984958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier active_live_ranges().clear(); 1985958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inactive_live_ranges().clear(); 1986b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1987b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1988b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1989b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochconst char* RegisterAllocator::RegisterName(int allocation_index) { 1990b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (mode_ == GENERAL_REGISTERS) { 1991958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return config()->general_register_name(allocation_index); 1992b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 1993958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return config()->double_register_name(allocation_index); 1994b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 1995b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 1996b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1997b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 1998b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool RegisterAllocator::HasTaggedValue(int virtual_register) const { 1999b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return code()->IsReference(virtual_register); 2000b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2001b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2002b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2003b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochRegisterKind RegisterAllocator::RequiredRegisterKind( 2004b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int virtual_register) const { 2005b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return (code()->IsDouble(virtual_register)) ? DOUBLE_REGISTERS 2006b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch : GENERAL_REGISTERS; 2007b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2008b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2009b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2010b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::AddToActive(LiveRange* range) { 2011b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceAlloc("Add live range %d to active\n", range->id()); 2012958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier active_live_ranges().push_back(range); 2013b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2014b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2015b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2016b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::AddToInactive(LiveRange* range) { 2017b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceAlloc("Add live range %d to inactive\n", range->id()); 2018958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inactive_live_ranges().push_back(range); 2019b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2020b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2021b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2022b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::AddToUnhandledSorted(LiveRange* range) { 2023958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (range == nullptr || range->IsEmpty()) return; 2024b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!range->HasRegisterAssigned() && !range->IsSpilled()); 2025b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(allocation_finger_.Value() <= range->Start().Value()); 2026958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (int i = static_cast<int>(unhandled_live_ranges().size() - 1); i >= 0; 2027958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier --i) { 2028958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto cur_range = unhandled_live_ranges().at(i); 2029958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!range->ShouldBeAllocatedBefore(cur_range)) continue; 2030958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier TraceAlloc("Add live range %d to unhandled at %d\n", range->id(), i + 1); 2031958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto it = unhandled_live_ranges().begin() + (i + 1); 2032958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier unhandled_live_ranges().insert(it, range); 2033958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(UnhandledIsSorted()); 2034958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return; 2035b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2036b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceAlloc("Add live range %d to unhandled at start\n", range->id()); 2037958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier unhandled_live_ranges().insert(unhandled_live_ranges().begin(), range); 2038b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(UnhandledIsSorted()); 2039b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2040b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2041b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2042b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::AddToUnhandledUnsorted(LiveRange* range) { 2043958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (range == nullptr || range->IsEmpty()) return; 2044b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!range->HasRegisterAssigned() && !range->IsSpilled()); 2045b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceAlloc("Add live range %d to unhandled unsorted at end\n", range->id()); 2046958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier unhandled_live_ranges().push_back(range); 2047b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2048b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2049b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2050958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic bool UnhandledSortHelper(LiveRange* a, LiveRange* b) { 2051958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!a->ShouldBeAllocatedBefore(b) || !b->ShouldBeAllocatedBefore(a)); 2052958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (a->ShouldBeAllocatedBefore(b)) return false; 2053958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (b->ShouldBeAllocatedBefore(a)) return true; 2054958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return a->id() < b->id(); 2055b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2056b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2057b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2058b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// Sort the unhandled live ranges so that the ranges to be processed first are 2059b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// at the end of the array list. This is convenient for the register allocation 2060b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch// algorithm because it is efficient to remove elements from the end. 2061b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::SortUnhandled() { 2062b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceAlloc("Sort unhandled\n"); 2063958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier std::sort(unhandled_live_ranges().begin(), unhandled_live_ranges().end(), 2064958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier &UnhandledSortHelper); 2065b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2066b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2067b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2068b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool RegisterAllocator::UnhandledIsSorted() { 2069958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier size_t len = unhandled_live_ranges().size(); 2070958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (size_t i = 1; i < len; i++) { 2071958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto a = unhandled_live_ranges().at(i - 1); 2072958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto b = unhandled_live_ranges().at(i); 2073b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (a->Start().Value() < b->Start().Value()) return false; 2074b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2075b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 2076b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2077b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2078b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2079b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::FreeSpillSlot(LiveRange* range) { 2080958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!FLAG_turbo_reuse_spill_slots); 2081b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Check that we are the last range. 2082958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (range->next() != nullptr) return; 2083958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!range->TopLevel()->HasSpillOperand()) return; 2084958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto spill_operand = range->TopLevel()->GetSpillOperand(); 2085b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (spill_operand->IsConstant()) return; 2086b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (spill_operand->index() >= 0) { 2087958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reusable_slots().push_back(range); 2088b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2089b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2090b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2091b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2092b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochInstructionOperand* RegisterAllocator::TryReuseSpillSlot(LiveRange* range) { 2093958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier DCHECK(!FLAG_turbo_reuse_spill_slots); 2094958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (reusable_slots().empty()) return nullptr; 2095958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (reusable_slots().front()->End().Value() > 2096b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch range->TopLevel()->Start().Value()) { 2097958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return nullptr; 2098b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2099958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto result = reusable_slots().front()->TopLevel()->GetSpillOperand(); 2100958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier reusable_slots().erase(reusable_slots().begin()); 2101b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 2102b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2103b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2104b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2105b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::ActiveToHandled(LiveRange* range) { 2106958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RemoveElement(&active_live_ranges(), range); 2107b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceAlloc("Moving live range %d from active to handled\n", range->id()); 2108958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!FLAG_turbo_reuse_spill_slots) FreeSpillSlot(range); 2109b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2110b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2111b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2112b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::ActiveToInactive(LiveRange* range) { 2113958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RemoveElement(&active_live_ranges(), range); 2114958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier inactive_live_ranges().push_back(range); 2115b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceAlloc("Moving live range %d from active to inactive\n", range->id()); 2116b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2117b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2118b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2119b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::InactiveToHandled(LiveRange* range) { 2120958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RemoveElement(&inactive_live_ranges(), range); 2121b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceAlloc("Moving live range %d from inactive to handled\n", range->id()); 2122958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!FLAG_turbo_reuse_spill_slots) FreeSpillSlot(range); 2123b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2124b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2125b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2126b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::InactiveToActive(LiveRange* range) { 2127958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RemoveElement(&inactive_live_ranges(), range); 2128958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier active_live_ranges().push_back(range); 2129b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceAlloc("Moving live range %d from inactive to active\n", range->id()); 2130b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2131b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2132b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2133b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool RegisterAllocator::TryAllocateFreeReg(LiveRange* current) { 2134958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LifetimePosition free_until_pos[RegisterConfiguration::kMaxDoubleRegisters]; 2135b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2136b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < num_registers_; i++) { 2137b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch free_until_pos[i] = LifetimePosition::MaxPosition(); 2138b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2139b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2140958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto cur_active : active_live_ranges()) { 2141b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch free_until_pos[cur_active->assigned_register()] = 2142b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LifetimePosition::FromInstructionIndex(0); 2143b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2144b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2145958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto cur_inactive : inactive_live_ranges()) { 2146b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(cur_inactive->End().Value() > current->Start().Value()); 2147958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto next_intersection = cur_inactive->FirstIntersection(current); 2148b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!next_intersection.IsValid()) continue; 2149b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int cur_reg = cur_inactive->assigned_register(); 2150b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch free_until_pos[cur_reg] = Min(free_until_pos[cur_reg], next_intersection); 2151b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2152b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2153958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto hint = current->FirstHint(); 2154958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (hint != nullptr && (hint->IsRegister() || hint->IsDoubleRegister())) { 2155b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int register_index = hint->index(); 2156b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceAlloc( 2157b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch "Found reg hint %s (free until [%d) for live range %d (end %d[).\n", 2158b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RegisterName(register_index), free_until_pos[register_index].Value(), 2159b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current->id(), current->End().Value()); 2160b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2161b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The desired register is free until the end of the current live range. 2162b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (free_until_pos[register_index].Value() >= current->End().Value()) { 2163b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceAlloc("Assigning preferred reg %s to live range %d\n", 2164b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch RegisterName(register_index), current->id()); 2165b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetLiveRangeAssignedRegister(current, register_index); 2166b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 2167b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2168b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2169b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2170b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Find the register which stays free for the longest time. 2171b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int reg = 0; 2172b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 1; i < RegisterCount(); ++i) { 2173b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (free_until_pos[i].Value() > free_until_pos[reg].Value()) { 2174b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reg = i; 2175b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2176b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2177b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2178958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto pos = free_until_pos[reg]; 2179b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2180b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (pos.Value() <= current->Start().Value()) { 2181b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // All registers are blocked. 2182b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return false; 2183b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2184b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2185b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (pos.Value() < current->End().Value()) { 2186b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Register reg is available at the range start but becomes blocked before 2187b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the range end. Split current at position where it becomes blocked. 2188958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto tail = SplitRangeAt(current, pos); 2189b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!AllocationOk()) return false; 2190b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddToUnhandledSorted(tail); 2191b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2192b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2193b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Register reg is available at the range start and is free until 2194b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // the range end. 2195b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(pos.Value() >= current->End().Value()); 2196b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceAlloc("Assigning free reg %s to live range %d\n", RegisterName(reg), 2197b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current->id()); 2198b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetLiveRangeAssignedRegister(current, reg); 2199b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2200b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return true; 2201b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2202b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2203b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2204b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::AllocateBlockedReg(LiveRange* current) { 2205958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto register_use = current->NextRegisterPosition(current->Start()); 2206958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (register_use == nullptr) { 2207b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // There is no use in the current live range that requires a register. 2208b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We can just spill it. 2209b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Spill(current); 2210b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 2211b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2212b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2213958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LifetimePosition use_pos[RegisterConfiguration::kMaxDoubleRegisters]; 2214958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier LifetimePosition block_pos[RegisterConfiguration::kMaxDoubleRegisters]; 2215b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2216b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 0; i < num_registers_; i++) { 2217b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch use_pos[i] = block_pos[i] = LifetimePosition::MaxPosition(); 2218b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2219b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2220958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto range : active_live_ranges()) { 2221b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int cur_reg = range->assigned_register(); 2222b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (range->IsFixed() || !range->CanBeSpilled(current->Start())) { 2223b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block_pos[cur_reg] = use_pos[cur_reg] = 2224b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LifetimePosition::FromInstructionIndex(0); 2225b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2226958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto next_use = 2227b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch range->NextUsePositionRegisterIsBeneficial(current->Start()); 2228958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (next_use == nullptr) { 2229b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch use_pos[cur_reg] = range->End(); 2230b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2231b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch use_pos[cur_reg] = next_use->pos(); 2232b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2233b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2234b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2235b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2236958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto range : inactive_live_ranges()) { 2237b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(range->End().Value() > current->Start().Value()); 2238958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto next_intersection = range->FirstIntersection(current); 2239b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!next_intersection.IsValid()) continue; 2240b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int cur_reg = range->assigned_register(); 2241b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (range->IsFixed()) { 2242b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block_pos[cur_reg] = Min(block_pos[cur_reg], next_intersection); 2243b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch use_pos[cur_reg] = Min(block_pos[cur_reg], use_pos[cur_reg]); 2244b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2245b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch use_pos[cur_reg] = Min(use_pos[cur_reg], next_intersection); 2246b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2247b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2248b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2249b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int reg = 0; 2250b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch for (int i = 1; i < RegisterCount(); ++i) { 2251b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (use_pos[i].Value() > use_pos[reg].Value()) { 2252b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch reg = i; 2253b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2254b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2255b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2256958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto pos = use_pos[reg]; 2257b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2258b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (pos.Value() < register_use->pos().Value()) { 2259b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // All registers are blocked before the first use that requires a register. 2260b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Spill starting part of live range up to that use. 2261b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SpillBetween(current, current->Start(), register_use->pos()); 2262b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return; 2263b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2264b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2265b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (block_pos[reg].Value() < current->End().Value()) { 2266b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Register becomes blocked before the current range end. Split before that 2267b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // position. 2268b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LiveRange* tail = SplitBetween(current, current->Start(), 2269b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block_pos[reg].InstructionStart()); 2270b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!AllocationOk()) return; 2271b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddToUnhandledSorted(tail); 2272b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2273b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2274b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Register reg is not blocked for the whole range. 2275b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(block_pos[reg].Value() >= current->End().Value()); 2276b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceAlloc("Assigning blocked reg %s to live range %d\n", RegisterName(reg), 2277b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch current->id()); 2278b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SetLiveRangeAssignedRegister(current, reg); 2279b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2280b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This register was not free. Thus we need to find and spill 2281b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // parts of active and inactive live regions that use the same register 2282b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // at the same lifetime positions as current. 2283b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SplitAndSpillIntersecting(current); 2284b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2285b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2286b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2287958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernierstatic const InstructionBlock* GetContainingLoop( 2288958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier const InstructionSequence* sequence, const InstructionBlock* block) { 2289958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto index = block->loop_header(); 2290958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!index.IsValid()) return nullptr; 2291958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier return sequence->InstructionBlockAt(index); 2292958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} 2293958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2294958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier 2295b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLifetimePosition RegisterAllocator::FindOptimalSpillingPos( 2296b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LiveRange* range, LifetimePosition pos) { 2297958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto block = GetInstructionBlock(pos.InstructionStart()); 2298958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto loop_header = 2299958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier block->IsLoopHeader() ? block : GetContainingLoop(code(), block); 2300b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2301958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (loop_header == nullptr) return pos; 2302b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2303958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto prev_use = range->PreviousUsePositionRegisterIsBeneficial(pos); 2304b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2305958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (loop_header != nullptr) { 2306b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We are going to spill live range inside the loop. 2307b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // If possible try to move spilling position backwards to loop header. 2308b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This will reduce number of memory moves on the back edge. 2309958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto loop_start = LifetimePosition::FromInstructionIndex( 2310b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch loop_header->first_instruction_index()); 2311b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2312b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (range->Covers(loop_start)) { 2313958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (prev_use == nullptr || prev_use->pos().Value() < loop_start.Value()) { 2314b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // No register beneficial use inside the loop before the pos. 2315b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch pos = loop_start; 2316b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2317b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2318b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2319b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Try hoisting out to an outer loop. 2320958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier loop_header = GetContainingLoop(code(), loop_header); 2321b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2322b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2323b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return pos; 2324b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2325b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2326b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2327b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::SplitAndSpillIntersecting(LiveRange* current) { 2328b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(current->HasRegisterAssigned()); 2329b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int reg = current->assigned_register(); 2330958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto split_pos = current->Start(); 2331958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (size_t i = 0; i < active_live_ranges().size(); ++i) { 2332958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto range = active_live_ranges()[i]; 2333b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (range->assigned_register() == reg) { 2334958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto next_pos = range->NextRegisterPosition(current->Start()); 2335958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto spill_pos = FindOptimalSpillingPos(range, split_pos); 2336958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (next_pos == nullptr) { 2337b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SpillAfter(range, spill_pos); 2338b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2339b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // When spilling between spill_pos and next_pos ensure that the range 2340b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // remains spilled at least until the start of the current live range. 2341b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // This guarantees that we will not introduce new unhandled ranges that 2342b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // start before the current range as this violates allocation invariant 2343b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // and will lead to an inconsistent state of active and inactive 2344b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // live-ranges: ranges are allocated in order of their start positions, 2345b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // ranges are retired from active/inactive when the start of the 2346b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // current live-range is larger than their end. 2347b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SpillBetweenUntil(range, spill_pos, current->Start(), next_pos->pos()); 2348b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2349b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!AllocationOk()) return; 2350b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch ActiveToHandled(range); 2351b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch --i; 2352b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2353b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2354b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2355958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (size_t i = 0; i < inactive_live_ranges().size(); ++i) { 2356958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto range = inactive_live_ranges()[i]; 2357b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(range->End().Value() > current->Start().Value()); 2358b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (range->assigned_register() == reg && !range->IsFixed()) { 2359b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LifetimePosition next_intersection = range->FirstIntersection(current); 2360b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (next_intersection.IsValid()) { 2361b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch UsePosition* next_pos = range->NextRegisterPosition(current->Start()); 2362958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (next_pos == nullptr) { 2363b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SpillAfter(range, split_pos); 2364b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2365b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch next_intersection = Min(next_intersection, next_pos->pos()); 2366b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SpillBetween(range, split_pos, next_intersection); 2367b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2368b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!AllocationOk()) return; 2369b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InactiveToHandled(range); 2370b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch --i; 2371b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2372b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2373b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2374b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2375b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2376b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2377b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochbool RegisterAllocator::IsBlockBoundary(LifetimePosition pos) { 2378b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return pos.IsInstructionStart() && 2379b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch InstructionAt(pos.InstructionIndex())->IsBlockStart(); 2380b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2381b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2382b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2383b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLiveRange* RegisterAllocator::SplitRangeAt(LiveRange* range, 2384b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LifetimePosition pos) { 2385b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!range->IsFixed()); 2386b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceAlloc("Splitting live range %d at %d\n", range->id(), pos.Value()); 2387b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2388b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (pos.Value() <= range->Start().Value()) return range; 2389b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2390b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We can't properly connect liveranges if split occured at the end 2391b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // of control instruction. 2392b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(pos.IsInstructionStart() || 2393b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch !InstructionAt(pos.InstructionIndex())->IsControl()); 2394b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2395b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int vreg = GetVirtualRegister(); 2396958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (!AllocationOk()) return nullptr; 2397958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto result = LiveRangeFor(vreg); 2398958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier range->SplitAt(pos, result, local_zone()); 2399b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return result; 2400b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2401b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2402b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2403b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLiveRange* RegisterAllocator::SplitBetween(LiveRange* range, 2404b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LifetimePosition start, 2405b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LifetimePosition end) { 2406b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!range->IsFixed()); 2407b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceAlloc("Splitting live range %d in position between [%d, %d]\n", 2408b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch range->id(), start.Value(), end.Value()); 2409b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2410958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto split_pos = FindOptimalSplitPos(start, end); 2411b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(split_pos.Value() >= start.Value()); 2412b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return SplitRangeAt(range, split_pos); 2413b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2414b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2415b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2416b8a8cc1952d61a2f3a2568848933943a543b5d3eBen MurdochLifetimePosition RegisterAllocator::FindOptimalSplitPos(LifetimePosition start, 2417b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LifetimePosition end) { 2418b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int start_instr = start.InstructionIndex(); 2419b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int end_instr = end.InstructionIndex(); 2420b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(start_instr <= end_instr); 2421b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2422b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We have no choice 2423b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (start_instr == end_instr) return end; 2424b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2425958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto start_block = GetInstructionBlock(start); 2426958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto end_block = GetInstructionBlock(end); 2427b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2428b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (end_block == start_block) { 2429b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The interval is split in the same basic block. Split at the latest 2430b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // possible position. 2431b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return end; 2432b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2433b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2434958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto block = end_block; 2435b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Find header of outermost loop. 2436b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // TODO(titzer): fix redundancy below. 2437958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier while (GetContainingLoop(code(), block) != nullptr && 2438958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier GetContainingLoop(code(), block)->rpo_number().ToInt() > 2439958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier start_block->rpo_number().ToInt()) { 2440958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier block = GetContainingLoop(code(), block); 2441b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2442b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2443b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // We did not find any suitable outer loop. Split at the latest possible 2444b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // position unless end_block is a loop header itself. 2445b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (block == end_block && !end_block->IsLoopHeader()) return end; 2446b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2447b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch return LifetimePosition::FromInstructionIndex( 2448b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch block->first_instruction_index()); 2449b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2450b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2451b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2452b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::SpillAfter(LiveRange* range, LifetimePosition pos) { 2453958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto second_part = SplitRangeAt(range, pos); 2454b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!AllocationOk()) return; 2455b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Spill(second_part); 2456b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2457b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2458b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2459b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::SpillBetween(LiveRange* range, LifetimePosition start, 2460b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LifetimePosition end) { 2461b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch SpillBetweenUntil(range, start, start, end); 2462b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2463b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2464b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2465b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::SpillBetweenUntil(LiveRange* range, 2466b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LifetimePosition start, 2467b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LifetimePosition until, 2468b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch LifetimePosition end) { 2469b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch CHECK(start.Value() < end.Value()); 2470958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto second_part = SplitRangeAt(range, start); 2471b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!AllocationOk()) return; 2472b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2473b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (second_part->Start().Value() < end.Value()) { 2474b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The split result intersects with [start, end[. 2475b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Split it at position between ]start+1, end[, spill the middle part 2476b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // and put the rest to unhandled. 2477958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto third_part = SplitBetween( 2478b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch second_part, Max(second_part->Start().InstructionEnd(), until), 2479b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch end.PrevInstruction().InstructionEnd()); 2480b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (!AllocationOk()) return; 2481b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2482b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(third_part != second_part); 2483b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2484b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch Spill(second_part); 2485b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddToUnhandledSorted(third_part); 2486b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2487b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // The split result does not intersect with [start, end[. 2488b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch // Nothing to spill. Just put it to unhandled as whole. 2489b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch AddToUnhandledSorted(second_part); 2490b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2491b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2492b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2493b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2494b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::Spill(LiveRange* range) { 2495b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(!range->IsSpilled()); 2496b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch TraceAlloc("Spilling live range %d\n", range->id()); 2497958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto first = range->TopLevel(); 2498958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (first->HasNoSpillType()) { 2499958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (FLAG_turbo_reuse_spill_slots) { 2500958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier AssignSpillRangeToLiveRange(first); 2501958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier } else { 2502958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto op = TryReuseSpillSlot(range); 2503958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (op == nullptr) { 2504958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier // Allocate a new operand referring to the spill slot. 2505958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier RegisterKind kind = range->Kind(); 2506958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier int index = frame()->AllocateSpillSlot(kind == DOUBLE_REGISTERS); 2507958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier auto op_kind = kind == DOUBLE_REGISTERS 2508958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier ? InstructionOperand::DOUBLE_STACK_SLOT 2509958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier : InstructionOperand::STACK_SLOT; 2510958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier op = new (code_zone()) InstructionOperand(op_kind, index); 2511b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2512958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier first->SetSpillOperand(op); 2513b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2514b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2515958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier range->MakeSpilled(); 2516b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2517b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2518b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2519b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochint RegisterAllocator::RegisterCount() const { return num_registers_; } 2520b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2521b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2522b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#ifdef DEBUG 2523b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2524b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2525b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::Verify() const { 2526958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier for (auto current : live_ranges()) { 2527958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier if (current != nullptr) current->Verify(); 2528b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2529b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2530b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2531b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2532b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch#endif 2533b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2534b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2535b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdochvoid RegisterAllocator::SetLiveRangeAssignedRegister(LiveRange* range, 2536b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch int reg) { 2537b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch if (range->Kind() == DOUBLE_REGISTERS) { 2538b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assigned_double_registers_->Add(reg); 2539b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } else { 2540b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch DCHECK(range->Kind() == GENERAL_REGISTERS); 2541b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch assigned_registers_->Add(reg); 2542b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch } 2543b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch range->set_assigned_register(reg, code_zone()); 2544b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch} 2545b8a8cc1952d61a2f3a2568848933943a543b5d3eBen Murdoch 2546958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} // namespace compiler 2547958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} // namespace internal 2548958fae7ec3f466955f8e5b50fa5b8d38b9e91675Emily Bernier} // namespace v8 2549