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 415 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
834 void TopLevelLiveRange::SetSpillRange(SpillRange* spill_range) { | 827 void TopLevelLiveRange::SetSpillRange(SpillRange* spill_range) { |
835 DCHECK(!HasSpillOperand()); | 828 DCHECK(!HasSpillOperand()); |
836 DCHECK(spill_range); | 829 DCHECK(spill_range); |
837 spill_range_ = spill_range; | 830 spill_range_ = spill_range; |
838 } | 831 } |
839 | 832 |
840 | 833 |
841 AllocatedOperand TopLevelLiveRange::GetSpillRangeOperand() const { | 834 AllocatedOperand TopLevelLiveRange::GetSpillRangeOperand() const { |
842 auto spill_range = GetSpillRange(); | 835 auto spill_range = GetSpillRange(); |
843 int index = spill_range->assigned_slot(); | 836 int index = spill_range->assigned_slot(); |
844 switch (kind()) { | 837 return AllocatedOperand(LocationOperand::STACK_SLOT, machine_type(), index); |
845 case GENERAL_REGISTERS: | |
846 return StackSlotOperand(machine_type(), index); | |
847 case DOUBLE_REGISTERS: | |
848 return DoubleStackSlotOperand(machine_type(), index); | |
849 } | |
850 UNREACHABLE(); | |
851 return StackSlotOperand(kMachNone, 0); | |
852 } | 838 } |
853 | 839 |
854 | 840 |
855 void TopLevelLiveRange::Splinter(LifetimePosition start, LifetimePosition end, | 841 void TopLevelLiveRange::Splinter(LifetimePosition start, LifetimePosition end, |
856 Zone* zone) { | 842 Zone* zone) { |
857 DCHECK(start != Start() || end != End()); | 843 DCHECK(start != Start() || end != End()); |
858 DCHECK(start < end); | 844 DCHECK(start < end); |
859 | 845 |
860 TopLevelLiveRange splinter_temp(-1, machine_type()); | 846 TopLevelLiveRange splinter_temp(-1, machine_type()); |
861 UsePosition* last_in_splinter = nullptr; | 847 UsePosition* last_in_splinter = nullptr; |
(...skipping 663 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1525 UnallocatedOperand* operand, int pos, bool is_tagged) { | 1511 UnallocatedOperand* operand, int pos, bool is_tagged) { |
1526 TRACE("Allocating fixed reg for op %d\n", operand->virtual_register()); | 1512 TRACE("Allocating fixed reg for op %d\n", operand->virtual_register()); |
1527 DCHECK(operand->HasFixedPolicy()); | 1513 DCHECK(operand->HasFixedPolicy()); |
1528 InstructionOperand allocated; | 1514 InstructionOperand allocated; |
1529 MachineType machine_type = InstructionSequence::DefaultRepresentation(); | 1515 MachineType machine_type = InstructionSequence::DefaultRepresentation(); |
1530 int virtual_register = operand->virtual_register(); | 1516 int virtual_register = operand->virtual_register(); |
1531 if (virtual_register != InstructionOperand::kInvalidVirtualRegister) { | 1517 if (virtual_register != InstructionOperand::kInvalidVirtualRegister) { |
1532 machine_type = data()->MachineTypeFor(virtual_register); | 1518 machine_type = data()->MachineTypeFor(virtual_register); |
1533 } | 1519 } |
1534 if (operand->HasFixedSlotPolicy()) { | 1520 if (operand->HasFixedSlotPolicy()) { |
1535 AllocatedOperand::AllocatedKind kind = | 1521 allocated = AllocatedOperand(AllocatedOperand::STACK_SLOT, machine_type, |
1536 IsFloatingPoint(machine_type) ? AllocatedOperand::DOUBLE_STACK_SLOT | 1522 operand->fixed_slot_index()); |
1537 : AllocatedOperand::STACK_SLOT; | |
1538 allocated = | |
1539 AllocatedOperand(kind, machine_type, operand->fixed_slot_index()); | |
1540 } else if (operand->HasFixedRegisterPolicy()) { | 1523 } else if (operand->HasFixedRegisterPolicy()) { |
| 1524 DCHECK(!IsFloatingPoint(machine_type)); |
1541 allocated = AllocatedOperand(AllocatedOperand::REGISTER, machine_type, | 1525 allocated = AllocatedOperand(AllocatedOperand::REGISTER, machine_type, |
1542 operand->fixed_register_index()); | 1526 operand->fixed_register_index()); |
1543 } else if (operand->HasFixedDoubleRegisterPolicy()) { | 1527 } else if (operand->HasFixedDoubleRegisterPolicy()) { |
| 1528 DCHECK(IsFloatingPoint(machine_type)); |
1544 DCHECK_NE(InstructionOperand::kInvalidVirtualRegister, virtual_register); | 1529 DCHECK_NE(InstructionOperand::kInvalidVirtualRegister, virtual_register); |
1545 allocated = AllocatedOperand(AllocatedOperand::DOUBLE_REGISTER, | 1530 allocated = AllocatedOperand(AllocatedOperand::REGISTER, machine_type, |
1546 machine_type, operand->fixed_register_index()); | 1531 operand->fixed_register_index()); |
1547 } else { | 1532 } else { |
1548 UNREACHABLE(); | 1533 UNREACHABLE(); |
1549 } | 1534 } |
1550 InstructionOperand::ReplaceWith(operand, &allocated); | 1535 InstructionOperand::ReplaceWith(operand, &allocated); |
1551 if (is_tagged) { | 1536 if (is_tagged) { |
1552 TRACE("Fixed reg is tagged at %d\n", pos); | 1537 TRACE("Fixed reg is tagged at %d\n", pos); |
1553 auto instr = code()->InstructionAt(pos); | 1538 auto instr = code()->InstructionAt(pos); |
1554 if (instr->HasReferenceMap()) { | 1539 if (instr->HasReferenceMap()) { |
1555 instr->reference_map()->RecordReference(*AllocatedOperand::cast(operand)); | 1540 instr->reference_map()->RecordReference(*AllocatedOperand::cast(operand)); |
1556 } | 1541 } |
(...skipping 30 matching lines...) Expand all Loading... |
1587 auto output_operand = last_instruction->OutputAt(i); | 1572 auto output_operand = last_instruction->OutputAt(i); |
1588 DCHECK(!output_operand->IsConstant()); | 1573 DCHECK(!output_operand->IsConstant()); |
1589 auto output = UnallocatedOperand::cast(output_operand); | 1574 auto output = UnallocatedOperand::cast(output_operand); |
1590 int output_vreg = output->virtual_register(); | 1575 int output_vreg = output->virtual_register(); |
1591 auto range = data()->GetOrCreateLiveRangeFor(output_vreg); | 1576 auto range = data()->GetOrCreateLiveRangeFor(output_vreg); |
1592 bool assigned = false; | 1577 bool assigned = false; |
1593 if (output->HasFixedPolicy()) { | 1578 if (output->HasFixedPolicy()) { |
1594 AllocateFixed(output, -1, false); | 1579 AllocateFixed(output, -1, false); |
1595 // This value is produced on the stack, we never need to spill it. | 1580 // This value is produced on the stack, we never need to spill it. |
1596 if (output->IsStackSlot()) { | 1581 if (output->IsStackSlot()) { |
1597 DCHECK(StackSlotOperand::cast(output)->index() < | 1582 DCHECK(LocationOperand::cast(output)->index() < |
1598 data()->frame()->GetSpillSlotCount()); | 1583 data()->frame()->GetSpillSlotCount()); |
1599 range->SetSpillOperand(StackSlotOperand::cast(output)); | 1584 range->SetSpillOperand(LocationOperand::cast(output)); |
1600 range->SetSpillStartIndex(end); | 1585 range->SetSpillStartIndex(end); |
1601 assigned = true; | 1586 assigned = true; |
1602 } | 1587 } |
1603 | 1588 |
1604 for (auto succ : block->successors()) { | 1589 for (auto succ : block->successors()) { |
1605 const InstructionBlock* successor = code()->InstructionBlockAt(succ); | 1590 const InstructionBlock* successor = code()->InstructionBlockAt(succ); |
1606 DCHECK(successor->PredecessorCount() == 1); | 1591 DCHECK(successor->PredecessorCount() == 1); |
1607 int gap_index = successor->first_instruction_index(); | 1592 int gap_index = successor->first_instruction_index(); |
1608 // Create an unconstrained operand for the same virtual register | 1593 // Create an unconstrained operand for the same virtual register |
1609 // and insert a gap move from the fixed output to the operand. | 1594 // 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... |
1647 data()->GetOrCreateLiveRangeFor(first_output->virtual_register()); | 1632 data()->GetOrCreateLiveRangeFor(first_output->virtual_register()); |
1648 bool assigned = false; | 1633 bool assigned = false; |
1649 if (first_output->HasFixedPolicy()) { | 1634 if (first_output->HasFixedPolicy()) { |
1650 int output_vreg = first_output->virtual_register(); | 1635 int output_vreg = first_output->virtual_register(); |
1651 UnallocatedOperand output_copy(UnallocatedOperand::ANY, output_vreg); | 1636 UnallocatedOperand output_copy(UnallocatedOperand::ANY, output_vreg); |
1652 bool is_tagged = code()->IsReference(output_vreg); | 1637 bool is_tagged = code()->IsReference(output_vreg); |
1653 AllocateFixed(first_output, instr_index, is_tagged); | 1638 AllocateFixed(first_output, instr_index, is_tagged); |
1654 | 1639 |
1655 // This value is produced on the stack, we never need to spill it. | 1640 // This value is produced on the stack, we never need to spill it. |
1656 if (first_output->IsStackSlot()) { | 1641 if (first_output->IsStackSlot()) { |
1657 DCHECK(StackSlotOperand::cast(first_output)->index() < | 1642 DCHECK(LocationOperand::cast(first_output)->index() < |
1658 data()->frame()->GetTotalFrameSlotCount()); | 1643 data()->frame()->GetTotalFrameSlotCount()); |
1659 range->SetSpillOperand(StackSlotOperand::cast(first_output)); | 1644 range->SetSpillOperand(LocationOperand::cast(first_output)); |
1660 range->SetSpillStartIndex(instr_index + 1); | 1645 range->SetSpillStartIndex(instr_index + 1); |
1661 assigned = true; | 1646 assigned = true; |
1662 } | 1647 } |
1663 data()->AddGapMove(instr_index + 1, Instruction::START, *first_output, | 1648 data()->AddGapMove(instr_index + 1, Instruction::START, *first_output, |
1664 output_copy); | 1649 output_copy); |
1665 } | 1650 } |
1666 // Make sure we add a gap move for spilling (if we have not done | 1651 // Make sure we add a gap move for spilling (if we have not done |
1667 // so already). | 1652 // so already). |
1668 if (!assigned) { | 1653 if (!assigned) { |
1669 range->SpillAtDefinition(allocation_zone(), instr_index + 1, | 1654 range->SpillAtDefinition(allocation_zone(), instr_index + 1, |
1670 first_output); | 1655 first_output); |
1671 range->SetSpillStartIndex(instr_index + 1); | 1656 range->SetSpillStartIndex(instr_index + 1); |
1672 } | 1657 } |
1673 } | 1658 } |
1674 } | 1659 } |
1675 | 1660 |
1676 | 1661 |
1677 void ConstraintBuilder::MeetConstraintsBefore(int instr_index) { | 1662 void ConstraintBuilder::MeetConstraintsBefore(int instr_index) { |
1678 auto second = code()->InstructionAt(instr_index); | 1663 auto second = code()->InstructionAt(instr_index); |
1679 // Handle fixed input operands of second instruction. | 1664 // Handle fixed input operands of second instruction. |
1680 for (size_t i = 0; i < second->InputCount(); i++) { | 1665 for (size_t i = 0; i < second->InputCount(); i++) { |
1681 auto input = second->InputAt(i); | 1666 auto input = second->InputAt(i); |
1682 if (input->IsImmediate()) continue; // Ignore immediates. | 1667 if (input->IsImmediate() || input->IsExplicit()) { |
| 1668 continue; // Ignore immediates and explicitly reserved registers. |
| 1669 } |
1683 auto cur_input = UnallocatedOperand::cast(input); | 1670 auto cur_input = UnallocatedOperand::cast(input); |
1684 if (cur_input->HasFixedPolicy()) { | 1671 if (cur_input->HasFixedPolicy()) { |
1685 int input_vreg = cur_input->virtual_register(); | 1672 int input_vreg = cur_input->virtual_register(); |
1686 UnallocatedOperand input_copy(UnallocatedOperand::ANY, input_vreg); | 1673 UnallocatedOperand input_copy(UnallocatedOperand::ANY, input_vreg); |
1687 bool is_tagged = code()->IsReference(input_vreg); | 1674 bool is_tagged = code()->IsReference(input_vreg); |
1688 AllocateFixed(cur_input, instr_index, is_tagged); | 1675 AllocateFixed(cur_input, instr_index, is_tagged); |
1689 data()->AddGapMove(instr_index, Instruction::END, input_copy, *cur_input); | 1676 data()->AddGapMove(instr_index, Instruction::END, input_copy, *cur_input); |
1690 } | 1677 } |
1691 } | 1678 } |
1692 // Handle "output same as input" for second instruction. | 1679 // Handle "output same as input" for second instruction. |
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1852 | 1839 |
1853 TopLevelLiveRange* LiveRangeBuilder::LiveRangeFor(InstructionOperand* operand) { | 1840 TopLevelLiveRange* LiveRangeBuilder::LiveRangeFor(InstructionOperand* operand) { |
1854 if (operand->IsUnallocated()) { | 1841 if (operand->IsUnallocated()) { |
1855 return data()->GetOrCreateLiveRangeFor( | 1842 return data()->GetOrCreateLiveRangeFor( |
1856 UnallocatedOperand::cast(operand)->virtual_register()); | 1843 UnallocatedOperand::cast(operand)->virtual_register()); |
1857 } else if (operand->IsConstant()) { | 1844 } else if (operand->IsConstant()) { |
1858 return data()->GetOrCreateLiveRangeFor( | 1845 return data()->GetOrCreateLiveRangeFor( |
1859 ConstantOperand::cast(operand)->virtual_register()); | 1846 ConstantOperand::cast(operand)->virtual_register()); |
1860 } else if (operand->IsRegister()) { | 1847 } else if (operand->IsRegister()) { |
1861 return FixedLiveRangeFor( | 1848 return FixedLiveRangeFor( |
1862 RegisterOperand::cast(operand)->GetRegister().code()); | 1849 LocationOperand::cast(operand)->GetRegister().code()); |
1863 } else if (operand->IsDoubleRegister()) { | 1850 } else if (operand->IsDoubleRegister()) { |
1864 return FixedDoubleLiveRangeFor( | 1851 return FixedDoubleLiveRangeFor( |
1865 DoubleRegisterOperand::cast(operand)->GetDoubleRegister().code()); | 1852 LocationOperand::cast(operand)->GetDoubleRegister().code()); |
1866 } else { | 1853 } else { |
1867 return nullptr; | 1854 return nullptr; |
1868 } | 1855 } |
1869 } | 1856 } |
1870 | 1857 |
1871 | 1858 |
1872 UsePosition* LiveRangeBuilder::NewUsePosition(LifetimePosition pos, | 1859 UsePosition* LiveRangeBuilder::NewUsePosition(LifetimePosition pos, |
1873 InstructionOperand* operand, | 1860 InstructionOperand* operand, |
1874 void* hint, | 1861 void* hint, |
1875 UsePositionHintType hint_type) { | 1862 UsePositionHintType hint_type) { |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1969 if (!IsOutputDoubleRegisterOf(instr, DoubleRegister::from_code(code))) { | 1956 if (!IsOutputDoubleRegisterOf(instr, DoubleRegister::from_code(code))) { |
1970 auto range = FixedDoubleLiveRangeFor(code); | 1957 auto range = FixedDoubleLiveRangeFor(code); |
1971 range->AddUseInterval(curr_position, curr_position.End(), | 1958 range->AddUseInterval(curr_position, curr_position.End(), |
1972 allocation_zone()); | 1959 allocation_zone()); |
1973 } | 1960 } |
1974 } | 1961 } |
1975 } | 1962 } |
1976 | 1963 |
1977 for (size_t i = 0; i < instr->InputCount(); i++) { | 1964 for (size_t i = 0; i < instr->InputCount(); i++) { |
1978 auto input = instr->InputAt(i); | 1965 auto input = instr->InputAt(i); |
1979 if (input->IsImmediate()) continue; // Ignore immediates. | 1966 if (input->IsImmediate() || input->IsExplicit()) { |
| 1967 continue; // Ignore immediates and explicitly reserved registers. |
| 1968 } |
1980 LifetimePosition use_pos; | 1969 LifetimePosition use_pos; |
1981 if (input->IsUnallocated() && | 1970 if (input->IsUnallocated() && |
1982 UnallocatedOperand::cast(input)->IsUsedAtStart()) { | 1971 UnallocatedOperand::cast(input)->IsUsedAtStart()) { |
1983 use_pos = curr_position; | 1972 use_pos = curr_position; |
1984 } else { | 1973 } else { |
1985 use_pos = curr_position.End(); | 1974 use_pos = curr_position.End(); |
1986 } | 1975 } |
1987 | 1976 |
1988 if (input->IsUnallocated()) { | 1977 if (input->IsUnallocated()) { |
1989 UnallocatedOperand* unalloc = UnallocatedOperand::cast(input); | 1978 UnallocatedOperand* unalloc = UnallocatedOperand::cast(input); |
(...skipping 1464 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3454 auto eliminate = moves->PrepareInsertAfter(move); | 3443 auto eliminate = moves->PrepareInsertAfter(move); |
3455 to_insert.push_back(move); | 3444 to_insert.push_back(move); |
3456 if (eliminate != nullptr) to_eliminate.push_back(eliminate); | 3445 if (eliminate != nullptr) to_eliminate.push_back(eliminate); |
3457 } | 3446 } |
3458 } | 3447 } |
3459 | 3448 |
3460 | 3449 |
3461 } // namespace compiler | 3450 } // namespace compiler |
3462 } // namespace internal | 3451 } // namespace internal |
3463 } // namespace v8 | 3452 } // namespace v8 |
OLD | NEW |