Chromium Code Reviews| 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 |