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

Side by Side Diff: src/compiler/simplified-lowering.cc

Issue 1841993002: [builtins] Make Math.ceil, Math.trunc and Math.round optimizable. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 8 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/simplified-lowering.h ('k') | src/compiler/simplified-operator.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/simplified-lowering.h" 5 #include "src/compiler/simplified-lowering.h"
6 6
7 #include <limits> 7 #include <limits>
8 8
9 #include "src/base/bits.h" 9 #include "src/base/bits.h"
10 #include "src/code-factory.h" 10 #include "src/code-factory.h"
(...skipping 944 matching lines...) Expand 10 before | Expand all | Expand 10 after
955 } 955 }
956 case IrOpcode::kNumberShiftRightLogical: { 956 case IrOpcode::kNumberShiftRightLogical: {
957 Type* rhs_type = GetUpperBound(node->InputAt(1)); 957 Type* rhs_type = GetUpperBound(node->InputAt(1));
958 VisitBinop(node, UseInfo::TruncatingWord32(), 958 VisitBinop(node, UseInfo::TruncatingWord32(),
959 UseInfo::TruncatingWord32(), MachineRepresentation::kWord32); 959 UseInfo::TruncatingWord32(), MachineRepresentation::kWord32);
960 if (lower()) { 960 if (lower()) {
961 lowering->DoShift(node, lowering->machine()->Word32Shr(), rhs_type); 961 lowering->DoShift(node, lowering->machine()->Word32Shr(), rhs_type);
962 } 962 }
963 break; 963 break;
964 } 964 }
965 case IrOpcode::kNumberCeil: {
966 VisitUnop(node, UseInfo::Float64(), MachineRepresentation::kFloat64);
967 if (lower()) DeferReplacement(node, lowering->Float64Ceil(node));
968 break;
969 }
965 case IrOpcode::kNumberFloor: { 970 case IrOpcode::kNumberFloor: {
966 VisitUnop(node, UseInfo::Float64(), MachineRepresentation::kFloat64); 971 VisitUnop(node, UseInfo::Float64(), MachineRepresentation::kFloat64);
967 if (lower()) DeferReplacement(node, lowering->Float64Floor(node)); 972 if (lower()) DeferReplacement(node, lowering->Float64Floor(node));
968 break; 973 break;
969 } 974 }
975 case IrOpcode::kNumberRound: {
976 VisitUnop(node, UseInfo::Float64(), MachineRepresentation::kFloat64);
977 if (lower()) DeferReplacement(node, lowering->Float64Round(node));
978 break;
979 }
980 case IrOpcode::kNumberTrunc: {
981 VisitUnop(node, UseInfo::Float64(), MachineRepresentation::kFloat64);
982 if (lower()) DeferReplacement(node, lowering->Float64Trunc(node));
983 break;
984 }
970 case IrOpcode::kNumberToInt32: { 985 case IrOpcode::kNumberToInt32: {
971 // Just change representation if necessary. 986 // Just change representation if necessary.
972 VisitUnop(node, UseInfo::TruncatingWord32(), 987 VisitUnop(node, UseInfo::TruncatingWord32(),
973 MachineRepresentation::kWord32); 988 MachineRepresentation::kWord32);
974 if (lower()) DeferReplacement(node, node->InputAt(0)); 989 if (lower()) DeferReplacement(node, node->InputAt(0));
975 break; 990 break;
976 } 991 }
977 case IrOpcode::kNumberToUint32: { 992 case IrOpcode::kNumberToUint32: {
978 // Just change representation if necessary. 993 // Just change representation if necessary.
979 VisitUnop(node, UseInfo::TruncatingWord32(), 994 VisitUnop(node, UseInfo::TruncatingWord32(),
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after
1517 } 1532 }
1518 1533
1519 1534
1520 void SimplifiedLowering::DoStoreBuffer(Node* node) { 1535 void SimplifiedLowering::DoStoreBuffer(Node* node) {
1521 DCHECK_EQ(IrOpcode::kStoreBuffer, node->opcode()); 1536 DCHECK_EQ(IrOpcode::kStoreBuffer, node->opcode());
1522 MachineRepresentation const rep = 1537 MachineRepresentation const rep =
1523 BufferAccessOf(node->op()).machine_type().representation(); 1538 BufferAccessOf(node->op()).machine_type().representation();
1524 NodeProperties::ChangeOp(node, machine()->CheckedStore(rep)); 1539 NodeProperties::ChangeOp(node, machine()->CheckedStore(rep));
1525 } 1540 }
1526 1541
1542 Node* SimplifiedLowering::Float64Ceil(Node* const node) {
1543 Node* const one = jsgraph()->Float64Constant(1.0);
1544 Node* const zero = jsgraph()->Float64Constant(0.0);
1545 Node* const minus_zero = jsgraph()->Float64Constant(-0.0);
1546 Node* const two_52 = jsgraph()->Float64Constant(4503599627370496.0E0);
1547 Node* const minus_two_52 = jsgraph()->Float64Constant(-4503599627370496.0E0);
1548 Node* const input = node->InputAt(0);
1549
1550 // Use fast hardware instruction if available.
1551 if (machine()->Float64RoundUp().IsSupported()) {
1552 return graph()->NewNode(machine()->Float64RoundUp().op(), input);
1553 }
1554
1555 // General case for ceil.
1556 //
1557 // if 0.0 < input then
1558 // if 2^52 <= input then
1559 // input
1560 // else
1561 // let temp1 = (2^52 + input) - 2^52 in
1562 // if temp1 < input then
1563 // temp1 + 1
1564 // else
1565 // temp1
1566 // else
1567 // if input == 0 then
1568 // input
1569 // else
1570 // if input <= -2^52 then
1571 // input
1572 // else
1573 // let temp1 = -0 - input in
1574 // let temp2 = (2^52 + temp1) - 2^52 in
1575 // let temp3 = (if temp1 < temp2 then temp2 - 1 else temp2) in
1576 // -0 - temp3
1577 //
1578 // Note: We do not use the Diamond helper class here, because it really hurts
1579 // readability with nested diamonds.
1580
1581 Node* check0 = graph()->NewNode(machine()->Float64LessThan(), zero, input);
1582 Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), check0,
1583 graph()->start());
1584
1585 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
1586 Node* vtrue0;
1587 {
1588 Node* check1 =
1589 graph()->NewNode(machine()->Float64LessThanOrEqual(), two_52, input);
1590 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
1591
1592 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
1593 Node* vtrue1 = input;
1594
1595 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
1596 Node* vfalse1;
1597 {
1598 Node* temp1 = graph()->NewNode(
1599 machine()->Float64Sub(),
1600 graph()->NewNode(machine()->Float64Add(), two_52, input), two_52);
1601 vfalse1 = graph()->NewNode(
1602 common()->Select(MachineRepresentation::kFloat64),
1603 graph()->NewNode(machine()->Float64LessThan(), temp1, input),
1604 graph()->NewNode(machine()->Float64Add(), temp1, one), temp1);
1605 }
1606
1607 if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
1608 vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
1609 vtrue1, vfalse1, if_true0);
1610 }
1611
1612 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
1613 Node* vfalse0;
1614 {
1615 Node* check1 = graph()->NewNode(machine()->Float64Equal(), input, zero);
1616 Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
1617 check1, if_false0);
1618
1619 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
1620 Node* vtrue1 = input;
1621
1622 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
1623 Node* vfalse1;
1624 {
1625 Node* check2 = graph()->NewNode(machine()->Float64LessThanOrEqual(),
1626 input, minus_two_52);
1627 Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
1628 check2, if_false1);
1629
1630 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
1631 Node* vtrue2 = input;
1632
1633 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
1634 Node* vfalse2;
1635 {
1636 Node* temp1 =
1637 graph()->NewNode(machine()->Float64Sub(), minus_zero, input);
1638 Node* temp2 = graph()->NewNode(
1639 machine()->Float64Sub(),
1640 graph()->NewNode(machine()->Float64Add(), two_52, temp1), two_52);
1641 Node* temp3 = graph()->NewNode(
1642 common()->Select(MachineRepresentation::kFloat64),
1643 graph()->NewNode(machine()->Float64LessThan(), temp1, temp2),
1644 graph()->NewNode(machine()->Float64Sub(), temp2, one), temp2);
1645 vfalse2 = graph()->NewNode(machine()->Float64Sub(), minus_zero, temp3);
1646 }
1647
1648 if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
1649 vfalse1 =
1650 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
1651 vtrue2, vfalse2, if_false1);
1652 }
1653
1654 if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
1655 vfalse0 =
1656 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
1657 vtrue1, vfalse1, if_false0);
1658 }
1659
1660 Node* merge0 = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
1661 return graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
1662 vtrue0, vfalse0, merge0);
1663 }
1664
1527 Node* SimplifiedLowering::Float64Floor(Node* const node) { 1665 Node* SimplifiedLowering::Float64Floor(Node* const node) {
1528 Node* const one = jsgraph()->Float64Constant(1.0); 1666 Node* const one = jsgraph()->Float64Constant(1.0);
1529 Node* const zero = jsgraph()->Float64Constant(0.0); 1667 Node* const zero = jsgraph()->Float64Constant(0.0);
1530 Node* const minus_one = jsgraph()->Float64Constant(-1.0); 1668 Node* const minus_one = jsgraph()->Float64Constant(-1.0);
1531 Node* const minus_zero = jsgraph()->Float64Constant(-0.0); 1669 Node* const minus_zero = jsgraph()->Float64Constant(-0.0);
1532 Node* const two_52 = jsgraph()->Float64Constant(4503599627370496.0E0); 1670 Node* const two_52 = jsgraph()->Float64Constant(4503599627370496.0E0);
1533 Node* const minus_two_52 = jsgraph()->Float64Constant(-4503599627370496.0E0); 1671 Node* const minus_two_52 = jsgraph()->Float64Constant(-4503599627370496.0E0);
1534 Node* const input = node->InputAt(0); 1672 Node* const input = node->InputAt(0);
1535 1673
1536 // Use fast hardware instruction if available. 1674 // Use fast hardware instruction if available.
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
1643 vfalse0 = 1781 vfalse0 =
1644 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), 1782 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
1645 vtrue1, vfalse1, if_false0); 1783 vtrue1, vfalse1, if_false0);
1646 } 1784 }
1647 1785
1648 Node* merge0 = graph()->NewNode(common()->Merge(2), if_true0, if_false0); 1786 Node* merge0 = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
1649 return graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2), 1787 return graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
1650 vtrue0, vfalse0, merge0); 1788 vtrue0, vfalse0, merge0);
1651 } 1789 }
1652 1790
1791 Node* SimplifiedLowering::Float64Round(Node* const node) {
1792 Node* const one = jsgraph()->Float64Constant(1.0);
1793 Node* const one_half = jsgraph()->Float64Constant(0.5);
1794 Node* const input = node->InputAt(0);
1795
1796 // Round up towards Infinity, and adjust if the difference exceeds 0.5.
1797 Node* result = Float64Ceil(node);
1798 return graph()->NewNode(
1799 common()->Select(MachineRepresentation::kFloat64),
1800 graph()->NewNode(
1801 machine()->Float64LessThanOrEqual(),
1802 graph()->NewNode(machine()->Float64Sub(), result, one_half), input),
1803 result, graph()->NewNode(machine()->Float64Sub(), result, one));
1804 }
1805
1806 Node* SimplifiedLowering::Float64Trunc(Node* const node) {
1807 Node* const one = jsgraph()->Float64Constant(1.0);
1808 Node* const zero = jsgraph()->Float64Constant(0.0);
1809 Node* const minus_zero = jsgraph()->Float64Constant(-0.0);
1810 Node* const two_52 = jsgraph()->Float64Constant(4503599627370496.0E0);
1811 Node* const minus_two_52 = jsgraph()->Float64Constant(-4503599627370496.0E0);
1812 Node* const input = node->InputAt(0);
1813
1814 // Use fast hardware instruction if available.
1815 if (machine()->Float64RoundTruncate().IsSupported()) {
1816 return graph()->NewNode(machine()->Float64RoundTruncate().op(), input);
1817 }
1818
1819 // General case for trunc.
1820 //
1821 // if 0.0 < input then
1822 // if 2^52 <= input then
1823 // input
1824 // else
1825 // let temp1 = (2^52 + input) - 2^52 in
1826 // if input < temp1 then
1827 // temp1 - 1
1828 // else
1829 // temp1
1830 // else
1831 // if input == 0 then
1832 // input
1833 // else
1834 // if input <= -2^52 then
1835 // input
1836 // else
1837 // let temp1 = -0 - input in
1838 // let temp2 = (2^52 + temp1) - 2^52 in
1839 // let temp3 = (if temp1 < temp2 then temp2 - 1 else temp2) in
1840 // -0 - temp3
1841 //
1842 // Note: We do not use the Diamond helper class here, because it really hurts
1843 // readability with nested diamonds.
1844
1845 Node* check0 = graph()->NewNode(machine()->Float64LessThan(), zero, input);
1846 Node* branch0 = graph()->NewNode(common()->Branch(BranchHint::kTrue), check0,
1847 graph()->start());
1848
1849 Node* if_true0 = graph()->NewNode(common()->IfTrue(), branch0);
1850 Node* vtrue0;
1851 {
1852 Node* check1 =
1853 graph()->NewNode(machine()->Float64LessThanOrEqual(), two_52, input);
1854 Node* branch1 = graph()->NewNode(common()->Branch(), check1, if_true0);
1855
1856 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
1857 Node* vtrue1 = input;
1858
1859 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
1860 Node* vfalse1;
1861 {
1862 Node* temp1 = graph()->NewNode(
1863 machine()->Float64Sub(),
1864 graph()->NewNode(machine()->Float64Add(), two_52, input), two_52);
1865 vfalse1 = graph()->NewNode(
1866 common()->Select(MachineRepresentation::kFloat64),
1867 graph()->NewNode(machine()->Float64LessThan(), input, temp1),
1868 graph()->NewNode(machine()->Float64Sub(), temp1, one), temp1);
1869 }
1870
1871 if_true0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
1872 vtrue0 = graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
1873 vtrue1, vfalse1, if_true0);
1874 }
1875
1876 Node* if_false0 = graph()->NewNode(common()->IfFalse(), branch0);
1877 Node* vfalse0;
1878 {
1879 Node* check1 = graph()->NewNode(machine()->Float64Equal(), input, zero);
1880 Node* branch1 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
1881 check1, if_false0);
1882
1883 Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1);
1884 Node* vtrue1 = input;
1885
1886 Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);
1887 Node* vfalse1;
1888 {
1889 Node* check2 = graph()->NewNode(machine()->Float64LessThanOrEqual(),
1890 input, minus_two_52);
1891 Node* branch2 = graph()->NewNode(common()->Branch(BranchHint::kFalse),
1892 check2, if_false1);
1893
1894 Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2);
1895 Node* vtrue2 = input;
1896
1897 Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2);
1898 Node* vfalse2;
1899 {
1900 Node* temp1 =
1901 graph()->NewNode(machine()->Float64Sub(), minus_zero, input);
1902 Node* temp2 = graph()->NewNode(
1903 machine()->Float64Sub(),
1904 graph()->NewNode(machine()->Float64Add(), two_52, temp1), two_52);
1905 Node* temp3 = graph()->NewNode(
1906 common()->Select(MachineRepresentation::kFloat64),
1907 graph()->NewNode(machine()->Float64LessThan(), temp1, temp2),
1908 graph()->NewNode(machine()->Float64Sub(), temp2, one), temp2);
1909 vfalse2 = graph()->NewNode(machine()->Float64Sub(), minus_zero, temp3);
1910 }
1911
1912 if_false1 = graph()->NewNode(common()->Merge(2), if_true2, if_false2);
1913 vfalse1 =
1914 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
1915 vtrue2, vfalse2, if_false1);
1916 }
1917
1918 if_false0 = graph()->NewNode(common()->Merge(2), if_true1, if_false1);
1919 vfalse0 =
1920 graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
1921 vtrue1, vfalse1, if_false0);
1922 }
1923
1924 Node* merge0 = graph()->NewNode(common()->Merge(2), if_true0, if_false0);
1925 return graph()->NewNode(common()->Phi(MachineRepresentation::kFloat64, 2),
1926 vtrue0, vfalse0, merge0);
1927 }
1928
1653 Node* SimplifiedLowering::Int32Div(Node* const node) { 1929 Node* SimplifiedLowering::Int32Div(Node* const node) {
1654 Int32BinopMatcher m(node); 1930 Int32BinopMatcher m(node);
1655 Node* const zero = jsgraph()->Int32Constant(0); 1931 Node* const zero = jsgraph()->Int32Constant(0);
1656 Node* const minus_one = jsgraph()->Int32Constant(-1); 1932 Node* const minus_one = jsgraph()->Int32Constant(-1);
1657 Node* const lhs = m.left().node(); 1933 Node* const lhs = m.left().node();
1658 Node* const rhs = m.right().node(); 1934 Node* const rhs = m.right().node();
1659 1935
1660 if (m.right().Is(-1)) { 1936 if (m.right().Is(-1)) {
1661 return graph()->NewNode(machine()->Int32Sub(), zero, lhs); 1937 return graph()->NewNode(machine()->Int32Sub(), zero, lhs);
1662 } else if (m.right().Is(0)) { 1938 } else if (m.right().Is(0)) {
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after
1908 if (!rhs_type->Is(type_cache_.kZeroToThirtyOne)) { 2184 if (!rhs_type->Is(type_cache_.kZeroToThirtyOne)) {
1909 node->ReplaceInput(1, graph()->NewNode(machine()->Word32And(), rhs, 2185 node->ReplaceInput(1, graph()->NewNode(machine()->Word32And(), rhs,
1910 jsgraph()->Int32Constant(0x1f))); 2186 jsgraph()->Int32Constant(0x1f)));
1911 } 2187 }
1912 NodeProperties::ChangeOp(node, op); 2188 NodeProperties::ChangeOp(node, op);
1913 } 2189 }
1914 2190
1915 } // namespace compiler 2191 } // namespace compiler
1916 } // namespace internal 2192 } // namespace internal
1917 } // namespace v8 2193 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/simplified-lowering.h ('k') | src/compiler/simplified-operator.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698