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

Side by Side Diff: src/compiler/arm64/instruction-selector-arm64.cc

Issue 1721103003: [turbofan] Introduce DeoptimizeIf And DeoptimizeUnless common operators. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Add comments Created 4 years, 10 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/arm/instruction-selector-arm.cc ('k') | src/compiler/branch-elimination.h » ('j') | 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/compiler/instruction-selector-impl.h" 5 #include "src/compiler/instruction-selector-impl.h"
6 #include "src/compiler/node-matchers.h" 6 #include "src/compiler/node-matchers.h"
7 #include "src/compiler/node-properties.h" 7 #include "src/compiler/node-properties.h"
8 8
9 namespace v8 { 9 namespace v8 {
10 namespace internal { 10 namespace internal {
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
282 282
283 if (cont->IsSet()) { 283 if (cont->IsSet()) {
284 outputs[output_count++] = g.DefineAsRegister(cont->result()); 284 outputs[output_count++] = g.DefineAsRegister(cont->result());
285 } 285 }
286 286
287 DCHECK_NE(0u, input_count); 287 DCHECK_NE(0u, input_count);
288 DCHECK((output_count != 0) || is_cmp); 288 DCHECK((output_count != 0) || is_cmp);
289 DCHECK_GE(arraysize(inputs), input_count); 289 DCHECK_GE(arraysize(inputs), input_count);
290 DCHECK_GE(arraysize(outputs), output_count); 290 DCHECK_GE(arraysize(outputs), output_count);
291 291
292 selector->Emit(cont->Encode(opcode), output_count, outputs, input_count, 292 opcode = cont->Encode(opcode);
293 inputs); 293 if (cont->IsDeoptimize()) {
294 selector->EmitDeoptimize(opcode, output_count, outputs, input_count, inputs,
295 cont->frame_state());
296 } else {
297 selector->Emit(opcode, output_count, outputs, input_count, inputs);
298 }
294 } 299 }
295 300
296 301
297 // Shared routine for multiple binary operations. 302 // Shared routine for multiple binary operations.
298 template <typename Matcher> 303 template <typename Matcher>
299 void VisitBinop(InstructionSelector* selector, Node* node, ArchOpcode opcode, 304 void VisitBinop(InstructionSelector* selector, Node* node, ArchOpcode opcode,
300 ImmediateMode operand_mode) { 305 ImmediateMode operand_mode) {
301 FlagsContinuation cont; 306 FlagsContinuation cont;
302 VisitBinop<Matcher>(selector, node, opcode, operand_mode, &cont); 307 VisitBinop<Matcher>(selector, node, opcode, operand_mode, &cont);
303 } 308 }
(...skipping 1363 matching lines...) Expand 10 before | Expand all | Expand 10 after
1667 1672
1668 // Shared routine for multiple compare operations. 1673 // Shared routine for multiple compare operations.
1669 void VisitCompare(InstructionSelector* selector, InstructionCode opcode, 1674 void VisitCompare(InstructionSelector* selector, InstructionCode opcode,
1670 InstructionOperand left, InstructionOperand right, 1675 InstructionOperand left, InstructionOperand right,
1671 FlagsContinuation* cont) { 1676 FlagsContinuation* cont) {
1672 Arm64OperandGenerator g(selector); 1677 Arm64OperandGenerator g(selector);
1673 opcode = cont->Encode(opcode); 1678 opcode = cont->Encode(opcode);
1674 if (cont->IsBranch()) { 1679 if (cont->IsBranch()) {
1675 selector->Emit(opcode, g.NoOutput(), left, right, 1680 selector->Emit(opcode, g.NoOutput(), left, right,
1676 g.Label(cont->true_block()), g.Label(cont->false_block())); 1681 g.Label(cont->true_block()), g.Label(cont->false_block()));
1682 } else if (cont->IsDeoptimize()) {
1683 selector->EmitDeoptimize(opcode, g.NoOutput(), left, right,
1684 cont->frame_state());
1677 } else { 1685 } else {
1678 DCHECK(cont->IsSet()); 1686 DCHECK(cont->IsSet());
1679 selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right); 1687 selector->Emit(opcode, g.DefineAsRegister(cont->result()), left, right);
1680 } 1688 }
1681 } 1689 }
1682 1690
1683 1691
1684 // Shared routine for multiple word compare operations. 1692 // Shared routine for multiple word compare operations.
1685 void VisitWordCompare(InstructionSelector* selector, Node* node, 1693 void VisitWordCompare(InstructionSelector* selector, Node* node,
1686 InstructionCode opcode, FlagsContinuation* cont, 1694 InstructionCode opcode, FlagsContinuation* cont,
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
1782 } else if (m.left().Is(0.0)) { 1790 } else if (m.left().Is(0.0)) {
1783 cont->Commute(); 1791 cont->Commute();
1784 VisitCompare(selector, kArm64Float64Cmp, g.UseRegister(m.right().node()), 1792 VisitCompare(selector, kArm64Float64Cmp, g.UseRegister(m.right().node()),
1785 g.UseImmediate(m.left().node()), cont); 1793 g.UseImmediate(m.left().node()), cont);
1786 } else { 1794 } else {
1787 VisitCompare(selector, kArm64Float64Cmp, g.UseRegister(m.left().node()), 1795 VisitCompare(selector, kArm64Float64Cmp, g.UseRegister(m.left().node()),
1788 g.UseRegister(m.right().node()), cont); 1796 g.UseRegister(m.right().node()), cont);
1789 } 1797 }
1790 } 1798 }
1791 1799
1792 } // namespace 1800 void VisitWordCompareZero(InstructionSelector* selector, Node* user,
1793 1801 Node* value, FlagsContinuation* cont) {
1794 1802 Arm64OperandGenerator g(selector);
1795 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch, 1803 while (selector->CanCover(user, value)) {
1796 BasicBlock* fbranch) {
1797 OperandGenerator g(this);
1798 Node* user = branch;
1799 Node* value = branch->InputAt(0);
1800
1801 FlagsContinuation cont(kNotEqual, tbranch, fbranch);
1802
1803 // Try to combine with comparisons against 0 by simply inverting the branch.
1804 while (CanCover(user, value) && value->opcode() == IrOpcode::kWord32Equal) {
1805 Int32BinopMatcher m(value);
1806 if (m.right().Is(0)) {
1807 user = value;
1808 value = m.left().node();
1809 cont.Negate();
1810 } else {
1811 break;
1812 }
1813 }
1814
1815 // Try to combine the branch with a comparison.
1816 if (CanCover(user, value)) {
1817 switch (value->opcode()) { 1804 switch (value->opcode()) {
1818 case IrOpcode::kWord32Equal: 1805 case IrOpcode::kWord32Equal: {
1819 cont.OverwriteAndNegateIfEqual(kEqual); 1806 Int32BinopMatcher m(value);
1820 return VisitWord32Compare(this, value, &cont); 1807 if (m.right().Is(0)) {
1808 user = value;
1809 value = m.left().node();
1810 cont->Negate();
1811 continue;
1812 }
1813 cont->OverwriteAndNegateIfEqual(kEqual);
1814 return VisitWord32Compare(selector, value, cont);
1815 }
1821 case IrOpcode::kInt32LessThan: 1816 case IrOpcode::kInt32LessThan:
1822 cont.OverwriteAndNegateIfEqual(kSignedLessThan); 1817 cont->OverwriteAndNegateIfEqual(kSignedLessThan);
1823 return VisitWord32Compare(this, value, &cont); 1818 return VisitWord32Compare(selector, value, cont);
1824 case IrOpcode::kInt32LessThanOrEqual: 1819 case IrOpcode::kInt32LessThanOrEqual:
1825 cont.OverwriteAndNegateIfEqual(kSignedLessThanOrEqual); 1820 cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
1826 return VisitWord32Compare(this, value, &cont); 1821 return VisitWord32Compare(selector, value, cont);
1827 case IrOpcode::kUint32LessThan: 1822 case IrOpcode::kUint32LessThan:
1828 cont.OverwriteAndNegateIfEqual(kUnsignedLessThan); 1823 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
1829 return VisitWord32Compare(this, value, &cont); 1824 return VisitWord32Compare(selector, value, cont);
1830 case IrOpcode::kUint32LessThanOrEqual: 1825 case IrOpcode::kUint32LessThanOrEqual:
1831 cont.OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); 1826 cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
1832 return VisitWord32Compare(this, value, &cont); 1827 return VisitWord32Compare(selector, value, cont);
1833 case IrOpcode::kWord64Equal: 1828 case IrOpcode::kWord64Equal:
1834 cont.OverwriteAndNegateIfEqual(kEqual); 1829 cont->OverwriteAndNegateIfEqual(kEqual);
1835 return VisitWordCompare(this, value, kArm64Cmp, &cont, false, 1830 return VisitWordCompare(selector, value, kArm64Cmp, cont, false,
1836 kArithmeticImm); 1831 kArithmeticImm);
1837 case IrOpcode::kInt64LessThan: 1832 case IrOpcode::kInt64LessThan:
1838 cont.OverwriteAndNegateIfEqual(kSignedLessThan); 1833 cont->OverwriteAndNegateIfEqual(kSignedLessThan);
1839 return VisitWordCompare(this, value, kArm64Cmp, &cont, false, 1834 return VisitWordCompare(selector, value, kArm64Cmp, cont, false,
1840 kArithmeticImm); 1835 kArithmeticImm);
1841 case IrOpcode::kInt64LessThanOrEqual: 1836 case IrOpcode::kInt64LessThanOrEqual:
1842 cont.OverwriteAndNegateIfEqual(kSignedLessThanOrEqual); 1837 cont->OverwriteAndNegateIfEqual(kSignedLessThanOrEqual);
1843 return VisitWordCompare(this, value, kArm64Cmp, &cont, false, 1838 return VisitWordCompare(selector, value, kArm64Cmp, cont, false,
1844 kArithmeticImm); 1839 kArithmeticImm);
1845 case IrOpcode::kUint64LessThan: 1840 case IrOpcode::kUint64LessThan:
1846 cont.OverwriteAndNegateIfEqual(kUnsignedLessThan); 1841 cont->OverwriteAndNegateIfEqual(kUnsignedLessThan);
1847 return VisitWordCompare(this, value, kArm64Cmp, &cont, false, 1842 return VisitWordCompare(selector, value, kArm64Cmp, cont, false,
1848 kArithmeticImm); 1843 kArithmeticImm);
1849 case IrOpcode::kUint64LessThanOrEqual: 1844 case IrOpcode::kUint64LessThanOrEqual:
1850 cont.OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual); 1845 cont->OverwriteAndNegateIfEqual(kUnsignedLessThanOrEqual);
1851 return VisitWordCompare(this, value, kArm64Cmp, &cont, false, 1846 return VisitWordCompare(selector, value, kArm64Cmp, cont, false,
1852 kArithmeticImm); 1847 kArithmeticImm);
1853 case IrOpcode::kFloat32Equal: 1848 case IrOpcode::kFloat32Equal:
1854 cont.OverwriteAndNegateIfEqual(kEqual); 1849 cont->OverwriteAndNegateIfEqual(kEqual);
1855 return VisitFloat32Compare(this, value, &cont); 1850 return VisitFloat32Compare(selector, value, cont);
1856 case IrOpcode::kFloat32LessThan: 1851 case IrOpcode::kFloat32LessThan:
1857 cont.OverwriteAndNegateIfEqual(kFloatLessThan); 1852 cont->OverwriteAndNegateIfEqual(kFloatLessThan);
1858 return VisitFloat32Compare(this, value, &cont); 1853 return VisitFloat32Compare(selector, value, cont);
1859 case IrOpcode::kFloat32LessThanOrEqual: 1854 case IrOpcode::kFloat32LessThanOrEqual:
1860 cont.OverwriteAndNegateIfEqual(kFloatLessThanOrEqual); 1855 cont->OverwriteAndNegateIfEqual(kFloatLessThanOrEqual);
1861 return VisitFloat32Compare(this, value, &cont); 1856 return VisitFloat32Compare(selector, value, cont);
1862 case IrOpcode::kFloat64Equal: 1857 case IrOpcode::kFloat64Equal:
1863 cont.OverwriteAndNegateIfEqual(kEqual); 1858 cont->OverwriteAndNegateIfEqual(kEqual);
1864 return VisitFloat64Compare(this, value, &cont); 1859 return VisitFloat64Compare(selector, value, cont);
1865 case IrOpcode::kFloat64LessThan: 1860 case IrOpcode::kFloat64LessThan:
1866 cont.OverwriteAndNegateIfEqual(kFloatLessThan); 1861 cont->OverwriteAndNegateIfEqual(kFloatLessThan);
1867 return VisitFloat64Compare(this, value, &cont); 1862 return VisitFloat64Compare(selector, value, cont);
1868 case IrOpcode::kFloat64LessThanOrEqual: 1863 case IrOpcode::kFloat64LessThanOrEqual:
1869 cont.OverwriteAndNegateIfEqual(kFloatLessThanOrEqual); 1864 cont->OverwriteAndNegateIfEqual(kFloatLessThanOrEqual);
1870 return VisitFloat64Compare(this, value, &cont); 1865 return VisitFloat64Compare(selector, value, cont);
1871 case IrOpcode::kProjection: 1866 case IrOpcode::kProjection:
1872 // Check if this is the overflow output projection of an 1867 // Check if this is the overflow output projection of an
1873 // <Operation>WithOverflow node. 1868 // <Operation>WithOverflow node.
1874 if (ProjectionIndexOf(value->op()) == 1u) { 1869 if (ProjectionIndexOf(value->op()) == 1u) {
1875 // We cannot combine the <Operation>WithOverflow with this branch 1870 // We cannot combine the <Operation>WithOverflow with this branch
1876 // unless the 0th projection (the use of the actual value of the 1871 // unless the 0th projection (the use of the actual value of the
1877 // <Operation> is either nullptr, which means there's no use of the 1872 // <Operation> is either nullptr, which means there's no use of the
1878 // actual value, or was already defined, which means it is scheduled 1873 // actual value, or was already defined, which means it is scheduled
1879 // *AFTER* this branch). 1874 // *AFTER* this branch).
1880 Node* const node = value->InputAt(0); 1875 Node* const node = value->InputAt(0);
1881 Node* const result = NodeProperties::FindProjection(node, 0); 1876 Node* const result = NodeProperties::FindProjection(node, 0);
1882 if (result == nullptr || IsDefined(result)) { 1877 if (result == nullptr || selector->IsDefined(result)) {
1883 switch (node->opcode()) { 1878 switch (node->opcode()) {
1884 case IrOpcode::kInt32AddWithOverflow: 1879 case IrOpcode::kInt32AddWithOverflow:
1885 cont.OverwriteAndNegateIfEqual(kOverflow); 1880 cont->OverwriteAndNegateIfEqual(kOverflow);
1886 return VisitBinop<Int32BinopMatcher>(this, node, kArm64Add32, 1881 return VisitBinop<Int32BinopMatcher>(
1887 kArithmeticImm, &cont); 1882 selector, node, kArm64Add32, kArithmeticImm, cont);
1888 case IrOpcode::kInt32SubWithOverflow: 1883 case IrOpcode::kInt32SubWithOverflow:
1889 cont.OverwriteAndNegateIfEqual(kOverflow); 1884 cont->OverwriteAndNegateIfEqual(kOverflow);
1890 return VisitBinop<Int32BinopMatcher>(this, node, kArm64Sub32, 1885 return VisitBinop<Int32BinopMatcher>(
1891 kArithmeticImm, &cont); 1886 selector, node, kArm64Sub32, kArithmeticImm, cont);
1892 case IrOpcode::kInt64AddWithOverflow: 1887 case IrOpcode::kInt64AddWithOverflow:
1893 cont.OverwriteAndNegateIfEqual(kOverflow); 1888 cont->OverwriteAndNegateIfEqual(kOverflow);
1894 return VisitBinop<Int64BinopMatcher>(this, node, kArm64Add, 1889 return VisitBinop<Int64BinopMatcher>(selector, node, kArm64Add,
1895 kArithmeticImm, &cont); 1890 kArithmeticImm, cont);
1896 case IrOpcode::kInt64SubWithOverflow: 1891 case IrOpcode::kInt64SubWithOverflow:
1897 cont.OverwriteAndNegateIfEqual(kOverflow); 1892 cont->OverwriteAndNegateIfEqual(kOverflow);
1898 return VisitBinop<Int64BinopMatcher>(this, node, kArm64Sub, 1893 return VisitBinop<Int64BinopMatcher>(selector, node, kArm64Sub,
1899 kArithmeticImm, &cont); 1894 kArithmeticImm, cont);
1900 default: 1895 default:
1901 break; 1896 break;
1902 } 1897 }
1903 } 1898 }
1904 } 1899 }
1905 break; 1900 break;
1906 case IrOpcode::kInt32Add: 1901 case IrOpcode::kInt32Add:
1907 return VisitWordCompare(this, value, kArm64Cmn32, &cont, true, 1902 return VisitWordCompare(selector, value, kArm64Cmn32, cont, true,
1908 kArithmeticImm); 1903 kArithmeticImm);
1909 case IrOpcode::kInt32Sub: 1904 case IrOpcode::kInt32Sub:
1910 return VisitWord32Compare(this, value, &cont); 1905 return VisitWord32Compare(selector, value, cont);
1911 case IrOpcode::kWord32And: { 1906 case IrOpcode::kWord32And: {
1912 Int32BinopMatcher m(value); 1907 Int32BinopMatcher m(value);
1913 if (m.right().HasValue() && 1908 if (cont->IsBranch() && m.right().HasValue() &&
1914 (base::bits::CountPopulation32(m.right().Value()) == 1)) { 1909 (base::bits::CountPopulation32(m.right().Value()) == 1)) {
1915 // If the mask has only one bit set, we can use tbz/tbnz. 1910 // If the mask has only one bit set, we can use tbz/tbnz.
1916 DCHECK((cont.condition() == kEqual) || 1911 DCHECK((cont->condition() == kEqual) ||
1917 (cont.condition() == kNotEqual)); 1912 (cont->condition() == kNotEqual));
1918 Emit(cont.Encode(kArm64TestAndBranch32), g.NoOutput(), 1913 selector->Emit(
1919 g.UseRegister(m.left().node()), 1914 cont->Encode(kArm64TestAndBranch32), g.NoOutput(),
1920 g.TempImmediate( 1915 g.UseRegister(m.left().node()),
1921 base::bits::CountTrailingZeros32(m.right().Value())), 1916 g.TempImmediate(
1922 g.Label(cont.true_block()), g.Label(cont.false_block())); 1917 base::bits::CountTrailingZeros32(m.right().Value())),
1918 g.Label(cont->true_block()), g.Label(cont->false_block()));
1923 return; 1919 return;
1924 } 1920 }
1925 return VisitWordCompare(this, value, kArm64Tst32, &cont, true, 1921 return VisitWordCompare(selector, value, kArm64Tst32, cont, true,
1926 kLogical32Imm); 1922 kLogical32Imm);
1927 } 1923 }
1928 case IrOpcode::kWord64And: { 1924 case IrOpcode::kWord64And: {
1929 Int64BinopMatcher m(value); 1925 Int64BinopMatcher m(value);
1930 if (m.right().HasValue() && 1926 if (cont->IsBranch() && m.right().HasValue() &&
1931 (base::bits::CountPopulation64(m.right().Value()) == 1)) { 1927 (base::bits::CountPopulation64(m.right().Value()) == 1)) {
1932 // If the mask has only one bit set, we can use tbz/tbnz. 1928 // If the mask has only one bit set, we can use tbz/tbnz.
1933 DCHECK((cont.condition() == kEqual) || 1929 DCHECK((cont->condition() == kEqual) ||
1934 (cont.condition() == kNotEqual)); 1930 (cont->condition() == kNotEqual));
1935 Emit(cont.Encode(kArm64TestAndBranch), g.NoOutput(), 1931 selector->Emit(
1936 g.UseRegister(m.left().node()), 1932 cont->Encode(kArm64TestAndBranch), g.NoOutput(),
1937 g.TempImmediate( 1933 g.UseRegister(m.left().node()),
1938 base::bits::CountTrailingZeros64(m.right().Value())), 1934 g.TempImmediate(
1939 g.Label(cont.true_block()), g.Label(cont.false_block())); 1935 base::bits::CountTrailingZeros64(m.right().Value())),
1936 g.Label(cont->true_block()), g.Label(cont->false_block()));
1940 return; 1937 return;
1941 } 1938 }
1942 return VisitWordCompare(this, value, kArm64Tst, &cont, true, 1939 return VisitWordCompare(selector, value, kArm64Tst, cont, true,
1943 kLogical64Imm); 1940 kLogical64Imm);
1944 } 1941 }
1945 default: 1942 default:
1946 break; 1943 break;
1947 } 1944 }
1945 break;
1948 } 1946 }
1949 1947
1950 // Branch could not be combined with a compare, compare against 0 and branch. 1948 // Branch could not be combined with a compare, compare against 0 and branch.
1951 Emit(cont.Encode(kArm64CompareAndBranch32), g.NoOutput(), 1949 if (cont->IsBranch()) {
1952 g.UseRegister(value), g.Label(cont.true_block()), 1950 selector->Emit(cont->Encode(kArm64CompareAndBranch32), g.NoOutput(),
1953 g.Label(cont.false_block())); 1951 g.UseRegister(value), g.Label(cont->true_block()),
1952 g.Label(cont->false_block()));
1953 } else {
1954 DCHECK(cont->IsDeoptimize());
1955 selector->EmitDeoptimize(cont->Encode(kArm64Tst32), g.NoOutput(),
1956 g.UseRegister(value), g.UseRegister(value),
1957 cont->frame_state());
1958 }
1954 } 1959 }
1955 1960
1961 } // namespace
1962
1963 void InstructionSelector::VisitBranch(Node* branch, BasicBlock* tbranch,
1964 BasicBlock* fbranch) {
1965 FlagsContinuation cont(kNotEqual, tbranch, fbranch);
1966 VisitWordCompareZero(this, branch, branch->InputAt(0), &cont);
1967 }
1968
1969 void InstructionSelector::VisitDeoptimizeIf(Node* node) {
1970 FlagsContinuation cont =
1971 FlagsContinuation::ForDeoptimize(kNotEqual, node->InputAt(1));
1972 VisitWordCompareZero(this, node, node->InputAt(0), &cont);
1973 }
1974
1975 void InstructionSelector::VisitDeoptimizeUnless(Node* node) {
1976 FlagsContinuation cont =
1977 FlagsContinuation::ForDeoptimize(kEqual, node->InputAt(1));
1978 VisitWordCompareZero(this, node, node->InputAt(0), &cont);
1979 }
1956 1980
1957 void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) { 1981 void InstructionSelector::VisitSwitch(Node* node, const SwitchInfo& sw) {
1958 Arm64OperandGenerator g(this); 1982 Arm64OperandGenerator g(this);
1959 InstructionOperand value_operand = g.UseRegister(node->InputAt(0)); 1983 InstructionOperand value_operand = g.UseRegister(node->InputAt(0));
1960 1984
1961 // Emit either ArchTableSwitch or ArchLookupSwitch. 1985 // Emit either ArchTableSwitch or ArchLookupSwitch.
1962 size_t table_space_cost = 4 + sw.value_range; 1986 size_t table_space_cost = 4 + sw.value_range;
1963 size_t table_time_cost = 3; 1987 size_t table_time_cost = 3;
1964 size_t lookup_space_cost = 3 + 2 * sw.case_count; 1988 size_t lookup_space_cost = 3 + 2 * sw.case_count;
1965 size_t lookup_time_cost = sw.case_count; 1989 size_t lookup_time_cost = sw.case_count;
(...skipping 11 matching lines...) Expand all
1977 return EmitTableSwitch(sw, index_operand); 2001 return EmitTableSwitch(sw, index_operand);
1978 } 2002 }
1979 2003
1980 // Generate a sequence of conditional jumps. 2004 // Generate a sequence of conditional jumps.
1981 return EmitLookupSwitch(sw, value_operand); 2005 return EmitLookupSwitch(sw, value_operand);
1982 } 2006 }
1983 2007
1984 2008
1985 void InstructionSelector::VisitWord32Equal(Node* const node) { 2009 void InstructionSelector::VisitWord32Equal(Node* const node) {
1986 Node* const user = node; 2010 Node* const user = node;
1987 FlagsContinuation cont(kEqual, node); 2011 FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node);
1988 Int32BinopMatcher m(user); 2012 Int32BinopMatcher m(user);
1989 if (m.right().Is(0)) { 2013 if (m.right().Is(0)) {
1990 Node* const value = m.left().node(); 2014 Node* const value = m.left().node();
1991 if (CanCover(user, value)) { 2015 if (CanCover(user, value)) {
1992 switch (value->opcode()) { 2016 switch (value->opcode()) {
1993 case IrOpcode::kInt32Add: 2017 case IrOpcode::kInt32Add:
1994 return VisitWordCompare(this, value, kArm64Cmn32, &cont, true, 2018 return VisitWordCompare(this, value, kArm64Cmn32, &cont, true,
1995 kArithmeticImm); 2019 kArithmeticImm);
1996 case IrOpcode::kInt32Sub: 2020 case IrOpcode::kInt32Sub:
1997 return VisitWordCompare(this, value, kArm64Cmp32, &cont, false, 2021 return VisitWordCompare(this, value, kArm64Cmp32, &cont, false,
(...skipping 13 matching lines...) Expand all
2011 break; 2035 break;
2012 } 2036 }
2013 return VisitWord32Test(this, value, &cont); 2037 return VisitWord32Test(this, value, &cont);
2014 } 2038 }
2015 } 2039 }
2016 VisitWord32Compare(this, node, &cont); 2040 VisitWord32Compare(this, node, &cont);
2017 } 2041 }
2018 2042
2019 2043
2020 void InstructionSelector::VisitInt32LessThan(Node* node) { 2044 void InstructionSelector::VisitInt32LessThan(Node* node) {
2021 FlagsContinuation cont(kSignedLessThan, node); 2045 FlagsContinuation cont = FlagsContinuation::ForSet(kSignedLessThan, node);
2022 VisitWord32Compare(this, node, &cont); 2046 VisitWord32Compare(this, node, &cont);
2023 } 2047 }
2024 2048
2025 2049
2026 void InstructionSelector::VisitInt32LessThanOrEqual(Node* node) { 2050 void InstructionSelector::VisitInt32LessThanOrEqual(Node* node) {
2027 FlagsContinuation cont(kSignedLessThanOrEqual, node); 2051 FlagsContinuation cont =
2052 FlagsContinuation::ForSet(kSignedLessThanOrEqual, node);
2028 VisitWord32Compare(this, node, &cont); 2053 VisitWord32Compare(this, node, &cont);
2029 } 2054 }
2030 2055
2031 2056
2032 void InstructionSelector::VisitUint32LessThan(Node* node) { 2057 void InstructionSelector::VisitUint32LessThan(Node* node) {
2033 FlagsContinuation cont(kUnsignedLessThan, node); 2058 FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node);
2034 VisitWord32Compare(this, node, &cont); 2059 VisitWord32Compare(this, node, &cont);
2035 } 2060 }
2036 2061
2037 2062
2038 void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) { 2063 void InstructionSelector::VisitUint32LessThanOrEqual(Node* node) {
2039 FlagsContinuation cont(kUnsignedLessThanOrEqual, node); 2064 FlagsContinuation cont =
2065 FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node);
2040 VisitWord32Compare(this, node, &cont); 2066 VisitWord32Compare(this, node, &cont);
2041 } 2067 }
2042 2068
2043 2069
2044 void InstructionSelector::VisitWord64Equal(Node* const node) { 2070 void InstructionSelector::VisitWord64Equal(Node* const node) {
2045 Node* const user = node; 2071 Node* const user = node;
2046 FlagsContinuation cont(kEqual, node); 2072 FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node);
2047 Int64BinopMatcher m(user); 2073 Int64BinopMatcher m(user);
2048 if (m.right().Is(0)) { 2074 if (m.right().Is(0)) {
2049 Node* const value = m.left().node(); 2075 Node* const value = m.left().node();
2050 if (CanCover(user, value)) { 2076 if (CanCover(user, value)) {
2051 switch (value->opcode()) { 2077 switch (value->opcode()) {
2052 case IrOpcode::kWord64And: 2078 case IrOpcode::kWord64And:
2053 return VisitWordCompare(this, value, kArm64Tst, &cont, true, 2079 return VisitWordCompare(this, value, kArm64Tst, &cont, true,
2054 kLogical64Imm); 2080 kLogical64Imm);
2055 default: 2081 default:
2056 break; 2082 break;
2057 } 2083 }
2058 return VisitWord64Test(this, value, &cont); 2084 return VisitWord64Test(this, value, &cont);
2059 } 2085 }
2060 } 2086 }
2061 VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm); 2087 VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm);
2062 } 2088 }
2063 2089
2064 2090
2065 void InstructionSelector::VisitInt32AddWithOverflow(Node* node) { 2091 void InstructionSelector::VisitInt32AddWithOverflow(Node* node) {
2066 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { 2092 if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
2067 FlagsContinuation cont(kOverflow, ovf); 2093 FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
2068 return VisitBinop<Int32BinopMatcher>(this, node, kArm64Add32, 2094 return VisitBinop<Int32BinopMatcher>(this, node, kArm64Add32,
2069 kArithmeticImm, &cont); 2095 kArithmeticImm, &cont);
2070 } 2096 }
2071 FlagsContinuation cont; 2097 FlagsContinuation cont;
2072 VisitBinop<Int32BinopMatcher>(this, node, kArm64Add32, kArithmeticImm, &cont); 2098 VisitBinop<Int32BinopMatcher>(this, node, kArm64Add32, kArithmeticImm, &cont);
2073 } 2099 }
2074 2100
2075 2101
2076 void InstructionSelector::VisitInt32SubWithOverflow(Node* node) { 2102 void InstructionSelector::VisitInt32SubWithOverflow(Node* node) {
2077 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { 2103 if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
2078 FlagsContinuation cont(kOverflow, ovf); 2104 FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
2079 return VisitBinop<Int32BinopMatcher>(this, node, kArm64Sub32, 2105 return VisitBinop<Int32BinopMatcher>(this, node, kArm64Sub32,
2080 kArithmeticImm, &cont); 2106 kArithmeticImm, &cont);
2081 } 2107 }
2082 FlagsContinuation cont; 2108 FlagsContinuation cont;
2083 VisitBinop<Int32BinopMatcher>(this, node, kArm64Sub32, kArithmeticImm, &cont); 2109 VisitBinop<Int32BinopMatcher>(this, node, kArm64Sub32, kArithmeticImm, &cont);
2084 } 2110 }
2085 2111
2086 2112
2087 void InstructionSelector::VisitInt64AddWithOverflow(Node* node) { 2113 void InstructionSelector::VisitInt64AddWithOverflow(Node* node) {
2088 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { 2114 if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
2089 FlagsContinuation cont(kOverflow, ovf); 2115 FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
2090 return VisitBinop<Int64BinopMatcher>(this, node, kArm64Add, kArithmeticImm, 2116 return VisitBinop<Int64BinopMatcher>(this, node, kArm64Add, kArithmeticImm,
2091 &cont); 2117 &cont);
2092 } 2118 }
2093 FlagsContinuation cont; 2119 FlagsContinuation cont;
2094 VisitBinop<Int64BinopMatcher>(this, node, kArm64Add, kArithmeticImm, &cont); 2120 VisitBinop<Int64BinopMatcher>(this, node, kArm64Add, kArithmeticImm, &cont);
2095 } 2121 }
2096 2122
2097 2123
2098 void InstructionSelector::VisitInt64SubWithOverflow(Node* node) { 2124 void InstructionSelector::VisitInt64SubWithOverflow(Node* node) {
2099 if (Node* ovf = NodeProperties::FindProjection(node, 1)) { 2125 if (Node* ovf = NodeProperties::FindProjection(node, 1)) {
2100 FlagsContinuation cont(kOverflow, ovf); 2126 FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf);
2101 return VisitBinop<Int64BinopMatcher>(this, node, kArm64Sub, kArithmeticImm, 2127 return VisitBinop<Int64BinopMatcher>(this, node, kArm64Sub, kArithmeticImm,
2102 &cont); 2128 &cont);
2103 } 2129 }
2104 FlagsContinuation cont; 2130 FlagsContinuation cont;
2105 VisitBinop<Int64BinopMatcher>(this, node, kArm64Sub, kArithmeticImm, &cont); 2131 VisitBinop<Int64BinopMatcher>(this, node, kArm64Sub, kArithmeticImm, &cont);
2106 } 2132 }
2107 2133
2108 2134
2109 void InstructionSelector::VisitInt64LessThan(Node* node) { 2135 void InstructionSelector::VisitInt64LessThan(Node* node) {
2110 FlagsContinuation cont(kSignedLessThan, node); 2136 FlagsContinuation cont = FlagsContinuation::ForSet(kSignedLessThan, node);
2111 VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm); 2137 VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm);
2112 } 2138 }
2113 2139
2114 2140
2115 void InstructionSelector::VisitInt64LessThanOrEqual(Node* node) { 2141 void InstructionSelector::VisitInt64LessThanOrEqual(Node* node) {
2116 FlagsContinuation cont(kSignedLessThanOrEqual, node); 2142 FlagsContinuation cont =
2143 FlagsContinuation::ForSet(kSignedLessThanOrEqual, node);
2117 VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm); 2144 VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm);
2118 } 2145 }
2119 2146
2120 2147
2121 void InstructionSelector::VisitUint64LessThan(Node* node) { 2148 void InstructionSelector::VisitUint64LessThan(Node* node) {
2122 FlagsContinuation cont(kUnsignedLessThan, node); 2149 FlagsContinuation cont = FlagsContinuation::ForSet(kUnsignedLessThan, node);
2123 VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm); 2150 VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm);
2124 } 2151 }
2125 2152
2126 2153
2127 void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) { 2154 void InstructionSelector::VisitUint64LessThanOrEqual(Node* node) {
2128 FlagsContinuation cont(kUnsignedLessThanOrEqual, node); 2155 FlagsContinuation cont =
2156 FlagsContinuation::ForSet(kUnsignedLessThanOrEqual, node);
2129 VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm); 2157 VisitWordCompare(this, node, kArm64Cmp, &cont, false, kArithmeticImm);
2130 } 2158 }
2131 2159
2132 2160
2133 void InstructionSelector::VisitFloat32Equal(Node* node) { 2161 void InstructionSelector::VisitFloat32Equal(Node* node) {
2134 FlagsContinuation cont(kEqual, node); 2162 FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node);
2135 VisitFloat32Compare(this, node, &cont); 2163 VisitFloat32Compare(this, node, &cont);
2136 } 2164 }
2137 2165
2138 2166
2139 void InstructionSelector::VisitFloat32LessThan(Node* node) { 2167 void InstructionSelector::VisitFloat32LessThan(Node* node) {
2140 FlagsContinuation cont(kFloatLessThan, node); 2168 FlagsContinuation cont = FlagsContinuation::ForSet(kFloatLessThan, node);
2141 VisitFloat32Compare(this, node, &cont); 2169 VisitFloat32Compare(this, node, &cont);
2142 } 2170 }
2143 2171
2144 2172
2145 void InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) { 2173 void InstructionSelector::VisitFloat32LessThanOrEqual(Node* node) {
2146 FlagsContinuation cont(kFloatLessThanOrEqual, node); 2174 FlagsContinuation cont =
2175 FlagsContinuation::ForSet(kFloatLessThanOrEqual, node);
2147 VisitFloat32Compare(this, node, &cont); 2176 VisitFloat32Compare(this, node, &cont);
2148 } 2177 }
2149 2178
2150 2179
2151 void InstructionSelector::VisitFloat64Equal(Node* node) { 2180 void InstructionSelector::VisitFloat64Equal(Node* node) {
2152 FlagsContinuation cont(kEqual, node); 2181 FlagsContinuation cont = FlagsContinuation::ForSet(kEqual, node);
2153 VisitFloat64Compare(this, node, &cont); 2182 VisitFloat64Compare(this, node, &cont);
2154 } 2183 }
2155 2184
2156 2185
2157 void InstructionSelector::VisitFloat64LessThan(Node* node) { 2186 void InstructionSelector::VisitFloat64LessThan(Node* node) {
2158 FlagsContinuation cont(kFloatLessThan, node); 2187 FlagsContinuation cont = FlagsContinuation::ForSet(kFloatLessThan, node);
2159 VisitFloat64Compare(this, node, &cont); 2188 VisitFloat64Compare(this, node, &cont);
2160 } 2189 }
2161 2190
2162 2191
2163 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) { 2192 void InstructionSelector::VisitFloat64LessThanOrEqual(Node* node) {
2164 FlagsContinuation cont(kFloatLessThanOrEqual, node); 2193 FlagsContinuation cont =
2194 FlagsContinuation::ForSet(kFloatLessThanOrEqual, node);
2165 VisitFloat64Compare(this, node, &cont); 2195 VisitFloat64Compare(this, node, &cont);
2166 } 2196 }
2167 2197
2168 2198
2169 void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) { 2199 void InstructionSelector::VisitFloat64ExtractLowWord32(Node* node) {
2170 Arm64OperandGenerator g(this); 2200 Arm64OperandGenerator g(this);
2171 Emit(kArm64Float64ExtractLowWord32, g.DefineAsRegister(node), 2201 Emit(kArm64Float64ExtractLowWord32, g.DefineAsRegister(node),
2172 g.UseRegister(node->InputAt(0))); 2202 g.UseRegister(node->InputAt(0)));
2173 } 2203 }
2174 2204
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
2234 MachineOperatorBuilder::kWord32ShiftIsSafe | 2264 MachineOperatorBuilder::kWord32ShiftIsSafe |
2235 MachineOperatorBuilder::kInt32DivIsSafe | 2265 MachineOperatorBuilder::kInt32DivIsSafe |
2236 MachineOperatorBuilder::kUint32DivIsSafe | 2266 MachineOperatorBuilder::kUint32DivIsSafe |
2237 MachineOperatorBuilder::kWord32ReverseBits | 2267 MachineOperatorBuilder::kWord32ReverseBits |
2238 MachineOperatorBuilder::kWord64ReverseBits; 2268 MachineOperatorBuilder::kWord64ReverseBits;
2239 } 2269 }
2240 2270
2241 } // namespace compiler 2271 } // namespace compiler
2242 } // namespace internal 2272 } // namespace internal
2243 } // namespace v8 2273 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/arm/instruction-selector-arm.cc ('k') | src/compiler/branch-elimination.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698