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

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

Issue 26191002: Hook ByteArrayViewLoad operations into polymorphic inliner (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
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/intermediate_language.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 811 matching lines...) Expand 10 before | Expand all | Expand 10 after
822 bool FlowGraphOptimizer::TryReplaceWithStoreIndexed(InstanceCallInstr* call) { 822 bool FlowGraphOptimizer::TryReplaceWithStoreIndexed(InstanceCallInstr* call) {
823 // Check for monomorphic IC data. 823 // Check for monomorphic IC data.
824 if (!call->HasICData()) return false; 824 if (!call->HasICData()) return false;
825 const ICData& ic_data = ICData::Handle(call->ic_data()->AsUnaryClassChecks()); 825 const ICData& ic_data = ICData::Handle(call->ic_data()->AsUnaryClassChecks());
826 if (ic_data.NumberOfChecks() != 1) return false; 826 if (ic_data.NumberOfChecks() != 1) return false;
827 ASSERT(ic_data.HasOneTarget()); 827 ASSERT(ic_data.HasOneTarget());
828 828
829 const Function& target = Function::Handle(ic_data.GetTargetAt(0)); 829 const Function& target = Function::Handle(ic_data.GetTargetAt(0));
830 TargetEntryInstr* entry; 830 TargetEntryInstr* entry;
831 Definition* last; 831 Definition* last;
832 if (!TryInlineRecognizedMethod(target, 832 if (!TryInlineRecognizedMethod(ic_data.GetReceiverClassIdAt(0),
833 target,
833 call, 834 call,
834 call->token_pos(), 835 call->token_pos(),
835 *call->ic_data(), 836 *call->ic_data(),
836 &entry, &last)) { 837 &entry, &last)) {
837 return false; 838 return false;
838 } 839 }
839 // Insert receiver class check. 840 // Insert receiver class check.
840 AddReceiverCheck(call); 841 AddReceiverCheck(call);
841 // Remove the original push arguments. 842 // Remove the original push arguments.
842 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { 843 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) {
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
988 array_cid, 989 array_cid,
989 call->deopt_id()); 990 call->deopt_id());
990 flow_graph()->AppendTo(cursor, 991 flow_graph()->AppendTo(cursor,
991 *last, 992 *last,
992 call->env(), 993 call->env(),
993 Definition::kEffect); 994 Definition::kEffect);
994 return true; 995 return true;
995 } 996 }
996 997
997 998
998 bool FlowGraphOptimizer::TryInlineRecognizedMethod(const Function& target, 999 bool FlowGraphOptimizer::TryInlineRecognizedMethod(intptr_t receiver_cid,
1000 const Function& target,
999 Instruction* call, 1001 Instruction* call,
1000 intptr_t token_pos, 1002 intptr_t token_pos,
1001 const ICData& ic_data, 1003 const ICData& ic_data,
1002 TargetEntryInstr** entry, 1004 TargetEntryInstr** entry,
1003 Definition** last) { 1005 Definition** last) {
1004 ICData& value_check = ICData::ZoneHandle(); 1006 ICData& value_check = ICData::ZoneHandle();
1005 MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(target); 1007 MethodRecognizer::Kind kind = MethodRecognizer::RecognizeKind(target);
1006 switch (kind) { 1008 switch (kind) {
1007 // Recognized [] operators. 1009 // Recognized [] operators.
1008 case MethodRecognizer::kImmutableArrayGetIndexed: 1010 case MethodRecognizer::kImmutableArrayGetIndexed:
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1067 value_check = ic_data.AsUnaryClassChecksForArgNr(2); 1069 value_check = ic_data.AsUnaryClassChecksForArgNr(2);
1068 return InlineSetIndexed(kind, target, call, token_pos, 1070 return InlineSetIndexed(kind, target, call, token_pos,
1069 &ic_data, value_check, entry, last); 1071 &ic_data, value_check, entry, last);
1070 case MethodRecognizer::kFloat32x4ArraySetIndexed: 1072 case MethodRecognizer::kFloat32x4ArraySetIndexed:
1071 if (!ShouldInlineSimd()) return false; 1073 if (!ShouldInlineSimd()) return false;
1072 // Check that value is always a Float32x4. 1074 // Check that value is always a Float32x4.
1073 if (!ArgIsAlways(kFloat32x4Cid, ic_data, 2)) return false; 1075 if (!ArgIsAlways(kFloat32x4Cid, ic_data, 2)) return false;
1074 value_check = ic_data.AsUnaryClassChecksForArgNr(2); 1076 value_check = ic_data.AsUnaryClassChecksForArgNr(2);
1075 return InlineSetIndexed(kind, target, call, token_pos, 1077 return InlineSetIndexed(kind, target, call, token_pos,
1076 &ic_data, value_check, entry, last); 1078 &ic_data, value_check, entry, last);
1079 case MethodRecognizer::kByteArrayBaseGetInt8:
1080 return InlineByteArrayViewLoad(call, receiver_cid,
1081 kTypedDataInt8ArrayCid,
1082 ic_data, entry, last);
1083 case MethodRecognizer::kByteArrayBaseGetUint8:
1084 return InlineByteArrayViewLoad(call, receiver_cid,
1085 kTypedDataUint8ArrayCid,
1086 ic_data, entry, last);
1087 case MethodRecognizer::kByteArrayBaseGetInt16:
1088 return InlineByteArrayViewLoad(call, receiver_cid,
1089 kTypedDataInt16ArrayCid,
1090 ic_data, entry, last);
1091 case MethodRecognizer::kByteArrayBaseGetUint16:
1092 return InlineByteArrayViewLoad(call, receiver_cid,
1093 kTypedDataUint16ArrayCid,
1094 ic_data, entry, last);
1095 case MethodRecognizer::kByteArrayBaseGetInt32:
1096 if (!CanUnboxInt32()) return false;
1097 return InlineByteArrayViewLoad(call, receiver_cid,
1098 kTypedDataInt32ArrayCid,
1099 ic_data, entry, last);
1100 case MethodRecognizer::kByteArrayBaseGetUint32:
1101 if (!CanUnboxInt32()) return false;
1102 return InlineByteArrayViewLoad(call, receiver_cid,
1103 kTypedDataUint32ArrayCid,
1104 ic_data, entry, last);
1105 case MethodRecognizer::kByteArrayBaseGetFloat32:
1106 return InlineByteArrayViewLoad(call, receiver_cid,
1107 kTypedDataFloat32ArrayCid,
1108 ic_data, entry, last);
1109 case MethodRecognizer::kByteArrayBaseGetFloat64:
1110 return InlineByteArrayViewLoad(call, receiver_cid,
1111 kTypedDataFloat64ArrayCid,
1112 ic_data, entry, last);
1113 case MethodRecognizer::kByteArrayBaseGetFloat32x4:
1114 if (!ShouldInlineSimd()) return false;
1115 return InlineByteArrayViewLoad(call, receiver_cid,
1116 kTypedDataFloat32x4ArrayCid,
1117 ic_data, entry, last);
1077 default: 1118 default:
1078 return false; 1119 return false;
1079 } 1120 }
1080 } 1121 }
1081 1122
1082 1123
1083 intptr_t FlowGraphOptimizer::PrepareInlineIndexedOp(Instruction* call, 1124 intptr_t FlowGraphOptimizer::PrepareInlineIndexedOp(Instruction* call,
1084 intptr_t array_cid, 1125 intptr_t array_cid,
1085 Definition** array, 1126 Definition** array,
1086 Definition* index, 1127 Definition* index,
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1191 bool FlowGraphOptimizer::TryReplaceWithLoadIndexed(InstanceCallInstr* call) { 1232 bool FlowGraphOptimizer::TryReplaceWithLoadIndexed(InstanceCallInstr* call) {
1192 // Check for monomorphic IC data. 1233 // Check for monomorphic IC data.
1193 if (!call->HasICData()) return false; 1234 if (!call->HasICData()) return false;
1194 const ICData& ic_data = ICData::Handle(call->ic_data()->AsUnaryClassChecks()); 1235 const ICData& ic_data = ICData::Handle(call->ic_data()->AsUnaryClassChecks());
1195 if (ic_data.NumberOfChecks() != 1) return false; 1236 if (ic_data.NumberOfChecks() != 1) return false;
1196 ASSERT(ic_data.HasOneTarget()); 1237 ASSERT(ic_data.HasOneTarget());
1197 1238
1198 const Function& target = Function::Handle(ic_data.GetTargetAt(0)); 1239 const Function& target = Function::Handle(ic_data.GetTargetAt(0));
1199 TargetEntryInstr* entry; 1240 TargetEntryInstr* entry;
1200 Definition* last; 1241 Definition* last;
1201 if (!TryInlineRecognizedMethod(target, 1242 if (!TryInlineRecognizedMethod(ic_data.GetReceiverClassIdAt(0),
1243 target,
1202 call, 1244 call,
1203 call->token_pos(), 1245 call->token_pos(),
1204 *call->ic_data(), 1246 *call->ic_data(),
1205 &entry, &last)) { 1247 &entry, &last)) {
1206 return false; 1248 return false;
1207 } 1249 }
1208 1250
1209 // Insert receiver class check. 1251 // Insert receiver class check.
1210 AddReceiverCheck(call); 1252 AddReceiverCheck(call);
1211 // Remove the original push arguments. 1253 // Remove the original push arguments.
(...skipping 807 matching lines...) Expand 10 before | Expand all | Expand 10 after
2019 if ((recognized_kind == MethodRecognizer::kByteArrayBaseGetInt32) || 2061 if ((recognized_kind == MethodRecognizer::kByteArrayBaseGetInt32) ||
2020 (recognized_kind == MethodRecognizer::kByteArrayBaseGetUint32) || 2062 (recognized_kind == MethodRecognizer::kByteArrayBaseGetUint32) ||
2021 (recognized_kind == MethodRecognizer::kByteArrayBaseSetInt32) || 2063 (recognized_kind == MethodRecognizer::kByteArrayBaseSetInt32) ||
2022 (recognized_kind == MethodRecognizer::kByteArrayBaseSetUint32)) { 2064 (recognized_kind == MethodRecognizer::kByteArrayBaseSetUint32)) {
2023 if (!CanUnboxInt32()) return false; 2065 if (!CanUnboxInt32()) return false;
2024 } 2066 }
2025 2067
2026 switch (recognized_kind) { 2068 switch (recognized_kind) {
2027 // ByteArray getters. 2069 // ByteArray getters.
2028 case MethodRecognizer::kByteArrayBaseGetInt8: 2070 case MethodRecognizer::kByteArrayBaseGetInt8:
2029 return BuildByteArrayViewLoad( 2071 return BuildByteArrayViewLoad(call, kTypedDataInt8ArrayCid);
2030 call, class_ids[0], kTypedDataInt8ArrayCid);
2031 case MethodRecognizer::kByteArrayBaseGetUint8: 2072 case MethodRecognizer::kByteArrayBaseGetUint8:
2032 return BuildByteArrayViewLoad( 2073 return BuildByteArrayViewLoad(call, kTypedDataUint8ArrayCid);
2033 call, class_ids[0], kTypedDataUint8ArrayCid);
2034 case MethodRecognizer::kByteArrayBaseGetInt16: 2074 case MethodRecognizer::kByteArrayBaseGetInt16:
2035 return BuildByteArrayViewLoad( 2075 return BuildByteArrayViewLoad(call, kTypedDataInt16ArrayCid);
2036 call, class_ids[0], kTypedDataInt16ArrayCid);
2037 case MethodRecognizer::kByteArrayBaseGetUint16: 2076 case MethodRecognizer::kByteArrayBaseGetUint16:
2038 return BuildByteArrayViewLoad( 2077 return BuildByteArrayViewLoad(call, kTypedDataUint16ArrayCid);
2039 call, class_ids[0], kTypedDataUint16ArrayCid);
2040 case MethodRecognizer::kByteArrayBaseGetInt32: 2078 case MethodRecognizer::kByteArrayBaseGetInt32:
2041 return BuildByteArrayViewLoad( 2079 return BuildByteArrayViewLoad(call, kTypedDataInt32ArrayCid);
2042 call, class_ids[0], kTypedDataInt32ArrayCid);
2043 case MethodRecognizer::kByteArrayBaseGetUint32: 2080 case MethodRecognizer::kByteArrayBaseGetUint32:
2044 return BuildByteArrayViewLoad( 2081 return BuildByteArrayViewLoad(call, kTypedDataUint32ArrayCid);
2045 call, class_ids[0], kTypedDataUint32ArrayCid);
2046 case MethodRecognizer::kByteArrayBaseGetFloat32: 2082 case MethodRecognizer::kByteArrayBaseGetFloat32:
2047 return BuildByteArrayViewLoad( 2083 return BuildByteArrayViewLoad(call, kTypedDataFloat32ArrayCid);
2048 call, class_ids[0], kTypedDataFloat32ArrayCid);
2049 case MethodRecognizer::kByteArrayBaseGetFloat64: 2084 case MethodRecognizer::kByteArrayBaseGetFloat64:
2050 return BuildByteArrayViewLoad( 2085 return BuildByteArrayViewLoad(call, kTypedDataFloat64ArrayCid);
2051 call, class_ids[0], kTypedDataFloat64ArrayCid);
2052 case MethodRecognizer::kByteArrayBaseGetFloat32x4: 2086 case MethodRecognizer::kByteArrayBaseGetFloat32x4:
2053 return BuildByteArrayViewLoad( 2087 return BuildByteArrayViewLoad(call, kTypedDataFloat32x4ArrayCid);
2054 call, class_ids[0], kTypedDataFloat32x4ArrayCid);
2055 2088
2056 // ByteArray setters. 2089 // ByteArray setters.
2057 case MethodRecognizer::kByteArrayBaseSetInt8: 2090 case MethodRecognizer::kByteArrayBaseSetInt8:
2058 return BuildByteArrayViewStore(call, kTypedDataInt8ArrayCid); 2091 return BuildByteArrayViewStore(call, kTypedDataInt8ArrayCid);
2059 case MethodRecognizer::kByteArrayBaseSetUint8: 2092 case MethodRecognizer::kByteArrayBaseSetUint8:
2060 return BuildByteArrayViewStore(call, kTypedDataUint8ArrayCid); 2093 return BuildByteArrayViewStore(call, kTypedDataUint8ArrayCid);
2061 case MethodRecognizer::kByteArrayBaseSetInt16: 2094 case MethodRecognizer::kByteArrayBaseSetInt16:
2062 return BuildByteArrayViewStore(call, kTypedDataInt16ArrayCid); 2095 return BuildByteArrayViewStore(call, kTypedDataInt16ArrayCid);
2063 case MethodRecognizer::kByteArrayBaseSetUint16: 2096 case MethodRecognizer::kByteArrayBaseSetUint16:
2064 return BuildByteArrayViewStore(call, kTypedDataUint16ArrayCid); 2097 return BuildByteArrayViewStore(call, kTypedDataUint16ArrayCid);
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
2442 call->deopt_id()); 2475 call->deopt_id());
2443 ReplaceCall(call, setFlag); 2476 ReplaceCall(call, setFlag);
2444 return true; 2477 return true;
2445 } 2478 }
2446 default: 2479 default:
2447 return false; 2480 return false;
2448 } 2481 }
2449 } 2482 }
2450 2483
2451 2484
2452 bool FlowGraphOptimizer::BuildByteArrayViewLoad( 2485 bool FlowGraphOptimizer::InlineByteArrayViewLoad(Instruction* call,
2453 InstanceCallInstr* call, 2486 intptr_t array_cid,
2454 intptr_t receiver_cid, 2487 intptr_t view_cid,
2455 intptr_t view_cid) { 2488 const ICData& ic_data,
2489 TargetEntryInstr** entry,
2490 Definition** last) {
2491 ASSERT(array_cid != kIllegalCid);
2492 Definition* array = call->ArgumentAt(0);
2493 Definition* index = call->ArgumentAt(1);
2494 *entry = new TargetEntryInstr(flow_graph()->allocate_block_id(),
2495 call->GetBlock()->try_index());
2496 (*entry)->InheritDeoptTarget(call);
2497 Instruction* cursor = *entry;
2498
2499 array_cid = PrepareInlineByteArrayViewOp(call,
2500 array_cid,
2501 view_cid,
2502 &array,
2503 index,
2504 &cursor);
2505
2506 intptr_t deopt_id = Isolate::kNoDeoptId;
2507 if ((array_cid == kTypedDataInt32ArrayCid) ||
2508 (array_cid == kTypedDataUint32ArrayCid)) {
2509 // Set deopt_id if we can optimistically assume that the result is Smi.
2510 // Assume mixed Mint/Smi if this instruction caused deoptimization once.
2511 deopt_id = (ic_data.deopt_reason() == kDeoptUnknown) ?
2512 call->deopt_id() : Isolate::kNoDeoptId;
2513 }
2514
2515 *last = new LoadIndexedInstr(new Value(array),
2516 new Value(index),
2517 1,
2518 view_cid,
2519 deopt_id);
2520 flow_graph()->AppendTo(cursor,
2521 *last,
2522 deopt_id != Isolate::kNoDeoptId ? call->env() : NULL,
2523 Definition::kValue);
2524 return true;
2525 }
2526
2527
2528 intptr_t FlowGraphOptimizer::PrepareInlineByteArrayViewOp(
2529 Instruction* call,
2530 intptr_t array_cid,
2531 intptr_t view_cid,
2532 Definition** array,
2533 Definition* byte_index,
2534 Instruction** cursor) {
2535 // Insert byte_index smi check.
2536 *cursor = flow_graph()->AppendTo(*cursor,
2537 new CheckSmiInstr(new Value(byte_index),
2538 call->deopt_id()),
2539 call->env(),
2540 Definition::kEffect);
2541
2542 const bool is_immutable = true;
2543 LoadFieldInstr* length =
2544 new LoadFieldInstr(new Value(*array),
2545 CheckArrayBoundInstr::LengthOffsetFor(array_cid),
2546 Type::ZoneHandle(Type::SmiType()),
2547 is_immutable);
2548 length->set_result_cid(kSmiCid);
2549 length->set_recognized_kind(
2550 LoadFieldInstr::RecognizedKindFromArrayCid(array_cid));
2551 *cursor = flow_graph()->AppendTo(*cursor,
2552 length,
2553 NULL,
2554 Definition::kValue);
2555
2556 intptr_t element_size = FlowGraphCompiler::ElementSizeFor(array_cid);
2557 ConstantInstr* bytes_per_element =
2558 flow_graph()->GetConstant(Smi::Handle(Smi::New(element_size)));
2559 BinarySmiOpInstr* len_in_bytes =
2560 new BinarySmiOpInstr(Token::kMUL,
2561 new Value(length),
2562 new Value(bytes_per_element),
2563 call->deopt_id());
2564 *cursor = flow_graph()->AppendTo(*cursor, len_in_bytes, call->env(),
2565 Definition::kValue);
2566
2567 ConstantInstr* length_adjustment =
2568 flow_graph()->GetConstant(Smi::Handle(Smi::New(
2569 FlowGraphCompiler::ElementSizeFor(view_cid) - 1)));
2570 // adjusted_length = len_in_bytes - (element_size - 1).
2571 BinarySmiOpInstr* adjusted_length =
2572 new BinarySmiOpInstr(Token::kSUB,
2573 new Value(len_in_bytes),
2574 new Value(length_adjustment),
2575 call->deopt_id());
2576 *cursor = flow_graph()->AppendTo(*cursor, adjusted_length, call->env(),
2577 Definition::kValue);
2578
2579 // Check adjusted_length > 0.
2580 ConstantInstr* zero = flow_graph()->GetConstant(Smi::Handle(Smi::New(0)));
2581 *cursor = flow_graph()->AppendTo(*cursor,
2582 new CheckArrayBoundInstr(
2583 new Value(adjusted_length),
2584 new Value(zero),
2585 call->deopt_id()),
2586 call->env(),
2587 Definition::kEffect);
2588 // Check 0 <= byte_index < adjusted_length.
2589 *cursor = flow_graph()->AppendTo(*cursor,
2590 new CheckArrayBoundInstr(
2591 new Value(adjusted_length),
2592 new Value(byte_index),
2593 call->deopt_id()),
2594 call->env(),
2595 Definition::kEffect);
2596
2597 if (RawObject::IsExternalTypedDataClassId(array_cid)) {
2598 LoadUntaggedInstr* elements =
2599 new LoadUntaggedInstr(new Value(*array),
2600 ExternalTypedData::data_offset());
2601 *cursor = flow_graph()->AppendTo(*cursor,
2602 elements,
2603 NULL,
2604 Definition::kValue);
2605 *array = elements;
2606 }
2607 return array_cid;
2608 }
2609
2610
2611 bool FlowGraphOptimizer::BuildByteArrayViewLoad(InstanceCallInstr* call,
2612 intptr_t view_cid) {
2456 if ((view_cid == kTypedDataFloat32x4ArrayCid) && !ShouldInlineSimd()) { 2613 if ((view_cid == kTypedDataFloat32x4ArrayCid) && !ShouldInlineSimd()) {
2457 return false; 2614 return false;
2458 } 2615 }
2459 2616
2460 Definition* array = call->ArgumentAt(0); 2617 ASSERT(call->HasICData());
2461 PrepareByteArrayViewOp(call, receiver_cid, view_cid, &array); 2618 Function& target = Function::Handle();
2619 GrowableArray<intptr_t> class_ids;
2620 call->ic_data()->GetCheckAt(0, &class_ids, &target);
2621 const intptr_t receiver_cid = class_ids[0];
2462 2622
2463 // Optimistically build a smi-checked load for Int32 and Uint32 2623 TargetEntryInstr* entry;
2464 // loads on ia32 like we do for normal array loads, and only revert to 2624 Definition* last;
2465 // mint case after deoptimizing here. 2625 if (!TryInlineRecognizedMethod(receiver_cid,
2466 intptr_t deopt_id = Isolate::kNoDeoptId; 2626 target,
2467 if ((view_cid == kTypedDataInt32ArrayCid || 2627 call,
2468 view_cid == kTypedDataUint32ArrayCid) && 2628 call->token_pos(),
2469 call->ic_data()->deopt_reason() == kDeoptUnknown) { 2629 *call->ic_data(),
2470 deopt_id = call->deopt_id(); 2630 &entry, &last)) {
2631 return false;
2471 } 2632 }
2472 Definition* byte_index = call->ArgumentAt(1); 2633
2473 LoadIndexedInstr* array_op = new LoadIndexedInstr(new Value(array), 2634 // Insert receiver class check.
2474 new Value(byte_index), 2635 AddReceiverCheck(call);
2475 1, // Index scale. 2636 // Remove the original push arguments.
2476 view_cid, 2637 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) {
2477 deopt_id); 2638 PushArgumentInstr* push = call->PushArgumentAt(i);
2478 ReplaceCall(call, array_op); 2639 push->ReplaceUsesWith(push->value()->definition());
2640 push->RemoveFromGraph();
2641 }
2642 // Replace all uses of this definition with the result.
2643 call->ReplaceUsesWith(last);
2644 // Finally insert the sequence other definition in place of this one in the
2645 // graph.
2646 call->previous()->LinkTo(entry->next());
2647 entry->UnuseAllInputs(); // Entry block is not in the graph.
2648 last->LinkTo(call);
2649 // Remove through the iterator.
2650 ASSERT(current_iterator()->Current() == call);
2651 current_iterator()->RemoveCurrentFromGraph();
2652 call->set_previous(NULL);
2653 call->set_next(NULL);
2479 return true; 2654 return true;
2480 } 2655 }
2481 2656
2482 2657
2483 bool FlowGraphOptimizer::BuildByteArrayViewStore(InstanceCallInstr* call, 2658 bool FlowGraphOptimizer::BuildByteArrayViewStore(InstanceCallInstr* call,
2484 intptr_t view_cid) { 2659 intptr_t view_cid) {
2485 if ((view_cid == kTypedDataFloat32x4ArrayCid) && !ShouldInlineSimd()) { 2660 if ((view_cid == kTypedDataFloat32x4ArrayCid) && !ShouldInlineSimd()) {
2486 return false; 2661 return false;
2487 } 2662 }
2488 ASSERT(call->HasICData()); 2663 ASSERT(call->HasICData());
(...skipping 329 matching lines...) Expand 10 before | Expand all | Expand 10 after
2818 return; 2993 return;
2819 } 2994 }
2820 if ((op_kind == Token::kSET) && 2995 if ((op_kind == Token::kSET) &&
2821 TryInlineInstanceSetter(instr, unary_checks)) { 2996 TryInlineInstanceSetter(instr, unary_checks)) {
2822 return; 2997 return;
2823 } 2998 }
2824 if (TryInlineInstanceMethod(instr)) { 2999 if (TryInlineInstanceMethod(instr)) {
2825 return; 3000 return;
2826 } 3001 }
2827 3002
2828 const bool has_one_target = unary_checks.HasOneTarget(); 3003 bool has_one_target = unary_checks.HasOneTarget();
3004
3005 if (has_one_target) {
3006 // Check if the single target is a polymorphic target, if it is,
3007 // we don't have one target.
3008 const Function& target = Function::Handle(unary_checks.GetTargetAt(0));
3009 const bool polymorphic_target = MethodRecognizer::PolymorphicTarget(target);
3010 has_one_target = !polymorphic_target;
3011 }
2829 3012
2830 if (has_one_target) { 3013 if (has_one_target) {
2831 const bool is_method_extraction = 3014 const bool is_method_extraction =
2832 Function::Handle(unary_checks.GetTargetAt(0)).IsMethodExtractor(); 3015 Function::Handle(unary_checks.GetTargetAt(0)).IsMethodExtractor();
2833 3016
2834 if ((is_method_extraction && !MethodExtractorNeedsClassCheck(instr)) || 3017 if ((is_method_extraction && !MethodExtractorNeedsClassCheck(instr)) ||
2835 (!is_method_extraction && !InstanceCallNeedsClassCheck(instr))) { 3018 (!is_method_extraction && !InstanceCallNeedsClassCheck(instr))) {
2836 const bool call_with_checks = false; 3019 const bool call_with_checks = false;
2837 PolymorphicInstanceCallInstr* call = 3020 PolymorphicInstanceCallInstr* call =
2838 new PolymorphicInstanceCallInstr(instr, unary_checks, 3021 new PolymorphicInstanceCallInstr(instr, unary_checks,
(...skipping 4925 matching lines...) Expand 10 before | Expand all | Expand 10 after
7764 } 7947 }
7765 7948
7766 // Insert materializations at environment uses. 7949 // Insert materializations at environment uses.
7767 for (intptr_t i = 0; i < exits.length(); i++) { 7950 for (intptr_t i = 0; i < exits.length(); i++) {
7768 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); 7951 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields);
7769 } 7952 }
7770 } 7953 }
7771 7954
7772 7955
7773 } // namespace dart 7956 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/intermediate_language.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698