Commit eb41d0cf authored by dcarney's avatar dcarney Committed by Commit bot

revert r25736

R=bmeurer@chromium.org

BUG=

Review URL: https://codereview.chromium.org/803493002

Cr-Commit-Position: refs/heads/master@{#25795}
parent 35951765
...@@ -725,7 +725,7 @@ void GraphC1Visualizer::PrintLiveRange(LiveRange* range, const char* type) { ...@@ -725,7 +725,7 @@ void GraphC1Visualizer::PrintLiveRange(LiveRange* range, const char* type) {
} }
} else if (range->IsSpilled()) { } else if (range->IsSpilled()) {
int index = -1; int index = -1;
if (range->TopLevel()->HasSpillRange()) { if (range->TopLevel()->GetSpillRange() != nullptr) {
index = kMaxInt; // This hasn't been set yet. index = kMaxInt; // This hasn't been set yet.
} else { } else {
index = range->TopLevel()->GetSpillOperand()->index(); index = range->TopLevel()->GetSpillOperand()->index();
......
...@@ -15,6 +15,8 @@ std::ostream& operator<<(std::ostream& os, ...@@ -15,6 +15,8 @@ std::ostream& operator<<(std::ostream& os,
const InstructionOperand& op = *printable.op_; const InstructionOperand& op = *printable.op_;
const RegisterConfiguration* conf = printable.register_configuration_; const RegisterConfiguration* conf = printable.register_configuration_;
switch (op.kind()) { switch (op.kind()) {
case InstructionOperand::INVALID:
return os << "(0)";
case InstructionOperand::UNALLOCATED: { case InstructionOperand::UNALLOCATED: {
const UnallocatedOperand* unalloc = UnallocatedOperand::cast(&op); const UnallocatedOperand* unalloc = UnallocatedOperand::cast(&op);
os << "v" << unalloc->virtual_register(); os << "v" << unalloc->virtual_register();
......
...@@ -39,6 +39,7 @@ const InstructionCode kSourcePositionInstruction = -3; ...@@ -39,6 +39,7 @@ const InstructionCode kSourcePositionInstruction = -3;
class InstructionOperand : public ZoneObject { class InstructionOperand : public ZoneObject {
public: public:
enum Kind { enum Kind {
INVALID,
UNALLOCATED, UNALLOCATED,
CONSTANT, CONSTANT,
IMMEDIATE, IMMEDIATE,
...@@ -48,6 +49,7 @@ class InstructionOperand : public ZoneObject { ...@@ -48,6 +49,7 @@ class InstructionOperand : public ZoneObject {
DOUBLE_REGISTER DOUBLE_REGISTER
}; };
InstructionOperand() : value_(KindField::encode(INVALID)) {}
InstructionOperand(Kind kind, int index) { ConvertTo(kind, index); } InstructionOperand(Kind kind, int index) { ConvertTo(kind, index); }
Kind kind() const { return KindField::decode(value_); } Kind kind() const { return KindField::decode(value_); }
...@@ -56,6 +58,7 @@ class InstructionOperand : public ZoneObject { ...@@ -56,6 +58,7 @@ class InstructionOperand : public ZoneObject {
bool Is##name() const { return kind() == type; } bool Is##name() const { return kind() == type; }
INSTRUCTION_OPERAND_LIST(INSTRUCTION_OPERAND_PREDICATE) INSTRUCTION_OPERAND_LIST(INSTRUCTION_OPERAND_PREDICATE)
INSTRUCTION_OPERAND_PREDICATE(Unallocated, UNALLOCATED, 0) INSTRUCTION_OPERAND_PREDICATE(Unallocated, UNALLOCATED, 0)
INSTRUCTION_OPERAND_PREDICATE(Ignored, INVALID, 0)
#undef INSTRUCTION_OPERAND_PREDICATE #undef INSTRUCTION_OPERAND_PREDICATE
bool Equals(const InstructionOperand* other) const { bool Equals(const InstructionOperand* other) const {
return value_ == other->value_; return value_ == other->value_;
...@@ -288,12 +291,16 @@ class MoveOperands FINAL { ...@@ -288,12 +291,16 @@ class MoveOperands FINAL {
} }
// A move is redundant if it's been eliminated, if its source and // A move is redundant if it's been eliminated, if its source and
// destination are the same, or if its destination is constant. // destination are the same, or if its destination is unneeded or constant.
bool IsRedundant() const { bool IsRedundant() const {
return IsEliminated() || source_->Equals(destination_) || return IsEliminated() || source_->Equals(destination_) || IsIgnored() ||
(destination_ != NULL && destination_->IsConstant()); (destination_ != NULL && destination_->IsConstant());
} }
bool IsIgnored() const {
return destination_ != NULL && destination_->IsIgnored();
}
// We clear both operands to indicate move that's been eliminated. // We clear both operands to indicate move that's been eliminated.
void Eliminate() { source_ = destination_ = NULL; } void Eliminate() { source_ = destination_ = NULL; }
bool IsEliminated() const { bool IsEliminated() const {
...@@ -341,7 +348,7 @@ class SubKindOperand FINAL : public InstructionOperand { ...@@ -341,7 +348,7 @@ class SubKindOperand FINAL : public InstructionOperand {
private: private:
static SubKindOperand* cache; static SubKindOperand* cache;
SubKindOperand() : InstructionOperand(kOperandKind, 0) {} // For the caches. SubKindOperand() : InstructionOperand() {}
explicit SubKindOperand(int index) explicit SubKindOperand(int index)
: InstructionOperand(kOperandKind, index) {} : InstructionOperand(kOperandKind, index) {}
}; };
......
...@@ -585,15 +585,6 @@ struct ReuseSpillSlotsPhase { ...@@ -585,15 +585,6 @@ struct ReuseSpillSlotsPhase {
}; };
struct CommitAssignmentPhase {
static const char* phase_name() { return "commit assignment"; }
void Run(PipelineData* data, Zone* temp_zone) {
data->register_allocator()->CommitAssignment();
}
};
struct PopulatePointerMapsPhase { struct PopulatePointerMapsPhase {
static const char* phase_name() { return "populate pointer maps"; } static const char* phase_name() { return "populate pointer maps"; }
...@@ -1045,7 +1036,6 @@ void Pipeline::AllocateRegisters(const RegisterConfiguration* config, ...@@ -1045,7 +1036,6 @@ void Pipeline::AllocateRegisters(const RegisterConfiguration* config,
if (FLAG_turbo_reuse_spill_slots) { if (FLAG_turbo_reuse_spill_slots) {
Run<ReuseSpillSlotsPhase>(); Run<ReuseSpillSlotsPhase>();
} }
Run<CommitAssignmentPhase>();
Run<PopulatePointerMapsPhase>(); Run<PopulatePointerMapsPhase>();
Run<ConnectRangesPhase>(); Run<ConnectRangesPhase>();
Run<ResolveControlFlowPhase>(); Run<ResolveControlFlowPhase>();
......
...@@ -276,8 +276,10 @@ class RegisterAllocatorVerifier::OutgoingMapping : public ZoneObject { ...@@ -276,8 +276,10 @@ class RegisterAllocatorVerifier::OutgoingMapping : public ZoneObject {
auto* moves = move->move_operands(); auto* moves = move->move_operands();
for (auto i = moves->begin(); i != moves->end(); ++i) { for (auto i = moves->begin(); i != moves->end(); ++i) {
if (i->IsEliminated()) continue; if (i->IsEliminated()) continue;
CHECK(i->source()->kind() != InstructionOperand::INVALID);
auto cur = locations()->find(i->source()); auto cur = locations()->find(i->source());
CHECK(cur != locations()->end()); CHECK(cur != locations()->end());
if (i->destination()->kind() == InstructionOperand::INVALID) continue;
to_insert.insert(std::make_pair(i->destination(), cur->second)); to_insert.insert(std::make_pair(i->destination(), cur->second));
} }
// Drop current mappings. // Drop current mappings.
......
...@@ -74,16 +74,6 @@ void UseInterval::SplitAt(LifetimePosition pos, Zone* zone) { ...@@ -74,16 +74,6 @@ void UseInterval::SplitAt(LifetimePosition pos, Zone* zone) {
} }
struct LiveRange::SpillAtDefinitionList : ZoneObject {
SpillAtDefinitionList(int gap_index, InstructionOperand* operand,
SpillAtDefinitionList* next)
: gap_index(gap_index), operand(operand), next(next) {}
const int gap_index;
InstructionOperand* const operand;
SpillAtDefinitionList* const next;
};
#ifdef DEBUG #ifdef DEBUG
...@@ -129,72 +119,53 @@ LiveRange::LiveRange(int id, Zone* zone) ...@@ -129,72 +119,53 @@ LiveRange::LiveRange(int id, Zone* zone)
current_interval_(nullptr), current_interval_(nullptr),
last_processed_use_(nullptr), last_processed_use_(nullptr),
current_hint_operand_(nullptr), current_hint_operand_(nullptr),
spill_operand_(new (zone) InstructionOperand()),
spill_start_index_(kMaxInt), spill_start_index_(kMaxInt),
spill_type_(SpillType::kNoSpillType), spill_range_(nullptr) {}
spill_operand_(nullptr),
spills_at_definition_(nullptr) {}
void LiveRange::set_assigned_register(int reg, Zone* zone) { void LiveRange::set_assigned_register(int reg, Zone* zone) {
DCHECK(!HasRegisterAssigned() && !IsSpilled()); DCHECK(!HasRegisterAssigned() && !IsSpilled());
assigned_register_ = reg; assigned_register_ = reg;
// TODO(dcarney): stop aliasing hint operands. if (spill_range_ == nullptr) {
ConvertUsesToOperand(CreateAssignedOperand(zone)); ConvertOperands(zone);
}
} }
void LiveRange::MakeSpilled() { void LiveRange::MakeSpilled(Zone* zone) {
DCHECK(!IsSpilled()); DCHECK(!IsSpilled());
DCHECK(!TopLevel()->HasNoSpillType()); DCHECK(TopLevel()->HasAllocatedSpillOperand());
spilled_ = true; spilled_ = true;
assigned_register_ = kInvalidAssignment; assigned_register_ = kInvalidAssignment;
ConvertOperands(zone);
} }
void LiveRange::SpillAtDefinition(Zone* zone, int gap_index, bool LiveRange::HasAllocatedSpillOperand() const {
InstructionOperand* operand) { DCHECK(spill_operand_ != nullptr);
DCHECK(HasNoSpillType()); return !spill_operand_->IsIgnored() || spill_range_ != nullptr;
spills_at_definition_ = new (zone)
SpillAtDefinitionList(gap_index, operand, spills_at_definition_);
}
void LiveRange::CommitSpillsAtDefinition(InstructionSequence* sequence,
InstructionOperand* op) {
auto to_spill = TopLevel()->spills_at_definition_;
if (to_spill == nullptr) return;
auto zone = sequence->zone();
for (; to_spill != nullptr; to_spill = to_spill->next) {
auto gap = sequence->GapAt(to_spill->gap_index);
auto move = gap->GetOrCreateParallelMove(GapInstruction::START, zone);
move->AddMove(to_spill->operand, op, zone);
}
TopLevel()->spills_at_definition_ = nullptr;
} }
void LiveRange::SetSpillOperand(InstructionOperand* operand) { void LiveRange::SetSpillOperand(InstructionOperand* operand) {
DCHECK(HasNoSpillType());
DCHECK(!operand->IsUnallocated()); DCHECK(!operand->IsUnallocated());
spill_type_ = SpillType::kSpillOperand; DCHECK(spill_operand_ != nullptr);
spill_operand_ = operand; DCHECK(spill_operand_->IsIgnored());
} spill_operand_->ConvertTo(operand->kind(), operand->index());
void LiveRange::SetSpillRange(SpillRange* spill_range) {
DCHECK(HasNoSpillType() || HasSpillRange());
DCHECK_NE(spill_range, nullptr);
spill_type_ = SpillType::kSpillRange;
spill_range_ = spill_range;
} }
void LiveRange::CommitSpillOperand(InstructionOperand* operand) { void LiveRange::CommitSpillOperand(InstructionOperand* operand) {
DCHECK(HasSpillRange()); DCHECK(spill_range_ != nullptr);
DCHECK(!operand->IsUnallocated());
DCHECK(!IsChild()); DCHECK(!IsChild());
spill_type_ = SpillType::kSpillOperand; spill_range_ = nullptr;
spill_operand_ = operand; SetSpillOperand(operand);
for (auto range = this; range != nullptr; range = range->next()) {
if (range->IsSpilled()) {
range->ConvertUsesToOperand(operand);
}
}
} }
...@@ -264,11 +235,15 @@ InstructionOperand* LiveRange::CreateAssignedOperand(Zone* zone) const { ...@@ -264,11 +235,15 @@ InstructionOperand* LiveRange::CreateAssignedOperand(Zone* zone) const {
default: default:
UNREACHABLE(); UNREACHABLE();
} }
} else { } else if (IsSpilled()) {
DCHECK(IsSpilled());
DCHECK(!HasRegisterAssigned()); DCHECK(!HasRegisterAssigned());
op = TopLevel()->GetSpillOperand(); op = TopLevel()->GetSpillOperand();
DCHECK(!op->IsUnallocated()); DCHECK(!op->IsUnallocated());
} else {
UnallocatedOperand* unalloc =
new (zone) UnallocatedOperand(UnallocatedOperand::NONE);
unalloc->set_virtual_register(id_);
op = unalloc;
} }
return op; return op;
} }
...@@ -507,6 +482,11 @@ void LiveRange::ConvertUsesToOperand(InstructionOperand* op) { ...@@ -507,6 +482,11 @@ void LiveRange::ConvertUsesToOperand(InstructionOperand* op) {
} }
void LiveRange::ConvertOperands(Zone* zone) {
ConvertUsesToOperand(CreateAssignedOperand(zone));
}
bool LiveRange::CanCover(LifetimePosition position) const { bool LiveRange::CanCover(LifetimePosition position) const {
if (IsEmpty()) return false; if (IsEmpty()) return false;
return Start().Value() <= position.Value() && return Start().Value() <= position.Value() &&
...@@ -837,7 +817,7 @@ SpillRange::SpillRange(LiveRange* range, Zone* zone) : live_ranges_(zone) { ...@@ -837,7 +817,7 @@ SpillRange::SpillRange(LiveRange* range, Zone* zone) : live_ranges_(zone) {
use_interval_ = result; use_interval_ = result;
live_ranges().push_back(range); live_ranges().push_back(range);
end_position_ = node->end(); end_position_ = node->end();
DCHECK(!range->HasSpillRange()); DCHECK(range->GetSpillRange() == nullptr);
range->SetSpillRange(this); range->SetSpillRange(this);
} }
...@@ -941,20 +921,6 @@ void RegisterAllocator::ReuseSpillSlots() { ...@@ -941,20 +921,6 @@ void RegisterAllocator::ReuseSpillSlots() {
} }
void RegisterAllocator::CommitAssignment() {
for (auto range : live_ranges()) {
if (range == nullptr || range->IsEmpty()) continue;
// Register assignments were committed in set_assigned_register.
if (range->HasRegisterAssigned()) continue;
auto assigned = range->CreateAssignedOperand(code_zone());
range->ConvertUsesToOperand(assigned);
if (range->IsSpilled()) {
range->CommitSpillsAtDefinition(code(), assigned);
}
}
}
SpillRange* RegisterAllocator::AssignSpillRangeToLiveRange(LiveRange* range) { SpillRange* RegisterAllocator::AssignSpillRangeToLiveRange(LiveRange* range) {
DCHECK(FLAG_turbo_reuse_spill_slots); DCHECK(FLAG_turbo_reuse_spill_slots);
auto spill_range = new (local_zone()) SpillRange(range, local_zone()); auto spill_range = new (local_zone()) SpillRange(range, local_zone());
...@@ -965,7 +931,7 @@ SpillRange* RegisterAllocator::AssignSpillRangeToLiveRange(LiveRange* range) { ...@@ -965,7 +931,7 @@ SpillRange* RegisterAllocator::AssignSpillRangeToLiveRange(LiveRange* range) {
bool RegisterAllocator::TryReuseSpillForPhi(LiveRange* range) { bool RegisterAllocator::TryReuseSpillForPhi(LiveRange* range) {
DCHECK(FLAG_turbo_reuse_spill_slots); DCHECK(FLAG_turbo_reuse_spill_slots);
DCHECK(range->HasNoSpillType()); DCHECK(!range->HasAllocatedSpillOperand());
if (range->IsChild() || !range->is_phi()) return false; if (range->IsChild() || !range->is_phi()) return false;
auto lookup = phi_map_.find(range->id()); auto lookup = phi_map_.find(range->id());
...@@ -1109,8 +1075,16 @@ void RegisterAllocator::MeetRegisterConstraintsForLastInstructionInBlock( ...@@ -1109,8 +1075,16 @@ void RegisterAllocator::MeetRegisterConstraintsForLastInstructionInBlock(
const InstructionBlock* successor = code()->InstructionBlockAt(succ); const InstructionBlock* successor = code()->InstructionBlockAt(succ);
DCHECK(successor->PredecessorCount() == 1); DCHECK(successor->PredecessorCount() == 1);
int gap_index = successor->first_instruction_index() + 1; int gap_index = successor->first_instruction_index() + 1;
range->SpillAtDefinition(local_zone(), gap_index, output);
range->SetSpillStartIndex(gap_index); range->SetSpillStartIndex(gap_index);
// This move to spill operand is not a real use. Liveness analysis
// and splitting of live ranges do not account for it.
// Thus it should be inserted to a lifetime position corresponding to
// the instruction end.
auto gap = code()->GapAt(gap_index);
auto move =
gap->GetOrCreateParallelMove(GapInstruction::BEFORE, code_zone());
move->AddMove(output, range->GetSpillOperand(), code_zone());
} }
} }
} }
...@@ -1159,8 +1133,16 @@ void RegisterAllocator::MeetConstraintsBetween(Instruction* first, ...@@ -1159,8 +1133,16 @@ void RegisterAllocator::MeetConstraintsBetween(Instruction* first,
// Make sure we add a gap move for spilling (if we have not done // Make sure we add a gap move for spilling (if we have not done
// so already). // so already).
if (!assigned) { if (!assigned) {
range->SpillAtDefinition(local_zone(), gap_index, first_output);
range->SetSpillStartIndex(gap_index); range->SetSpillStartIndex(gap_index);
// This move to spill operand is not a real use. Liveness analysis
// and splitting of live ranges do not account for it.
// Thus it should be inserted to a lifetime position corresponding to
// the instruction end.
auto gap = code()->GapAt(gap_index);
auto move =
gap->GetOrCreateParallelMove(GapInstruction::BEFORE, code_zone());
move->AddMove(first_output, range->GetSpillOperand(), code_zone());
} }
} }
} }
...@@ -1256,6 +1238,7 @@ void RegisterAllocator::ProcessInstructions(const InstructionBlock* block, ...@@ -1256,6 +1238,7 @@ void RegisterAllocator::ProcessInstructions(const InstructionBlock* block,
const ZoneList<MoveOperands>* move_operands = move->move_operands(); const ZoneList<MoveOperands>* move_operands = move->move_operands();
for (int i = 0; i < move_operands->length(); ++i) { for (int i = 0; i < move_operands->length(); ++i) {
auto cur = &move_operands->at(i); auto cur = &move_operands->at(i);
if (cur->IsIgnored()) continue;
auto from = cur->source(); auto from = cur->source();
auto to = cur->destination(); auto to = cur->destination();
auto hint = to; auto hint = to;
...@@ -1378,9 +1361,10 @@ void RegisterAllocator::ResolvePhis(const InstructionBlock* block) { ...@@ -1378,9 +1361,10 @@ void RegisterAllocator::ResolvePhis(const InstructionBlock* block) {
} }
} }
auto live_range = LiveRangeFor(phi_vreg); auto live_range = LiveRangeFor(phi_vreg);
int gap_index = block->first_instruction_index(); auto block_start = code()->GetBlockStart(block->rpo_number());
live_range->SpillAtDefinition(local_zone(), gap_index, output); block_start->GetOrCreateParallelMove(GapInstruction::BEFORE, code_zone())
live_range->SetSpillStartIndex(gap_index); ->AddMove(output, live_range->GetSpillOperand(), code_zone());
live_range->SetSpillStartIndex(block->first_instruction_index());
// We use the phi-ness of some nodes in some later heuristics. // We use the phi-ness of some nodes in some later heuristics.
live_range->set_is_phi(true); live_range->set_is_phi(true);
live_range->set_is_non_loop_phi(!block->IsLoopHeader()); live_range->set_is_non_loop_phi(!block->IsLoopHeader());
...@@ -1739,7 +1723,8 @@ void RegisterAllocator::BuildLiveRanges() { ...@@ -1739,7 +1723,8 @@ void RegisterAllocator::BuildLiveRanges() {
// live ranges, every use requires the constant to be in a register. // live ranges, every use requires the constant to be in a register.
// Without this hack, all uses with "any" policy would get the constant // Without this hack, all uses with "any" policy would get the constant
// operand assigned. // operand assigned.
if (range->HasSpillOperand() && range->GetSpillOperand()->IsConstant()) { if (range->HasAllocatedSpillOperand() &&
range->GetSpillOperand()->IsConstant()) {
for (auto pos = range->first_pos(); pos != nullptr; pos = pos->next_) { for (auto pos = range->first_pos(); pos != nullptr; pos = pos->next_) {
pos->register_beneficial_ = true; pos->register_beneficial_ = true;
// TODO(dcarney): should the else case assert requires_reg_ == false? // TODO(dcarney): should the else case assert requires_reg_ == false?
...@@ -1843,7 +1828,7 @@ void RegisterAllocator::PopulatePointerMaps() { ...@@ -1843,7 +1828,7 @@ void RegisterAllocator::PopulatePointerMaps() {
// Check if the live range is spilled and the safe point is after // Check if the live range is spilled and the safe point is after
// the spill position. // the spill position.
if (range->HasSpillOperand() && if (range->HasAllocatedSpillOperand() &&
safe_point >= range->spill_start_index() && safe_point >= range->spill_start_index() &&
!range->GetSpillOperand()->IsConstant()) { !range->GetSpillOperand()->IsConstant()) {
TraceAlloc("Pointer for range %d (spilled at %d) at safe point %d\n", TraceAlloc("Pointer for range %d (spilled at %d) at safe point %d\n",
...@@ -1923,7 +1908,7 @@ void RegisterAllocator::AllocateRegisters() { ...@@ -1923,7 +1908,7 @@ void RegisterAllocator::AllocateRegisters() {
TraceAlloc("Processing interval %d start=%d\n", current->id(), TraceAlloc("Processing interval %d start=%d\n", current->id(),
position.Value()); position.Value());
if (!current->HasNoSpillType()) { if (current->HasAllocatedSpillOperand()) {
TraceAlloc("Live range %d already has a spill operand\n", current->id()); TraceAlloc("Live range %d already has a spill operand\n", current->id());
auto next_pos = position; auto next_pos = position;
if (code()->IsGapAt(next_pos.InstructionIndex())) { if (code()->IsGapAt(next_pos.InstructionIndex())) {
...@@ -2088,7 +2073,7 @@ void RegisterAllocator::FreeSpillSlot(LiveRange* range) { ...@@ -2088,7 +2073,7 @@ void RegisterAllocator::FreeSpillSlot(LiveRange* range) {
DCHECK(!FLAG_turbo_reuse_spill_slots); DCHECK(!FLAG_turbo_reuse_spill_slots);
// Check that we are the last range. // Check that we are the last range.
if (range->next() != nullptr) return; if (range->next() != nullptr) return;
if (!range->TopLevel()->HasSpillOperand()) return; if (!range->TopLevel()->HasAllocatedSpillOperand()) return;
auto spill_operand = range->TopLevel()->GetSpillOperand(); auto spill_operand = range->TopLevel()->GetSpillOperand();
if (spill_operand->IsConstant()) return; if (spill_operand->IsConstant()) return;
if (spill_operand->index() >= 0) { if (spill_operand->index() >= 0) {
...@@ -2503,7 +2488,7 @@ void RegisterAllocator::Spill(LiveRange* range) { ...@@ -2503,7 +2488,7 @@ void RegisterAllocator::Spill(LiveRange* range) {
DCHECK(!range->IsSpilled()); DCHECK(!range->IsSpilled());
TraceAlloc("Spilling live range %d\n", range->id()); TraceAlloc("Spilling live range %d\n", range->id());
auto first = range->TopLevel(); auto first = range->TopLevel();
if (first->HasNoSpillType()) { if (!first->HasAllocatedSpillOperand()) {
if (FLAG_turbo_reuse_spill_slots) { if (FLAG_turbo_reuse_spill_slots) {
AssignSpillRangeToLiveRange(first); AssignSpillRangeToLiveRange(first);
} else { } else {
...@@ -2512,15 +2497,17 @@ void RegisterAllocator::Spill(LiveRange* range) { ...@@ -2512,15 +2497,17 @@ void RegisterAllocator::Spill(LiveRange* range) {
// Allocate a new operand referring to the spill slot. // Allocate a new operand referring to the spill slot.
RegisterKind kind = range->Kind(); RegisterKind kind = range->Kind();
int index = frame()->AllocateSpillSlot(kind == DOUBLE_REGISTERS); int index = frame()->AllocateSpillSlot(kind == DOUBLE_REGISTERS);
auto op_kind = kind == DOUBLE_REGISTERS if (kind == DOUBLE_REGISTERS) {
? InstructionOperand::DOUBLE_STACK_SLOT op = DoubleStackSlotOperand::Create(index, local_zone());
: InstructionOperand::STACK_SLOT; } else {
op = new (code_zone()) InstructionOperand(op_kind, index); DCHECK(kind == GENERAL_REGISTERS);
op = StackSlotOperand::Create(index, local_zone());
}
} }
first->SetSpillOperand(op); first->SetSpillOperand(op);
} }
} }
range->MakeSpilled(); range->MakeSpilled(code_zone());
} }
......
...@@ -197,7 +197,7 @@ class LiveRange FINAL : public ZoneObject { ...@@ -197,7 +197,7 @@ class LiveRange FINAL : public ZoneObject {
int assigned_register() const { return assigned_register_; } int assigned_register() const { return assigned_register_; }
int spill_start_index() const { return spill_start_index_; } int spill_start_index() const { return spill_start_index_; }
void set_assigned_register(int reg, Zone* zone); void set_assigned_register(int reg, Zone* zone);
void MakeSpilled(); void MakeSpilled(Zone* zone);
bool is_phi() const { return is_phi_; } bool is_phi() const { return is_phi_; }
void set_is_phi(bool is_phi) { is_phi_ = is_phi; } void set_is_phi(bool is_phi) { is_phi_ = is_phi; }
bool is_non_loop_phi() const { return is_non_loop_phi_; } bool is_non_loop_phi() const { return is_non_loop_phi_; }
...@@ -260,27 +260,13 @@ class LiveRange FINAL : public ZoneObject { ...@@ -260,27 +260,13 @@ class LiveRange FINAL : public ZoneObject {
return last_interval_->end(); return last_interval_->end();
} }
enum class SpillType { kNoSpillType, kSpillOperand, kSpillRange }; bool HasAllocatedSpillOperand() const;
SpillType spill_type() const { return spill_type_; } InstructionOperand* GetSpillOperand() const { return spill_operand_; }
InstructionOperand* GetSpillOperand() const {
return spill_type_ == SpillType::kSpillOperand ? spill_operand_ : nullptr;
}
SpillRange* GetSpillRange() const {
return spill_type_ == SpillType::kSpillRange ? spill_range_ : nullptr;
}
bool HasNoSpillType() const { return spill_type_ == SpillType::kNoSpillType; }
bool HasSpillOperand() const {
return spill_type_ == SpillType::kSpillOperand;
}
bool HasSpillRange() const { return spill_type_ == SpillType::kSpillRange; }
void SpillAtDefinition(Zone* zone, int gap_index,
InstructionOperand* operand);
void SetSpillOperand(InstructionOperand* operand); void SetSpillOperand(InstructionOperand* operand);
void SetSpillRange(SpillRange* spill_range);
void SetSpillRange(SpillRange* spill_range) { spill_range_ = spill_range; }
SpillRange* GetSpillRange() const { return spill_range_; }
void CommitSpillOperand(InstructionOperand* operand); void CommitSpillOperand(InstructionOperand* operand);
void CommitSpillsAtDefinition(InstructionSequence* sequence,
InstructionOperand* operand);
void SetSpillStartIndex(int start) { void SetSpillStartIndex(int start) {
spill_start_index_ = Min(start, spill_start_index_); spill_start_index_ = Min(start, spill_start_index_);
...@@ -307,14 +293,12 @@ class LiveRange FINAL : public ZoneObject { ...@@ -307,14 +293,12 @@ class LiveRange FINAL : public ZoneObject {
#endif #endif
private: private:
struct SpillAtDefinitionList; void ConvertOperands(Zone* zone);
void ConvertUsesToOperand(InstructionOperand* op); void ConvertUsesToOperand(InstructionOperand* op);
UseInterval* FirstSearchIntervalForPosition(LifetimePosition position) const; UseInterval* FirstSearchIntervalForPosition(LifetimePosition position) const;
void AdvanceLastProcessedMarker(UseInterval* to_start_of, void AdvanceLastProcessedMarker(UseInterval* to_start_of,
LifetimePosition but_not_past) const; LifetimePosition but_not_past) const;
// TODO(dcarney): pack this structure better.
int id_; int id_;
bool spilled_; bool spilled_;
bool is_phi_; bool is_phi_;
...@@ -331,13 +315,9 @@ class LiveRange FINAL : public ZoneObject { ...@@ -331,13 +315,9 @@ class LiveRange FINAL : public ZoneObject {
UsePosition* last_processed_use_; UsePosition* last_processed_use_;
// This is used as a cache, it's invalid outside of BuildLiveRanges. // This is used as a cache, it's invalid outside of BuildLiveRanges.
InstructionOperand* current_hint_operand_; InstructionOperand* current_hint_operand_;
InstructionOperand* spill_operand_;
int spill_start_index_; int spill_start_index_;
SpillType spill_type_; SpillRange* spill_range_;
union {
InstructionOperand* spill_operand_;
SpillRange* spill_range_;
};
SpillAtDefinitionList* spills_at_definition_;
friend class RegisterAllocator; // Assigns to kind_. friend class RegisterAllocator; // Assigns to kind_.
...@@ -408,16 +388,13 @@ class RegisterAllocator FINAL : public ZoneObject { ...@@ -408,16 +388,13 @@ class RegisterAllocator FINAL : public ZoneObject {
// Phase 5: reassign spill splots for maximal reuse. // Phase 5: reassign spill splots for maximal reuse.
void ReuseSpillSlots(); void ReuseSpillSlots();
// Phase 6: commit assignment. // Phase 6: compute values for pointer maps.
void CommitAssignment();
// Phase 7: compute values for pointer maps.
void PopulatePointerMaps(); // TODO(titzer): rename to PopulateReferenceMaps. void PopulatePointerMaps(); // TODO(titzer): rename to PopulateReferenceMaps.
// Phase 8: reconnect split ranges with moves. // Phase 7: reconnect split ranges with moves.
void ConnectRanges(); void ConnectRanges();
// Phase 9: insert moves to connect ranges across basic blocks. // Phase 8: insert moves to connect ranges across basic blocks.
void ResolveControlFlow(); void ResolveControlFlow();
private: private:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment