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 1665 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1676 if (!ShouldInlineSimd()) { | 1676 if (!ShouldInlineSimd()) { |
1677 return false; | 1677 return false; |
1678 } | 1678 } |
1679 AddCheckClass(call->ArgumentAt(0), | 1679 AddCheckClass(call->ArgumentAt(0), |
1680 ICData::ZoneHandle( | 1680 ICData::ZoneHandle( |
1681 call->ic_data()->AsUnaryClassChecksForArgNr(0)), | 1681 call->ic_data()->AsUnaryClassChecksForArgNr(0)), |
1682 call->deopt_id(), | 1682 call->deopt_id(), |
1683 call->env(), | 1683 call->env(), |
1684 call); | 1684 call); |
1685 intptr_t mask = 0; | 1685 intptr_t mask = 0; |
1686 if (getter == MethodRecognizer::kFloat32x4Shuffle) { | 1686 if ((getter == MethodRecognizer::kFloat32x4Shuffle) || |
| 1687 (getter == MethodRecognizer::kFloat32x4ShuffleMix)) { |
1687 // Extract shuffle mask. | 1688 // Extract shuffle mask. |
1688 ASSERT(call->ArgumentCount() == 2); | 1689 Definition* mask_definition = NULL; |
1689 Definition* mask_definition = call->ArgumentAt(1); | 1690 if (getter == MethodRecognizer::kFloat32x4Shuffle) { |
| 1691 ASSERT(call->ArgumentCount() == 2); |
| 1692 mask_definition = call->ArgumentAt(1); |
| 1693 } else { |
| 1694 ASSERT(getter == MethodRecognizer::kFloat32x4ShuffleMix); |
| 1695 ASSERT(call->ArgumentCount() == 3); |
| 1696 mask_definition = call->ArgumentAt(2); |
| 1697 } |
1690 if (!mask_definition->IsConstant()) { | 1698 if (!mask_definition->IsConstant()) { |
1691 // Not a constant. | 1699 // Not a constant. |
1692 return false; | 1700 return false; |
1693 } | 1701 } |
1694 ASSERT(mask_definition->IsConstant()); | 1702 ASSERT(mask_definition->IsConstant()); |
1695 ConstantInstr* constant_instruction = mask_definition->AsConstant(); | 1703 ConstantInstr* constant_instruction = mask_definition->AsConstant(); |
1696 const Object& constant_mask = constant_instruction->value(); | 1704 const Object& constant_mask = constant_instruction->value(); |
1697 if (!constant_mask.IsSmi()) { | 1705 if (!constant_mask.IsSmi()) { |
1698 // Not a smi. | 1706 // Not a smi. |
1699 return false; | 1707 return false; |
1700 } | 1708 } |
1701 ASSERT(constant_mask.IsSmi()); | 1709 ASSERT(constant_mask.IsSmi()); |
1702 mask = Smi::Cast(constant_mask).Value(); | 1710 mask = Smi::Cast(constant_mask).Value(); |
1703 if (mask < 0 || mask > 255) { | 1711 if (mask < 0 || mask > 255) { |
1704 // Not a valid mask. | 1712 // Not a valid mask. |
1705 return false; | 1713 return false; |
1706 } | 1714 } |
1707 } | 1715 } |
1708 if (getter == MethodRecognizer::kFloat32x4GetSignMask) { | 1716 if (getter == MethodRecognizer::kFloat32x4GetSignMask) { |
1709 Simd32x4GetSignMaskInstr* instr = new Simd32x4GetSignMaskInstr( | 1717 Simd32x4GetSignMaskInstr* instr = new Simd32x4GetSignMaskInstr( |
1710 getter, | 1718 getter, |
1711 new Value(call->ArgumentAt(0)), | 1719 new Value(call->ArgumentAt(0)), |
1712 call->deopt_id()); | 1720 call->deopt_id()); |
1713 ReplaceCall(call, instr); | 1721 ReplaceCall(call, instr); |
1714 return true; | 1722 return true; |
| 1723 } else if (getter == MethodRecognizer::kFloat32x4ShuffleMix) { |
| 1724 Simd32x4ShuffleMixInstr* instr = new Simd32x4ShuffleMixInstr( |
| 1725 getter, |
| 1726 new Value(call->ArgumentAt(0)), |
| 1727 new Value(call->ArgumentAt(1)), |
| 1728 mask, |
| 1729 call->deopt_id()); |
| 1730 ReplaceCall(call, instr); |
| 1731 return true; |
1715 } else { | 1732 } else { |
1716 ASSERT((getter == MethodRecognizer::kFloat32x4Shuffle) || | 1733 ASSERT((getter == MethodRecognizer::kFloat32x4Shuffle) || |
1717 (getter == MethodRecognizer::kFloat32x4ShuffleX) || | 1734 (getter == MethodRecognizer::kFloat32x4ShuffleX) || |
1718 (getter == MethodRecognizer::kFloat32x4ShuffleY) || | 1735 (getter == MethodRecognizer::kFloat32x4ShuffleY) || |
1719 (getter == MethodRecognizer::kFloat32x4ShuffleZ) || | 1736 (getter == MethodRecognizer::kFloat32x4ShuffleZ) || |
1720 (getter == MethodRecognizer::kFloat32x4ShuffleW)); | 1737 (getter == MethodRecognizer::kFloat32x4ShuffleW)); |
1721 Float32x4ShuffleInstr* instr = new Float32x4ShuffleInstr( | 1738 Simd32x4ShuffleInstr* instr = new Simd32x4ShuffleInstr( |
1722 getter, | 1739 getter, |
1723 new Value(call->ArgumentAt(0)), | 1740 new Value(call->ArgumentAt(0)), |
1724 mask, | 1741 mask, |
1725 call->deopt_id()); | 1742 call->deopt_id()); |
1726 ReplaceCall(call, instr); | 1743 ReplaceCall(call, instr); |
1727 return true; | 1744 return true; |
1728 } | 1745 } |
1729 UNREACHABLE(); | 1746 UNREACHABLE(); |
1730 return false; | 1747 return false; |
1731 } | 1748 } |
1732 | 1749 |
1733 | 1750 |
1734 bool FlowGraphOptimizer::InlineUint32x4Getter(InstanceCallInstr* call, | 1751 bool FlowGraphOptimizer::InlineUint32x4Getter(InstanceCallInstr* call, |
1735 MethodRecognizer::Kind getter) { | 1752 MethodRecognizer::Kind getter) { |
1736 if (!ShouldInlineSimd()) { | 1753 if (!ShouldInlineSimd()) { |
1737 return false; | 1754 return false; |
1738 } | 1755 } |
1739 AddCheckClass(call->ArgumentAt(0), | 1756 AddCheckClass(call->ArgumentAt(0), |
1740 ICData::ZoneHandle( | 1757 ICData::ZoneHandle( |
1741 call->ic_data()->AsUnaryClassChecksForArgNr(0)), | 1758 call->ic_data()->AsUnaryClassChecksForArgNr(0)), |
1742 call->deopt_id(), | 1759 call->deopt_id(), |
1743 call->env(), | 1760 call->env(), |
1744 call); | 1761 call); |
| 1762 intptr_t mask = 0; |
| 1763 if ((getter == MethodRecognizer::kUint32x4Shuffle) || |
| 1764 (getter == MethodRecognizer::kUint32x4ShuffleMix)) { |
| 1765 // Extract shuffle mask. |
| 1766 Definition* mask_definition = NULL; |
| 1767 if (getter == MethodRecognizer::kUint32x4Shuffle) { |
| 1768 ASSERT(call->ArgumentCount() == 2); |
| 1769 mask_definition = call->ArgumentAt(1); |
| 1770 } else { |
| 1771 ASSERT(getter == MethodRecognizer::kUint32x4ShuffleMix); |
| 1772 ASSERT(call->ArgumentCount() == 3); |
| 1773 mask_definition = call->ArgumentAt(2); |
| 1774 } |
| 1775 if (!mask_definition->IsConstant()) { |
| 1776 // Not a constant. |
| 1777 return false; |
| 1778 } |
| 1779 ASSERT(mask_definition->IsConstant()); |
| 1780 ConstantInstr* constant_instruction = mask_definition->AsConstant(); |
| 1781 const Object& constant_mask = constant_instruction->value(); |
| 1782 if (!constant_mask.IsSmi()) { |
| 1783 // Not a smi. |
| 1784 return false; |
| 1785 } |
| 1786 ASSERT(constant_mask.IsSmi()); |
| 1787 mask = Smi::Cast(constant_mask).Value(); |
| 1788 if (mask < 0 || mask > 255) { |
| 1789 // Not a valid mask. |
| 1790 return false; |
| 1791 } |
| 1792 } |
1745 if (getter == MethodRecognizer::kUint32x4GetSignMask) { | 1793 if (getter == MethodRecognizer::kUint32x4GetSignMask) { |
1746 Simd32x4GetSignMaskInstr* instr = new Simd32x4GetSignMaskInstr( | 1794 Simd32x4GetSignMaskInstr* instr = new Simd32x4GetSignMaskInstr( |
1747 getter, | 1795 getter, |
1748 new Value(call->ArgumentAt(0)), | 1796 new Value(call->ArgumentAt(0)), |
1749 call->deopt_id()); | 1797 call->deopt_id()); |
1750 ReplaceCall(call, instr); | 1798 ReplaceCall(call, instr); |
1751 return true; | 1799 return true; |
| 1800 } else if (getter == MethodRecognizer::kUint32x4ShuffleMix) { |
| 1801 Simd32x4ShuffleMixInstr* instr = new Simd32x4ShuffleMixInstr( |
| 1802 getter, |
| 1803 new Value(call->ArgumentAt(0)), |
| 1804 new Value(call->ArgumentAt(1)), |
| 1805 mask, |
| 1806 call->deopt_id()); |
| 1807 ReplaceCall(call, instr); |
| 1808 return true; |
| 1809 } else if (getter == MethodRecognizer::kUint32x4Shuffle) { |
| 1810 Simd32x4ShuffleInstr* instr = new Simd32x4ShuffleInstr( |
| 1811 getter, |
| 1812 new Value(call->ArgumentAt(0)), |
| 1813 mask, |
| 1814 call->deopt_id()); |
| 1815 ReplaceCall(call, instr); |
| 1816 return true; |
1752 } else { | 1817 } else { |
1753 Uint32x4GetFlagInstr* instr = new Uint32x4GetFlagInstr( | 1818 Uint32x4GetFlagInstr* instr = new Uint32x4GetFlagInstr( |
1754 getter, | 1819 getter, |
1755 new Value(call->ArgumentAt(0)), | 1820 new Value(call->ArgumentAt(0)), |
1756 call->deopt_id()); | 1821 call->deopt_id()); |
1757 ReplaceCall(call, instr); | 1822 ReplaceCall(call, instr); |
1758 return true; | 1823 return true; |
1759 } | 1824 } |
1760 } | 1825 } |
1761 | 1826 |
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2299 call->ic_data()->AsUnaryClassChecksForArgNr(0)), | 2364 call->ic_data()->AsUnaryClassChecksForArgNr(0)), |
2300 call->deopt_id(), | 2365 call->deopt_id(), |
2301 call->env(), | 2366 call->env(), |
2302 call); | 2367 call); |
2303 Float32x4MinMaxInstr* minmax = | 2368 Float32x4MinMaxInstr* minmax = |
2304 new Float32x4MinMaxInstr(recognized_kind, new Value(left), | 2369 new Float32x4MinMaxInstr(recognized_kind, new Value(left), |
2305 new Value(right), call->deopt_id()); | 2370 new Value(right), call->deopt_id()); |
2306 ReplaceCall(call, minmax); | 2371 ReplaceCall(call, minmax); |
2307 return true; | 2372 return true; |
2308 } | 2373 } |
2309 case MethodRecognizer::kFloat32x4WithZWInXY: | |
2310 case MethodRecognizer::kFloat32x4InterleaveXY: | |
2311 case MethodRecognizer::kFloat32x4InterleaveZW: | |
2312 case MethodRecognizer::kFloat32x4InterleaveXYPairs: | |
2313 case MethodRecognizer::kFloat32x4InterleaveZWPairs: { | |
2314 Definition* left = call->ArgumentAt(0); | |
2315 Definition* right = call->ArgumentAt(1); | |
2316 // Type check left. | |
2317 AddCheckClass(left, | |
2318 ICData::ZoneHandle( | |
2319 call->ic_data()->AsUnaryClassChecksForArgNr(0)), | |
2320 call->deopt_id(), | |
2321 call->env(), | |
2322 call); | |
2323 Float32x4TwoArgShuffleInstr* two_arg_shuffle = | |
2324 new Float32x4TwoArgShuffleInstr(recognized_kind, new Value(left), | |
2325 new Value(right), call->deopt_id()); | |
2326 ReplaceCall(call, two_arg_shuffle); | |
2327 return true; | |
2328 } | |
2329 case MethodRecognizer::kFloat32x4Scale: { | 2374 case MethodRecognizer::kFloat32x4Scale: { |
2330 Definition* left = call->ArgumentAt(0); | 2375 Definition* left = call->ArgumentAt(0); |
2331 Definition* right = call->ArgumentAt(1); | 2376 Definition* right = call->ArgumentAt(1); |
2332 // Type check left. | 2377 // Type check left. |
2333 AddCheckClass(left, | 2378 AddCheckClass(left, |
2334 ICData::ZoneHandle( | 2379 ICData::ZoneHandle( |
2335 call->ic_data()->AsUnaryClassChecksForArgNr(0)), | 2380 call->ic_data()->AsUnaryClassChecksForArgNr(0)), |
2336 call->deopt_id(), | 2381 call->deopt_id(), |
2337 call->env(), | 2382 call->env(), |
2338 call); | 2383 call); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2408 call->deopt_id(), | 2453 call->deopt_id(), |
2409 call->env(), | 2454 call->env(), |
2410 call); | 2455 call); |
2411 Float32x4ClampInstr* clamp = new Float32x4ClampInstr(new Value(left), | 2456 Float32x4ClampInstr* clamp = new Float32x4ClampInstr(new Value(left), |
2412 new Value(lower), | 2457 new Value(lower), |
2413 new Value(upper), | 2458 new Value(upper), |
2414 call->deopt_id()); | 2459 call->deopt_id()); |
2415 ReplaceCall(call, clamp); | 2460 ReplaceCall(call, clamp); |
2416 return true; | 2461 return true; |
2417 } | 2462 } |
| 2463 case MethodRecognizer::kFloat32x4ShuffleMix: |
2418 case MethodRecognizer::kFloat32x4Shuffle: { | 2464 case MethodRecognizer::kFloat32x4Shuffle: { |
2419 return InlineFloat32x4Getter(call, recognized_kind); | 2465 return InlineFloat32x4Getter(call, recognized_kind); |
2420 } | 2466 } |
2421 default: | 2467 default: |
2422 return false; | 2468 return false; |
2423 } | 2469 } |
2424 } | 2470 } |
2425 | 2471 |
2426 | 2472 |
2427 bool FlowGraphOptimizer::TryInlineUint32x4Method( | 2473 bool FlowGraphOptimizer::TryInlineUint32x4Method( |
2428 InstanceCallInstr* call, | 2474 InstanceCallInstr* call, |
2429 MethodRecognizer::Kind recognized_kind) { | 2475 MethodRecognizer::Kind recognized_kind) { |
2430 if (!ShouldInlineSimd()) { | 2476 if (!ShouldInlineSimd()) { |
2431 return false; | 2477 return false; |
2432 } | 2478 } |
2433 ASSERT(call->HasICData()); | 2479 ASSERT(call->HasICData()); |
2434 switch (recognized_kind) { | 2480 switch (recognized_kind) { |
| 2481 case MethodRecognizer::kUint32x4ShuffleMix: |
| 2482 case MethodRecognizer::kUint32x4Shuffle: |
2435 case MethodRecognizer::kUint32x4GetFlagX: | 2483 case MethodRecognizer::kUint32x4GetFlagX: |
2436 case MethodRecognizer::kUint32x4GetFlagY: | 2484 case MethodRecognizer::kUint32x4GetFlagY: |
2437 case MethodRecognizer::kUint32x4GetFlagZ: | 2485 case MethodRecognizer::kUint32x4GetFlagZ: |
2438 case MethodRecognizer::kUint32x4GetFlagW: | 2486 case MethodRecognizer::kUint32x4GetFlagW: |
2439 case MethodRecognizer::kUint32x4GetSignMask: | 2487 case MethodRecognizer::kUint32x4GetSignMask: |
2440 ASSERT(call->ic_data()->HasReceiverClassId(kUint32x4Cid)); | 2488 ASSERT(call->ic_data()->HasReceiverClassId(kUint32x4Cid)); |
2441 ASSERT(call->ic_data()->HasOneTarget()); | 2489 ASSERT(call->ic_data()->HasOneTarget()); |
2442 return InlineUint32x4Getter(call, recognized_kind); | 2490 return InlineUint32x4Getter(call, recognized_kind); |
2443 | 2491 |
2444 case MethodRecognizer::kUint32x4Select: { | 2492 case MethodRecognizer::kUint32x4Select: { |
(...skipping 4382 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6827 } | 6875 } |
6828 } | 6876 } |
6829 | 6877 |
6830 | 6878 |
6831 void ConstantPropagator::VisitFloat32x4Constructor( | 6879 void ConstantPropagator::VisitFloat32x4Constructor( |
6832 Float32x4ConstructorInstr* instr) { | 6880 Float32x4ConstructorInstr* instr) { |
6833 SetValue(instr, non_constant_); | 6881 SetValue(instr, non_constant_); |
6834 } | 6882 } |
6835 | 6883 |
6836 | 6884 |
6837 void ConstantPropagator::VisitFloat32x4Shuffle(Float32x4ShuffleInstr* instr) { | 6885 void ConstantPropagator::VisitSimd32x4Shuffle(Simd32x4ShuffleInstr* instr) { |
6838 SetValue(instr, non_constant_); | 6886 SetValue(instr, non_constant_); |
6839 } | 6887 } |
6840 | 6888 |
| 6889 |
| 6890 void ConstantPropagator::VisitSimd32x4ShuffleMix( |
| 6891 Simd32x4ShuffleMixInstr* instr) { |
| 6892 SetValue(instr, non_constant_); |
| 6893 } |
| 6894 |
6841 | 6895 |
6842 void ConstantPropagator::VisitSimd32x4GetSignMask( | 6896 void ConstantPropagator::VisitSimd32x4GetSignMask( |
6843 Simd32x4GetSignMaskInstr* instr) { | 6897 Simd32x4GetSignMaskInstr* instr) { |
6844 SetValue(instr, non_constant_); | 6898 SetValue(instr, non_constant_); |
6845 } | 6899 } |
6846 | 6900 |
6847 | 6901 |
6848 void ConstantPropagator::VisitFloat32x4Zero(Float32x4ZeroInstr* instr) { | 6902 void ConstantPropagator::VisitFloat32x4Zero(Float32x4ZeroInstr* instr) { |
6849 SetValue(instr, non_constant_); | 6903 SetValue(instr, non_constant_); |
6850 } | 6904 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6890 SetValue(instr, non_constant_); | 6944 SetValue(instr, non_constant_); |
6891 } | 6945 } |
6892 | 6946 |
6893 | 6947 |
6894 void ConstantPropagator::VisitFloat32x4ToUint32x4( | 6948 void ConstantPropagator::VisitFloat32x4ToUint32x4( |
6895 Float32x4ToUint32x4Instr* instr) { | 6949 Float32x4ToUint32x4Instr* instr) { |
6896 SetValue(instr, non_constant_); | 6950 SetValue(instr, non_constant_); |
6897 } | 6951 } |
6898 | 6952 |
6899 | 6953 |
6900 void ConstantPropagator::VisitFloat32x4TwoArgShuffle( | |
6901 Float32x4TwoArgShuffleInstr* instr) { | |
6902 SetValue(instr, non_constant_); | |
6903 } | |
6904 | |
6905 | |
6906 void ConstantPropagator::VisitUint32x4BoolConstructor( | 6954 void ConstantPropagator::VisitUint32x4BoolConstructor( |
6907 Uint32x4BoolConstructorInstr* instr) { | 6955 Uint32x4BoolConstructorInstr* instr) { |
6908 SetValue(instr, non_constant_); | 6956 SetValue(instr, non_constant_); |
6909 } | 6957 } |
6910 | 6958 |
6911 | 6959 |
6912 void ConstantPropagator::VisitUint32x4GetFlag(Uint32x4GetFlagInstr* instr) { | 6960 void ConstantPropagator::VisitUint32x4GetFlag(Uint32x4GetFlagInstr* instr) { |
6913 SetValue(instr, non_constant_); | 6961 SetValue(instr, non_constant_); |
6914 } | 6962 } |
6915 | 6963 |
(...skipping 956 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7872 } | 7920 } |
7873 | 7921 |
7874 // Insert materializations at environment uses. | 7922 // Insert materializations at environment uses. |
7875 for (intptr_t i = 0; i < exits.length(); i++) { | 7923 for (intptr_t i = 0; i < exits.length(); i++) { |
7876 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); | 7924 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); |
7877 } | 7925 } |
7878 } | 7926 } |
7879 | 7927 |
7880 | 7928 |
7881 } // namespace dart | 7929 } // namespace dart |
OLD | NEW |