| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/base/adapters.h" | 5 #include "src/base/adapters.h" |
| 6 #include "src/compiler/linkage.h" | 6 #include "src/compiler/linkage.h" |
| 7 #include "src/compiler/register-allocator.h" | 7 #include "src/compiler/register-allocator.h" |
| 8 #include "src/string-stream.h" | 8 #include "src/string-stream.h" |
| 9 | 9 |
| 10 namespace v8 { | 10 namespace v8 { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 64 Instruction* GetLastInstruction(InstructionSequence* code, | 64 Instruction* GetLastInstruction(InstructionSequence* code, |
| 65 const InstructionBlock* block) { | 65 const InstructionBlock* block) { |
| 66 return code->InstructionAt(block->last_instruction_index()); | 66 return code->InstructionAt(block->last_instruction_index()); |
| 67 } | 67 } |
| 68 | 68 |
| 69 | 69 |
| 70 bool IsOutputRegisterOf(Instruction* instr, Register reg) { | 70 bool IsOutputRegisterOf(Instruction* instr, Register reg) { |
| 71 for (size_t i = 0; i < instr->OutputCount(); i++) { | 71 for (size_t i = 0; i < instr->OutputCount(); i++) { |
| 72 auto output = instr->OutputAt(i); | 72 auto output = instr->OutputAt(i); |
| 73 if (output->IsRegister() && | 73 if (output->IsRegister() && |
| 74 RegisterOperand::cast(output)->GetRegister().is(reg)) { | 74 LocationOperand::cast(output)->GetRegister().is(reg)) { |
| 75 return true; | 75 return true; |
| 76 } | 76 } |
| 77 } | 77 } |
| 78 return false; | 78 return false; |
| 79 } | 79 } |
| 80 | 80 |
| 81 | 81 |
| 82 bool IsOutputDoubleRegisterOf(Instruction* instr, DoubleRegister reg) { | 82 bool IsOutputDoubleRegisterOf(Instruction* instr, DoubleRegister reg) { |
| 83 for (size_t i = 0; i < instr->OutputCount(); i++) { | 83 for (size_t i = 0; i < instr->OutputCount(); i++) { |
| 84 auto output = instr->OutputAt(i); | 84 auto output = instr->OutputAt(i); |
| 85 if (output->IsDoubleRegister() && | 85 if (output->IsDoubleRegister() && |
| 86 DoubleRegisterOperand::cast(output)->GetDoubleRegister().is(reg)) { | 86 LocationOperand::cast(output)->GetDoubleRegister().is(reg)) { |
| 87 return true; | 87 return true; |
| 88 } | 88 } |
| 89 } | 89 } |
| 90 return false; | 90 return false; |
| 91 } | 91 } |
| 92 | 92 |
| 93 | 93 |
| 94 // TODO(dcarney): fix frame to allow frame accesses to half size location. | 94 // TODO(dcarney): fix frame to allow frame accesses to half size location. |
| 95 int GetByteWidth(MachineType machine_type) { | 95 int GetByteWidth(MachineType machine_type) { |
| 96 DCHECK_EQ(RepresentationOf(machine_type), machine_type); | 96 DCHECK_EQ(RepresentationOf(machine_type), machine_type); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 154 auto use_pos = reinterpret_cast<UsePosition*>(hint_); | 154 auto use_pos = reinterpret_cast<UsePosition*>(hint_); |
| 155 int assigned_register = AssignedRegisterField::decode(use_pos->flags_); | 155 int assigned_register = AssignedRegisterField::decode(use_pos->flags_); |
| 156 if (assigned_register == kUnassignedRegister) return false; | 156 if (assigned_register == kUnassignedRegister) return false; |
| 157 *register_code = assigned_register; | 157 *register_code = assigned_register; |
| 158 return true; | 158 return true; |
| 159 } | 159 } |
| 160 case UsePositionHintType::kOperand: { | 160 case UsePositionHintType::kOperand: { |
| 161 auto operand = reinterpret_cast<InstructionOperand*>(hint_); | 161 auto operand = reinterpret_cast<InstructionOperand*>(hint_); |
| 162 int assigned_register = | 162 int assigned_register = |
| 163 operand->IsRegister() | 163 operand->IsRegister() |
| 164 ? RegisterOperand::cast(operand)->GetRegister().code() | 164 ? LocationOperand::cast(operand)->GetRegister().code() |
| 165 : DoubleRegisterOperand::cast(operand) | 165 : LocationOperand::cast(operand)->GetDoubleRegister().code(); |
| 166 ->GetDoubleRegister() | |
| 167 .code(); | |
| 168 *register_code = assigned_register; | 166 *register_code = assigned_register; |
| 169 return true; | 167 return true; |
| 170 } | 168 } |
| 171 case UsePositionHintType::kPhi: { | 169 case UsePositionHintType::kPhi: { |
| 172 auto phi = reinterpret_cast<RegisterAllocationData::PhiMapValue*>(hint_); | 170 auto phi = reinterpret_cast<RegisterAllocationData::PhiMapValue*>(hint_); |
| 173 int assigned_register = phi->assigned_register(); | 171 int assigned_register = phi->assigned_register(); |
| 174 if (assigned_register == kUnassignedRegister) return false; | 172 if (assigned_register == kUnassignedRegister) return false; |
| 175 *register_code = assigned_register; | 173 *register_code = assigned_register; |
| 176 return true; | 174 return true; |
| 177 } | 175 } |
| 178 } | 176 } |
| 179 UNREACHABLE(); | 177 UNREACHABLE(); |
| 180 return false; | 178 return false; |
| 181 } | 179 } |
| 182 | 180 |
| 183 | 181 |
| 184 UsePositionHintType UsePosition::HintTypeForOperand( | 182 UsePositionHintType UsePosition::HintTypeForOperand( |
| 185 const InstructionOperand& op) { | 183 const InstructionOperand& op) { |
| 186 switch (op.kind()) { | 184 switch (op.kind()) { |
| 187 case InstructionOperand::CONSTANT: | 185 case InstructionOperand::CONSTANT: |
| 188 case InstructionOperand::IMMEDIATE: | 186 case InstructionOperand::IMMEDIATE: |
| 187 case InstructionOperand::EXPLICIT: |
| 189 return UsePositionHintType::kNone; | 188 return UsePositionHintType::kNone; |
| 190 case InstructionOperand::UNALLOCATED: | 189 case InstructionOperand::UNALLOCATED: |
| 191 return UsePositionHintType::kUnresolved; | 190 return UsePositionHintType::kUnresolved; |
| 192 case InstructionOperand::ALLOCATED: | 191 case InstructionOperand::ALLOCATED: |
| 193 switch (AllocatedOperand::cast(op).allocated_kind()) { | 192 if (op.IsRegister() || op.IsDoubleRegister()) { |
| 194 case AllocatedOperand::REGISTER: | 193 return UsePositionHintType::kOperand; |
| 195 case AllocatedOperand::DOUBLE_REGISTER: | 194 } else { |
| 196 return UsePositionHintType::kOperand; | 195 DCHECK(op.IsStackSlot() || op.IsDoubleStackSlot()); |
| 197 case AllocatedOperand::STACK_SLOT: | 196 return UsePositionHintType::kNone; |
| 198 case AllocatedOperand::DOUBLE_STACK_SLOT: | |
| 199 return UsePositionHintType::kNone; | |
| 200 } | 197 } |
| 201 case InstructionOperand::INVALID: | 198 case InstructionOperand::INVALID: |
| 202 break; | 199 break; |
| 203 } | 200 } |
| 204 UNREACHABLE(); | 201 UNREACHABLE(); |
| 205 return UsePositionHintType::kNone; | 202 return UsePositionHintType::kNone; |
| 206 } | 203 } |
| 207 | 204 |
| 208 | 205 |
| 209 void UsePosition::ResolveHint(UsePosition* use_pos) { | 206 void UsePosition::ResolveHint(UsePosition* use_pos) { |
| (...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 393 return use_pos->pos() > pos.NextStart().End(); | 390 return use_pos->pos() > pos.NextStart().End(); |
| 394 } | 391 } |
| 395 | 392 |
| 396 | 393 |
| 397 bool LiveRange::IsTopLevel() const { return top_level_ == this; } | 394 bool LiveRange::IsTopLevel() const { return top_level_ == this; } |
| 398 | 395 |
| 399 | 396 |
| 400 InstructionOperand LiveRange::GetAssignedOperand() const { | 397 InstructionOperand LiveRange::GetAssignedOperand() const { |
| 401 if (HasRegisterAssigned()) { | 398 if (HasRegisterAssigned()) { |
| 402 DCHECK(!spilled()); | 399 DCHECK(!spilled()); |
| 403 switch (kind()) { | 400 return AllocatedOperand(LocationOperand::REGISTER, machine_type(), |
| 404 case GENERAL_REGISTERS: | 401 assigned_register()); |
| 405 return RegisterOperand(machine_type(), assigned_register()); | |
| 406 case DOUBLE_REGISTERS: | |
| 407 return DoubleRegisterOperand(machine_type(), assigned_register()); | |
| 408 } | |
| 409 } | 402 } |
| 410 DCHECK(spilled()); | 403 DCHECK(spilled()); |
| 411 DCHECK(!HasRegisterAssigned()); | 404 DCHECK(!HasRegisterAssigned()); |
| 412 if (TopLevel()->HasSpillOperand()) { | 405 if (TopLevel()->HasSpillOperand()) { |
| 413 auto op = TopLevel()->GetSpillOperand(); | 406 auto op = TopLevel()->GetSpillOperand(); |
| 414 DCHECK(!op->IsUnallocated()); | 407 DCHECK(!op->IsUnallocated()); |
| 415 return *op; | 408 return *op; |
| 416 } | 409 } |
| 417 return TopLevel()->GetSpillRangeOperand(); | 410 return TopLevel()->GetSpillRangeOperand(); |
| 418 } | 411 } |
| (...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 827 void TopLevelLiveRange::SetSpillRange(SpillRange* spill_range) { | 820 void TopLevelLiveRange::SetSpillRange(SpillRange* spill_range) { |
| 828 DCHECK(!HasSpillOperand()); | 821 DCHECK(!HasSpillOperand()); |
| 829 DCHECK(spill_range); | 822 DCHECK(spill_range); |
| 830 spill_range_ = spill_range; | 823 spill_range_ = spill_range; |
| 831 } | 824 } |
| 832 | 825 |
| 833 | 826 |
| 834 AllocatedOperand TopLevelLiveRange::GetSpillRangeOperand() const { | 827 AllocatedOperand TopLevelLiveRange::GetSpillRangeOperand() const { |
| 835 auto spill_range = GetSpillRange(); | 828 auto spill_range = GetSpillRange(); |
| 836 int index = spill_range->assigned_slot(); | 829 int index = spill_range->assigned_slot(); |
| 837 switch (kind()) { | 830 return AllocatedOperand(LocationOperand::STACK_SLOT, machine_type(), index); |
| 838 case GENERAL_REGISTERS: | |
| 839 return StackSlotOperand(machine_type(), index); | |
| 840 case DOUBLE_REGISTERS: | |
| 841 return DoubleStackSlotOperand(machine_type(), index); | |
| 842 } | |
| 843 UNREACHABLE(); | |
| 844 return StackSlotOperand(kMachNone, 0); | |
| 845 } | 831 } |
| 846 | 832 |
| 847 | 833 |
| 848 void TopLevelLiveRange::Splinter(LifetimePosition start, LifetimePosition end, | 834 void TopLevelLiveRange::Splinter(LifetimePosition start, LifetimePosition end, |
| 849 Zone* zone) { | 835 Zone* zone) { |
| 850 DCHECK(start != Start() || end != End()); | 836 DCHECK(start != Start() || end != End()); |
| 851 DCHECK(start < end); | 837 DCHECK(start < end); |
| 852 | 838 |
| 853 TopLevelLiveRange splinter_temp(-1, machine_type()); | 839 TopLevelLiveRange splinter_temp(-1, machine_type()); |
| 854 UsePosition* last_in_splinter = nullptr; | 840 UsePosition* last_in_splinter = nullptr; |
| (...skipping 663 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1518 UnallocatedOperand* operand, int pos, bool is_tagged) { | 1504 UnallocatedOperand* operand, int pos, bool is_tagged) { |
| 1519 TRACE("Allocating fixed reg for op %d\n", operand->virtual_register()); | 1505 TRACE("Allocating fixed reg for op %d\n", operand->virtual_register()); |
| 1520 DCHECK(operand->HasFixedPolicy()); | 1506 DCHECK(operand->HasFixedPolicy()); |
| 1521 InstructionOperand allocated; | 1507 InstructionOperand allocated; |
| 1522 MachineType machine_type = InstructionSequence::DefaultRepresentation(); | 1508 MachineType machine_type = InstructionSequence::DefaultRepresentation(); |
| 1523 int virtual_register = operand->virtual_register(); | 1509 int virtual_register = operand->virtual_register(); |
| 1524 if (virtual_register != InstructionOperand::kInvalidVirtualRegister) { | 1510 if (virtual_register != InstructionOperand::kInvalidVirtualRegister) { |
| 1525 machine_type = data()->MachineTypeFor(virtual_register); | 1511 machine_type = data()->MachineTypeFor(virtual_register); |
| 1526 } | 1512 } |
| 1527 if (operand->HasFixedSlotPolicy()) { | 1513 if (operand->HasFixedSlotPolicy()) { |
| 1528 AllocatedOperand::AllocatedKind kind = | 1514 allocated = AllocatedOperand(AllocatedOperand::STACK_SLOT, machine_type, |
| 1529 IsFloatingPoint(machine_type) ? AllocatedOperand::DOUBLE_STACK_SLOT | 1515 operand->fixed_slot_index()); |
| 1530 : AllocatedOperand::STACK_SLOT; | |
| 1531 allocated = | |
| 1532 AllocatedOperand(kind, machine_type, operand->fixed_slot_index()); | |
| 1533 } else if (operand->HasFixedRegisterPolicy()) { | 1516 } else if (operand->HasFixedRegisterPolicy()) { |
| 1517 DCHECK(!IsFloatingPoint(machine_type)); |
| 1534 allocated = AllocatedOperand(AllocatedOperand::REGISTER, machine_type, | 1518 allocated = AllocatedOperand(AllocatedOperand::REGISTER, machine_type, |
| 1535 operand->fixed_register_index()); | 1519 operand->fixed_register_index()); |
| 1536 } else if (operand->HasFixedDoubleRegisterPolicy()) { | 1520 } else if (operand->HasFixedDoubleRegisterPolicy()) { |
| 1521 DCHECK(IsFloatingPoint(machine_type)); |
| 1537 DCHECK_NE(InstructionOperand::kInvalidVirtualRegister, virtual_register); | 1522 DCHECK_NE(InstructionOperand::kInvalidVirtualRegister, virtual_register); |
| 1538 allocated = AllocatedOperand(AllocatedOperand::DOUBLE_REGISTER, | 1523 allocated = AllocatedOperand(AllocatedOperand::REGISTER, machine_type, |
| 1539 machine_type, operand->fixed_register_index()); | 1524 operand->fixed_register_index()); |
| 1540 } else { | 1525 } else { |
| 1541 UNREACHABLE(); | 1526 UNREACHABLE(); |
| 1542 } | 1527 } |
| 1543 InstructionOperand::ReplaceWith(operand, &allocated); | 1528 InstructionOperand::ReplaceWith(operand, &allocated); |
| 1544 if (is_tagged) { | 1529 if (is_tagged) { |
| 1545 TRACE("Fixed reg is tagged at %d\n", pos); | 1530 TRACE("Fixed reg is tagged at %d\n", pos); |
| 1546 auto instr = code()->InstructionAt(pos); | 1531 auto instr = code()->InstructionAt(pos); |
| 1547 if (instr->HasReferenceMap()) { | 1532 if (instr->HasReferenceMap()) { |
| 1548 instr->reference_map()->RecordReference(*AllocatedOperand::cast(operand)); | 1533 instr->reference_map()->RecordReference(*AllocatedOperand::cast(operand)); |
| 1549 } | 1534 } |
| (...skipping 30 matching lines...) Expand all Loading... |
| 1580 auto output_operand = last_instruction->OutputAt(i); | 1565 auto output_operand = last_instruction->OutputAt(i); |
| 1581 DCHECK(!output_operand->IsConstant()); | 1566 DCHECK(!output_operand->IsConstant()); |
| 1582 auto output = UnallocatedOperand::cast(output_operand); | 1567 auto output = UnallocatedOperand::cast(output_operand); |
| 1583 int output_vreg = output->virtual_register(); | 1568 int output_vreg = output->virtual_register(); |
| 1584 auto range = data()->GetOrCreateLiveRangeFor(output_vreg); | 1569 auto range = data()->GetOrCreateLiveRangeFor(output_vreg); |
| 1585 bool assigned = false; | 1570 bool assigned = false; |
| 1586 if (output->HasFixedPolicy()) { | 1571 if (output->HasFixedPolicy()) { |
| 1587 AllocateFixed(output, -1, false); | 1572 AllocateFixed(output, -1, false); |
| 1588 // This value is produced on the stack, we never need to spill it. | 1573 // This value is produced on the stack, we never need to spill it. |
| 1589 if (output->IsStackSlot()) { | 1574 if (output->IsStackSlot()) { |
| 1590 DCHECK(StackSlotOperand::cast(output)->index() < | 1575 DCHECK(LocationOperand::cast(output)->index() < |
| 1591 data()->frame()->GetSpillSlotCount()); | 1576 data()->frame()->GetSpillSlotCount()); |
| 1592 range->SetSpillOperand(StackSlotOperand::cast(output)); | 1577 range->SetSpillOperand(LocationOperand::cast(output)); |
| 1593 range->SetSpillStartIndex(end); | 1578 range->SetSpillStartIndex(end); |
| 1594 assigned = true; | 1579 assigned = true; |
| 1595 } | 1580 } |
| 1596 | 1581 |
| 1597 for (auto succ : block->successors()) { | 1582 for (auto succ : block->successors()) { |
| 1598 const InstructionBlock* successor = code()->InstructionBlockAt(succ); | 1583 const InstructionBlock* successor = code()->InstructionBlockAt(succ); |
| 1599 DCHECK(successor->PredecessorCount() == 1); | 1584 DCHECK(successor->PredecessorCount() == 1); |
| 1600 int gap_index = successor->first_instruction_index(); | 1585 int gap_index = successor->first_instruction_index(); |
| 1601 // Create an unconstrained operand for the same virtual register | 1586 // Create an unconstrained operand for the same virtual register |
| 1602 // and insert a gap move from the fixed output to the operand. | 1587 // and insert a gap move from the fixed output to the operand. |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1640 data()->GetOrCreateLiveRangeFor(first_output->virtual_register()); | 1625 data()->GetOrCreateLiveRangeFor(first_output->virtual_register()); |
| 1641 bool assigned = false; | 1626 bool assigned = false; |
| 1642 if (first_output->HasFixedPolicy()) { | 1627 if (first_output->HasFixedPolicy()) { |
| 1643 int output_vreg = first_output->virtual_register(); | 1628 int output_vreg = first_output->virtual_register(); |
| 1644 UnallocatedOperand output_copy(UnallocatedOperand::ANY, output_vreg); | 1629 UnallocatedOperand output_copy(UnallocatedOperand::ANY, output_vreg); |
| 1645 bool is_tagged = code()->IsReference(output_vreg); | 1630 bool is_tagged = code()->IsReference(output_vreg); |
| 1646 AllocateFixed(first_output, instr_index, is_tagged); | 1631 AllocateFixed(first_output, instr_index, is_tagged); |
| 1647 | 1632 |
| 1648 // This value is produced on the stack, we never need to spill it. | 1633 // This value is produced on the stack, we never need to spill it. |
| 1649 if (first_output->IsStackSlot()) { | 1634 if (first_output->IsStackSlot()) { |
| 1650 DCHECK(StackSlotOperand::cast(first_output)->index() < | 1635 DCHECK(LocationOperand::cast(first_output)->index() < |
| 1651 data()->frame()->GetTotalFrameSlotCount()); | 1636 data()->frame()->GetTotalFrameSlotCount()); |
| 1652 range->SetSpillOperand(StackSlotOperand::cast(first_output)); | 1637 range->SetSpillOperand(LocationOperand::cast(first_output)); |
| 1653 range->SetSpillStartIndex(instr_index + 1); | 1638 range->SetSpillStartIndex(instr_index + 1); |
| 1654 assigned = true; | 1639 assigned = true; |
| 1655 } | 1640 } |
| 1656 data()->AddGapMove(instr_index + 1, Instruction::START, *first_output, | 1641 data()->AddGapMove(instr_index + 1, Instruction::START, *first_output, |
| 1657 output_copy); | 1642 output_copy); |
| 1658 } | 1643 } |
| 1659 // Make sure we add a gap move for spilling (if we have not done | 1644 // Make sure we add a gap move for spilling (if we have not done |
| 1660 // so already). | 1645 // so already). |
| 1661 if (!assigned) { | 1646 if (!assigned) { |
| 1662 range->SpillAtDefinition(allocation_zone(), instr_index + 1, | 1647 range->SpillAtDefinition(allocation_zone(), instr_index + 1, |
| 1663 first_output); | 1648 first_output); |
| 1664 range->SetSpillStartIndex(instr_index + 1); | 1649 range->SetSpillStartIndex(instr_index + 1); |
| 1665 } | 1650 } |
| 1666 } | 1651 } |
| 1667 } | 1652 } |
| 1668 | 1653 |
| 1669 | 1654 |
| 1670 void ConstraintBuilder::MeetConstraintsBefore(int instr_index) { | 1655 void ConstraintBuilder::MeetConstraintsBefore(int instr_index) { |
| 1671 auto second = code()->InstructionAt(instr_index); | 1656 auto second = code()->InstructionAt(instr_index); |
| 1672 // Handle fixed input operands of second instruction. | 1657 // Handle fixed input operands of second instruction. |
| 1673 for (size_t i = 0; i < second->InputCount(); i++) { | 1658 for (size_t i = 0; i < second->InputCount(); i++) { |
| 1674 auto input = second->InputAt(i); | 1659 auto input = second->InputAt(i); |
| 1675 if (input->IsImmediate()) continue; // Ignore immediates. | 1660 if (input->IsImmediate() || input->IsExplicit()) { |
| 1661 continue; // Ignore immediates and explicitly reserved registers. |
| 1662 } |
| 1676 auto cur_input = UnallocatedOperand::cast(input); | 1663 auto cur_input = UnallocatedOperand::cast(input); |
| 1677 if (cur_input->HasFixedPolicy()) { | 1664 if (cur_input->HasFixedPolicy()) { |
| 1678 int input_vreg = cur_input->virtual_register(); | 1665 int input_vreg = cur_input->virtual_register(); |
| 1679 UnallocatedOperand input_copy(UnallocatedOperand::ANY, input_vreg); | 1666 UnallocatedOperand input_copy(UnallocatedOperand::ANY, input_vreg); |
| 1680 bool is_tagged = code()->IsReference(input_vreg); | 1667 bool is_tagged = code()->IsReference(input_vreg); |
| 1681 AllocateFixed(cur_input, instr_index, is_tagged); | 1668 AllocateFixed(cur_input, instr_index, is_tagged); |
| 1682 data()->AddGapMove(instr_index, Instruction::END, input_copy, *cur_input); | 1669 data()->AddGapMove(instr_index, Instruction::END, input_copy, *cur_input); |
| 1683 } | 1670 } |
| 1684 } | 1671 } |
| 1685 // Handle "output same as input" for second instruction. | 1672 // Handle "output same as input" for second instruction. |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1845 | 1832 |
| 1846 TopLevelLiveRange* LiveRangeBuilder::LiveRangeFor(InstructionOperand* operand) { | 1833 TopLevelLiveRange* LiveRangeBuilder::LiveRangeFor(InstructionOperand* operand) { |
| 1847 if (operand->IsUnallocated()) { | 1834 if (operand->IsUnallocated()) { |
| 1848 return data()->GetOrCreateLiveRangeFor( | 1835 return data()->GetOrCreateLiveRangeFor( |
| 1849 UnallocatedOperand::cast(operand)->virtual_register()); | 1836 UnallocatedOperand::cast(operand)->virtual_register()); |
| 1850 } else if (operand->IsConstant()) { | 1837 } else if (operand->IsConstant()) { |
| 1851 return data()->GetOrCreateLiveRangeFor( | 1838 return data()->GetOrCreateLiveRangeFor( |
| 1852 ConstantOperand::cast(operand)->virtual_register()); | 1839 ConstantOperand::cast(operand)->virtual_register()); |
| 1853 } else if (operand->IsRegister()) { | 1840 } else if (operand->IsRegister()) { |
| 1854 return FixedLiveRangeFor( | 1841 return FixedLiveRangeFor( |
| 1855 RegisterOperand::cast(operand)->GetRegister().code()); | 1842 LocationOperand::cast(operand)->GetRegister().code()); |
| 1856 } else if (operand->IsDoubleRegister()) { | 1843 } else if (operand->IsDoubleRegister()) { |
| 1857 return FixedDoubleLiveRangeFor( | 1844 return FixedDoubleLiveRangeFor( |
| 1858 DoubleRegisterOperand::cast(operand)->GetDoubleRegister().code()); | 1845 LocationOperand::cast(operand)->GetDoubleRegister().code()); |
| 1859 } else { | 1846 } else { |
| 1860 return nullptr; | 1847 return nullptr; |
| 1861 } | 1848 } |
| 1862 } | 1849 } |
| 1863 | 1850 |
| 1864 | 1851 |
| 1865 UsePosition* LiveRangeBuilder::NewUsePosition(LifetimePosition pos, | 1852 UsePosition* LiveRangeBuilder::NewUsePosition(LifetimePosition pos, |
| 1866 InstructionOperand* operand, | 1853 InstructionOperand* operand, |
| 1867 void* hint, | 1854 void* hint, |
| 1868 UsePositionHintType hint_type) { | 1855 UsePositionHintType hint_type) { |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1962 if (!IsOutputDoubleRegisterOf(instr, DoubleRegister::from_code(code))) { | 1949 if (!IsOutputDoubleRegisterOf(instr, DoubleRegister::from_code(code))) { |
| 1963 auto range = FixedDoubleLiveRangeFor(code); | 1950 auto range = FixedDoubleLiveRangeFor(code); |
| 1964 range->AddUseInterval(curr_position, curr_position.End(), | 1951 range->AddUseInterval(curr_position, curr_position.End(), |
| 1965 allocation_zone()); | 1952 allocation_zone()); |
| 1966 } | 1953 } |
| 1967 } | 1954 } |
| 1968 } | 1955 } |
| 1969 | 1956 |
| 1970 for (size_t i = 0; i < instr->InputCount(); i++) { | 1957 for (size_t i = 0; i < instr->InputCount(); i++) { |
| 1971 auto input = instr->InputAt(i); | 1958 auto input = instr->InputAt(i); |
| 1972 if (input->IsImmediate()) continue; // Ignore immediates. | 1959 if (input->IsImmediate() || input->IsExplicit()) { |
| 1960 continue; // Ignore immediates and explicitly reserved registers. |
| 1961 } |
| 1973 LifetimePosition use_pos; | 1962 LifetimePosition use_pos; |
| 1974 if (input->IsUnallocated() && | 1963 if (input->IsUnallocated() && |
| 1975 UnallocatedOperand::cast(input)->IsUsedAtStart()) { | 1964 UnallocatedOperand::cast(input)->IsUsedAtStart()) { |
| 1976 use_pos = curr_position; | 1965 use_pos = curr_position; |
| 1977 } else { | 1966 } else { |
| 1978 use_pos = curr_position.End(); | 1967 use_pos = curr_position.End(); |
| 1979 } | 1968 } |
| 1980 | 1969 |
| 1981 if (input->IsUnallocated()) { | 1970 if (input->IsUnallocated()) { |
| 1982 UnallocatedOperand* unalloc = UnallocatedOperand::cast(input); | 1971 UnallocatedOperand* unalloc = UnallocatedOperand::cast(input); |
| (...skipping 1410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3393 auto eliminate = moves->PrepareInsertAfter(move); | 3382 auto eliminate = moves->PrepareInsertAfter(move); |
| 3394 to_insert.push_back(move); | 3383 to_insert.push_back(move); |
| 3395 if (eliminate != nullptr) to_eliminate.push_back(eliminate); | 3384 if (eliminate != nullptr) to_eliminate.push_back(eliminate); |
| 3396 } | 3385 } |
| 3397 } | 3386 } |
| 3398 | 3387 |
| 3399 | 3388 |
| 3400 } // namespace compiler | 3389 } // namespace compiler |
| 3401 } // namespace internal | 3390 } // namespace internal |
| 3402 } // namespace v8 | 3391 } // namespace v8 |
| OLD | NEW |