| Index: src/compiler/register-allocator.cc
|
| diff --git a/src/compiler/register-allocator.cc b/src/compiler/register-allocator.cc
|
| index a36ea361208f73c2ee91a2abcb0e6c002eecb313..f6c339234abb4d8a143d4858134e16fa272d5dac 100644
|
| --- a/src/compiler/register-allocator.cc
|
| +++ b/src/compiler/register-allocator.cc
|
| @@ -1201,13 +1201,14 @@ RegisterAllocationData::RegisterAllocationData(
|
| config_(config),
|
| phi_map_(allocation_zone()),
|
| live_in_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()),
|
| + live_out_sets_(code->InstructionBlockCount(), nullptr, allocation_zone()),
|
| live_ranges_(code->VirtualRegisterCount() * 2, nullptr,
|
| allocation_zone()),
|
| fixed_live_ranges_(this->config()->num_general_registers(), nullptr,
|
| allocation_zone()),
|
| fixed_double_live_ranges_(this->config()->num_double_registers(), nullptr,
|
| allocation_zone()),
|
| - spill_ranges_(allocation_zone()),
|
| + spill_ranges_(code->VirtualRegisterCount(), nullptr, allocation_zone()),
|
| delayed_references_(allocation_zone()),
|
| assigned_registers_(nullptr),
|
| assigned_double_registers_(nullptr),
|
| @@ -1334,7 +1335,11 @@ SpillRange* RegisterAllocationData::AssignSpillRangeToLiveRange(
|
| }
|
| range->set_spill_type(TopLevelLiveRange::SpillType::kSpillRange);
|
|
|
| - spill_ranges().insert(spill_range);
|
| + int spill_range_index =
|
| + range->IsSplinter() ? range->splintered_from()->vreg() : range->vreg();
|
| +
|
| + spill_ranges()[spill_range_index] = spill_range;
|
| +
|
| return spill_range;
|
| }
|
|
|
| @@ -1683,28 +1688,33 @@ LiveRangeBuilder::LiveRangeBuilder(RegisterAllocationData* data,
|
|
|
| BitVector* LiveRangeBuilder::ComputeLiveOut(const InstructionBlock* block,
|
| RegisterAllocationData* data) {
|
| - // Compute live out for the given block, except not including backward
|
| - // successor edges.
|
| - Zone* zone = data->allocation_zone();
|
| - const InstructionSequence* code = data->code();
|
| -
|
| - auto live_out = new (zone) BitVector(code->VirtualRegisterCount(), zone);
|
| -
|
| - // Process all successor blocks.
|
| - for (auto succ : block->successors()) {
|
| - // Add values live on entry to the successor.
|
| - if (succ <= block->rpo_number()) continue;
|
| - auto live_in = data->live_in_sets()[succ.ToSize()];
|
| - if (live_in != nullptr) live_out->Union(*live_in);
|
| -
|
| - // All phi input operands corresponding to this successor edge are live
|
| - // out from this block.
|
| - auto successor = code->InstructionBlockAt(succ);
|
| - size_t index = successor->PredecessorIndexOf(block->rpo_number());
|
| - DCHECK(index < successor->PredecessorCount());
|
| - for (auto phi : successor->phis()) {
|
| - live_out->Add(phi->operands()[index]);
|
| + size_t block_index = block->rpo_number().ToSize();
|
| + BitVector* live_out = data->live_out_sets()[block_index];
|
| + if (live_out == nullptr) {
|
| + // Compute live out for the given block, except not including backward
|
| + // successor edges.
|
| + Zone* zone = data->allocation_zone();
|
| + const InstructionSequence* code = data->code();
|
| +
|
| + live_out = new (zone) BitVector(code->VirtualRegisterCount(), zone);
|
| +
|
| + // Process all successor blocks.
|
| + for (const RpoNumber& succ : block->successors()) {
|
| + // Add values live on entry to the successor.
|
| + if (succ <= block->rpo_number()) continue;
|
| + BitVector* live_in = data->live_in_sets()[succ.ToSize()];
|
| + if (live_in != nullptr) live_out->Union(*live_in);
|
| +
|
| + // All phi input operands corresponding to this successor edge are live
|
| + // out from this block.
|
| + auto successor = code->InstructionBlockAt(succ);
|
| + size_t index = successor->PredecessorIndexOf(block->rpo_number());
|
| + DCHECK(index < successor->PredecessorCount());
|
| + for (PhiInstruction* phi : successor->phis()) {
|
| + live_out->Add(phi->operands()[index]);
|
| + }
|
| }
|
| + data->live_out_sets()[block_index] = live_out;
|
| }
|
| return live_out;
|
| }
|
| @@ -2829,23 +2839,22 @@ OperandAssigner::OperandAssigner(RegisterAllocationData* data) : data_(data) {}
|
|
|
|
|
| void OperandAssigner::AssignSpillSlots() {
|
| - ZoneSet<SpillRange*>& spill_ranges = data()->spill_ranges();
|
| + ZoneVector<SpillRange*>& spill_ranges = data()->spill_ranges();
|
| // Merge disjoint spill ranges
|
| - for (auto i = spill_ranges.begin(), end = spill_ranges.end(); i != end; ++i) {
|
| - SpillRange* range = *i;
|
| + for (size_t i = 0; i < spill_ranges.size(); ++i) {
|
| + SpillRange* range = spill_ranges[i];
|
| + if (range == nullptr) continue;
|
| if (range->IsEmpty()) continue;
|
| - auto j = i;
|
| - j++;
|
| - for (; j != end; ++j) {
|
| - SpillRange* other = *j;
|
| - if (!other->IsEmpty()) {
|
| + for (size_t j = i + 1; j < spill_ranges.size(); ++j) {
|
| + SpillRange* other = spill_ranges[j];
|
| + if (other != nullptr && !other->IsEmpty()) {
|
| range->TryMerge(other);
|
| }
|
| }
|
| }
|
| // Allocate slots for the merged spill ranges.
|
| - for (auto range : spill_ranges) {
|
| - if (range->IsEmpty()) continue;
|
| + for (SpillRange* range : spill_ranges) {
|
| + if (range == nullptr || range->IsEmpty()) continue;
|
| // Allocate a new operand referring to the spill slot.
|
| int byte_width = range->ByteWidth();
|
| int index = data()->frame()->AllocateSpillSlot(byte_width);
|
|
|