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