Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(77)

Side by Side Diff: runtime/vm/flow_graph_optimizer.cc

Issue 51373004: SIMD shuffle API changes (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698