| 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 674 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 685 } | 685 } |
| 686 call->ReplaceWith(replacement, current_iterator()); | 686 call->ReplaceWith(replacement, current_iterator()); |
| 687 } | 687 } |
| 688 | 688 |
| 689 | 689 |
| 690 static intptr_t ReceiverClassId(InstanceCallInstr* call) { | 690 static intptr_t ReceiverClassId(InstanceCallInstr* call) { |
| 691 if (!call->HasICData()) return kIllegalCid; | 691 if (!call->HasICData()) return kIllegalCid; |
| 692 | 692 |
| 693 const ICData& ic_data = ICData::Handle(call->ic_data()->AsUnaryClassChecks()); | 693 const ICData& ic_data = ICData::Handle(call->ic_data()->AsUnaryClassChecks()); |
| 694 | 694 |
| 695 if (ic_data.NumberOfChecks() == 0) return kIllegalCid; | |
| 696 // TODO(vegorov): Add multiple receiver type support. | |
| 697 if (ic_data.NumberOfChecks() != 1) return kIllegalCid; | 695 if (ic_data.NumberOfChecks() != 1) return kIllegalCid; |
| 698 ASSERT(ic_data.HasOneTarget()); | 696 ASSERT(ic_data.HasOneTarget()); |
| 699 | 697 |
| 700 Function& target = Function::Handle(); | 698 Function& target = Function::Handle(); |
| 701 intptr_t class_id; | 699 intptr_t class_id; |
| 702 ic_data.GetOneClassCheckAt(0, &class_id, &target); | 700 ic_data.GetOneClassCheckAt(0, &class_id, &target); |
| 703 return class_id; | 701 return class_id; |
| 704 } | 702 } |
| 705 | 703 |
| 706 | 704 |
| (...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1062 case MethodRecognizer::kGrowableArrayGetIndexed: | 1060 case MethodRecognizer::kGrowableArrayGetIndexed: |
| 1063 case MethodRecognizer::kFloat32ArrayGetIndexed: | 1061 case MethodRecognizer::kFloat32ArrayGetIndexed: |
| 1064 case MethodRecognizer::kFloat64ArrayGetIndexed: | 1062 case MethodRecognizer::kFloat64ArrayGetIndexed: |
| 1065 case MethodRecognizer::kInt8ArrayGetIndexed: | 1063 case MethodRecognizer::kInt8ArrayGetIndexed: |
| 1066 case MethodRecognizer::kUint8ArrayGetIndexed: | 1064 case MethodRecognizer::kUint8ArrayGetIndexed: |
| 1067 case MethodRecognizer::kUint8ClampedArrayGetIndexed: | 1065 case MethodRecognizer::kUint8ClampedArrayGetIndexed: |
| 1068 case MethodRecognizer::kExternalUint8ArrayGetIndexed: | 1066 case MethodRecognizer::kExternalUint8ArrayGetIndexed: |
| 1069 case MethodRecognizer::kExternalUint8ClampedArrayGetIndexed: | 1067 case MethodRecognizer::kExternalUint8ClampedArrayGetIndexed: |
| 1070 case MethodRecognizer::kInt16ArrayGetIndexed: | 1068 case MethodRecognizer::kInt16ArrayGetIndexed: |
| 1071 case MethodRecognizer::kUint16ArrayGetIndexed: | 1069 case MethodRecognizer::kUint16ArrayGetIndexed: |
| 1070 return TryInlineGetIndexed(kind, call, ic_data, entry, last); |
| 1071 case MethodRecognizer::kFloat32x4ArrayGetIndexed: |
| 1072 if (!ShouldInlineSimd()) return false; |
| 1073 return TryInlineGetIndexed(kind, call, ic_data, entry, last); |
| 1072 case MethodRecognizer::kInt32ArrayGetIndexed: | 1074 case MethodRecognizer::kInt32ArrayGetIndexed: |
| 1073 case MethodRecognizer::kUint32ArrayGetIndexed: | 1075 case MethodRecognizer::kUint32ArrayGetIndexed: |
| 1074 case MethodRecognizer::kFloat32x4ArrayGetIndexed: | 1076 if (!CanUnboxInt32()) return false; |
| 1075 return TryInlineGetIndexed(kind, call, ic_data, entry, last); | 1077 return TryInlineGetIndexed(kind, call, ic_data, entry, last); |
| 1076 default: | 1078 default: |
| 1077 return false; | 1079 return false; |
| 1078 } | 1080 } |
| 1079 } | 1081 } |
| 1080 | 1082 |
| 1081 | 1083 |
| 1082 bool FlowGraphOptimizer::TryInlineGetIndexed(MethodRecognizer::Kind kind, | 1084 bool FlowGraphOptimizer::TryInlineGetIndexed(MethodRecognizer::Kind kind, |
| 1083 Instruction* call, | 1085 Instruction* call, |
| 1084 const ICData& ic_data, | 1086 const ICData& ic_data, |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1169 deopt_id); | 1171 deopt_id); |
| 1170 flow_graph()->AppendTo(cursor, | 1172 flow_graph()->AppendTo(cursor, |
| 1171 *last, | 1173 *last, |
| 1172 deopt_id != Isolate::kNoDeoptId ? call->env() : NULL, | 1174 deopt_id != Isolate::kNoDeoptId ? call->env() : NULL, |
| 1173 Definition::kValue); | 1175 Definition::kValue); |
| 1174 return true; | 1176 return true; |
| 1175 } | 1177 } |
| 1176 | 1178 |
| 1177 | 1179 |
| 1178 bool FlowGraphOptimizer::TryReplaceWithLoadIndexed(InstanceCallInstr* call) { | 1180 bool FlowGraphOptimizer::TryReplaceWithLoadIndexed(InstanceCallInstr* call) { |
| 1179 const intptr_t class_id = ReceiverClassId(call); | 1181 // Check for monomorphic IC data. |
| 1180 switch (class_id) { | 1182 if (!call->HasICData()) return false; |
| 1181 case kArrayCid: | 1183 const ICData& ic_data = ICData::Handle(call->ic_data()->AsUnaryClassChecks()); |
| 1182 case kImmutableArrayCid: | 1184 if (ic_data.NumberOfChecks() != 1) return false; |
| 1183 case kGrowableObjectArrayCid: | 1185 ASSERT(ic_data.HasOneTarget()); |
| 1184 case kTypedDataFloat32ArrayCid: | 1186 |
| 1185 case kTypedDataFloat64ArrayCid: | 1187 const Function& target = Function::Handle(ic_data.GetTargetAt(0)); |
| 1186 case kTypedDataInt8ArrayCid: | 1188 TargetEntryInstr* entry; |
| 1187 case kTypedDataUint8ArrayCid: | 1189 Definition* last; |
| 1188 case kTypedDataUint8ClampedArrayCid: | 1190 if (!TryInlineRecognizedMethod(target, |
| 1189 case kExternalTypedDataUint8ArrayCid: | 1191 call, |
| 1190 case kExternalTypedDataUint8ClampedArrayCid: | 1192 *call->ic_data(), |
| 1191 case kTypedDataInt16ArrayCid: | 1193 &entry, &last)) { |
| 1192 case kTypedDataUint16ArrayCid: | 1194 return false; |
| 1193 break; | |
| 1194 case kTypedDataFloat32x4ArrayCid: | |
| 1195 if (!ShouldInlineSimd()) { | |
| 1196 return false; | |
| 1197 } | |
| 1198 break; | |
| 1199 case kTypedDataInt32ArrayCid: | |
| 1200 case kTypedDataUint32ArrayCid: | |
| 1201 if (!CanUnboxInt32()) return false; | |
| 1202 break; | |
| 1203 default: | |
| 1204 return false; | |
| 1205 } | 1195 } |
| 1206 | 1196 |
| 1207 const Function& target = | |
| 1208 Function::Handle(call->ic_data()->GetTargetAt(0)); | |
| 1209 TargetEntryInstr* entry; | |
| 1210 Definition* last; | |
| 1211 ASSERT(class_id == MethodKindToCid(MethodRecognizer::RecognizeKind(target))); | |
| 1212 bool success = TryInlineRecognizedMethod(target, | |
| 1213 call, | |
| 1214 *call->ic_data(), | |
| 1215 &entry, &last); | |
| 1216 ASSERT(success); | |
| 1217 // Insert receiver class check. | 1197 // Insert receiver class check. |
| 1218 AddReceiverCheck(call); | 1198 AddReceiverCheck(call); |
| 1219 // Remove the original push arguments. | 1199 // Remove the original push arguments. |
| 1220 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { | 1200 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { |
| 1221 PushArgumentInstr* push = call->PushArgumentAt(i); | 1201 PushArgumentInstr* push = call->PushArgumentAt(i); |
| 1222 push->ReplaceUsesWith(push->value()->definition()); | 1202 push->ReplaceUsesWith(push->value()->definition()); |
| 1223 push->RemoveFromGraph(); | 1203 push->RemoveFromGraph(); |
| 1224 } | 1204 } |
| 1225 // Replace all uses of this definition with the result. | 1205 // Replace all uses of this definition with the result. |
| 1226 call->ReplaceUsesWith(last); | 1206 call->ReplaceUsesWith(last); |
| (...skipping 6426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7653 } | 7633 } |
| 7654 | 7634 |
| 7655 // Insert materializations at environment uses. | 7635 // Insert materializations at environment uses. |
| 7656 for (intptr_t i = 0; i < exits.length(); i++) { | 7636 for (intptr_t i = 0; i < exits.length(); i++) { |
| 7657 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); | 7637 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); |
| 7658 } | 7638 } |
| 7659 } | 7639 } |
| 7660 | 7640 |
| 7661 | 7641 |
| 7662 } // namespace dart | 7642 } // namespace dart |
| OLD | NEW |