| 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 |