OLD | NEW |
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/dart_entry.h" | 9 #include "vm/dart_entry.h" |
10 #include "vm/flow_graph_builder.h" | 10 #include "vm/flow_graph_builder.h" |
(...skipping 1674 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1685 if (!ShouldInlineSimd()) { | 1685 if (!ShouldInlineSimd()) { |
1686 return false; | 1686 return false; |
1687 } | 1687 } |
1688 AddCheckClass(call->ArgumentAt(0), | 1688 AddCheckClass(call->ArgumentAt(0), |
1689 ICData::ZoneHandle( | 1689 ICData::ZoneHandle( |
1690 call->ic_data()->AsUnaryClassChecksForArgNr(0)), | 1690 call->ic_data()->AsUnaryClassChecksForArgNr(0)), |
1691 call->deopt_id(), | 1691 call->deopt_id(), |
1692 call->env(), | 1692 call->env(), |
1693 call); | 1693 call); |
1694 intptr_t mask = 0; | 1694 intptr_t mask = 0; |
1695 if (getter == MethodRecognizer::kFloat32x4Shuffle) { | 1695 if ((getter == MethodRecognizer::kFloat32x4Shuffle) || |
| 1696 (getter == MethodRecognizer::kFloat32x4ShuffleMix)) { |
1696 // Extract shuffle mask. | 1697 // Extract shuffle mask. |
1697 ASSERT(call->ArgumentCount() == 2); | 1698 Definition* mask_definition = NULL; |
1698 Definition* mask_definition = call->ArgumentAt(1); | 1699 if (getter == MethodRecognizer::kFloat32x4Shuffle) { |
| 1700 ASSERT(call->ArgumentCount() == 2); |
| 1701 mask_definition = call->ArgumentAt(1); |
| 1702 } else { |
| 1703 ASSERT(getter == MethodRecognizer::kFloat32x4ShuffleMix); |
| 1704 ASSERT(call->ArgumentCount() == 3); |
| 1705 mask_definition = call->ArgumentAt(2); |
| 1706 } |
1699 if (!mask_definition->IsConstant()) { | 1707 if (!mask_definition->IsConstant()) { |
1700 // Not a constant. | |
1701 return false; | 1708 return false; |
1702 } | 1709 } |
1703 ASSERT(mask_definition->IsConstant()); | 1710 ASSERT(mask_definition->IsConstant()); |
1704 ConstantInstr* constant_instruction = mask_definition->AsConstant(); | 1711 ConstantInstr* constant_instruction = mask_definition->AsConstant(); |
1705 const Object& constant_mask = constant_instruction->value(); | 1712 const Object& constant_mask = constant_instruction->value(); |
1706 if (!constant_mask.IsSmi()) { | 1713 if (!constant_mask.IsSmi()) { |
1707 // Not a smi. | |
1708 return false; | 1714 return false; |
1709 } | 1715 } |
1710 ASSERT(constant_mask.IsSmi()); | 1716 ASSERT(constant_mask.IsSmi()); |
1711 mask = Smi::Cast(constant_mask).Value(); | 1717 mask = Smi::Cast(constant_mask).Value(); |
1712 if (mask < 0 || mask > 255) { | 1718 if ((mask < 0) || (mask > 255)) { |
1713 // Not a valid mask. | 1719 // Not a valid mask. |
1714 return false; | 1720 return false; |
1715 } | 1721 } |
1716 } | 1722 } |
1717 if (getter == MethodRecognizer::kFloat32x4GetSignMask) { | 1723 if (getter == MethodRecognizer::kFloat32x4GetSignMask) { |
1718 Simd32x4GetSignMaskInstr* instr = new Simd32x4GetSignMaskInstr( | 1724 Simd32x4GetSignMaskInstr* instr = new Simd32x4GetSignMaskInstr( |
1719 getter, | 1725 getter, |
1720 new Value(call->ArgumentAt(0)), | 1726 new Value(call->ArgumentAt(0)), |
1721 call->deopt_id()); | 1727 call->deopt_id()); |
1722 ReplaceCall(call, instr); | 1728 ReplaceCall(call, instr); |
1723 return true; | 1729 return true; |
| 1730 } else if (getter == MethodRecognizer::kFloat32x4ShuffleMix) { |
| 1731 Simd32x4ShuffleMixInstr* instr = new Simd32x4ShuffleMixInstr( |
| 1732 getter, |
| 1733 new Value(call->ArgumentAt(0)), |
| 1734 new Value(call->ArgumentAt(1)), |
| 1735 mask, |
| 1736 call->deopt_id()); |
| 1737 ReplaceCall(call, instr); |
| 1738 return true; |
1724 } else { | 1739 } else { |
1725 ASSERT((getter == MethodRecognizer::kFloat32x4Shuffle) || | 1740 ASSERT((getter == MethodRecognizer::kFloat32x4Shuffle) || |
1726 (getter == MethodRecognizer::kFloat32x4ShuffleX) || | 1741 (getter == MethodRecognizer::kFloat32x4ShuffleX) || |
1727 (getter == MethodRecognizer::kFloat32x4ShuffleY) || | 1742 (getter == MethodRecognizer::kFloat32x4ShuffleY) || |
1728 (getter == MethodRecognizer::kFloat32x4ShuffleZ) || | 1743 (getter == MethodRecognizer::kFloat32x4ShuffleZ) || |
1729 (getter == MethodRecognizer::kFloat32x4ShuffleW)); | 1744 (getter == MethodRecognizer::kFloat32x4ShuffleW)); |
1730 Float32x4ShuffleInstr* instr = new Float32x4ShuffleInstr( | 1745 Simd32x4ShuffleInstr* instr = new Simd32x4ShuffleInstr( |
1731 getter, | 1746 getter, |
1732 new Value(call->ArgumentAt(0)), | 1747 new Value(call->ArgumentAt(0)), |
1733 mask, | 1748 mask, |
1734 call->deopt_id()); | 1749 call->deopt_id()); |
1735 ReplaceCall(call, instr); | 1750 ReplaceCall(call, instr); |
1736 return true; | 1751 return true; |
1737 } | 1752 } |
1738 UNREACHABLE(); | 1753 UNREACHABLE(); |
1739 return false; | 1754 return false; |
1740 } | 1755 } |
1741 | 1756 |
1742 | 1757 |
1743 bool FlowGraphOptimizer::InlineUint32x4Getter(InstanceCallInstr* call, | 1758 bool FlowGraphOptimizer::InlineUint32x4Getter(InstanceCallInstr* call, |
1744 MethodRecognizer::Kind getter) { | 1759 MethodRecognizer::Kind getter) { |
1745 if (!ShouldInlineSimd()) { | 1760 if (!ShouldInlineSimd()) { |
1746 return false; | 1761 return false; |
1747 } | 1762 } |
1748 AddCheckClass(call->ArgumentAt(0), | 1763 AddCheckClass(call->ArgumentAt(0), |
1749 ICData::ZoneHandle( | 1764 ICData::ZoneHandle( |
1750 call->ic_data()->AsUnaryClassChecksForArgNr(0)), | 1765 call->ic_data()->AsUnaryClassChecksForArgNr(0)), |
1751 call->deopt_id(), | 1766 call->deopt_id(), |
1752 call->env(), | 1767 call->env(), |
1753 call); | 1768 call); |
| 1769 intptr_t mask = 0; |
| 1770 if ((getter == MethodRecognizer::kUint32x4Shuffle) || |
| 1771 (getter == MethodRecognizer::kUint32x4ShuffleMix)) { |
| 1772 // Extract shuffle mask. |
| 1773 Definition* mask_definition = NULL; |
| 1774 if (getter == MethodRecognizer::kUint32x4Shuffle) { |
| 1775 ASSERT(call->ArgumentCount() == 2); |
| 1776 mask_definition = call->ArgumentAt(1); |
| 1777 } else { |
| 1778 ASSERT(getter == MethodRecognizer::kUint32x4ShuffleMix); |
| 1779 ASSERT(call->ArgumentCount() == 3); |
| 1780 mask_definition = call->ArgumentAt(2); |
| 1781 } |
| 1782 if (!mask_definition->IsConstant()) { |
| 1783 return false; |
| 1784 } |
| 1785 ASSERT(mask_definition->IsConstant()); |
| 1786 ConstantInstr* constant_instruction = mask_definition->AsConstant(); |
| 1787 const Object& constant_mask = constant_instruction->value(); |
| 1788 if (!constant_mask.IsSmi()) { |
| 1789 return false; |
| 1790 } |
| 1791 ASSERT(constant_mask.IsSmi()); |
| 1792 mask = Smi::Cast(constant_mask).Value(); |
| 1793 if ((mask < 0) || (mask > 255)) { |
| 1794 // Not a valid mask. |
| 1795 return false; |
| 1796 } |
| 1797 } |
1754 if (getter == MethodRecognizer::kUint32x4GetSignMask) { | 1798 if (getter == MethodRecognizer::kUint32x4GetSignMask) { |
1755 Simd32x4GetSignMaskInstr* instr = new Simd32x4GetSignMaskInstr( | 1799 Simd32x4GetSignMaskInstr* instr = new Simd32x4GetSignMaskInstr( |
1756 getter, | 1800 getter, |
1757 new Value(call->ArgumentAt(0)), | 1801 new Value(call->ArgumentAt(0)), |
1758 call->deopt_id()); | 1802 call->deopt_id()); |
1759 ReplaceCall(call, instr); | 1803 ReplaceCall(call, instr); |
1760 return true; | 1804 return true; |
| 1805 } else if (getter == MethodRecognizer::kUint32x4ShuffleMix) { |
| 1806 Simd32x4ShuffleMixInstr* instr = new Simd32x4ShuffleMixInstr( |
| 1807 getter, |
| 1808 new Value(call->ArgumentAt(0)), |
| 1809 new Value(call->ArgumentAt(1)), |
| 1810 mask, |
| 1811 call->deopt_id()); |
| 1812 ReplaceCall(call, instr); |
| 1813 return true; |
| 1814 } else if (getter == MethodRecognizer::kUint32x4Shuffle) { |
| 1815 Simd32x4ShuffleInstr* instr = new Simd32x4ShuffleInstr( |
| 1816 getter, |
| 1817 new Value(call->ArgumentAt(0)), |
| 1818 mask, |
| 1819 call->deopt_id()); |
| 1820 ReplaceCall(call, instr); |
| 1821 return true; |
1761 } else { | 1822 } else { |
1762 Uint32x4GetFlagInstr* instr = new Uint32x4GetFlagInstr( | 1823 Uint32x4GetFlagInstr* instr = new Uint32x4GetFlagInstr( |
1763 getter, | 1824 getter, |
1764 new Value(call->ArgumentAt(0)), | 1825 new Value(call->ArgumentAt(0)), |
1765 call->deopt_id()); | 1826 call->deopt_id()); |
1766 ReplaceCall(call, instr); | 1827 ReplaceCall(call, instr); |
1767 return true; | 1828 return true; |
1768 } | 1829 } |
1769 } | 1830 } |
1770 | 1831 |
(...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2313 call->ic_data()->AsUnaryClassChecksForArgNr(0)), | 2374 call->ic_data()->AsUnaryClassChecksForArgNr(0)), |
2314 call->deopt_id(), | 2375 call->deopt_id(), |
2315 call->env(), | 2376 call->env(), |
2316 call); | 2377 call); |
2317 Float32x4MinMaxInstr* minmax = | 2378 Float32x4MinMaxInstr* minmax = |
2318 new Float32x4MinMaxInstr(recognized_kind, new Value(left), | 2379 new Float32x4MinMaxInstr(recognized_kind, new Value(left), |
2319 new Value(right), call->deopt_id()); | 2380 new Value(right), call->deopt_id()); |
2320 ReplaceCall(call, minmax); | 2381 ReplaceCall(call, minmax); |
2321 return true; | 2382 return true; |
2322 } | 2383 } |
2323 case MethodRecognizer::kFloat32x4WithZWInXY: | |
2324 case MethodRecognizer::kFloat32x4InterleaveXY: | |
2325 case MethodRecognizer::kFloat32x4InterleaveZW: | |
2326 case MethodRecognizer::kFloat32x4InterleaveXYPairs: | |
2327 case MethodRecognizer::kFloat32x4InterleaveZWPairs: { | |
2328 Definition* left = call->ArgumentAt(0); | |
2329 Definition* right = call->ArgumentAt(1); | |
2330 // Type check left. | |
2331 AddCheckClass(left, | |
2332 ICData::ZoneHandle( | |
2333 call->ic_data()->AsUnaryClassChecksForArgNr(0)), | |
2334 call->deopt_id(), | |
2335 call->env(), | |
2336 call); | |
2337 Float32x4TwoArgShuffleInstr* two_arg_shuffle = | |
2338 new Float32x4TwoArgShuffleInstr(recognized_kind, new Value(left), | |
2339 new Value(right), call->deopt_id()); | |
2340 ReplaceCall(call, two_arg_shuffle); | |
2341 return true; | |
2342 } | |
2343 case MethodRecognizer::kFloat32x4Scale: { | 2384 case MethodRecognizer::kFloat32x4Scale: { |
2344 Definition* left = call->ArgumentAt(0); | 2385 Definition* left = call->ArgumentAt(0); |
2345 Definition* right = call->ArgumentAt(1); | 2386 Definition* right = call->ArgumentAt(1); |
2346 // Type check left. | 2387 // Type check left. |
2347 AddCheckClass(left, | 2388 AddCheckClass(left, |
2348 ICData::ZoneHandle( | 2389 ICData::ZoneHandle( |
2349 call->ic_data()->AsUnaryClassChecksForArgNr(0)), | 2390 call->ic_data()->AsUnaryClassChecksForArgNr(0)), |
2350 call->deopt_id(), | 2391 call->deopt_id(), |
2351 call->env(), | 2392 call->env(), |
2352 call); | 2393 call); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2422 call->deopt_id(), | 2463 call->deopt_id(), |
2423 call->env(), | 2464 call->env(), |
2424 call); | 2465 call); |
2425 Float32x4ClampInstr* clamp = new Float32x4ClampInstr(new Value(left), | 2466 Float32x4ClampInstr* clamp = new Float32x4ClampInstr(new Value(left), |
2426 new Value(lower), | 2467 new Value(lower), |
2427 new Value(upper), | 2468 new Value(upper), |
2428 call->deopt_id()); | 2469 call->deopt_id()); |
2429 ReplaceCall(call, clamp); | 2470 ReplaceCall(call, clamp); |
2430 return true; | 2471 return true; |
2431 } | 2472 } |
| 2473 case MethodRecognizer::kFloat32x4ShuffleMix: |
2432 case MethodRecognizer::kFloat32x4Shuffle: { | 2474 case MethodRecognizer::kFloat32x4Shuffle: { |
2433 return InlineFloat32x4Getter(call, recognized_kind); | 2475 return InlineFloat32x4Getter(call, recognized_kind); |
2434 } | 2476 } |
2435 default: | 2477 default: |
2436 return false; | 2478 return false; |
2437 } | 2479 } |
2438 } | 2480 } |
2439 | 2481 |
2440 | 2482 |
2441 bool FlowGraphOptimizer::TryInlineUint32x4Method( | 2483 bool FlowGraphOptimizer::TryInlineUint32x4Method( |
2442 InstanceCallInstr* call, | 2484 InstanceCallInstr* call, |
2443 MethodRecognizer::Kind recognized_kind) { | 2485 MethodRecognizer::Kind recognized_kind) { |
2444 if (!ShouldInlineSimd()) { | 2486 if (!ShouldInlineSimd()) { |
2445 return false; | 2487 return false; |
2446 } | 2488 } |
2447 ASSERT(call->HasICData()); | 2489 ASSERT(call->HasICData()); |
2448 switch (recognized_kind) { | 2490 switch (recognized_kind) { |
| 2491 case MethodRecognizer::kUint32x4ShuffleMix: |
| 2492 case MethodRecognizer::kUint32x4Shuffle: |
2449 case MethodRecognizer::kUint32x4GetFlagX: | 2493 case MethodRecognizer::kUint32x4GetFlagX: |
2450 case MethodRecognizer::kUint32x4GetFlagY: | 2494 case MethodRecognizer::kUint32x4GetFlagY: |
2451 case MethodRecognizer::kUint32x4GetFlagZ: | 2495 case MethodRecognizer::kUint32x4GetFlagZ: |
2452 case MethodRecognizer::kUint32x4GetFlagW: | 2496 case MethodRecognizer::kUint32x4GetFlagW: |
2453 case MethodRecognizer::kUint32x4GetSignMask: | 2497 case MethodRecognizer::kUint32x4GetSignMask: |
2454 ASSERT(call->ic_data()->HasReceiverClassId(kUint32x4Cid)); | 2498 ASSERT(call->ic_data()->HasReceiverClassId(kUint32x4Cid)); |
2455 ASSERT(call->ic_data()->HasOneTarget()); | 2499 ASSERT(call->ic_data()->HasOneTarget()); |
2456 return InlineUint32x4Getter(call, recognized_kind); | 2500 return InlineUint32x4Getter(call, recognized_kind); |
2457 | 2501 |
2458 case MethodRecognizer::kUint32x4Select: { | 2502 case MethodRecognizer::kUint32x4Select: { |
(...skipping 4419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6878 } | 6922 } |
6879 } | 6923 } |
6880 | 6924 |
6881 | 6925 |
6882 void ConstantPropagator::VisitFloat32x4Constructor( | 6926 void ConstantPropagator::VisitFloat32x4Constructor( |
6883 Float32x4ConstructorInstr* instr) { | 6927 Float32x4ConstructorInstr* instr) { |
6884 SetValue(instr, non_constant_); | 6928 SetValue(instr, non_constant_); |
6885 } | 6929 } |
6886 | 6930 |
6887 | 6931 |
6888 void ConstantPropagator::VisitFloat32x4Shuffle(Float32x4ShuffleInstr* instr) { | 6932 void ConstantPropagator::VisitSimd32x4Shuffle(Simd32x4ShuffleInstr* instr) { |
6889 SetValue(instr, non_constant_); | 6933 SetValue(instr, non_constant_); |
6890 } | 6934 } |
6891 | 6935 |
| 6936 |
| 6937 void ConstantPropagator::VisitSimd32x4ShuffleMix( |
| 6938 Simd32x4ShuffleMixInstr* instr) { |
| 6939 SetValue(instr, non_constant_); |
| 6940 } |
| 6941 |
6892 | 6942 |
6893 void ConstantPropagator::VisitSimd32x4GetSignMask( | 6943 void ConstantPropagator::VisitSimd32x4GetSignMask( |
6894 Simd32x4GetSignMaskInstr* instr) { | 6944 Simd32x4GetSignMaskInstr* instr) { |
6895 SetValue(instr, non_constant_); | 6945 SetValue(instr, non_constant_); |
6896 } | 6946 } |
6897 | 6947 |
6898 | 6948 |
6899 void ConstantPropagator::VisitFloat32x4Zero(Float32x4ZeroInstr* instr) { | 6949 void ConstantPropagator::VisitFloat32x4Zero(Float32x4ZeroInstr* instr) { |
6900 SetValue(instr, non_constant_); | 6950 SetValue(instr, non_constant_); |
6901 } | 6951 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6941 SetValue(instr, non_constant_); | 6991 SetValue(instr, non_constant_); |
6942 } | 6992 } |
6943 | 6993 |
6944 | 6994 |
6945 void ConstantPropagator::VisitFloat32x4ToUint32x4( | 6995 void ConstantPropagator::VisitFloat32x4ToUint32x4( |
6946 Float32x4ToUint32x4Instr* instr) { | 6996 Float32x4ToUint32x4Instr* instr) { |
6947 SetValue(instr, non_constant_); | 6997 SetValue(instr, non_constant_); |
6948 } | 6998 } |
6949 | 6999 |
6950 | 7000 |
6951 void ConstantPropagator::VisitFloat32x4TwoArgShuffle( | |
6952 Float32x4TwoArgShuffleInstr* instr) { | |
6953 SetValue(instr, non_constant_); | |
6954 } | |
6955 | |
6956 | |
6957 void ConstantPropagator::VisitUint32x4BoolConstructor( | 7001 void ConstantPropagator::VisitUint32x4BoolConstructor( |
6958 Uint32x4BoolConstructorInstr* instr) { | 7002 Uint32x4BoolConstructorInstr* instr) { |
6959 SetValue(instr, non_constant_); | 7003 SetValue(instr, non_constant_); |
6960 } | 7004 } |
6961 | 7005 |
6962 | 7006 |
6963 void ConstantPropagator::VisitUint32x4GetFlag(Uint32x4GetFlagInstr* instr) { | 7007 void ConstantPropagator::VisitUint32x4GetFlag(Uint32x4GetFlagInstr* instr) { |
6964 SetValue(instr, non_constant_); | 7008 SetValue(instr, non_constant_); |
6965 } | 7009 } |
6966 | 7010 |
(...skipping 956 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7923 } | 7967 } |
7924 | 7968 |
7925 // Insert materializations at environment uses. | 7969 // Insert materializations at environment uses. |
7926 for (intptr_t i = 0; i < exits.length(); i++) { | 7970 for (intptr_t i = 0; i < exits.length(); i++) { |
7927 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); | 7971 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); |
7928 } | 7972 } |
7929 } | 7973 } |
7930 | 7974 |
7931 | 7975 |
7932 } // namespace dart | 7976 } // namespace dart |
OLD | NEW |