| 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 794 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 805 return kTypedDataInt32ArrayCid; | 805 return kTypedDataInt32ArrayCid; |
| 806 | 806 |
| 807 case MethodRecognizer::kUint32ArrayGetIndexed: | 807 case MethodRecognizer::kUint32ArrayGetIndexed: |
| 808 case MethodRecognizer::kUint32ArraySetIndexed: | 808 case MethodRecognizer::kUint32ArraySetIndexed: |
| 809 return kTypedDataUint32ArrayCid; | 809 return kTypedDataUint32ArrayCid; |
| 810 | 810 |
| 811 case MethodRecognizer::kFloat32x4ArrayGetIndexed: | 811 case MethodRecognizer::kFloat32x4ArrayGetIndexed: |
| 812 case MethodRecognizer::kFloat32x4ArraySetIndexed: | 812 case MethodRecognizer::kFloat32x4ArraySetIndexed: |
| 813 return kTypedDataFloat32x4ArrayCid; | 813 return kTypedDataFloat32x4ArrayCid; |
| 814 | 814 |
| 815 case MethodRecognizer::kUint32x4ArrayGetIndexed: |
| 816 case MethodRecognizer::kUint32x4ArraySetIndexed: |
| 817 return kTypedDataUint32x4ArrayCid; |
| 818 |
| 815 default: | 819 default: |
| 816 break; | 820 break; |
| 817 } | 821 } |
| 818 return kIllegalCid; | 822 return kIllegalCid; |
| 819 } | 823 } |
| 820 | 824 |
| 821 | 825 |
| 822 bool FlowGraphOptimizer::TryReplaceWithStoreIndexed(InstanceCallInstr* call) { | 826 bool FlowGraphOptimizer::TryReplaceWithStoreIndexed(InstanceCallInstr* call) { |
| 823 // Check for monomorphic IC data. | 827 // Check for monomorphic IC data. |
| 824 if (!call->HasICData()) return false; | 828 if (!call->HasICData()) return false; |
| (...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1111 ic_data, entry, last); | 1115 ic_data, entry, last); |
| 1112 case MethodRecognizer::kByteArrayBaseGetFloat64: | 1116 case MethodRecognizer::kByteArrayBaseGetFloat64: |
| 1113 return InlineByteArrayViewLoad(call, receiver, receiver_cid, | 1117 return InlineByteArrayViewLoad(call, receiver, receiver_cid, |
| 1114 kTypedDataFloat64ArrayCid, | 1118 kTypedDataFloat64ArrayCid, |
| 1115 ic_data, entry, last); | 1119 ic_data, entry, last); |
| 1116 case MethodRecognizer::kByteArrayBaseGetFloat32x4: | 1120 case MethodRecognizer::kByteArrayBaseGetFloat32x4: |
| 1117 if (!ShouldInlineSimd()) return false; | 1121 if (!ShouldInlineSimd()) return false; |
| 1118 return InlineByteArrayViewLoad(call, receiver, receiver_cid, | 1122 return InlineByteArrayViewLoad(call, receiver, receiver_cid, |
| 1119 kTypedDataFloat32x4ArrayCid, | 1123 kTypedDataFloat32x4ArrayCid, |
| 1120 ic_data, entry, last); | 1124 ic_data, entry, last); |
| 1125 case MethodRecognizer::kByteArrayBaseGetUint32x4: |
| 1126 if (!ShouldInlineSimd()) return false; |
| 1127 return InlineByteArrayViewLoad(call, receiver, receiver_cid, |
| 1128 kTypedDataUint32x4ArrayCid, |
| 1129 ic_data, entry, last); |
| 1121 default: | 1130 default: |
| 1122 return false; | 1131 return false; |
| 1123 } | 1132 } |
| 1124 } | 1133 } |
| 1125 | 1134 |
| 1126 | 1135 |
| 1127 intptr_t FlowGraphOptimizer::PrepareInlineIndexedOp(Instruction* call, | 1136 intptr_t FlowGraphOptimizer::PrepareInlineIndexedOp(Instruction* call, |
| 1128 intptr_t array_cid, | 1137 intptr_t array_cid, |
| 1129 Definition** array, | 1138 Definition** array, |
| 1130 Definition* index, | 1139 Definition* index, |
| (...skipping 779 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1910 case kExternalTypedDataUint8ArrayCid: | 1919 case kExternalTypedDataUint8ArrayCid: |
| 1911 case kTypedDataUint8ClampedArrayCid: | 1920 case kTypedDataUint8ClampedArrayCid: |
| 1912 case kExternalTypedDataUint8ClampedArrayCid: | 1921 case kExternalTypedDataUint8ClampedArrayCid: |
| 1913 case kTypedDataInt16ArrayCid: | 1922 case kTypedDataInt16ArrayCid: |
| 1914 case kTypedDataUint16ArrayCid: | 1923 case kTypedDataUint16ArrayCid: |
| 1915 case kTypedDataInt32ArrayCid: | 1924 case kTypedDataInt32ArrayCid: |
| 1916 case kTypedDataUint32ArrayCid: | 1925 case kTypedDataUint32ArrayCid: |
| 1917 case kTypedDataFloat32ArrayCid: | 1926 case kTypedDataFloat32ArrayCid: |
| 1918 case kTypedDataFloat64ArrayCid: | 1927 case kTypedDataFloat64ArrayCid: |
| 1919 case kTypedDataFloat32x4ArrayCid: | 1928 case kTypedDataFloat32x4ArrayCid: |
| 1929 case kTypedDataUint32x4ArrayCid: |
| 1920 return true; | 1930 return true; |
| 1921 default: | 1931 default: |
| 1922 return false; | 1932 return false; |
| 1923 } | 1933 } |
| 1924 } | 1934 } |
| 1925 | 1935 |
| 1926 | 1936 |
| 1927 // Inline only simple, frequently called core library methods. | 1937 // Inline only simple, frequently called core library methods. |
| 1928 bool FlowGraphOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) { | 1938 bool FlowGraphOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) { |
| 1929 ASSERT(call->HasICData()); | 1939 ASSERT(call->HasICData()); |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2083 case MethodRecognizer::kByteArrayBaseGetInt32: | 2093 case MethodRecognizer::kByteArrayBaseGetInt32: |
| 2084 return BuildByteArrayViewLoad(call, kTypedDataInt32ArrayCid); | 2094 return BuildByteArrayViewLoad(call, kTypedDataInt32ArrayCid); |
| 2085 case MethodRecognizer::kByteArrayBaseGetUint32: | 2095 case MethodRecognizer::kByteArrayBaseGetUint32: |
| 2086 return BuildByteArrayViewLoad(call, kTypedDataUint32ArrayCid); | 2096 return BuildByteArrayViewLoad(call, kTypedDataUint32ArrayCid); |
| 2087 case MethodRecognizer::kByteArrayBaseGetFloat32: | 2097 case MethodRecognizer::kByteArrayBaseGetFloat32: |
| 2088 return BuildByteArrayViewLoad(call, kTypedDataFloat32ArrayCid); | 2098 return BuildByteArrayViewLoad(call, kTypedDataFloat32ArrayCid); |
| 2089 case MethodRecognizer::kByteArrayBaseGetFloat64: | 2099 case MethodRecognizer::kByteArrayBaseGetFloat64: |
| 2090 return BuildByteArrayViewLoad(call, kTypedDataFloat64ArrayCid); | 2100 return BuildByteArrayViewLoad(call, kTypedDataFloat64ArrayCid); |
| 2091 case MethodRecognizer::kByteArrayBaseGetFloat32x4: | 2101 case MethodRecognizer::kByteArrayBaseGetFloat32x4: |
| 2092 return BuildByteArrayViewLoad(call, kTypedDataFloat32x4ArrayCid); | 2102 return BuildByteArrayViewLoad(call, kTypedDataFloat32x4ArrayCid); |
| 2103 case MethodRecognizer::kByteArrayBaseGetUint32x4: |
| 2104 return BuildByteArrayViewLoad(call, kTypedDataUint32x4ArrayCid); |
| 2093 | 2105 |
| 2094 // ByteArray setters. | 2106 // ByteArray setters. |
| 2095 case MethodRecognizer::kByteArrayBaseSetInt8: | 2107 case MethodRecognizer::kByteArrayBaseSetInt8: |
| 2096 return BuildByteArrayViewStore(call, kTypedDataInt8ArrayCid); | 2108 return BuildByteArrayViewStore(call, kTypedDataInt8ArrayCid); |
| 2097 case MethodRecognizer::kByteArrayBaseSetUint8: | 2109 case MethodRecognizer::kByteArrayBaseSetUint8: |
| 2098 return BuildByteArrayViewStore(call, kTypedDataUint8ArrayCid); | 2110 return BuildByteArrayViewStore(call, kTypedDataUint8ArrayCid); |
| 2099 case MethodRecognizer::kByteArrayBaseSetInt16: | 2111 case MethodRecognizer::kByteArrayBaseSetInt16: |
| 2100 return BuildByteArrayViewStore(call, kTypedDataInt16ArrayCid); | 2112 return BuildByteArrayViewStore(call, kTypedDataInt16ArrayCid); |
| 2101 case MethodRecognizer::kByteArrayBaseSetUint16: | 2113 case MethodRecognizer::kByteArrayBaseSetUint16: |
| 2102 return BuildByteArrayViewStore(call, kTypedDataUint16ArrayCid); | 2114 return BuildByteArrayViewStore(call, kTypedDataUint16ArrayCid); |
| 2103 case MethodRecognizer::kByteArrayBaseSetInt32: | 2115 case MethodRecognizer::kByteArrayBaseSetInt32: |
| 2104 return BuildByteArrayViewStore(call, kTypedDataInt32ArrayCid); | 2116 return BuildByteArrayViewStore(call, kTypedDataInt32ArrayCid); |
| 2105 case MethodRecognizer::kByteArrayBaseSetUint32: | 2117 case MethodRecognizer::kByteArrayBaseSetUint32: |
| 2106 return BuildByteArrayViewStore(call, kTypedDataUint32ArrayCid); | 2118 return BuildByteArrayViewStore(call, kTypedDataUint32ArrayCid); |
| 2107 case MethodRecognizer::kByteArrayBaseSetFloat32: | 2119 case MethodRecognizer::kByteArrayBaseSetFloat32: |
| 2108 return BuildByteArrayViewStore(call, kTypedDataFloat32ArrayCid); | 2120 return BuildByteArrayViewStore(call, kTypedDataFloat32ArrayCid); |
| 2109 case MethodRecognizer::kByteArrayBaseSetFloat64: | 2121 case MethodRecognizer::kByteArrayBaseSetFloat64: |
| 2110 return BuildByteArrayViewStore(call, kTypedDataFloat64ArrayCid); | 2122 return BuildByteArrayViewStore(call, kTypedDataFloat64ArrayCid); |
| 2111 case MethodRecognizer::kByteArrayBaseSetFloat32x4: | 2123 case MethodRecognizer::kByteArrayBaseSetFloat32x4: |
| 2112 return BuildByteArrayViewStore(call, kTypedDataFloat32x4ArrayCid); | 2124 return BuildByteArrayViewStore(call, kTypedDataFloat32x4ArrayCid); |
| 2125 case MethodRecognizer::kByteArrayBaseSetUint32x4: |
| 2126 return BuildByteArrayViewStore(call, kTypedDataUint32x4ArrayCid); |
| 2113 default: | 2127 default: |
| 2114 // Unsupported method. | 2128 // Unsupported method. |
| 2115 return false; | 2129 return false; |
| 2116 } | 2130 } |
| 2117 } | 2131 } |
| 2118 | 2132 |
| 2119 if ((class_ids[0] == kFloat32x4Cid) && (ic_data.NumberOfChecks() == 1)) { | 2133 if ((class_ids[0] == kFloat32x4Cid) && (ic_data.NumberOfChecks() == 1)) { |
| 2120 return TryInlineFloat32x4Method(call, recognized_kind); | 2134 return TryInlineFloat32x4Method(call, recognized_kind); |
| 2121 } | 2135 } |
| 2122 | 2136 |
| (...skipping 486 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2609 NULL, | 2623 NULL, |
| 2610 Definition::kValue); | 2624 Definition::kValue); |
| 2611 *array = elements; | 2625 *array = elements; |
| 2612 } | 2626 } |
| 2613 return array_cid; | 2627 return array_cid; |
| 2614 } | 2628 } |
| 2615 | 2629 |
| 2616 | 2630 |
| 2617 bool FlowGraphOptimizer::BuildByteArrayViewLoad(InstanceCallInstr* call, | 2631 bool FlowGraphOptimizer::BuildByteArrayViewLoad(InstanceCallInstr* call, |
| 2618 intptr_t view_cid) { | 2632 intptr_t view_cid) { |
| 2619 if ((view_cid == kTypedDataFloat32x4ArrayCid) && !ShouldInlineSimd()) { | 2633 bool simd_view = (view_cid == kTypedDataFloat32x4ArrayCid) || |
| 2634 (view_cid == kTypedDataUint32x4ArrayCid); |
| 2635 if (simd_view && !ShouldInlineSimd()) { |
| 2620 return false; | 2636 return false; |
| 2621 } | 2637 } |
| 2622 | 2638 |
| 2623 ASSERT(call->HasICData()); | 2639 ASSERT(call->HasICData()); |
| 2624 Function& target = Function::Handle(); | 2640 Function& target = Function::Handle(); |
| 2625 GrowableArray<intptr_t> class_ids; | 2641 GrowableArray<intptr_t> class_ids; |
| 2626 call->ic_data()->GetCheckAt(0, &class_ids, &target); | 2642 call->ic_data()->GetCheckAt(0, &class_ids, &target); |
| 2627 const intptr_t receiver_cid = class_ids[0]; | 2643 const intptr_t receiver_cid = class_ids[0]; |
| 2628 | 2644 |
| 2629 TargetEntryInstr* entry; | 2645 TargetEntryInstr* entry; |
| (...skipping 27 matching lines...) Expand all Loading... |
| 2657 ASSERT(current_iterator()->Current() == call); | 2673 ASSERT(current_iterator()->Current() == call); |
| 2658 current_iterator()->RemoveCurrentFromGraph(); | 2674 current_iterator()->RemoveCurrentFromGraph(); |
| 2659 call->set_previous(NULL); | 2675 call->set_previous(NULL); |
| 2660 call->set_next(NULL); | 2676 call->set_next(NULL); |
| 2661 return true; | 2677 return true; |
| 2662 } | 2678 } |
| 2663 | 2679 |
| 2664 | 2680 |
| 2665 bool FlowGraphOptimizer::BuildByteArrayViewStore(InstanceCallInstr* call, | 2681 bool FlowGraphOptimizer::BuildByteArrayViewStore(InstanceCallInstr* call, |
| 2666 intptr_t view_cid) { | 2682 intptr_t view_cid) { |
| 2667 if ((view_cid == kTypedDataFloat32x4ArrayCid) && !ShouldInlineSimd()) { | 2683 bool simd_view = (view_cid == kTypedDataFloat32x4ArrayCid) || |
| 2684 (view_cid == kTypedDataUint32x4ArrayCid); |
| 2685 if (simd_view && !ShouldInlineSimd()) { |
| 2668 return false; | 2686 return false; |
| 2669 } | 2687 } |
| 2670 ASSERT(call->HasICData()); | 2688 ASSERT(call->HasICData()); |
| 2671 Function& target = Function::Handle(); | 2689 Function& target = Function::Handle(); |
| 2672 GrowableArray<intptr_t> class_ids; | 2690 GrowableArray<intptr_t> class_ids; |
| 2673 call->ic_data()->GetCheckAt(0, &class_ids, &target); | 2691 call->ic_data()->GetCheckAt(0, &class_ids, &target); |
| 2674 const intptr_t receiver_cid = class_ids[0]; | 2692 const intptr_t receiver_cid = class_ids[0]; |
| 2675 | 2693 |
| 2676 Definition* array = call->ArgumentAt(0); | 2694 Definition* array = call->ArgumentAt(0); |
| 2677 PrepareByteArrayViewOp(call, receiver_cid, view_cid, &array); | 2695 PrepareByteArrayViewOp(call, receiver_cid, view_cid, &array); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2711 case kTypedDataFloat64ArrayCid: { | 2729 case kTypedDataFloat64ArrayCid: { |
| 2712 // Check that value is always double. | 2730 // Check that value is always double. |
| 2713 value_check = ICData::New(flow_graph_->parsed_function().function(), | 2731 value_check = ICData::New(flow_graph_->parsed_function().function(), |
| 2714 call->function_name(), | 2732 call->function_name(), |
| 2715 Object::empty_array(), // Dummy args. descr. | 2733 Object::empty_array(), // Dummy args. descr. |
| 2716 Isolate::kNoDeoptId, | 2734 Isolate::kNoDeoptId, |
| 2717 1); | 2735 1); |
| 2718 value_check.AddReceiverCheck(kDoubleCid, target); | 2736 value_check.AddReceiverCheck(kDoubleCid, target); |
| 2719 break; | 2737 break; |
| 2720 } | 2738 } |
| 2739 case kTypedDataUint32x4ArrayCid: { |
| 2740 // Check that value is always Uint32x4. |
| 2741 value_check = ICData::New(flow_graph_->parsed_function().function(), |
| 2742 call->function_name(), |
| 2743 Object::empty_array(), // Dummy args. descr. |
| 2744 Isolate::kNoDeoptId, |
| 2745 1); |
| 2746 value_check.AddReceiverCheck(kUint32x4Cid, target); |
| 2747 break; |
| 2748 } |
| 2721 case kTypedDataFloat32x4ArrayCid: { | 2749 case kTypedDataFloat32x4ArrayCid: { |
| 2722 // Check that value is always Float32x4. | 2750 // Check that value is always Float32x4. |
| 2723 value_check = ICData::New(flow_graph_->parsed_function().function(), | 2751 value_check = ICData::New(flow_graph_->parsed_function().function(), |
| 2724 call->function_name(), | 2752 call->function_name(), |
| 2725 Object::empty_array(), // Dummy args. descr. | 2753 Object::empty_array(), // Dummy args. descr. |
| 2726 Isolate::kNoDeoptId, | 2754 Isolate::kNoDeoptId, |
| 2727 1); | 2755 1); |
| 2728 value_check.AddReceiverCheck(kFloat32x4Cid, target); | 2756 value_check.AddReceiverCheck(kFloat32x4Cid, target); |
| 2729 break; | 2757 break; |
| 2730 } | 2758 } |
| (...skipping 5152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7883 } | 7911 } |
| 7884 | 7912 |
| 7885 // Insert materializations at environment uses. | 7913 // Insert materializations at environment uses. |
| 7886 for (intptr_t i = 0; i < exits.length(); i++) { | 7914 for (intptr_t i = 0; i < exits.length(); i++) { |
| 7887 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); | 7915 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); |
| 7888 } | 7916 } |
| 7889 } | 7917 } |
| 7890 | 7918 |
| 7891 | 7919 |
| 7892 } // namespace dart | 7920 } // namespace dart |
| OLD | NEW |