Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(214)

Side by Side Diff: src/compiler/register-allocator.cc

Issue 2711633006: [wasm] Reuse constrained input for same vreg
Patch Set: alternative mulpair Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/instruction-selector-impl.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1687 matching lines...) Expand 10 before | Expand all | Expand 10 after
1698 void ConstraintBuilder::MeetConstraintsAfter(int instr_index) { 1698 void ConstraintBuilder::MeetConstraintsAfter(int instr_index) {
1699 Instruction* first = code()->InstructionAt(instr_index); 1699 Instruction* first = code()->InstructionAt(instr_index);
1700 // Handle fixed temporaries. 1700 // Handle fixed temporaries.
1701 for (size_t i = 0; i < first->TempCount(); i++) { 1701 for (size_t i = 0; i < first->TempCount(); i++) {
1702 UnallocatedOperand* temp = UnallocatedOperand::cast(first->TempAt(i)); 1702 UnallocatedOperand* temp = UnallocatedOperand::cast(first->TempAt(i));
1703 if (temp->HasFixedPolicy()) AllocateFixed(temp, instr_index, false); 1703 if (temp->HasFixedPolicy()) AllocateFixed(temp, instr_index, false);
1704 } 1704 }
1705 // Handle constant/fixed output operands. 1705 // Handle constant/fixed output operands.
1706 for (size_t i = 0; i < first->OutputCount(); i++) { 1706 for (size_t i = 0; i < first->OutputCount(); i++) {
1707 InstructionOperand* output = first->OutputAt(i); 1707 InstructionOperand* output = first->OutputAt(i);
1708 if (output->IsAllocated()) continue;
1708 if (output->IsConstant()) { 1709 if (output->IsConstant()) {
1709 int output_vreg = ConstantOperand::cast(output)->virtual_register(); 1710 int output_vreg = ConstantOperand::cast(output)->virtual_register();
1710 TopLevelLiveRange* range = data()->GetOrCreateLiveRangeFor(output_vreg); 1711 TopLevelLiveRange* range = data()->GetOrCreateLiveRangeFor(output_vreg);
1711 range->SetSpillStartIndex(instr_index + 1); 1712 range->SetSpillStartIndex(instr_index + 1);
1712 range->SetSpillOperand(output); 1713 range->SetSpillOperand(output);
1713 continue; 1714 continue;
1714 } 1715 }
1715 UnallocatedOperand* first_output = UnallocatedOperand::cast(output); 1716 UnallocatedOperand* first_output = UnallocatedOperand::cast(output);
1716 TopLevelLiveRange* range = 1717 TopLevelLiveRange* range =
1717 data()->GetOrCreateLiveRangeFor(first_output->virtual_register()); 1718 data()->GetOrCreateLiveRangeFor(first_output->virtual_register());
(...skipping 26 matching lines...) Expand all
1744 range->RecordSpillLocation(allocation_zone(), instr_index + 1, 1745 range->RecordSpillLocation(allocation_zone(), instr_index + 1,
1745 first_output); 1746 first_output);
1746 range->SetSpillStartIndex(instr_index + 1); 1747 range->SetSpillStartIndex(instr_index + 1);
1747 } 1748 }
1748 } 1749 }
1749 } 1750 }
1750 1751
1751 1752
1752 void ConstraintBuilder::MeetConstraintsBefore(int instr_index) { 1753 void ConstraintBuilder::MeetConstraintsBefore(int instr_index) {
1753 Instruction* second = code()->InstructionAt(instr_index); 1754 Instruction* second = code()->InstructionAt(instr_index);
1755 ZoneMap<int, InstructionOperand> constraints(allocation_zone());
1756
1754 // Handle fixed input operands of second instruction. 1757 // Handle fixed input operands of second instruction.
1755 for (size_t i = 0; i < second->InputCount(); i++) { 1758 for (size_t i = 0; i < second->InputCount(); ++i) {
1756 InstructionOperand* input = second->InputAt(i); 1759 InstructionOperand* input = second->InputAt(i);
1757 if (input->IsImmediate() || input->IsExplicit()) { 1760 if (input->IsImmediate() || input->IsExplicit()) {
1758 continue; // Ignore immediates and explicitly reserved registers. 1761 continue; // Ignore immediates and explicitly reserved registers.
1759 } 1762 }
1760 UnallocatedOperand* cur_input = UnallocatedOperand::cast(input); 1763 UnallocatedOperand* cur_input = UnallocatedOperand::cast(input);
1761 if (cur_input->HasFixedPolicy()) { 1764 if (cur_input->HasFixedPolicy()) {
1762 int input_vreg = cur_input->virtual_register(); 1765 int input_vreg = cur_input->virtual_register();
1763 UnallocatedOperand input_copy(UnallocatedOperand::ANY, input_vreg); 1766 UnallocatedOperand input_copy(UnallocatedOperand::ANY, input_vreg);
1764 bool is_tagged = code()->IsReference(input_vreg); 1767 bool is_tagged = code()->IsReference(input_vreg);
1765 AllocateFixed(cur_input, instr_index, is_tagged); 1768 AllocateFixed(cur_input, instr_index, is_tagged);
1769 // TODO(mtrofin): refactor AllocateFixed, its behavior is
1770 // not the most maintainable: cur_input is mutated.
1771 if (cur_input->IsAnyRegister()) {
1772 // It may be that the vreg is constrained to be in different registers.
1773 // We just want one of them for the other potential non-fixed register
1774 // uses.
1775 constraints.insert(std::make_pair(input_vreg, *cur_input));
1776 }
1766 data()->AddGapMove(instr_index, Instruction::END, input_copy, *cur_input); 1777 data()->AddGapMove(instr_index, Instruction::END, input_copy, *cur_input);
1767 } 1778 }
1768 } 1779 }
1769 // Handle "output same as input" for second instruction. 1780 // Handle "output same as input" for second instruction.
1770 for (size_t i = 0; i < second->OutputCount(); i++) { 1781 for (size_t i = 0; i < second->OutputCount(); ++i) {
1771 InstructionOperand* output = second->OutputAt(i); 1782 InstructionOperand* output = second->OutputAt(i);
1772 if (!output->IsUnallocated()) continue; 1783 if (!output->IsUnallocated()) continue;
1773 UnallocatedOperand* second_output = UnallocatedOperand::cast(output); 1784 UnallocatedOperand* second_output = UnallocatedOperand::cast(output);
1774 if (!second_output->HasSameAsInputPolicy()) continue; 1785 if (!second_output->HasSameAsInputPolicy()) continue;
1775 DCHECK(i == 0); // Only valid for first output. 1786 DCHECK(i == 0); // Only valid for first output.
1776 UnallocatedOperand* cur_input = 1787 UnallocatedOperand* cur_input =
1777 UnallocatedOperand::cast(second->InputAt(0)); 1788 UnallocatedOperand::cast(second->InputAt(0));
1778 int output_vreg = second_output->virtual_register(); 1789 int output_vreg = second_output->virtual_register();
1779 int input_vreg = cur_input->virtual_register(); 1790 int input_vreg = cur_input->virtual_register();
1780 UnallocatedOperand input_copy(UnallocatedOperand::ANY, input_vreg); 1791 if (constraints.count(input_vreg) > 0) {
1781 cur_input->set_virtual_register(second_output->virtual_register()); 1792 InstructionOperand reg_operand = constraints[input_vreg];
1782 MoveOperands* gap_move = data()->AddGapMove(instr_index, Instruction::END, 1793 InstructionOperand::ReplaceWith(second_output, &reg_operand);
1783 input_copy, *cur_input); 1794 if (data()->code()->instructions().size() >
1784 if (code()->IsReference(input_vreg) && !code()->IsReference(output_vreg)) { 1795 static_cast<size_t>(instr_index) + 1) {
1785 if (second->HasReferenceMap()) { 1796 UnallocatedOperand new_output_op(UnallocatedOperand::ANY, output_vreg);
1786 RegisterAllocationData::DelayedReference delayed_reference = { 1797 data()->AddGapMove(instr_index + 1, Instruction::START, reg_operand,
1787 second->reference_map(), &gap_move->source()}; 1798 new_output_op);
1788 data()->delayed_references().push_back(delayed_reference); 1799 TopLevelLiveRange* range = data()->GetOrCreateLiveRangeFor(output_vreg);
1800 range->RecordSpillLocation(allocation_zone(), instr_index + 1,
1801 second_output);
1802 range->SetSpillStartIndex(instr_index + 1);
1789 } 1803 }
1790 } else if (!code()->IsReference(input_vreg) && 1804 } else {
1791 code()->IsReference(output_vreg)) { 1805 UnallocatedOperand input_copy(UnallocatedOperand::ANY, input_vreg);
1792 // The input is assumed to immediately have a tagged representation, 1806 cur_input->set_virtual_register(second_output->virtual_register());
1793 // before the pointer map can be used. I.e. the pointer map at the 1807 MoveOperands* gap_move = data()->AddGapMove(instr_index, Instruction::END,
1794 // instruction will include the output operand (whose value at the 1808 input_copy, *cur_input);
1795 // beginning of the instruction is equal to the input operand). If 1809 if (code()->IsReference(input_vreg) &&
1796 // this is not desired, then the pointer map at this instruction needs 1810 !code()->IsReference(output_vreg)) {
1797 // to be adjusted manually. 1811 if (second->HasReferenceMap()) {
1812 RegisterAllocationData::DelayedReference delayed_reference = {
1813 second->reference_map(), &gap_move->source()};
1814 data()->delayed_references().push_back(delayed_reference);
1815 }
1816 } else if (!code()->IsReference(input_vreg) &&
1817 code()->IsReference(output_vreg)) {
1818 // The input is assumed to immediately have a tagged representation,
1819 // before the pointer map can be used. I.e. the pointer map at the
1820 // instruction will include the output operand (whose value at the
1821 // beginning of the instruction is equal to the input operand). If
1822 // this is not desired, then the pointer map at this instruction needs
1823 // to be adjusted manually.
1824 }
1825 }
1826 }
1827
1828 for (size_t i = 0; i < second->InputCount(); ++i) {
1829 InstructionOperand* input = second->InputAt(i);
1830 if (!input->IsUnallocated()) continue;
1831 UnallocatedOperand* cur_input = UnallocatedOperand::cast(input);
1832 if (cur_input->HasFixedPolicy() || cur_input->HasSlotPolicy()) {
1833 continue;
1834 }
1835 int vreg = cur_input->virtual_register();
1836 if (constraints.count(vreg) > 0) {
1837 InstructionOperand::ReplaceWith(input, &constraints.at(vreg));
1798 } 1838 }
1799 } 1839 }
1800 } 1840 }
1801 1841
1802 1842
1803 void ConstraintBuilder::ResolvePhis() { 1843 void ConstraintBuilder::ResolvePhis() {
1804 // Process the blocks in reverse order. 1844 // Process the blocks in reverse order.
1805 for (InstructionBlock* block : base::Reversed(code()->instruction_blocks())) { 1845 for (InstructionBlock* block : base::Reversed(code()->instruction_blocks())) {
1806 ResolvePhis(block); 1846 ResolvePhis(block);
1807 } 1847 }
(...skipping 2202 matching lines...) Expand 10 before | Expand all | Expand 10 after
4010 } 4050 }
4011 } 4051 }
4012 } 4052 }
4013 } 4053 }
4014 } 4054 }
4015 4055
4016 4056
4017 } // namespace compiler 4057 } // namespace compiler
4018 } // namespace internal 4058 } // namespace internal
4019 } // namespace v8 4059 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/instruction-selector-impl.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698