| Index: src/lithium-allocator.cc
|
| diff --git a/src/lithium-allocator.cc b/src/lithium-allocator.cc
|
| index 29c31942e44387903929e80e83241003a84ba8c2..5b68a2f0f8572024f18502fea0cb0783638a968b 100644
|
| --- a/src/lithium-allocator.cc
|
| +++ b/src/lithium-allocator.cc
|
| @@ -238,6 +238,12 @@ LOperand* LiveRange::CreateAssignedOperand(Zone* zone) {
|
| case DOUBLE_REGISTERS:
|
| op = LDoubleRegister::Create(assigned_register(), zone);
|
| break;
|
| + case FLOAT32x4_REGISTERS:
|
| + op = LFloat32x4Register::Create(assigned_register(), zone);
|
| + break;
|
| + case INT32x4_REGISTERS:
|
| + op = LInt32x4Register::Create(assigned_register(), zone);
|
| + break;
|
| default:
|
| UNREACHABLE();
|
| }
|
| @@ -488,6 +494,7 @@ void LiveRange::ConvertOperands(Zone* zone) {
|
|
|
| if (use_pos->HasOperand()) {
|
| ASSERT(op->IsRegister() || op->IsDoubleRegister() ||
|
| + op->IsFloat32x4Register() || op->IsInt32x4Register() ||
|
| !use_pos->RequiresRegister());
|
| use_pos->operand()->ConvertTo(op->kind(), op->index());
|
| }
|
| @@ -554,6 +561,7 @@ LAllocator::LAllocator(int num_values, HGraph* graph)
|
| active_live_ranges_(8, zone()),
|
| inactive_live_ranges_(8, zone()),
|
| reusable_slots_(8, zone()),
|
| + reusable_xmm_slots_(8, zone()),
|
| next_virtual_register_(num_values),
|
| first_artificial_register_(num_values),
|
| mode_(UNALLOCATED_REGISTERS),
|
| @@ -873,6 +881,16 @@ void LAllocator::MeetConstraintsBetween(LInstruction* first,
|
| double_artificial_registers_.Add(
|
| cur_input->virtual_register() - first_artificial_register_,
|
| zone());
|
| + } else if (RequiredRegisterKind(input_copy->virtual_register()) ==
|
| + FLOAT32x4_REGISTERS) {
|
| + float32x4_artificial_registers_.Add(
|
| + cur_input->virtual_register() - first_artificial_register_,
|
| + zone());
|
| + } else if (RequiredRegisterKind(input_copy->virtual_register()) ==
|
| + INT32x4_REGISTERS) {
|
| + int32x4_artificial_registers_.Add(
|
| + cur_input->virtual_register() - first_artificial_register_,
|
| + zone());
|
| }
|
|
|
| AddConstraintsGapMove(gap_index, input_copy, cur_input);
|
| @@ -1185,8 +1203,12 @@ void LAllocator::ResolveControlFlow(LiveRange* range,
|
| if (branch->HasPointerMap()) {
|
| if (HasTaggedValue(range->id())) {
|
| branch->pointer_map()->RecordPointer(cur_op, chunk()->zone());
|
| - } else if (!cur_op->IsDoubleStackSlot() &&
|
| - !cur_op->IsDoubleRegister()) {
|
| + } else if (!cur_op->IsDoubleStackSlot() &&
|
| + !cur_op->IsDoubleRegister() &&
|
| + !cur_op->IsFloat32x4StackSlot() &&
|
| + !cur_op->IsFloat32x4Register() &&
|
| + !cur_op->IsInt32x4StackSlot() &&
|
| + !cur_op->IsInt32x4Register()) {
|
| branch->pointer_map()->RemovePointer(cur_op);
|
| }
|
| }
|
| @@ -1512,6 +1534,10 @@ void LAllocator::AllocateRegisters() {
|
| if (live_ranges_[i] != NULL) {
|
| if (live_ranges_[i]->Kind() == mode_) {
|
| AddToUnhandledUnsorted(live_ranges_[i]);
|
| + } else if (mode_ == DOUBLE_REGISTERS &&
|
| + (live_ranges_[i]->Kind() == FLOAT32x4_REGISTERS ||
|
| + live_ranges_[i]->Kind() == INT32x4_REGISTERS)) {
|
| + AddToUnhandledUnsorted(live_ranges_[i]);
|
| }
|
| }
|
| }
|
| @@ -1519,6 +1545,7 @@ void LAllocator::AllocateRegisters() {
|
| ASSERT(UnhandledIsSorted());
|
|
|
| ASSERT(reusable_slots_.is_empty());
|
| + ASSERT(reusable_xmm_slots_.is_empty());
|
| ASSERT(active_live_ranges_.is_empty());
|
| ASSERT(inactive_live_ranges_.is_empty());
|
|
|
| @@ -1610,6 +1637,7 @@ void LAllocator::AllocateRegisters() {
|
| }
|
|
|
| reusable_slots_.Rewind(0);
|
| + reusable_xmm_slots_.Rewind(0);
|
| active_live_ranges_.Rewind(0);
|
| inactive_live_ranges_.Rewind(0);
|
| }
|
| @@ -1646,10 +1674,20 @@ RegisterKind LAllocator::RequiredRegisterKind(int virtual_register) const {
|
| HValue* value = graph_->LookupValue(virtual_register);
|
| if (value != NULL && value->representation().IsDouble()) {
|
| return DOUBLE_REGISTERS;
|
| + } else if (value != NULL && (value->representation().IsFloat32x4())) {
|
| + return FLOAT32x4_REGISTERS;
|
| + } else if (value != NULL && (value->representation().IsInt32x4())) {
|
| + return INT32x4_REGISTERS;
|
| }
|
| } else if (double_artificial_registers_.Contains(
|
| virtual_register - first_artificial_register_)) {
|
| return DOUBLE_REGISTERS;
|
| + } else if (float32x4_artificial_registers_.Contains(
|
| + virtual_register - first_artificial_register_)) {
|
| + return FLOAT32x4_REGISTERS;
|
| + } else if (int32x4_artificial_registers_.Contains(
|
| + virtual_register - first_artificial_register_)) {
|
| + return INT32x4_REGISTERS;
|
| }
|
|
|
| return GENERAL_REGISTERS;
|
| @@ -1732,19 +1770,29 @@ void LAllocator::FreeSpillSlot(LiveRange* range) {
|
|
|
| int index = range->TopLevel()->GetSpillOperand()->index();
|
| if (index >= 0) {
|
| - reusable_slots_.Add(range, zone());
|
| + if (range->Kind() == FLOAT32x4_REGISTERS) {
|
| + reusable_xmm_slots_.Add(range, zone());
|
| + } else if (range->Kind() == INT32x4_REGISTERS) {
|
| + reusable_xmm_slots_.Add(range, zone());
|
| + } else {
|
| + reusable_slots_.Add(range, zone());
|
| + }
|
| }
|
| }
|
|
|
|
|
| LOperand* LAllocator::TryReuseSpillSlot(LiveRange* range) {
|
| - if (reusable_slots_.is_empty()) return NULL;
|
| - if (reusable_slots_.first()->End().Value() >
|
| + ZoneList<LiveRange*>* reusable_slots =
|
| + (range->Kind() == FLOAT32x4_REGISTERS ||
|
| + range->Kind() == INT32x4_REGISTERS)
|
| + ? &reusable_xmm_slots_ : &reusable_slots_;
|
| + if (reusable_slots->is_empty()) return NULL;
|
| + if (reusable_slots->first()->End().Value() >
|
| range->TopLevel()->Start().Value()) {
|
| return NULL;
|
| }
|
| - LOperand* result = reusable_slots_.first()->TopLevel()->GetSpillOperand();
|
| - reusable_slots_.Remove(0);
|
| + LOperand* result = reusable_slots->first()->TopLevel()->GetSpillOperand();
|
| + reusable_slots->Remove(0);
|
| return result;
|
| }
|
|
|
| @@ -1811,7 +1859,8 @@ bool LAllocator::TryAllocateFreeReg(LiveRange* current) {
|
| }
|
|
|
| LOperand* hint = current->FirstHint();
|
| - if (hint != NULL && (hint->IsRegister() || hint->IsDoubleRegister())) {
|
| + if (hint != NULL && (hint->IsRegister() || hint->IsDoubleRegister() ||
|
| + hint->IsFloat32x4Register() || hint->IsInt32x4Register())) {
|
| int register_index = hint->index();
|
| TraceAlloc(
|
| "Found reg hint %s (free until [%d) for live range %d (end %d[).\n",
|
| @@ -2162,7 +2211,15 @@ void LAllocator::Spill(LiveRange* range) {
|
|
|
| if (!first->HasAllocatedSpillOperand()) {
|
| LOperand* op = TryReuseSpillSlot(range);
|
| - if (op == NULL) op = chunk_->GetNextSpillSlot(range->Kind());
|
| + if (op == NULL) {
|
| + op = chunk_->GetNextSpillSlot(range->Kind());
|
| + } else if (range->Kind() == FLOAT32x4_REGISTERS &&
|
| + op->kind() != LOperand::FLOAT32x4_STACK_SLOT) {
|
| + op = LFloat32x4StackSlot::Create(op->index(), zone());
|
| + } else if (range->Kind() == INT32x4_REGISTERS &&
|
| + op->kind() != LOperand::INT32x4_STACK_SLOT) {
|
| + op = LInt32x4StackSlot::Create(op->index(), zone());
|
| + }
|
| first->SetSpillOperand(op);
|
| }
|
| range->MakeSpilled(chunk()->zone());
|
|
|