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