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 |