| 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/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/cpu.h" | 10 #include "vm/cpu.h" |
| (...skipping 3054 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3065 case MethodRecognizer::kDoubleDiv: | 3065 case MethodRecognizer::kDoubleDiv: |
| 3066 return TryReplaceInstanceCallWithInline(call); | 3066 return TryReplaceInstanceCallWithInline(call); |
| 3067 default: | 3067 default: |
| 3068 // Unsupported method. | 3068 // Unsupported method. |
| 3069 return false; | 3069 return false; |
| 3070 } | 3070 } |
| 3071 } | 3071 } |
| 3072 | 3072 |
| 3073 if (IsSupportedByteArrayViewCid(class_ids[0]) && | 3073 if (IsSupportedByteArrayViewCid(class_ids[0]) && |
| 3074 (ic_data.NumberOfChecks() == 1)) { | 3074 (ic_data.NumberOfChecks() == 1)) { |
| 3075 // For elements that may not fit into a smi on all platforms, check if | 3075 return TryReplaceInstanceCallWithInline(call); |
| 3076 // elements fit into a smi or the platform supports unboxed mints. | |
| 3077 if ((recognized_kind == MethodRecognizer::kByteArrayBaseGetInt32) || | |
| 3078 (recognized_kind == MethodRecognizer::kByteArrayBaseGetUint32) || | |
| 3079 (recognized_kind == MethodRecognizer::kByteArrayBaseSetInt32) || | |
| 3080 (recognized_kind == MethodRecognizer::kByteArrayBaseSetUint32)) { | |
| 3081 if (!CanUnboxInt32()) { | |
| 3082 return false; | |
| 3083 } | |
| 3084 } | |
| 3085 | |
| 3086 if ((recognized_kind == MethodRecognizer::kByteArrayBaseGetFloat32) || | |
| 3087 (recognized_kind == MethodRecognizer::kByteArrayBaseGetFloat64) || | |
| 3088 (recognized_kind == MethodRecognizer::kByteArrayBaseSetFloat32) || | |
| 3089 (recognized_kind == MethodRecognizer::kByteArrayBaseSetFloat64)) { | |
| 3090 if (!CanUnboxDouble()) { | |
| 3091 return false; | |
| 3092 } | |
| 3093 } | |
| 3094 | |
| 3095 switch (recognized_kind) { | |
| 3096 // ByteArray getters. | |
| 3097 case MethodRecognizer::kByteArrayBaseGetInt8: | |
| 3098 return BuildByteArrayBaseLoad(call, kTypedDataInt8ArrayCid); | |
| 3099 case MethodRecognizer::kByteArrayBaseGetUint8: | |
| 3100 return BuildByteArrayBaseLoad(call, kTypedDataUint8ArrayCid); | |
| 3101 case MethodRecognizer::kByteArrayBaseGetInt16: | |
| 3102 return BuildByteArrayBaseLoad(call, kTypedDataInt16ArrayCid); | |
| 3103 case MethodRecognizer::kByteArrayBaseGetUint16: | |
| 3104 return BuildByteArrayBaseLoad(call, kTypedDataUint16ArrayCid); | |
| 3105 case MethodRecognizer::kByteArrayBaseGetInt32: | |
| 3106 return BuildByteArrayBaseLoad(call, kTypedDataInt32ArrayCid); | |
| 3107 case MethodRecognizer::kByteArrayBaseGetUint32: | |
| 3108 return BuildByteArrayBaseLoad(call, kTypedDataUint32ArrayCid); | |
| 3109 case MethodRecognizer::kByteArrayBaseGetFloat32: | |
| 3110 return BuildByteArrayBaseLoad(call, kTypedDataFloat32ArrayCid); | |
| 3111 case MethodRecognizer::kByteArrayBaseGetFloat64: | |
| 3112 return BuildByteArrayBaseLoad(call, kTypedDataFloat64ArrayCid); | |
| 3113 case MethodRecognizer::kByteArrayBaseGetFloat32x4: | |
| 3114 return BuildByteArrayBaseLoad(call, kTypedDataFloat32x4ArrayCid); | |
| 3115 case MethodRecognizer::kByteArrayBaseGetInt32x4: | |
| 3116 return BuildByteArrayBaseLoad(call, kTypedDataInt32x4ArrayCid); | |
| 3117 | |
| 3118 // ByteArray setters. | |
| 3119 case MethodRecognizer::kByteArrayBaseSetInt8: | |
| 3120 return BuildByteArrayBaseStore(call, kTypedDataInt8ArrayCid); | |
| 3121 case MethodRecognizer::kByteArrayBaseSetUint8: | |
| 3122 return BuildByteArrayBaseStore(call, kTypedDataUint8ArrayCid); | |
| 3123 case MethodRecognizer::kByteArrayBaseSetInt16: | |
| 3124 return BuildByteArrayBaseStore(call, kTypedDataInt16ArrayCid); | |
| 3125 case MethodRecognizer::kByteArrayBaseSetUint16: | |
| 3126 return BuildByteArrayBaseStore(call, kTypedDataUint16ArrayCid); | |
| 3127 case MethodRecognizer::kByteArrayBaseSetInt32: | |
| 3128 return BuildByteArrayBaseStore(call, kTypedDataInt32ArrayCid); | |
| 3129 case MethodRecognizer::kByteArrayBaseSetUint32: | |
| 3130 return BuildByteArrayBaseStore(call, kTypedDataUint32ArrayCid); | |
| 3131 case MethodRecognizer::kByteArrayBaseSetFloat32: | |
| 3132 return BuildByteArrayBaseStore(call, kTypedDataFloat32ArrayCid); | |
| 3133 case MethodRecognizer::kByteArrayBaseSetFloat64: | |
| 3134 return BuildByteArrayBaseStore(call, kTypedDataFloat64ArrayCid); | |
| 3135 case MethodRecognizer::kByteArrayBaseSetFloat32x4: | |
| 3136 return BuildByteArrayBaseStore(call, kTypedDataFloat32x4ArrayCid); | |
| 3137 case MethodRecognizer::kByteArrayBaseSetInt32x4: | |
| 3138 return BuildByteArrayBaseStore(call, kTypedDataInt32x4ArrayCid); | |
| 3139 default: | |
| 3140 // Unsupported method. | |
| 3141 return false; | |
| 3142 } | |
| 3143 } | 3076 } |
| 3144 | 3077 |
| 3145 if ((class_ids[0] == kFloat32x4Cid) && (ic_data.NumberOfChecks() == 1)) { | 3078 if ((class_ids[0] == kFloat32x4Cid) && (ic_data.NumberOfChecks() == 1)) { |
| 3146 return TryInlineFloat32x4Method(call, recognized_kind); | 3079 return TryInlineFloat32x4Method(call, recognized_kind); |
| 3147 } | 3080 } |
| 3148 | 3081 |
| 3149 if ((class_ids[0] == kInt32x4Cid) && (ic_data.NumberOfChecks() == 1)) { | 3082 if ((class_ids[0] == kInt32x4Cid) && (ic_data.NumberOfChecks() == 1)) { |
| 3150 return TryInlineInt32x4Method(call, recognized_kind); | 3083 return TryInlineInt32x4Method(call, recognized_kind); |
| 3151 } | 3084 } |
| 3152 | 3085 |
| (...skipping 772 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3925 *cursor = flow_graph()->AppendTo(*cursor, | 3858 *cursor = flow_graph()->AppendTo(*cursor, |
| 3926 elements, | 3859 elements, |
| 3927 NULL, | 3860 NULL, |
| 3928 FlowGraph::kValue); | 3861 FlowGraph::kValue); |
| 3929 *array = elements; | 3862 *array = elements; |
| 3930 } | 3863 } |
| 3931 return array_cid; | 3864 return array_cid; |
| 3932 } | 3865 } |
| 3933 | 3866 |
| 3934 | 3867 |
| 3935 bool FlowGraphOptimizer::BuildByteArrayBaseLoad(InstanceCallInstr* call, | |
| 3936 intptr_t view_cid) { | |
| 3937 const bool simd_view = (view_cid == kTypedDataFloat32x4ArrayCid) || | |
| 3938 (view_cid == kTypedDataInt32x4ArrayCid); | |
| 3939 const bool float_view = (view_cid == kTypedDataFloat32ArrayCid) || | |
| 3940 (view_cid == kTypedDataFloat64ArrayCid); | |
| 3941 if (float_view && !CanUnboxDouble()) { | |
| 3942 return false; | |
| 3943 } | |
| 3944 if (simd_view && !ShouldInlineSimd()) { | |
| 3945 return false; | |
| 3946 } | |
| 3947 return TryReplaceInstanceCallWithInline(call); | |
| 3948 } | |
| 3949 | |
| 3950 | |
| 3951 bool FlowGraphOptimizer::BuildByteArrayBaseStore(InstanceCallInstr* call, | |
| 3952 intptr_t view_cid) { | |
| 3953 const bool simd_view = (view_cid == kTypedDataFloat32x4ArrayCid) || | |
| 3954 (view_cid == kTypedDataInt32x4ArrayCid); | |
| 3955 const bool float_view = (view_cid == kTypedDataFloat32ArrayCid) || | |
| 3956 (view_cid == kTypedDataFloat64ArrayCid); | |
| 3957 if (float_view && !CanUnboxDouble()) { | |
| 3958 return false; | |
| 3959 } | |
| 3960 if (simd_view && !ShouldInlineSimd()) { | |
| 3961 return false; | |
| 3962 } | |
| 3963 return TryReplaceInstanceCallWithInline(call); | |
| 3964 } | |
| 3965 | |
| 3966 | |
| 3967 // If type tests specified by 'ic_data' do not depend on type arguments, | 3868 // If type tests specified by 'ic_data' do not depend on type arguments, |
| 3968 // return mapping cid->result in 'results' (i : cid; i + 1: result). | 3869 // return mapping cid->result in 'results' (i : cid; i + 1: result). |
| 3969 // If all tests yield the same result, return it otherwise return Bool::null. | 3870 // If all tests yield the same result, return it otherwise return Bool::null. |
| 3970 // If no mapping is possible, 'results' is empty. | 3871 // If no mapping is possible, 'results' is empty. |
| 3971 // An instance-of test returning all same results can be converted to a class | 3872 // An instance-of test returning all same results can be converted to a class |
| 3972 // check. | 3873 // check. |
| 3973 RawBool* FlowGraphOptimizer::InstanceOfAsBool( | 3874 RawBool* FlowGraphOptimizer::InstanceOfAsBool( |
| 3974 const ICData& ic_data, | 3875 const ICData& ic_data, |
| 3975 const AbstractType& type, | 3876 const AbstractType& type, |
| 3976 ZoneGrowableArray<intptr_t>* results) const { | 3877 ZoneGrowableArray<intptr_t>* results) const { |
| (...skipping 4838 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8815 | 8716 |
| 8816 // Insert materializations at environment uses. | 8717 // Insert materializations at environment uses. |
| 8817 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { | 8718 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { |
| 8818 CreateMaterializationAt( | 8719 CreateMaterializationAt( |
| 8819 exits_collector_.exits()[i], alloc, *slots); | 8720 exits_collector_.exits()[i], alloc, *slots); |
| 8820 } | 8721 } |
| 8821 } | 8722 } |
| 8822 | 8723 |
| 8823 | 8724 |
| 8824 } // namespace dart | 8725 } // namespace dart |
| OLD | NEW |