| Index: src/lithium-allocator.cc
|
| diff --git a/src/lithium-allocator.cc b/src/lithium-allocator.cc
|
| index 9e4ae7962125f110ba94c54f32fe13fef50b253c..acb012a331f5535c367f9a46086145262fad8998 100644
|
| --- a/src/lithium-allocator.cc
|
| +++ b/src/lithium-allocator.cc
|
| @@ -124,7 +124,8 @@ LiveRange::LiveRange(int id, Zone* zone)
|
| last_processed_use_(NULL),
|
| current_hint_operand_(NULL),
|
| spill_operand_(new(zone) LOperand()),
|
| - spill_start_index_(kMaxInt) { }
|
| + spill_start_index_(kMaxInt),
|
| + parent_linstr_(NULL) { }
|
|
|
|
|
| void LiveRange::set_assigned_register(int reg, Zone* zone) {
|
| @@ -140,6 +141,7 @@ void LiveRange::MakeSpilled(Zone* zone) {
|
| spilled_ = true;
|
| assigned_register_ = kInvalidAssignment;
|
| ConvertOperands(zone);
|
| + spill_operand_->set_parent_linstr(parent_linstr());
|
| }
|
|
|
|
|
| @@ -153,7 +155,10 @@ void LiveRange::SetSpillOperand(LOperand* operand) {
|
| ASSERT(!operand->IsUnallocated());
|
| ASSERT(spill_operand_ != NULL);
|
| ASSERT(spill_operand_->IsIgnored());
|
| + ASSERT((spill_operand_->parent_linstr() == NULL) ||
|
| + (spill_operand_->parent_linstr() == parent_linstr()));
|
| spill_operand_->ConvertTo(operand->kind(), operand->index());
|
| + spill_operand_->set_parent_linstr(parent_linstr());
|
| }
|
|
|
|
|
| @@ -211,14 +216,16 @@ bool LiveRange::CanBeSpilled(LifetimePosition pos) {
|
|
|
| LOperand* LiveRange::CreateAssignedOperand(Zone* zone) {
|
| LOperand* op = NULL;
|
| + bool allow_use_cache = parent_linstr() == NULL;
|
| if (HasRegisterAssigned()) {
|
| ASSERT(!IsSpilled());
|
| switch (Kind()) {
|
| case GENERAL_REGISTERS:
|
| - op = LRegister::Create(assigned_register(), zone);
|
| + op = LRegister::Create(assigned_register(), zone, allow_use_cache);
|
| break;
|
| case DOUBLE_REGISTERS:
|
| - op = LDoubleRegister::Create(assigned_register(), zone);
|
| + op = LDoubleRegister::Create(assigned_register(), zone,
|
| + allow_use_cache);
|
| break;
|
| default:
|
| UNREACHABLE();
|
| @@ -227,11 +234,13 @@ LOperand* LiveRange::CreateAssignedOperand(Zone* zone) {
|
| ASSERT(!HasRegisterAssigned());
|
| op = TopLevel()->GetSpillOperand();
|
| ASSERT(!op->IsUnallocated());
|
| + ASSERT(op->parent_linstr() == parent_linstr());
|
| } else {
|
| LUnallocated* unalloc = new(zone) LUnallocated(LUnallocated::NONE);
|
| unalloc->set_virtual_register(id_);
|
| op = unalloc;
|
| }
|
| + op->set_parent_linstr(parent_linstr());
|
| return op;
|
| }
|
|
|
| @@ -265,6 +274,9 @@ void LiveRange::SplitAt(LifetimePosition position,
|
| Zone* zone) {
|
| ASSERT(Start().Value() < position.Value());
|
| ASSERT(result->IsEmpty());
|
| +
|
| + result->set_parent_linstr(parent_linstr());
|
| +
|
| // Find the last interval that ends before the position. If the
|
| // position is contained in one of the intervals in the chain, we
|
| // split that interval and use the first part.
|
| @@ -693,15 +705,18 @@ HPhi* LAllocator::LookupPhi(LOperand* operand) const {
|
|
|
|
|
| LiveRange* LAllocator::LiveRangeFor(LOperand* operand) {
|
| + LiveRange* result;
|
| if (operand->IsUnallocated()) {
|
| - return LiveRangeFor(LUnallocated::cast(operand)->virtual_register());
|
| + result = LiveRangeFor(LUnallocated::cast(operand)->virtual_register());
|
| } else if (operand->IsRegister()) {
|
| - return FixedLiveRangeFor(operand->index());
|
| + result = FixedLiveRangeFor(operand->index());
|
| } else if (operand->IsDoubleRegister()) {
|
| - return FixedDoubleLiveRangeFor(operand->index());
|
| + result = FixedDoubleLiveRangeFor(operand->index());
|
| } else {
|
| return NULL;
|
| }
|
| + result->set_parent_linstr(operand->parent_linstr());
|
| + return result;
|
| }
|
|
|
|
|
| @@ -1720,6 +1735,12 @@ void LAllocator::FreeSpillSlot(LiveRange* range) {
|
|
|
| if (!range->TopLevel()->HasAllocatedSpillOperand()) return;
|
|
|
| + if (range->parent_linstr() != NULL) {
|
| + // Reusing live ranges with parent instruction information may prevent
|
| + // optimizing away gap moves.
|
| + return;
|
| + }
|
| +
|
| int index = range->TopLevel()->GetSpillOperand()->index();
|
| if (index >= 0) {
|
| reusable_slots_.Add(range, zone());
|
| @@ -2149,6 +2170,7 @@ void LAllocator::Spill(LiveRange* range) {
|
| ASSERT(!range->IsSpilled());
|
| TraceAlloc("Spilling live range %d\n", range->id());
|
| LiveRange* first = range->TopLevel();
|
| + ASSERT(first->parent_linstr() == range->parent_linstr());
|
|
|
| if (!first->HasAllocatedSpillOperand()) {
|
| LOperand* op = TryReuseSpillSlot(range);
|
|
|