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

Side by Side Diff: runtime/vm/flow_graph_optimizer.cc

Issue 15085006: Inline Uint32x4 operations (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/flow_graph_type_propagator.cc » ('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 (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/flow_graph_optimizer.h" 5 #include "vm/flow_graph_optimizer.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/cha.h" 8 #include "vm/cha.h"
9 #include "vm/flow_graph_builder.h" 9 #include "vm/flow_graph_builder.h"
10 #include "vm/flow_graph_compiler.h" 10 #include "vm/flow_graph_compiler.h"
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 static bool HasOnlyTwoSmis(const ICData& ic_data) { 549 static bool HasOnlyTwoSmis(const ICData& ic_data) {
550 return (ic_data.NumberOfChecks() == 1) && 550 return (ic_data.NumberOfChecks() == 1) &&
551 ICDataHasReceiverArgumentClassIds(ic_data, kSmiCid, kSmiCid); 551 ICDataHasReceiverArgumentClassIds(ic_data, kSmiCid, kSmiCid);
552 } 552 }
553 553
554 static bool HasOnlyTwoFloat32x4s(const ICData& ic_data) { 554 static bool HasOnlyTwoFloat32x4s(const ICData& ic_data) {
555 return (ic_data.NumberOfChecks() == 1) && 555 return (ic_data.NumberOfChecks() == 1) &&
556 ICDataHasReceiverArgumentClassIds(ic_data, kFloat32x4Cid, kFloat32x4Cid); 556 ICDataHasReceiverArgumentClassIds(ic_data, kFloat32x4Cid, kFloat32x4Cid);
557 } 557 }
558 558
559 static bool HasOnlyTwoUint32x4s(const ICData& ic_data) {
560 return (ic_data.NumberOfChecks() == 1) &&
561 ICDataHasReceiverArgumentClassIds(ic_data, kUint32x4Cid, kUint32x4Cid);
562 }
559 563
560 // Returns false if the ICData contains anything other than the 4 combinations 564 // Returns false if the ICData contains anything other than the 4 combinations
561 // of Mint and Smi for the receiver and argument classes. 565 // of Mint and Smi for the receiver and argument classes.
562 static bool HasTwoMintOrSmi(const ICData& ic_data) { 566 static bool HasTwoMintOrSmi(const ICData& ic_data) {
563 GrowableArray<intptr_t> class_ids(2); 567 GrowableArray<intptr_t> class_ids(2);
564 class_ids.Add(kSmiCid); 568 class_ids.Add(kSmiCid);
565 class_ids.Add(kMintCid); 569 class_ids.Add(kMintCid);
566 return ICDataHasOnlyReceiverArgumentClassIds(ic_data, class_ids, class_ids); 570 return ICDataHasOnlyReceiverArgumentClassIds(ic_data, class_ids, class_ids);
567 } 571 }
568 572
(...skipping 458 matching lines...) Expand 10 before | Expand all | Expand 10 after
1027 return false; 1031 return false;
1028 } 1032 }
1029 break; 1033 break;
1030 case Token::kBIT_AND: 1034 case Token::kBIT_AND:
1031 case Token::kBIT_OR: 1035 case Token::kBIT_OR:
1032 case Token::kBIT_XOR: 1036 case Token::kBIT_XOR:
1033 if (HasOnlyTwoSmis(ic_data)) { 1037 if (HasOnlyTwoSmis(ic_data)) {
1034 operands_type = kSmiCid; 1038 operands_type = kSmiCid;
1035 } else if (HasTwoMintOrSmi(ic_data)) { 1039 } else if (HasTwoMintOrSmi(ic_data)) {
1036 operands_type = kMintCid; 1040 operands_type = kMintCid;
1041 } else if (HasOnlyTwoUint32x4s(ic_data)) {
1042 operands_type = kUint32x4Cid;
1037 } else { 1043 } else {
1038 return false; 1044 return false;
1039 } 1045 }
1040 break; 1046 break;
1041 case Token::kSHR: 1047 case Token::kSHR:
1042 case Token::kSHL: 1048 case Token::kSHL:
1043 if (HasOnlyTwoSmis(ic_data)) { 1049 if (HasOnlyTwoSmis(ic_data)) {
1044 // Left shift may overflow from smi into mint or big ints. 1050 // Left shift may overflow from smi into mint or big ints.
1045 // Don't generate smi code if the IC data is marked because 1051 // Don't generate smi code if the IC data is marked because
1046 // of an overflow. 1052 // of an overflow.
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1113 // Type check right. 1119 // Type check right.
1114 AddCheckClass(right, 1120 AddCheckClass(right,
1115 ICData::ZoneHandle( 1121 ICData::ZoneHandle(
1116 call->ic_data()->AsUnaryClassChecksForArgNr(1)), 1122 call->ic_data()->AsUnaryClassChecksForArgNr(1)),
1117 call->deopt_id(), 1123 call->deopt_id(),
1118 call->env(), 1124 call->env(),
1119 call); 1125 call);
1120 // Replace call. 1126 // Replace call.
1121 BinaryFloat32x4OpInstr* float32x4_bin_op = 1127 BinaryFloat32x4OpInstr* float32x4_bin_op =
1122 new BinaryFloat32x4OpInstr(op_kind, new Value(left), new Value(right), 1128 new BinaryFloat32x4OpInstr(op_kind, new Value(left), new Value(right),
1123 call); 1129 call->deopt_id());
1124 ReplaceCall(call, float32x4_bin_op); 1130 ReplaceCall(call, float32x4_bin_op);
1131 } else if (operands_type == kUint32x4Cid) {
1132 // Type check left.
1133 AddCheckClass(left,
1134 ICData::ZoneHandle(
1135 call->ic_data()->AsUnaryClassChecksForArgNr(0)),
1136 call->deopt_id(),
1137 call->env(),
1138 call);
1139 // Type check right.
1140 AddCheckClass(right,
1141 ICData::ZoneHandle(
1142 call->ic_data()->AsUnaryClassChecksForArgNr(1)),
1143 call->deopt_id(),
1144 call->env(),
1145 call);
1146 // Replace call.
1147 BinaryUint32x4OpInstr* uint32x4_bin_op =
1148 new BinaryUint32x4OpInstr(op_kind, new Value(left), new Value(right),
1149 call->deopt_id());
1150 ReplaceCall(call, uint32x4_bin_op);
1125 } else if (op_kind == Token::kMOD) { 1151 } else if (op_kind == Token::kMOD) {
1126 // TODO(vegorov): implement fast path code for modulo. 1152 // TODO(vegorov): implement fast path code for modulo.
1127 ASSERT(operands_type == kSmiCid); 1153 ASSERT(operands_type == kSmiCid);
1128 if (!right->IsConstant()) return false; 1154 if (!right->IsConstant()) return false;
1129 const Object& obj = right->AsConstant()->value(); 1155 const Object& obj = right->AsConstant()->value();
1130 if (!obj.IsSmi()) return false; 1156 if (!obj.IsSmi()) return false;
1131 const intptr_t value = Smi::Cast(obj).Value(); 1157 const intptr_t value = Smi::Cast(obj).Value();
1132 if ((value <= 0) || !Utils::IsPowerOfTwo(value)) return false; 1158 if ((value <= 0) || !Utils::IsPowerOfTwo(value)) return false;
1133 1159
1134 // Insert smi check and attach a copy of the original environment 1160 // Insert smi check and attach a copy of the original environment
(...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after
1409 MethodRecognizer::Kind getter) { 1435 MethodRecognizer::Kind getter) {
1410 AddCheckClass(call->ArgumentAt(0), 1436 AddCheckClass(call->ArgumentAt(0),
1411 ICData::ZoneHandle( 1437 ICData::ZoneHandle(
1412 call->ic_data()->AsUnaryClassChecksForArgNr(0)), 1438 call->ic_data()->AsUnaryClassChecksForArgNr(0)),
1413 call->deopt_id(), 1439 call->deopt_id(),
1414 call->env(), 1440 call->env(),
1415 call); 1441 call);
1416 Float32x4ShuffleInstr* instr = new Float32x4ShuffleInstr( 1442 Float32x4ShuffleInstr* instr = new Float32x4ShuffleInstr(
1417 getter, 1443 getter,
1418 new Value(call->ArgumentAt(0)), 1444 new Value(call->ArgumentAt(0)),
1419 call); 1445 call->deopt_id());
1420 ReplaceCall(call, instr); 1446 ReplaceCall(call, instr);
1421 return true; 1447 return true;
1422 } 1448 }
1449
1450
1451 bool FlowGraphOptimizer::InlineUint32x4Getter(InstanceCallInstr* call,
1452 MethodRecognizer::Kind getter) {
1453 AddCheckClass(call->ArgumentAt(0),
1454 ICData::ZoneHandle(
1455 call->ic_data()->AsUnaryClassChecksForArgNr(0)),
1456 call->deopt_id(),
1457 call->env(),
1458 call);
1459 Uint32x4GetFlagInstr* instr = new Uint32x4GetFlagInstr(
1460 getter,
1461 new Value(call->ArgumentAt(0)),
1462 call->deopt_id());
1463 ReplaceCall(call, instr);
1464 return true;
1465 }
1423 1466
1424 1467
1425 // Only unique implicit instance getters can be currently handled. 1468 // Only unique implicit instance getters can be currently handled.
1426 bool FlowGraphOptimizer::TryInlineInstanceGetter(InstanceCallInstr* call) { 1469 bool FlowGraphOptimizer::TryInlineInstanceGetter(InstanceCallInstr* call) {
1427 ASSERT(call->HasICData()); 1470 ASSERT(call->HasICData());
1428 const ICData& ic_data = *call->ic_data(); 1471 const ICData& ic_data = *call->ic_data();
1429 if (ic_data.NumberOfChecks() == 0) { 1472 if (ic_data.NumberOfChecks() == 0) {
1430 // No type feedback collected. 1473 // No type feedback collected.
1431 return false; 1474 return false;
1432 } 1475 }
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1489 case MethodRecognizer::kFloat32x4ShuffleWWWW: 1532 case MethodRecognizer::kFloat32x4ShuffleWWWW:
1490 case MethodRecognizer::kFloat32x4ShuffleX: 1533 case MethodRecognizer::kFloat32x4ShuffleX:
1491 case MethodRecognizer::kFloat32x4ShuffleY: 1534 case MethodRecognizer::kFloat32x4ShuffleY:
1492 case MethodRecognizer::kFloat32x4ShuffleZ: 1535 case MethodRecognizer::kFloat32x4ShuffleZ:
1493 case MethodRecognizer::kFloat32x4ShuffleW: 1536 case MethodRecognizer::kFloat32x4ShuffleW:
1494 if (!ic_data.HasReceiverClassId(kFloat32x4Cid) || 1537 if (!ic_data.HasReceiverClassId(kFloat32x4Cid) ||
1495 !ic_data.HasOneTarget()) { 1538 !ic_data.HasOneTarget()) {
1496 return false; 1539 return false;
1497 } 1540 }
1498 return InlineFloat32x4Getter(call, recognized_kind); 1541 return InlineFloat32x4Getter(call, recognized_kind);
1542 case MethodRecognizer::kUint32x4GetFlagX:
1543 case MethodRecognizer::kUint32x4GetFlagY:
1544 case MethodRecognizer::kUint32x4GetFlagZ:
1545 case MethodRecognizer::kUint32x4GetFlagW: {
1546 if (!ic_data.HasReceiverClassId(kUint32x4Cid) ||
1547 !ic_data.HasOneTarget()) {
1548 return false;
1549 }
1550 return InlineUint32x4Getter(call, recognized_kind);
1551 }
1499 default: 1552 default:
1500 ASSERT(recognized_kind == MethodRecognizer::kUnknown); 1553 ASSERT(recognized_kind == MethodRecognizer::kUnknown);
1501 } 1554 }
1502 return false; 1555 return false;
1503 } 1556 }
1504 1557
1505 1558
1506 LoadIndexedInstr* FlowGraphOptimizer::BuildStringCodeUnitAt( 1559 LoadIndexedInstr* FlowGraphOptimizer::BuildStringCodeUnitAt(
1507 InstanceCallInstr* call, 1560 InstanceCallInstr* call,
1508 intptr_t cid) { 1561 intptr_t cid) {
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after
1756 call, class_ids[0], kTypedDataFloat32x4ArrayCid); 1809 call, class_ids[0], kTypedDataFloat32x4ArrayCid);
1757 default: 1810 default:
1758 // Unsupported method. 1811 // Unsupported method.
1759 return false; 1812 return false;
1760 } 1813 }
1761 } 1814 }
1762 1815
1763 if ((class_ids[0] == kFloat32x4Cid) && (ic_data.NumberOfChecks() == 1)) { 1816 if ((class_ids[0] == kFloat32x4Cid) && (ic_data.NumberOfChecks() == 1)) {
1764 return TryInlineFloat32x4Method(call, recognized_kind); 1817 return TryInlineFloat32x4Method(call, recognized_kind);
1765 } 1818 }
1819
1820 if ((class_ids[0] == kUint32x4Cid) && (ic_data.NumberOfChecks() == 1)) {
1821 return TryInlineUint32x4Method(call, recognized_kind);
1822 }
1766 return false; 1823 return false;
1767 } 1824 }
1768 1825
1769 1826
1770 bool FlowGraphOptimizer::TryInlineFloat32x4Method( 1827 bool FlowGraphOptimizer::TryInlineFloat32x4Method(
1771 InstanceCallInstr* call, 1828 InstanceCallInstr* call,
1772 MethodRecognizer::Kind recognized_kind) { 1829 MethodRecognizer::Kind recognized_kind) {
1773 ASSERT(call->HasICData()); 1830 ASSERT(call->HasICData());
1774 switch (recognized_kind) { 1831 switch (recognized_kind) {
1775 case MethodRecognizer::kFloat32x4Equal: 1832 case MethodRecognizer::kFloat32x4Equal:
1776 case MethodRecognizer::kFloat32x4GreaterThan: 1833 case MethodRecognizer::kFloat32x4GreaterThan:
1777 case MethodRecognizer::kFloat32x4GreaterThanOrEqual: 1834 case MethodRecognizer::kFloat32x4GreaterThanOrEqual:
1778 case MethodRecognizer::kFloat32x4LessThan: 1835 case MethodRecognizer::kFloat32x4LessThan:
1779 case MethodRecognizer::kFloat32x4LessThanOrEqual: 1836 case MethodRecognizer::kFloat32x4LessThanOrEqual:
1780 case MethodRecognizer::kFloat32x4NotEqual: { 1837 case MethodRecognizer::kFloat32x4NotEqual: {
1781 Definition* left = call->ArgumentAt(0); 1838 Definition* left = call->ArgumentAt(0);
1782 Definition* right = call->ArgumentAt(1); 1839 Definition* right = call->ArgumentAt(1);
1783 // Type check left. 1840 // Type check left.
1784 AddCheckClass(left, 1841 AddCheckClass(left,
1785 ICData::ZoneHandle( 1842 ICData::ZoneHandle(
1786 call->ic_data()->AsUnaryClassChecksForArgNr(0)), 1843 call->ic_data()->AsUnaryClassChecksForArgNr(0)),
1787 call->deopt_id(), 1844 call->deopt_id(),
1788 call->env(), 1845 call->env(),
1789 call); 1846 call);
1790 // Replace call. 1847 // Replace call.
1791 Float32x4ComparisonInstr* cmp = 1848 Float32x4ComparisonInstr* cmp =
1792 new Float32x4ComparisonInstr(recognized_kind, new Value(left), 1849 new Float32x4ComparisonInstr(recognized_kind, new Value(left),
1793 new Value(right), call); 1850 new Value(right), call->deopt_id());
1794 ReplaceCall(call, cmp); 1851 ReplaceCall(call, cmp);
1795 return true; 1852 return true;
1796 } 1853 }
1797 case MethodRecognizer::kFloat32x4Min: 1854 case MethodRecognizer::kFloat32x4Min:
1798 case MethodRecognizer::kFloat32x4Max: { 1855 case MethodRecognizer::kFloat32x4Max: {
1799 Definition* left = call->ArgumentAt(0); 1856 Definition* left = call->ArgumentAt(0);
1800 Definition* right = call->ArgumentAt(1); 1857 Definition* right = call->ArgumentAt(1);
1801 // Type check left. 1858 // Type check left.
1802 AddCheckClass(left, 1859 AddCheckClass(left,
1803 ICData::ZoneHandle( 1860 ICData::ZoneHandle(
1804 call->ic_data()->AsUnaryClassChecksForArgNr(0)), 1861 call->ic_data()->AsUnaryClassChecksForArgNr(0)),
1805 call->deopt_id(), 1862 call->deopt_id(),
1806 call->env(), 1863 call->env(),
1807 call); 1864 call);
1808 Float32x4MinMaxInstr* minmax = 1865 Float32x4MinMaxInstr* minmax =
1809 new Float32x4MinMaxInstr(recognized_kind, new Value(left), 1866 new Float32x4MinMaxInstr(recognized_kind, new Value(left),
1810 new Value(right), call); 1867 new Value(right), call->deopt_id());
1811 ReplaceCall(call, minmax); 1868 ReplaceCall(call, minmax);
1812 return true; 1869 return true;
1813 } 1870 }
1814 case MethodRecognizer::kFloat32x4Scale: { 1871 case MethodRecognizer::kFloat32x4Scale: {
1815 Definition* left = call->ArgumentAt(0); 1872 Definition* left = call->ArgumentAt(0);
1816 Definition* right = call->ArgumentAt(1); 1873 Definition* right = call->ArgumentAt(1);
1817 // Type check left. 1874 // Type check left.
1818 AddCheckClass(left, 1875 AddCheckClass(left,
1819 ICData::ZoneHandle( 1876 ICData::ZoneHandle(
1820 call->ic_data()->AsUnaryClassChecksForArgNr(0)), 1877 call->ic_data()->AsUnaryClassChecksForArgNr(0)),
1821 call->deopt_id(), 1878 call->deopt_id(),
1822 call->env(), 1879 call->env(),
1823 call); 1880 call);
1824 // Left and right values are swapped when handed to the instruction, 1881 // Left and right values are swapped when handed to the instruction,
1825 // this is done so that the double value is loaded into the output 1882 // this is done so that the double value is loaded into the output
1826 // register and can be destroyed. 1883 // register and can be destroyed.
1827 Float32x4ScaleInstr* scale = 1884 Float32x4ScaleInstr* scale =
1828 new Float32x4ScaleInstr(recognized_kind, new Value(right), 1885 new Float32x4ScaleInstr(recognized_kind, new Value(right),
1829 new Value(left), call); 1886 new Value(left), call->deopt_id());
1830 ReplaceCall(call, scale); 1887 ReplaceCall(call, scale);
1831 return true; 1888 return true;
1832 } 1889 }
1833 case MethodRecognizer::kFloat32x4Sqrt: 1890 case MethodRecognizer::kFloat32x4Sqrt:
1834 case MethodRecognizer::kFloat32x4ReciprocalSqrt: 1891 case MethodRecognizer::kFloat32x4ReciprocalSqrt:
1835 case MethodRecognizer::kFloat32x4Reciprocal: { 1892 case MethodRecognizer::kFloat32x4Reciprocal: {
1836 Definition* left = call->ArgumentAt(0); 1893 Definition* left = call->ArgumentAt(0);
1837 AddCheckClass(left, 1894 AddCheckClass(left,
1838 ICData::ZoneHandle( 1895 ICData::ZoneHandle(
1839 call->ic_data()->AsUnaryClassChecksForArgNr(0)), 1896 call->ic_data()->AsUnaryClassChecksForArgNr(0)),
1840 call->deopt_id(), 1897 call->deopt_id(),
1841 call->env(), 1898 call->env(),
1842 call); 1899 call);
1843 Float32x4SqrtInstr* sqrt = 1900 Float32x4SqrtInstr* sqrt =
1844 new Float32x4SqrtInstr(recognized_kind, new Value(left), call); 1901 new Float32x4SqrtInstr(recognized_kind, new Value(left),
1902 call->deopt_id());
1845 ReplaceCall(call, sqrt); 1903 ReplaceCall(call, sqrt);
1846 return true; 1904 return true;
1847 } 1905 }
1848 case MethodRecognizer::kFloat32x4WithX: 1906 case MethodRecognizer::kFloat32x4WithX:
1849 case MethodRecognizer::kFloat32x4WithY: 1907 case MethodRecognizer::kFloat32x4WithY:
1850 case MethodRecognizer::kFloat32x4WithZ: 1908 case MethodRecognizer::kFloat32x4WithZ:
1851 case MethodRecognizer::kFloat32x4WithW: { 1909 case MethodRecognizer::kFloat32x4WithW: {
1852 Definition* left = call->ArgumentAt(0); 1910 Definition* left = call->ArgumentAt(0);
1853 Definition* right = call->ArgumentAt(1); 1911 Definition* right = call->ArgumentAt(1);
1854 // Type check left. 1912 // Type check left.
1855 AddCheckClass(left, 1913 AddCheckClass(left,
1856 ICData::ZoneHandle( 1914 ICData::ZoneHandle(
1857 call->ic_data()->AsUnaryClassChecksForArgNr(0)), 1915 call->ic_data()->AsUnaryClassChecksForArgNr(0)),
1858 call->deopt_id(), 1916 call->deopt_id(),
1859 call->env(), 1917 call->env(),
1860 call); 1918 call);
1861 Float32x4WithInstr* with = new Float32x4WithInstr(recognized_kind, 1919 Float32x4WithInstr* with = new Float32x4WithInstr(recognized_kind,
1862 new Value(left), 1920 new Value(left),
1863 new Value(right), 1921 new Value(right),
1864 call); 1922 call->deopt_id());
1865 ReplaceCall(call, with); 1923 ReplaceCall(call, with);
1866 return true; 1924 return true;
1867 } 1925 }
1868 case MethodRecognizer::kFloat32x4Absolute: 1926 case MethodRecognizer::kFloat32x4Absolute:
1869 case MethodRecognizer::kFloat32x4Negate: { 1927 case MethodRecognizer::kFloat32x4Negate: {
1870 Definition* left = call->ArgumentAt(0); 1928 Definition* left = call->ArgumentAt(0);
1871 // Type check left. 1929 // Type check left.
1872 AddCheckClass(left, 1930 AddCheckClass(left,
1873 ICData::ZoneHandle( 1931 ICData::ZoneHandle(
1874 call->ic_data()->AsUnaryClassChecksForArgNr(0)), 1932 call->ic_data()->AsUnaryClassChecksForArgNr(0)),
1875 call->deopt_id(), 1933 call->deopt_id(),
1876 call->env(), 1934 call->env(),
1877 call); 1935 call);
1878 Float32x4ZeroArgInstr* zeroArg = 1936 Float32x4ZeroArgInstr* zeroArg =
1879 new Float32x4ZeroArgInstr(recognized_kind, new Value(left), call); 1937 new Float32x4ZeroArgInstr(recognized_kind, new Value(left),
1938 call->deopt_id());
1880 ReplaceCall(call, zeroArg); 1939 ReplaceCall(call, zeroArg);
1881 return true; 1940 return true;
1882 } 1941 }
1883 case MethodRecognizer::kFloat32x4Clamp: { 1942 case MethodRecognizer::kFloat32x4Clamp: {
1884 Definition* left = call->ArgumentAt(0); 1943 Definition* left = call->ArgumentAt(0);
1885 Definition* lower = call->ArgumentAt(1); 1944 Definition* lower = call->ArgumentAt(1);
1886 Definition* upper = call->ArgumentAt(2); 1945 Definition* upper = call->ArgumentAt(2);
1887 // Type check left. 1946 // Type check left.
1888 AddCheckClass(left, 1947 AddCheckClass(left,
1889 ICData::ZoneHandle( 1948 ICData::ZoneHandle(
1890 call->ic_data()->AsUnaryClassChecksForArgNr(0)), 1949 call->ic_data()->AsUnaryClassChecksForArgNr(0)),
1891 call->deopt_id(), 1950 call->deopt_id(),
1892 call->env(), 1951 call->env(),
1893 call); 1952 call);
1894 Float32x4ClampInstr* clamp = new Float32x4ClampInstr(new Value(left), 1953 Float32x4ClampInstr* clamp = new Float32x4ClampInstr(new Value(left),
1895 new Value(lower), 1954 new Value(lower),
1896 new Value(upper), 1955 new Value(upper),
1897 call); 1956 call->deopt_id());
1898 ReplaceCall(call, clamp); 1957 ReplaceCall(call, clamp);
1899 return true; 1958 return true;
1900 } 1959 }
1901 case MethodRecognizer::kFloat32x4ToUint32x4: { 1960 case MethodRecognizer::kFloat32x4ToUint32x4: {
1902 Definition* left = call->ArgumentAt(0); 1961 Definition* left = call->ArgumentAt(0);
1903 // Type check left. 1962 // Type check left.
1904 AddCheckClass(left, 1963 AddCheckClass(left,
1905 ICData::ZoneHandle( 1964 ICData::ZoneHandle(
1906 call->ic_data()->AsUnaryClassChecksForArgNr(0)), 1965 call->ic_data()->AsUnaryClassChecksForArgNr(0)),
1907 call->deopt_id(), 1966 call->deopt_id(),
1908 call->env(), 1967 call->env(),
1909 call); 1968 call);
1910 Float32x4ToUint32x4Instr* cast = 1969 Float32x4ToUint32x4Instr* cast =
1911 new Float32x4ToUint32x4Instr(new Value(left), call); 1970 new Float32x4ToUint32x4Instr(new Value(left), call->deopt_id());
1912 ReplaceCall(call, cast); 1971 ReplaceCall(call, cast);
1913 return true; 1972 return true;
1914 } 1973 }
1915 default: 1974 default:
1916 return false; 1975 return false;
1917 } 1976 }
1977 }
1978
1979
1980 bool FlowGraphOptimizer::TryInlineUint32x4Method(
1981 InstanceCallInstr* call,
1982 MethodRecognizer::Kind recognized_kind) {
1983 ASSERT(call->HasICData());
1984 switch (recognized_kind) {
1985 case MethodRecognizer::kUint32x4Select: {
1986 Definition* mask = call->ArgumentAt(0);
1987 Definition* trueValue = call->ArgumentAt(1);
1988 Definition* falseValue = call->ArgumentAt(2);
1989 // Type check left.
1990 AddCheckClass(mask,
1991 ICData::ZoneHandle(
1992 call->ic_data()->AsUnaryClassChecksForArgNr(0)),
1993 call->deopt_id(),
1994 call->env(),
1995 call);
1996 Uint32x4SelectInstr* select = new Uint32x4SelectInstr(
1997 new Value(mask),
1998 new Value(trueValue),
1999 new Value(falseValue),
2000 call->deopt_id());
2001 ReplaceCall(call, select);
2002 return true;
2003 }
2004 case MethodRecognizer::kUint32x4ToUint32x4: {
2005 Definition* left = call->ArgumentAt(0);
2006 // Type check left.
2007 AddCheckClass(left,
2008 ICData::ZoneHandle(
2009 call->ic_data()->AsUnaryClassChecksForArgNr(0)),
2010 call->deopt_id(),
2011 call->env(),
2012 call);
2013 Uint32x4ToFloat32x4Instr* cast =
2014 new Uint32x4ToFloat32x4Instr(new Value(left), call->deopt_id());
2015 ReplaceCall(call, cast);
2016 return true;
2017 }
2018 case MethodRecognizer::kUint32x4WithFlagX:
2019 case MethodRecognizer::kUint32x4WithFlagY:
2020 case MethodRecognizer::kUint32x4WithFlagZ:
2021 case MethodRecognizer::kUint32x4WithFlagW: {
2022 Definition* left = call->ArgumentAt(0);
2023 Definition* flag = call->ArgumentAt(1);
2024 // Type check left.
2025 AddCheckClass(left,
2026 ICData::ZoneHandle(
2027 call->ic_data()->AsUnaryClassChecksForArgNr(0)),
2028 call->deopt_id(),
2029 call->env(),
2030 call);
2031 Uint32x4SetFlagInstr* setFlag = new Uint32x4SetFlagInstr(
2032 recognized_kind,
2033 new Value(left),
2034 new Value(flag),
2035 call->deopt_id());
2036 ReplaceCall(call, setFlag);
2037 return true;
2038 }
2039 default:
2040 return false;
2041 }
1918 } 2042 }
1919 2043
1920 2044
1921 bool FlowGraphOptimizer::BuildByteArrayViewLoad( 2045 bool FlowGraphOptimizer::BuildByteArrayViewLoad(
1922 InstanceCallInstr* call, 2046 InstanceCallInstr* call,
1923 intptr_t receiver_cid, 2047 intptr_t receiver_cid,
1924 intptr_t view_cid) { 2048 intptr_t view_cid) {
1925 Definition* array = call->ArgumentAt(0); 2049 Definition* array = call->ArgumentAt(0);
1926 PrepareByteArrayViewOp(call, receiver_cid, view_cid, &array); 2050 PrepareByteArrayViewOp(call, receiver_cid, view_cid, &array);
1927 2051
(...skipping 362 matching lines...) Expand 10 before | Expand all | Expand 10 after
2290 2414
2291 2415
2292 void FlowGraphOptimizer::VisitStaticCall(StaticCallInstr* call) { 2416 void FlowGraphOptimizer::VisitStaticCall(StaticCallInstr* call) {
2293 MethodRecognizer::Kind recognized_kind = 2417 MethodRecognizer::Kind recognized_kind =
2294 MethodRecognizer::RecognizeKind(call->function()); 2418 MethodRecognizer::RecognizeKind(call->function());
2295 if (recognized_kind == MethodRecognizer::kMathSqrt) { 2419 if (recognized_kind == MethodRecognizer::kMathSqrt) {
2296 MathSqrtInstr* sqrt = 2420 MathSqrtInstr* sqrt =
2297 new MathSqrtInstr(new Value(call->ArgumentAt(0)), call); 2421 new MathSqrtInstr(new Value(call->ArgumentAt(0)), call);
2298 ReplaceCall(call, sqrt); 2422 ReplaceCall(call, sqrt);
2299 } else if (recognized_kind == MethodRecognizer::kFloat32x4Zero) { 2423 } else if (recognized_kind == MethodRecognizer::kFloat32x4Zero) {
2300 Float32x4ZeroInstr* zero = new Float32x4ZeroInstr(call); 2424 Float32x4ZeroInstr* zero = new Float32x4ZeroInstr(call->deopt_id());
2301 ReplaceCall(call, zero); 2425 ReplaceCall(call, zero);
2302 } else if (recognized_kind == MethodRecognizer::kFloat32x4Splat) { 2426 } else if (recognized_kind == MethodRecognizer::kFloat32x4Splat) {
2303 Float32x4SplatInstr* splat = 2427 Float32x4SplatInstr* splat =
2304 new Float32x4SplatInstr(new Value(call->ArgumentAt(1)), call); 2428 new Float32x4SplatInstr(new Value(call->ArgumentAt(1)),
2429 call->deopt_id());
2305 ReplaceCall(call, splat); 2430 ReplaceCall(call, splat);
2306 } else if (recognized_kind == MethodRecognizer::kFloat32x4Constructor) { 2431 } else if (recognized_kind == MethodRecognizer::kFloat32x4Constructor) {
2307 Float32x4ConstructorInstr* con = 2432 Float32x4ConstructorInstr* con =
2308 new Float32x4ConstructorInstr(new Value(call->ArgumentAt(1)), 2433 new Float32x4ConstructorInstr(new Value(call->ArgumentAt(1)),
2309 new Value(call->ArgumentAt(2)), 2434 new Value(call->ArgumentAt(2)),
2310 new Value(call->ArgumentAt(3)), 2435 new Value(call->ArgumentAt(3)),
2311 new Value(call->ArgumentAt(4)), 2436 new Value(call->ArgumentAt(4)),
2312 call); 2437 call->deopt_id());
2438 ReplaceCall(call, con);
2439 } else if (recognized_kind == MethodRecognizer::kUint32x4BoolConstructor) {
2440 Uint32x4BoolConstructorInstr* con = new Uint32x4BoolConstructorInstr(
2441 new Value(call->ArgumentAt(1)),
2442 new Value(call->ArgumentAt(2)),
2443 new Value(call->ArgumentAt(3)),
2444 new Value(call->ArgumentAt(4)),
2445 call->deopt_id());
2313 ReplaceCall(call, con); 2446 ReplaceCall(call, con);
2314 } 2447 }
2315 } 2448 }
2316 2449
2317 2450
2318 bool FlowGraphOptimizer::TryInlineInstanceSetter(InstanceCallInstr* instr, 2451 bool FlowGraphOptimizer::TryInlineInstanceSetter(InstanceCallInstr* instr,
2319 const ICData& unary_ic_data) { 2452 const ICData& unary_ic_data) {
2320 ASSERT((unary_ic_data.NumberOfChecks() > 0) && 2453 ASSERT((unary_ic_data.NumberOfChecks() > 0) &&
2321 (unary_ic_data.num_args_tested() == 1)); 2454 (unary_ic_data.num_args_tested() == 1));
2322 if (FLAG_enable_type_checks) { 2455 if (FLAG_enable_type_checks) {
(...skipping 3036 matching lines...) Expand 10 before | Expand all | Expand 10 after
5359 SetValue(instr, non_constant_); 5492 SetValue(instr, non_constant_);
5360 } 5493 }
5361 5494
5362 5495
5363 void ConstantPropagator::VisitFloat32x4ToUint32x4( 5496 void ConstantPropagator::VisitFloat32x4ToUint32x4(
5364 Float32x4ToUint32x4Instr* instr) { 5497 Float32x4ToUint32x4Instr* instr) {
5365 SetValue(instr, non_constant_); 5498 SetValue(instr, non_constant_);
5366 } 5499 }
5367 5500
5368 5501
5502 void ConstantPropagator::VisitUint32x4BoolConstructor(
5503 Uint32x4BoolConstructorInstr* instr) {
5504 SetValue(instr, non_constant_);
5505 }
5506
5507
5508 void ConstantPropagator::VisitUint32x4GetFlag(Uint32x4GetFlagInstr* instr) {
5509 SetValue(instr, non_constant_);
5510 }
5511
5512
5513 void ConstantPropagator::VisitUint32x4SetFlag(Uint32x4SetFlagInstr* instr) {
5514 SetValue(instr, non_constant_);
5515 }
5516
5517
5518 void ConstantPropagator::VisitUint32x4Select(Uint32x4SelectInstr* instr) {
5519 SetValue(instr, non_constant_);
5520 }
5521
5522
5523 void ConstantPropagator::VisitUint32x4ToFloat32x4(
5524 Uint32x4ToFloat32x4Instr* instr) {
5525 SetValue(instr, non_constant_);
5526 }
5527
5528
5529 void ConstantPropagator::VisitBinaryUint32x4Op(BinaryUint32x4OpInstr* instr) {
5530 SetValue(instr, non_constant_);
5531 }
5532
5533
5369 void ConstantPropagator::VisitMathSqrt(MathSqrtInstr* instr) { 5534 void ConstantPropagator::VisitMathSqrt(MathSqrtInstr* instr) {
5370 const Object& value = instr->value()->definition()->constant_value(); 5535 const Object& value = instr->value()->definition()->constant_value();
5371 if (IsNonConstant(value)) { 5536 if (IsNonConstant(value)) {
5372 SetValue(instr, non_constant_); 5537 SetValue(instr, non_constant_);
5373 } else if (IsConstant(value)) { 5538 } else if (IsConstant(value)) {
5374 // TODO(kmillikin): Handle sqrt. 5539 // TODO(kmillikin): Handle sqrt.
5375 SetValue(instr, non_constant_); 5540 SetValue(instr, non_constant_);
5376 } 5541 }
5377 } 5542 }
5378 5543
(...skipping 879 matching lines...) Expand 10 before | Expand all | Expand 10 after
6258 6423
6259 // Insert materializations at environment uses. 6424 // Insert materializations at environment uses.
6260 const Class& cls = Class::Handle(alloc->constructor().Owner()); 6425 const Class& cls = Class::Handle(alloc->constructor().Owner());
6261 for (intptr_t i = 0; i < exits.length(); i++) { 6426 for (intptr_t i = 0; i < exits.length(); i++) {
6262 CreateMaterializationAt(exits[i], alloc, cls, *fields); 6427 CreateMaterializationAt(exits[i], alloc, cls, *fields);
6263 } 6428 }
6264 } 6429 }
6265 6430
6266 6431
6267 } // namespace dart 6432 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/flow_graph_type_propagator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698