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

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

Issue 2254053002: Move inlining of recognized SIMD methods to the flow-graph inliner. (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: addressed comment Created 4 years, 4 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 | « runtime/vm/jit_optimizer.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 (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/jit_optimizer.h" 5 #include "vm/jit_optimizer.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/branch_optimizer.h" 8 #include "vm/branch_optimizer.h"
9 #include "vm/cha.h" 9 #include "vm/cha.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 1320 matching lines...) Expand 10 before | Expand all | Expand 10 after
1331 for (Value::Iterator it(load->input_use_list()); 1331 for (Value::Iterator it(load->input_use_list());
1332 !it.Done(); 1332 !it.Done();
1333 it.Advance()) { 1333 it.Advance()) {
1334 it.Current()->SetReachingType(NULL); 1334 it.Current()->SetReachingType(NULL);
1335 } 1335 }
1336 } 1336 }
1337 return true; 1337 return true;
1338 } 1338 }
1339 1339
1340 1340
1341 bool JitOptimizer::InlineFloat32x4Getter(InstanceCallInstr* call,
1342 MethodRecognizer::Kind getter) {
1343 if (!ShouldInlineSimd()) {
1344 return false;
1345 }
1346 AddCheckClass(call->ArgumentAt(0),
1347 ICData::ZoneHandle(
1348 Z, call->ic_data()->AsUnaryClassChecksForArgNr(0)),
1349 call->deopt_id(),
1350 call->env(),
1351 call);
1352 intptr_t mask = 0;
1353 if ((getter == MethodRecognizer::kFloat32x4Shuffle) ||
1354 (getter == MethodRecognizer::kFloat32x4ShuffleMix)) {
1355 // Extract shuffle mask.
1356 Definition* mask_definition = NULL;
1357 if (getter == MethodRecognizer::kFloat32x4Shuffle) {
1358 ASSERT(call->ArgumentCount() == 2);
1359 mask_definition = call->ArgumentAt(1);
1360 } else {
1361 ASSERT(getter == MethodRecognizer::kFloat32x4ShuffleMix);
1362 ASSERT(call->ArgumentCount() == 3);
1363 mask_definition = call->ArgumentAt(2);
1364 }
1365 if (!mask_definition->IsConstant()) {
1366 return false;
1367 }
1368 ASSERT(mask_definition->IsConstant());
1369 ConstantInstr* constant_instruction = mask_definition->AsConstant();
1370 const Object& constant_mask = constant_instruction->value();
1371 if (!constant_mask.IsSmi()) {
1372 return false;
1373 }
1374 ASSERT(constant_mask.IsSmi());
1375 mask = Smi::Cast(constant_mask).Value();
1376 if ((mask < 0) || (mask > 255)) {
1377 // Not a valid mask.
1378 return false;
1379 }
1380 }
1381 if (getter == MethodRecognizer::kFloat32x4GetSignMask) {
1382 Simd32x4GetSignMaskInstr* instr = new(Z) Simd32x4GetSignMaskInstr(
1383 getter,
1384 new(Z) Value(call->ArgumentAt(0)),
1385 call->deopt_id());
1386 ReplaceCall(call, instr);
1387 return true;
1388 } else if (getter == MethodRecognizer::kFloat32x4ShuffleMix) {
1389 Simd32x4ShuffleMixInstr* instr = new(Z) Simd32x4ShuffleMixInstr(
1390 getter,
1391 new(Z) Value(call->ArgumentAt(0)),
1392 new(Z) Value(call->ArgumentAt(1)),
1393 mask,
1394 call->deopt_id());
1395 ReplaceCall(call, instr);
1396 return true;
1397 } else {
1398 ASSERT((getter == MethodRecognizer::kFloat32x4Shuffle) ||
1399 (getter == MethodRecognizer::kFloat32x4ShuffleX) ||
1400 (getter == MethodRecognizer::kFloat32x4ShuffleY) ||
1401 (getter == MethodRecognizer::kFloat32x4ShuffleZ) ||
1402 (getter == MethodRecognizer::kFloat32x4ShuffleW));
1403 Simd32x4ShuffleInstr* instr = new(Z) Simd32x4ShuffleInstr(
1404 getter,
1405 new(Z) Value(call->ArgumentAt(0)),
1406 mask,
1407 call->deopt_id());
1408 ReplaceCall(call, instr);
1409 return true;
1410 }
1411 UNREACHABLE();
1412 return false;
1413 }
1414
1415
1416 bool JitOptimizer::InlineFloat64x2Getter(InstanceCallInstr* call, 1341 bool JitOptimizer::InlineFloat64x2Getter(InstanceCallInstr* call,
1417 MethodRecognizer::Kind getter) { 1342 MethodRecognizer::Kind getter) {
1418 if (!ShouldInlineSimd()) { 1343 if (!ShouldInlineSimd()) {
1419 return false; 1344 return false;
1420 } 1345 }
1421 AddCheckClass(call->ArgumentAt(0), 1346 AddCheckClass(call->ArgumentAt(0),
1422 ICData::ZoneHandle( 1347 ICData::ZoneHandle(
1423 Z, call->ic_data()->AsUnaryClassChecksForArgNr(0)), 1348 Z, call->ic_data()->AsUnaryClassChecksForArgNr(0)),
1424 call->deopt_id(), 1349 call->deopt_id(),
1425 call->env(), 1350 call->env(),
1426 call); 1351 call);
1427 if ((getter == MethodRecognizer::kFloat64x2GetX) || 1352 if ((getter == MethodRecognizer::kFloat64x2GetX) ||
1428 (getter == MethodRecognizer::kFloat64x2GetY)) { 1353 (getter == MethodRecognizer::kFloat64x2GetY)) {
1429 Simd64x2ShuffleInstr* instr = new(Z) Simd64x2ShuffleInstr( 1354 Simd64x2ShuffleInstr* instr = new(Z) Simd64x2ShuffleInstr(
1430 getter, 1355 getter,
1431 new(Z) Value(call->ArgumentAt(0)), 1356 new(Z) Value(call->ArgumentAt(0)),
1432 0, 1357 0,
1433 call->deopt_id()); 1358 call->deopt_id());
1434 ReplaceCall(call, instr); 1359 ReplaceCall(call, instr);
1435 return true; 1360 return true;
1436 } 1361 }
1437 UNREACHABLE(); 1362 UNREACHABLE();
1438 return false; 1363 return false;
1439 } 1364 }
1440 1365
1441 1366
1442 bool JitOptimizer::InlineInt32x4Getter(InstanceCallInstr* call,
1443 MethodRecognizer::Kind getter) {
1444 if (!ShouldInlineSimd()) {
1445 return false;
1446 }
1447 AddCheckClass(call->ArgumentAt(0),
1448 ICData::ZoneHandle(
1449 Z, call->ic_data()->AsUnaryClassChecksForArgNr(0)),
1450 call->deopt_id(),
1451 call->env(),
1452 call);
1453 intptr_t mask = 0;
1454 if ((getter == MethodRecognizer::kInt32x4Shuffle) ||
1455 (getter == MethodRecognizer::kInt32x4ShuffleMix)) {
1456 // Extract shuffle mask.
1457 Definition* mask_definition = NULL;
1458 if (getter == MethodRecognizer::kInt32x4Shuffle) {
1459 ASSERT(call->ArgumentCount() == 2);
1460 mask_definition = call->ArgumentAt(1);
1461 } else {
1462 ASSERT(getter == MethodRecognizer::kInt32x4ShuffleMix);
1463 ASSERT(call->ArgumentCount() == 3);
1464 mask_definition = call->ArgumentAt(2);
1465 }
1466 if (!mask_definition->IsConstant()) {
1467 return false;
1468 }
1469 ASSERT(mask_definition->IsConstant());
1470 ConstantInstr* constant_instruction = mask_definition->AsConstant();
1471 const Object& constant_mask = constant_instruction->value();
1472 if (!constant_mask.IsSmi()) {
1473 return false;
1474 }
1475 ASSERT(constant_mask.IsSmi());
1476 mask = Smi::Cast(constant_mask).Value();
1477 if ((mask < 0) || (mask > 255)) {
1478 // Not a valid mask.
1479 return false;
1480 }
1481 }
1482 if (getter == MethodRecognizer::kInt32x4GetSignMask) {
1483 Simd32x4GetSignMaskInstr* instr = new(Z) Simd32x4GetSignMaskInstr(
1484 getter,
1485 new(Z) Value(call->ArgumentAt(0)),
1486 call->deopt_id());
1487 ReplaceCall(call, instr);
1488 return true;
1489 } else if (getter == MethodRecognizer::kInt32x4ShuffleMix) {
1490 Simd32x4ShuffleMixInstr* instr = new(Z) Simd32x4ShuffleMixInstr(
1491 getter,
1492 new(Z) Value(call->ArgumentAt(0)),
1493 new(Z) Value(call->ArgumentAt(1)),
1494 mask,
1495 call->deopt_id());
1496 ReplaceCall(call, instr);
1497 return true;
1498 } else if (getter == MethodRecognizer::kInt32x4Shuffle) {
1499 Simd32x4ShuffleInstr* instr = new(Z) Simd32x4ShuffleInstr(
1500 getter,
1501 new(Z) Value(call->ArgumentAt(0)),
1502 mask,
1503 call->deopt_id());
1504 ReplaceCall(call, instr);
1505 return true;
1506 } else {
1507 Int32x4GetFlagInstr* instr = new(Z) Int32x4GetFlagInstr(
1508 getter,
1509 new(Z) Value(call->ArgumentAt(0)),
1510 call->deopt_id());
1511 ReplaceCall(call, instr);
1512 return true;
1513 }
1514 }
1515
1516
1517 bool JitOptimizer::InlineFloat32x4BinaryOp(InstanceCallInstr* call, 1367 bool JitOptimizer::InlineFloat32x4BinaryOp(InstanceCallInstr* call,
1518 Token::Kind op_kind) { 1368 Token::Kind op_kind) {
1519 if (!ShouldInlineSimd()) { 1369 if (!ShouldInlineSimd()) {
1520 return false; 1370 return false;
1521 } 1371 }
1522 ASSERT(call->ArgumentCount() == 2); 1372 ASSERT(call->ArgumentCount() == 2);
1523 Definition* left = call->ArgumentAt(0); 1373 Definition* left = call->ArgumentAt(0);
1524 Definition* right = call->ArgumentAt(1); 1374 Definition* right = call->ArgumentAt(1);
1525 // Type check left. 1375 // Type check left.
1526 AddCheckClass(left, 1376 AddCheckClass(left,
(...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
1796 case MethodRecognizer::kDoubleMul: 1646 case MethodRecognizer::kDoubleMul:
1797 case MethodRecognizer::kDoubleDiv: 1647 case MethodRecognizer::kDoubleDiv:
1798 return FlowGraphInliner::TryReplaceInstanceCallWithInline( 1648 return FlowGraphInliner::TryReplaceInstanceCallWithInline(
1799 flow_graph_, current_iterator(), call); 1649 flow_graph_, current_iterator(), call);
1800 default: 1650 default:
1801 // Unsupported method. 1651 // Unsupported method.
1802 return false; 1652 return false;
1803 } 1653 }
1804 } 1654 }
1805 1655
1806 if (IsSupportedByteArrayViewCid(class_ids[0])) { 1656 if (IsSupportedByteArrayViewCid(class_ids[0]) ||
1657 (class_ids[0] == kFloat32x4Cid) ||
1658 (class_ids[0] == kInt32x4Cid) ||
1659 (class_ids[0] == kFloat64x2Cid)) {
1807 return FlowGraphInliner::TryReplaceInstanceCallWithInline( 1660 return FlowGraphInliner::TryReplaceInstanceCallWithInline(
1808 flow_graph_, current_iterator(), call); 1661 flow_graph_, current_iterator(), call);
1809 } 1662 }
1810 1663
1811 if (class_ids[0] == kFloat32x4Cid) {
1812 return TryInlineFloat32x4Method(call, recognized_kind);
1813 }
1814
1815 if (class_ids[0] == kInt32x4Cid) {
1816 return TryInlineInt32x4Method(call, recognized_kind);
1817 }
1818
1819 if (class_ids[0] == kFloat64x2Cid) {
1820 return TryInlineFloat64x2Method(call, recognized_kind);
1821 }
1822
1823 return false; 1664 return false;
1824 } 1665 }
1825 1666
1826 1667
1827 bool JitOptimizer::TryInlineFloat32x4Constructor(
1828 StaticCallInstr* call,
1829 MethodRecognizer::Kind recognized_kind) {
1830 if (!ShouldInlineSimd()) {
1831 return false;
1832 }
1833 if (recognized_kind == MethodRecognizer::kFloat32x4Zero) {
1834 Float32x4ZeroInstr* zero = new(Z) Float32x4ZeroInstr();
1835 ReplaceCall(call, zero);
1836 return true;
1837 } else if (recognized_kind == MethodRecognizer::kFloat32x4Splat) {
1838 Float32x4SplatInstr* splat =
1839 new(Z) Float32x4SplatInstr(
1840 new(Z) Value(call->ArgumentAt(1)), call->deopt_id());
1841 ReplaceCall(call, splat);
1842 return true;
1843 } else if (recognized_kind == MethodRecognizer::kFloat32x4Constructor) {
1844 Float32x4ConstructorInstr* con =
1845 new(Z) Float32x4ConstructorInstr(
1846 new(Z) Value(call->ArgumentAt(1)),
1847 new(Z) Value(call->ArgumentAt(2)),
1848 new(Z) Value(call->ArgumentAt(3)),
1849 new(Z) Value(call->ArgumentAt(4)),
1850 call->deopt_id());
1851 ReplaceCall(call, con);
1852 return true;
1853 } else if (recognized_kind == MethodRecognizer::kFloat32x4FromInt32x4Bits) {
1854 Int32x4ToFloat32x4Instr* cast =
1855 new(Z) Int32x4ToFloat32x4Instr(
1856 new(Z) Value(call->ArgumentAt(1)), call->deopt_id());
1857 ReplaceCall(call, cast);
1858 return true;
1859 } else if (recognized_kind == MethodRecognizer::kFloat32x4FromFloat64x2) {
1860 Float64x2ToFloat32x4Instr* cast =
1861 new(Z) Float64x2ToFloat32x4Instr(
1862 new(Z) Value(call->ArgumentAt(1)), call->deopt_id());
1863 ReplaceCall(call, cast);
1864 return true;
1865 }
1866 return false;
1867 }
1868
1869
1870 bool JitOptimizer::TryInlineFloat64x2Constructor(
1871 StaticCallInstr* call,
1872 MethodRecognizer::Kind recognized_kind) {
1873 if (!ShouldInlineSimd()) {
1874 return false;
1875 }
1876 if (recognized_kind == MethodRecognizer::kFloat64x2Zero) {
1877 Float64x2ZeroInstr* zero = new(Z) Float64x2ZeroInstr();
1878 ReplaceCall(call, zero);
1879 return true;
1880 } else if (recognized_kind == MethodRecognizer::kFloat64x2Splat) {
1881 Float64x2SplatInstr* splat =
1882 new(Z) Float64x2SplatInstr(
1883 new(Z) Value(call->ArgumentAt(1)), call->deopt_id());
1884 ReplaceCall(call, splat);
1885 return true;
1886 } else if (recognized_kind == MethodRecognizer::kFloat64x2Constructor) {
1887 Float64x2ConstructorInstr* con =
1888 new(Z) Float64x2ConstructorInstr(
1889 new(Z) Value(call->ArgumentAt(1)),
1890 new(Z) Value(call->ArgumentAt(2)),
1891 call->deopt_id());
1892 ReplaceCall(call, con);
1893 return true;
1894 } else if (recognized_kind == MethodRecognizer::kFloat64x2FromFloat32x4) {
1895 Float32x4ToFloat64x2Instr* cast =
1896 new(Z) Float32x4ToFloat64x2Instr(
1897 new(Z) Value(call->ArgumentAt(1)), call->deopt_id());
1898 ReplaceCall(call, cast);
1899 return true;
1900 }
1901 return false;
1902 }
1903
1904
1905 bool JitOptimizer::TryInlineInt32x4Constructor(
1906 StaticCallInstr* call,
1907 MethodRecognizer::Kind recognized_kind) {
1908 if (!ShouldInlineSimd()) {
1909 return false;
1910 }
1911 if (recognized_kind == MethodRecognizer::kInt32x4BoolConstructor) {
1912 Int32x4BoolConstructorInstr* con =
1913 new(Z) Int32x4BoolConstructorInstr(
1914 new(Z) Value(call->ArgumentAt(1)),
1915 new(Z) Value(call->ArgumentAt(2)),
1916 new(Z) Value(call->ArgumentAt(3)),
1917 new(Z) Value(call->ArgumentAt(4)),
1918 call->deopt_id());
1919 ReplaceCall(call, con);
1920 return true;
1921 } else if (recognized_kind == MethodRecognizer::kInt32x4FromFloat32x4Bits) {
1922 Float32x4ToInt32x4Instr* cast =
1923 new(Z) Float32x4ToInt32x4Instr(
1924 new(Z) Value(call->ArgumentAt(1)), call->deopt_id());
1925 ReplaceCall(call, cast);
1926 return true;
1927 } else if (recognized_kind == MethodRecognizer::kInt32x4Constructor) {
1928 Int32x4ConstructorInstr* con =
1929 new(Z) Int32x4ConstructorInstr(
1930 new(Z) Value(call->ArgumentAt(1)),
1931 new(Z) Value(call->ArgumentAt(2)),
1932 new(Z) Value(call->ArgumentAt(3)),
1933 new(Z) Value(call->ArgumentAt(4)),
1934 call->deopt_id());
1935 ReplaceCall(call, con);
1936 return true;
1937 }
1938 return false;
1939 }
1940
1941
1942 bool JitOptimizer::TryInlineFloat32x4Method(
1943 InstanceCallInstr* call,
1944 MethodRecognizer::Kind recognized_kind) {
1945 if (!ShouldInlineSimd()) {
1946 return false;
1947 }
1948 ASSERT(call->HasICData());
1949 switch (recognized_kind) {
1950 case MethodRecognizer::kFloat32x4ShuffleX:
1951 case MethodRecognizer::kFloat32x4ShuffleY:
1952 case MethodRecognizer::kFloat32x4ShuffleZ:
1953 case MethodRecognizer::kFloat32x4ShuffleW:
1954 case MethodRecognizer::kFloat32x4GetSignMask:
1955 ASSERT(call->ic_data()->HasReceiverClassId(kFloat32x4Cid));
1956 ASSERT(call->ic_data()->HasOneTarget());
1957 return InlineFloat32x4Getter(call, recognized_kind);
1958
1959 case MethodRecognizer::kFloat32x4Equal:
1960 case MethodRecognizer::kFloat32x4GreaterThan:
1961 case MethodRecognizer::kFloat32x4GreaterThanOrEqual:
1962 case MethodRecognizer::kFloat32x4LessThan:
1963 case MethodRecognizer::kFloat32x4LessThanOrEqual:
1964 case MethodRecognizer::kFloat32x4NotEqual: {
1965 Definition* left = call->ArgumentAt(0);
1966 Definition* right = call->ArgumentAt(1);
1967 Float32x4ComparisonInstr* cmp =
1968 new(Z) Float32x4ComparisonInstr(recognized_kind,
1969 new(Z) Value(left),
1970 new(Z) Value(right),
1971 call->deopt_id());
1972 ReplaceCall(call, cmp);
1973 return true;
1974 }
1975 case MethodRecognizer::kFloat32x4Min:
1976 case MethodRecognizer::kFloat32x4Max: {
1977 Definition* left = call->ArgumentAt(0);
1978 Definition* right = call->ArgumentAt(1);
1979 Float32x4MinMaxInstr* minmax =
1980 new(Z) Float32x4MinMaxInstr(
1981 recognized_kind,
1982 new(Z) Value(left),
1983 new(Z) Value(right),
1984 call->deopt_id());
1985 ReplaceCall(call, minmax);
1986 return true;
1987 }
1988 case MethodRecognizer::kFloat32x4Scale: {
1989 Definition* left = call->ArgumentAt(0);
1990 Definition* right = call->ArgumentAt(1);
1991 // Left and right values are swapped when handed to the instruction,
1992 // this is done so that the double value is loaded into the output
1993 // register and can be destroyed.
1994 Float32x4ScaleInstr* scale =
1995 new(Z) Float32x4ScaleInstr(recognized_kind,
1996 new(Z) Value(right),
1997 new(Z) Value(left),
1998 call->deopt_id());
1999 ReplaceCall(call, scale);
2000 return true;
2001 }
2002 case MethodRecognizer::kFloat32x4Sqrt:
2003 case MethodRecognizer::kFloat32x4ReciprocalSqrt:
2004 case MethodRecognizer::kFloat32x4Reciprocal: {
2005 Definition* left = call->ArgumentAt(0);
2006 Float32x4SqrtInstr* sqrt =
2007 new(Z) Float32x4SqrtInstr(recognized_kind,
2008 new(Z) Value(left),
2009 call->deopt_id());
2010 ReplaceCall(call, sqrt);
2011 return true;
2012 }
2013 case MethodRecognizer::kFloat32x4WithX:
2014 case MethodRecognizer::kFloat32x4WithY:
2015 case MethodRecognizer::kFloat32x4WithZ:
2016 case MethodRecognizer::kFloat32x4WithW: {
2017 Definition* left = call->ArgumentAt(0);
2018 Definition* right = call->ArgumentAt(1);
2019 Float32x4WithInstr* with = new(Z) Float32x4WithInstr(recognized_kind,
2020 new(Z) Value(left),
2021 new(Z) Value(right),
2022 call->deopt_id());
2023 ReplaceCall(call, with);
2024 return true;
2025 }
2026 case MethodRecognizer::kFloat32x4Absolute:
2027 case MethodRecognizer::kFloat32x4Negate: {
2028 Definition* left = call->ArgumentAt(0);
2029 Float32x4ZeroArgInstr* zeroArg =
2030 new(Z) Float32x4ZeroArgInstr(
2031 recognized_kind, new(Z) Value(left), call->deopt_id());
2032 ReplaceCall(call, zeroArg);
2033 return true;
2034 }
2035 case MethodRecognizer::kFloat32x4Clamp: {
2036 Definition* left = call->ArgumentAt(0);
2037 Definition* lower = call->ArgumentAt(1);
2038 Definition* upper = call->ArgumentAt(2);
2039 Float32x4ClampInstr* clamp = new(Z) Float32x4ClampInstr(
2040 new(Z) Value(left),
2041 new(Z) Value(lower),
2042 new(Z) Value(upper),
2043 call->deopt_id());
2044 ReplaceCall(call, clamp);
2045 return true;
2046 }
2047 case MethodRecognizer::kFloat32x4ShuffleMix:
2048 case MethodRecognizer::kFloat32x4Shuffle: {
2049 return InlineFloat32x4Getter(call, recognized_kind);
2050 }
2051 default:
2052 return false;
2053 }
2054 }
2055
2056
2057 bool JitOptimizer::TryInlineFloat64x2Method(
2058 InstanceCallInstr* call,
2059 MethodRecognizer::Kind recognized_kind) {
2060 if (!ShouldInlineSimd()) {
2061 return false;
2062 }
2063 ASSERT(call->HasICData());
2064 switch (recognized_kind) {
2065 case MethodRecognizer::kFloat64x2GetX:
2066 case MethodRecognizer::kFloat64x2GetY:
2067 ASSERT(call->ic_data()->HasReceiverClassId(kFloat64x2Cid));
2068 ASSERT(call->ic_data()->HasOneTarget());
2069 return InlineFloat64x2Getter(call, recognized_kind);
2070 case MethodRecognizer::kFloat64x2Negate:
2071 case MethodRecognizer::kFloat64x2Abs:
2072 case MethodRecognizer::kFloat64x2Sqrt:
2073 case MethodRecognizer::kFloat64x2GetSignMask: {
2074 Definition* left = call->ArgumentAt(0);
2075 Float64x2ZeroArgInstr* zeroArg =
2076 new(Z) Float64x2ZeroArgInstr(
2077 recognized_kind, new(Z) Value(left), call->deopt_id());
2078 ReplaceCall(call, zeroArg);
2079 return true;
2080 }
2081 case MethodRecognizer::kFloat64x2Scale:
2082 case MethodRecognizer::kFloat64x2WithX:
2083 case MethodRecognizer::kFloat64x2WithY:
2084 case MethodRecognizer::kFloat64x2Min:
2085 case MethodRecognizer::kFloat64x2Max: {
2086 Definition* left = call->ArgumentAt(0);
2087 Definition* right = call->ArgumentAt(1);
2088 Float64x2OneArgInstr* zeroArg =
2089 new(Z) Float64x2OneArgInstr(recognized_kind,
2090 new(Z) Value(left),
2091 new(Z) Value(right),
2092 call->deopt_id());
2093 ReplaceCall(call, zeroArg);
2094 return true;
2095 }
2096 default:
2097 return false;
2098 }
2099 }
2100
2101
2102 bool JitOptimizer::TryInlineInt32x4Method(
2103 InstanceCallInstr* call,
2104 MethodRecognizer::Kind recognized_kind) {
2105 if (!ShouldInlineSimd()) {
2106 return false;
2107 }
2108 ASSERT(call->HasICData());
2109 switch (recognized_kind) {
2110 case MethodRecognizer::kInt32x4ShuffleMix:
2111 case MethodRecognizer::kInt32x4Shuffle:
2112 case MethodRecognizer::kInt32x4GetFlagX:
2113 case MethodRecognizer::kInt32x4GetFlagY:
2114 case MethodRecognizer::kInt32x4GetFlagZ:
2115 case MethodRecognizer::kInt32x4GetFlagW:
2116 case MethodRecognizer::kInt32x4GetSignMask:
2117 ASSERT(call->ic_data()->HasReceiverClassId(kInt32x4Cid));
2118 ASSERT(call->ic_data()->HasOneTarget());
2119 return InlineInt32x4Getter(call, recognized_kind);
2120
2121 case MethodRecognizer::kInt32x4Select: {
2122 Definition* mask = call->ArgumentAt(0);
2123 Definition* trueValue = call->ArgumentAt(1);
2124 Definition* falseValue = call->ArgumentAt(2);
2125 // Type check left.
2126 AddCheckClass(mask,
2127 ICData::ZoneHandle(
2128 Z, call->ic_data()->AsUnaryClassChecksForArgNr(0)),
2129 call->deopt_id(),
2130 call->env(),
2131 call);
2132 Int32x4SelectInstr* select = new(Z) Int32x4SelectInstr(
2133 new(Z) Value(mask),
2134 new(Z) Value(trueValue),
2135 new(Z) Value(falseValue),
2136 call->deopt_id());
2137 ReplaceCall(call, select);
2138 return true;
2139 }
2140 case MethodRecognizer::kInt32x4WithFlagX:
2141 case MethodRecognizer::kInt32x4WithFlagY:
2142 case MethodRecognizer::kInt32x4WithFlagZ:
2143 case MethodRecognizer::kInt32x4WithFlagW: {
2144 Definition* left = call->ArgumentAt(0);
2145 Definition* flag = call->ArgumentAt(1);
2146 // Type check left.
2147 AddCheckClass(left,
2148 ICData::ZoneHandle(
2149 Z, call->ic_data()->AsUnaryClassChecksForArgNr(0)),
2150 call->deopt_id(),
2151 call->env(),
2152 call);
2153 Int32x4SetFlagInstr* setFlag = new(Z) Int32x4SetFlagInstr(
2154 recognized_kind,
2155 new(Z) Value(left),
2156 new(Z) Value(flag),
2157 call->deopt_id());
2158 ReplaceCall(call, setFlag);
2159 return true;
2160 }
2161 default:
2162 return false;
2163 }
2164 }
2165
2166
2167 // If type tests specified by 'ic_data' do not depend on type arguments, 1668 // If type tests specified by 'ic_data' do not depend on type arguments,
2168 // return mapping cid->result in 'results' (i : cid; i + 1: result). 1669 // return mapping cid->result in 'results' (i : cid; i + 1: result).
2169 // If all tests yield the same result, return it otherwise return Bool::null. 1670 // If all tests yield the same result, return it otherwise return Bool::null.
2170 // If no mapping is possible, 'results' is empty. 1671 // If no mapping is possible, 'results' is empty.
2171 // An instance-of test returning all same results can be converted to a class 1672 // An instance-of test returning all same results can be converted to a class
2172 // check. 1673 // check.
2173 RawBool* JitOptimizer::InstanceOfAsBool( 1674 RawBool* JitOptimizer::InstanceOfAsBool(
2174 const ICData& ic_data, 1675 const ICData& ic_data,
2175 const AbstractType& type, 1676 const AbstractType& type,
2176 ZoneGrowableArray<intptr_t>* results) const { 1677 ZoneGrowableArray<intptr_t>* results) const {
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after
2630 new(Z) Value(call->ArgumentAt(0)), 2131 new(Z) Value(call->ArgumentAt(0)),
2631 call->deopt_id()); 2132 call->deopt_id());
2632 ReplaceCall(call, math_unary); 2133 ReplaceCall(call, math_unary);
2633 return; 2134 return;
2634 } 2135 }
2635 switch (recognized_kind) { 2136 switch (recognized_kind) {
2636 case MethodRecognizer::kFloat32x4Zero: 2137 case MethodRecognizer::kFloat32x4Zero:
2637 case MethodRecognizer::kFloat32x4Splat: 2138 case MethodRecognizer::kFloat32x4Splat:
2638 case MethodRecognizer::kFloat32x4Constructor: 2139 case MethodRecognizer::kFloat32x4Constructor:
2639 case MethodRecognizer::kFloat32x4FromFloat64x2: 2140 case MethodRecognizer::kFloat32x4FromFloat64x2:
2640 TryInlineFloat32x4Constructor(call, recognized_kind);
2641 break;
2642 case MethodRecognizer::kFloat64x2Constructor: 2141 case MethodRecognizer::kFloat64x2Constructor:
2643 case MethodRecognizer::kFloat64x2Zero: 2142 case MethodRecognizer::kFloat64x2Zero:
2644 case MethodRecognizer::kFloat64x2Splat: 2143 case MethodRecognizer::kFloat64x2Splat:
2645 case MethodRecognizer::kFloat64x2FromFloat32x4: 2144 case MethodRecognizer::kFloat64x2FromFloat32x4:
2646 TryInlineFloat64x2Constructor(call, recognized_kind);
2647 break;
2648 case MethodRecognizer::kInt32x4BoolConstructor: 2145 case MethodRecognizer::kInt32x4BoolConstructor:
2649 case MethodRecognizer::kInt32x4Constructor: 2146 case MethodRecognizer::kInt32x4Constructor:
2650 TryInlineInt32x4Constructor(call, recognized_kind); 2147 FlowGraphInliner::TryReplaceStaticCallWithInline(
2148 flow_graph_, current_iterator(), call);
2651 break; 2149 break;
2652 case MethodRecognizer::kObjectConstructor: { 2150 case MethodRecognizer::kObjectConstructor: {
2653 // Remove the original push arguments. 2151 // Remove the original push arguments.
2654 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { 2152 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) {
2655 PushArgumentInstr* push = call->PushArgumentAt(i); 2153 PushArgumentInstr* push = call->PushArgumentAt(i);
2656 push->ReplaceUsesWith(push->value()->definition()); 2154 push->ReplaceUsesWith(push->value()->definition());
2657 push->RemoveFromGraph(); 2155 push->RemoveFromGraph();
2658 } 2156 }
2659 // Manually replace call with global null constant. ReplaceCall can't 2157 // Manually replace call with global null constant. ReplaceCall can't
2660 // be used for definitions that are already in the graph. 2158 // be used for definitions that are already in the graph.
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after
2949 2447
2950 // Discard the environment from the original instruction because the store 2448 // Discard the environment from the original instruction because the store
2951 // can't deoptimize. 2449 // can't deoptimize.
2952 instr->RemoveEnvironment(); 2450 instr->RemoveEnvironment();
2953 ReplaceCall(instr, store); 2451 ReplaceCall(instr, store);
2954 return true; 2452 return true;
2955 } 2453 }
2956 2454
2957 2455
2958 } // namespace dart 2456 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/jit_optimizer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698