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

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

Issue 59073003: Version 0.8.10.4 (Closed) Base URL: http://dart.googlecode.com/svn/trunk/
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 | « dart/runtime/vm/flow_graph_optimizer.h ('k') | dart/runtime/vm/flow_graph_type_propagator.cc » ('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 375 matching lines...) Expand 10 before | Expand all | Expand 10 after
386 converted = new UnboxDoubleInstr(use->CopyWithType(), deopt_id); 386 converted = new UnboxDoubleInstr(use->CopyWithType(), deopt_id);
387 } 387 }
388 } else if ((from == kTagged) && (to == kUnboxedFloat32x4)) { 388 } else if ((from == kTagged) && (to == kUnboxedFloat32x4)) {
389 ASSERT((deopt_target != NULL) || 389 ASSERT((deopt_target != NULL) ||
390 (use->Type()->ToCid() == kFloat32x4Cid)); 390 (use->Type()->ToCid() == kFloat32x4Cid));
391 const intptr_t deopt_id = (deopt_target != NULL) ? 391 const intptr_t deopt_id = (deopt_target != NULL) ?
392 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; 392 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
393 converted = new UnboxFloat32x4Instr(use->CopyWithType(), deopt_id); 393 converted = new UnboxFloat32x4Instr(use->CopyWithType(), deopt_id);
394 } else if ((from == kUnboxedFloat32x4) && (to == kTagged)) { 394 } else if ((from == kUnboxedFloat32x4) && (to == kTagged)) {
395 converted = new BoxFloat32x4Instr(use->CopyWithType()); 395 converted = new BoxFloat32x4Instr(use->CopyWithType());
396 } else if ((from == kTagged) && (to == kUnboxedUint32x4)) { 396 } else if ((from == kTagged) && (to == kUnboxedInt32x4)) {
397 ASSERT((deopt_target != NULL) || (use->Type()->ToCid() == kUint32x4Cid)); 397 ASSERT((deopt_target != NULL) || (use->Type()->ToCid() == kInt32x4Cid));
398 const intptr_t deopt_id = (deopt_target != NULL) ? 398 const intptr_t deopt_id = (deopt_target != NULL) ?
399 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; 399 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
400 converted = new UnboxUint32x4Instr(use->CopyWithType(), deopt_id); 400 converted = new UnboxInt32x4Instr(use->CopyWithType(), deopt_id);
401 } else if ((from == kUnboxedUint32x4) && (to == kTagged)) { 401 } else if ((from == kUnboxedInt32x4) && (to == kTagged)) {
402 converted = new BoxUint32x4Instr(use->CopyWithType()); 402 converted = new BoxInt32x4Instr(use->CopyWithType());
403 } else { 403 } else {
404 // We have failed to find a suitable conversion instruction. 404 // We have failed to find a suitable conversion instruction.
405 // Insert two "dummy" conversion instructions with the correct 405 // Insert two "dummy" conversion instructions with the correct
406 // "from" and "to" representation. The inserted instructions will 406 // "from" and "to" representation. The inserted instructions will
407 // trigger a deoptimization if executed. See #12417 for a discussion. 407 // trigger a deoptimization if executed. See #12417 for a discussion.
408 const intptr_t deopt_id = (deopt_target != NULL) ? 408 const intptr_t deopt_id = (deopt_target != NULL) ?
409 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; 409 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId;
410 ASSERT(from != kTagged); 410 ASSERT(from != kTagged);
411 ASSERT(to != kTagged); 411 ASSERT(to != kTagged);
412 Definition* boxed = NULL; 412 Definition* boxed = NULL;
413 if (from == kUnboxedDouble) { 413 if (from == kUnboxedDouble) {
414 boxed = new BoxDoubleInstr(use->CopyWithType()); 414 boxed = new BoxDoubleInstr(use->CopyWithType());
415 } else if (from == kUnboxedUint32x4) { 415 } else if (from == kUnboxedInt32x4) {
416 boxed = new BoxUint32x4Instr(use->CopyWithType()); 416 boxed = new BoxInt32x4Instr(use->CopyWithType());
417 } else if (from == kUnboxedFloat32x4) { 417 } else if (from == kUnboxedFloat32x4) {
418 boxed = new BoxFloat32x4Instr(use->CopyWithType()); 418 boxed = new BoxFloat32x4Instr(use->CopyWithType());
419 } else if (from == kUnboxedMint) { 419 } else if (from == kUnboxedMint) {
420 boxed = new BoxIntegerInstr(use->CopyWithType()); 420 boxed = new BoxIntegerInstr(use->CopyWithType());
421 } else { 421 } else {
422 UNIMPLEMENTED(); 422 UNIMPLEMENTED();
423 } 423 }
424 use->BindTo(boxed); 424 use->BindTo(boxed);
425 InsertBefore(insert_before, boxed, NULL, Definition::kValue); 425 InsertBefore(insert_before, boxed, NULL, Definition::kValue);
426 Value* to_value = new Value(boxed); 426 Value* to_value = new Value(boxed);
427 if (to == kUnboxedDouble) { 427 if (to == kUnboxedDouble) {
428 converted = new UnboxDoubleInstr(to_value, deopt_id); 428 converted = new UnboxDoubleInstr(to_value, deopt_id);
429 } else if (to == kUnboxedUint32x4) { 429 } else if (to == kUnboxedInt32x4) {
430 converted = new UnboxUint32x4Instr(to_value, deopt_id); 430 converted = new UnboxInt32x4Instr(to_value, deopt_id);
431 } else if (to == kUnboxedFloat32x4) { 431 } else if (to == kUnboxedFloat32x4) {
432 converted = new UnboxFloat32x4Instr(to_value, deopt_id); 432 converted = new UnboxFloat32x4Instr(to_value, deopt_id);
433 } else if (to == kUnboxedMint) { 433 } else if (to == kUnboxedMint) {
434 converted = new UnboxIntegerInstr(to_value, deopt_id); 434 converted = new UnboxIntegerInstr(to_value, deopt_id);
435 } else { 435 } else {
436 UNIMPLEMENTED(); 436 UNIMPLEMENTED();
437 } 437 }
438 } 438 }
439 ASSERT(converted != NULL); 439 ASSERT(converted != NULL);
440 use->BindTo(converted); 440 use->BindTo(converted);
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
485 485
486 switch (phi->Type()->ToCid()) { 486 switch (phi->Type()->ToCid()) {
487 case kDoubleCid: 487 case kDoubleCid:
488 unboxed = kUnboxedDouble; 488 unboxed = kUnboxedDouble;
489 break; 489 break;
490 case kFloat32x4Cid: 490 case kFloat32x4Cid:
491 if (ShouldInlineSimd()) { 491 if (ShouldInlineSimd()) {
492 unboxed = kUnboxedFloat32x4; 492 unboxed = kUnboxedFloat32x4;
493 } 493 }
494 break; 494 break;
495 case kUint32x4Cid: 495 case kInt32x4Cid:
496 if (ShouldInlineSimd()) { 496 if (ShouldInlineSimd()) {
497 unboxed = kUnboxedUint32x4; 497 unboxed = kUnboxedInt32x4;
498 } 498 }
499 break; 499 break;
500 } 500 }
501 501
502 if (unboxed != current) { 502 if (unboxed != current) {
503 phi->set_representation(unboxed); 503 phi->set_representation(unboxed);
504 return true; 504 return true;
505 } 505 }
506 506
507 return false; 507 return false;
508 } 508 }
509 509
510 510
511 void FlowGraphOptimizer::SelectRepresentations() { 511 void FlowGraphOptimizer::SelectRepresentations() {
512 // Convervatively unbox all phis that were proven to be of Double, 512 // Convervatively unbox all phis that were proven to be of Double,
513 // Float32x4, or Uint32x4 type. 513 // Float32x4, or Int32x4 type.
514 for (intptr_t i = 0; i < block_order_.length(); ++i) { 514 for (intptr_t i = 0; i < block_order_.length(); ++i) {
515 JoinEntryInstr* join_entry = block_order_[i]->AsJoinEntry(); 515 JoinEntryInstr* join_entry = block_order_[i]->AsJoinEntry();
516 if (join_entry != NULL) { 516 if (join_entry != NULL) {
517 for (PhiIterator it(join_entry); !it.Done(); it.Advance()) { 517 for (PhiIterator it(join_entry); !it.Done(); it.Advance()) {
518 PhiInstr* phi = it.Current(); 518 PhiInstr* phi = it.Current();
519 UnboxPhi(phi); 519 UnboxPhi(phi);
520 } 520 }
521 } 521 }
522 } 522 }
523 523
(...skipping 281 matching lines...) Expand 10 before | Expand all | Expand 10 after
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: 815 case MethodRecognizer::kInt32x4ArrayGetIndexed:
816 case MethodRecognizer::kUint32x4ArraySetIndexed: 816 case MethodRecognizer::kInt32x4ArraySetIndexed:
817 return kTypedDataUint32x4ArrayCid; 817 return kTypedDataInt32x4ArrayCid;
818 818
819 default: 819 default:
820 break; 820 break;
821 } 821 }
822 return kIllegalCid; 822 return kIllegalCid;
823 } 823 }
824 824
825 825
826 bool FlowGraphOptimizer::TryReplaceWithStoreIndexed(InstanceCallInstr* call) { 826 bool FlowGraphOptimizer::TryReplaceWithStoreIndexed(InstanceCallInstr* call) {
827 // Check for monomorphic IC data. 827 // Check for monomorphic IC data.
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
969 &cursor); 969 &cursor);
970 970
971 // Check if store barrier is needed. Byte arrays don't need a store barrier. 971 // Check if store barrier is needed. Byte arrays don't need a store barrier.
972 StoreBarrierType needs_store_barrier = 972 StoreBarrierType needs_store_barrier =
973 (RawObject::IsTypedDataClassId(array_cid) || 973 (RawObject::IsTypedDataClassId(array_cid) ||
974 RawObject::IsTypedDataViewClassId(array_cid) || 974 RawObject::IsTypedDataViewClassId(array_cid) ||
975 RawObject::IsExternalTypedDataClassId(array_cid)) ? kNoStoreBarrier 975 RawObject::IsExternalTypedDataClassId(array_cid)) ? kNoStoreBarrier
976 : kEmitStoreBarrier; 976 : kEmitStoreBarrier;
977 if (!value_check.IsNull()) { 977 if (!value_check.IsNull()) {
978 // No store barrier needed because checked value is a smi, an unboxed mint, 978 // No store barrier needed because checked value is a smi, an unboxed mint,
979 // an unboxed double, an unboxed Float32x4, or unboxed Uint32x4. 979 // an unboxed double, an unboxed Float32x4, or unboxed Int32x4.
980 needs_store_barrier = kNoStoreBarrier; 980 needs_store_barrier = kNoStoreBarrier;
981 Instruction* check = 981 Instruction* check =
982 GetCheckClass(stored_value, value_check, call->deopt_id()); 982 GetCheckClass(stored_value, value_check, call->deopt_id());
983 cursor = flow_graph()->AppendTo(cursor, 983 cursor = flow_graph()->AppendTo(cursor,
984 check, 984 check,
985 call->env(), 985 call->env(),
986 Definition::kEffect); 986 Definition::kEffect);
987 } 987 }
988 988
989 intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(array_cid); 989 intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(array_cid);
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1115 ic_data, entry, last); 1115 ic_data, entry, last);
1116 case MethodRecognizer::kByteArrayBaseGetFloat64: 1116 case MethodRecognizer::kByteArrayBaseGetFloat64:
1117 return InlineByteArrayViewLoad(call, receiver, receiver_cid, 1117 return InlineByteArrayViewLoad(call, receiver, receiver_cid,
1118 kTypedDataFloat64ArrayCid, 1118 kTypedDataFloat64ArrayCid,
1119 ic_data, entry, last); 1119 ic_data, entry, last);
1120 case MethodRecognizer::kByteArrayBaseGetFloat32x4: 1120 case MethodRecognizer::kByteArrayBaseGetFloat32x4:
1121 if (!ShouldInlineSimd()) return false; 1121 if (!ShouldInlineSimd()) return false;
1122 return InlineByteArrayViewLoad(call, receiver, receiver_cid, 1122 return InlineByteArrayViewLoad(call, receiver, receiver_cid,
1123 kTypedDataFloat32x4ArrayCid, 1123 kTypedDataFloat32x4ArrayCid,
1124 ic_data, entry, last); 1124 ic_data, entry, last);
1125 case MethodRecognizer::kByteArrayBaseGetUint32x4: 1125 case MethodRecognizer::kByteArrayBaseGetInt32x4:
1126 if (!ShouldInlineSimd()) return false; 1126 if (!ShouldInlineSimd()) return false;
1127 return InlineByteArrayViewLoad(call, receiver, receiver_cid, 1127 return InlineByteArrayViewLoad(call, receiver, receiver_cid,
1128 kTypedDataUint32x4ArrayCid, 1128 kTypedDataInt32x4ArrayCid,
1129 ic_data, entry, last); 1129 ic_data, entry, last);
1130 default: 1130 default:
1131 return false; 1131 return false;
1132 } 1132 }
1133 } 1133 }
1134 1134
1135 1135
1136 intptr_t FlowGraphOptimizer::PrepareInlineIndexedOp(Instruction* call, 1136 intptr_t FlowGraphOptimizer::PrepareInlineIndexedOp(Instruction* call,
1137 intptr_t array_cid, 1137 intptr_t array_cid,
1138 Definition** array, 1138 Definition** array,
(...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after
1363 } else if (HasTwoMintOrSmi(ic_data) && 1363 } else if (HasTwoMintOrSmi(ic_data) &&
1364 FlowGraphCompiler::SupportsUnboxedMints()) { 1364 FlowGraphCompiler::SupportsUnboxedMints()) {
1365 // Don't generate mint code if the IC data is marked because of an 1365 // Don't generate mint code if the IC data is marked because of an
1366 // overflow. 1366 // overflow.
1367 if (ic_data.deopt_reason() == kDeoptBinaryMintOp) return false; 1367 if (ic_data.deopt_reason() == kDeoptBinaryMintOp) return false;
1368 operands_type = kMintCid; 1368 operands_type = kMintCid;
1369 } else if (ShouldSpecializeForDouble(ic_data)) { 1369 } else if (ShouldSpecializeForDouble(ic_data)) {
1370 operands_type = kDoubleCid; 1370 operands_type = kDoubleCid;
1371 } else if (HasOnlyTwoOf(ic_data, kFloat32x4Cid)) { 1371 } else if (HasOnlyTwoOf(ic_data, kFloat32x4Cid)) {
1372 operands_type = kFloat32x4Cid; 1372 operands_type = kFloat32x4Cid;
1373 } else if (HasOnlyTwoOf(ic_data, kUint32x4Cid)) { 1373 } else if (HasOnlyTwoOf(ic_data, kInt32x4Cid)) {
1374 operands_type = kUint32x4Cid; 1374 operands_type = kInt32x4Cid;
1375 } else { 1375 } else {
1376 return false; 1376 return false;
1377 } 1377 }
1378 break; 1378 break;
1379 case Token::kMUL: 1379 case Token::kMUL:
1380 if (HasOnlyTwoOf(ic_data, kSmiCid)) { 1380 if (HasOnlyTwoOf(ic_data, kSmiCid)) {
1381 // Don't generate smi code if the IC data is marked because of an 1381 // Don't generate smi code if the IC data is marked because of an
1382 // overflow. 1382 // overflow.
1383 // TODO(fschneider): Add unboxed mint multiplication. 1383 // TODO(fschneider): Add unboxed mint multiplication.
1384 if (ic_data.deopt_reason() == kDeoptBinarySmiOp) return false; 1384 if (ic_data.deopt_reason() == kDeoptBinarySmiOp) return false;
(...skipping 23 matching lines...) Expand all
1408 return false; 1408 return false;
1409 } 1409 }
1410 break; 1410 break;
1411 case Token::kBIT_AND: 1411 case Token::kBIT_AND:
1412 case Token::kBIT_OR: 1412 case Token::kBIT_OR:
1413 case Token::kBIT_XOR: 1413 case Token::kBIT_XOR:
1414 if (HasOnlyTwoOf(ic_data, kSmiCid)) { 1414 if (HasOnlyTwoOf(ic_data, kSmiCid)) {
1415 operands_type = kSmiCid; 1415 operands_type = kSmiCid;
1416 } else if (HasTwoMintOrSmi(ic_data)) { 1416 } else if (HasTwoMintOrSmi(ic_data)) {
1417 operands_type = kMintCid; 1417 operands_type = kMintCid;
1418 } else if (HasOnlyTwoOf(ic_data, kUint32x4Cid)) { 1418 } else if (HasOnlyTwoOf(ic_data, kInt32x4Cid)) {
1419 operands_type = kUint32x4Cid; 1419 operands_type = kInt32x4Cid;
1420 } else { 1420 } else {
1421 return false; 1421 return false;
1422 } 1422 }
1423 break; 1423 break;
1424 case Token::kSHR: 1424 case Token::kSHR:
1425 case Token::kSHL: 1425 case Token::kSHL:
1426 if (HasOnlyTwoOf(ic_data, kSmiCid)) { 1426 if (HasOnlyTwoOf(ic_data, kSmiCid)) {
1427 // Left shift may overflow from smi into mint or big ints. 1427 // Left shift may overflow from smi into mint or big ints.
1428 // Don't generate smi code if the IC data is marked because 1428 // Don't generate smi code if the IC data is marked because
1429 // of an overflow. 1429 // of an overflow.
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1483 call->deopt_id()); 1483 call->deopt_id());
1484 ReplaceCall(call, shift_op); 1484 ReplaceCall(call, shift_op);
1485 } else { 1485 } else {
1486 BinaryMintOpInstr* bin_op = 1486 BinaryMintOpInstr* bin_op =
1487 new BinaryMintOpInstr(op_kind, new Value(left), new Value(right), 1487 new BinaryMintOpInstr(op_kind, new Value(left), new Value(right),
1488 call->deopt_id()); 1488 call->deopt_id());
1489 ReplaceCall(call, bin_op); 1489 ReplaceCall(call, bin_op);
1490 } 1490 }
1491 } else if (operands_type == kFloat32x4Cid) { 1491 } else if (operands_type == kFloat32x4Cid) {
1492 return InlineFloat32x4BinaryOp(call, op_kind); 1492 return InlineFloat32x4BinaryOp(call, op_kind);
1493 } else if (operands_type == kUint32x4Cid) { 1493 } else if (operands_type == kInt32x4Cid) {
1494 return InlineUint32x4BinaryOp(call, op_kind); 1494 return InlineInt32x4BinaryOp(call, op_kind);
1495 } else if (op_kind == Token::kMOD) { 1495 } else if (op_kind == Token::kMOD) {
1496 // TODO(vegorov): implement fast path code for modulo. 1496 // TODO(vegorov): implement fast path code for modulo.
1497 ASSERT(operands_type == kSmiCid); 1497 ASSERT(operands_type == kSmiCid);
1498 if (!right->IsConstant()) return false; 1498 if (!right->IsConstant()) return false;
1499 const Object& obj = right->AsConstant()->value(); 1499 const Object& obj = right->AsConstant()->value();
1500 if (!obj.IsSmi()) return false; 1500 if (!obj.IsSmi()) return false;
1501 const intptr_t value = Smi::Cast(obj).Value(); 1501 const intptr_t value = Smi::Cast(obj).Value();
1502 if (!Utils::IsPowerOfTwo(value)) return false; 1502 if (!Utils::IsPowerOfTwo(value)) return false;
1503 1503
1504 // Insert smi check and attach a copy of the original environment 1504 // Insert smi check and attach a copy of the original environment
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
1748 mask, 1748 mask,
1749 call->deopt_id()); 1749 call->deopt_id());
1750 ReplaceCall(call, instr); 1750 ReplaceCall(call, instr);
1751 return true; 1751 return true;
1752 } 1752 }
1753 UNREACHABLE(); 1753 UNREACHABLE();
1754 return false; 1754 return false;
1755 } 1755 }
1756 1756
1757 1757
1758 bool FlowGraphOptimizer::InlineUint32x4Getter(InstanceCallInstr* call, 1758 bool FlowGraphOptimizer::InlineInt32x4Getter(InstanceCallInstr* call,
1759 MethodRecognizer::Kind getter) { 1759 MethodRecognizer::Kind getter) {
1760 if (!ShouldInlineSimd()) { 1760 if (!ShouldInlineSimd()) {
1761 return false; 1761 return false;
1762 } 1762 }
1763 AddCheckClass(call->ArgumentAt(0), 1763 AddCheckClass(call->ArgumentAt(0),
1764 ICData::ZoneHandle( 1764 ICData::ZoneHandle(
1765 call->ic_data()->AsUnaryClassChecksForArgNr(0)), 1765 call->ic_data()->AsUnaryClassChecksForArgNr(0)),
1766 call->deopt_id(), 1766 call->deopt_id(),
1767 call->env(), 1767 call->env(),
1768 call); 1768 call);
1769 intptr_t mask = 0; 1769 intptr_t mask = 0;
1770 if ((getter == MethodRecognizer::kUint32x4Shuffle) || 1770 if ((getter == MethodRecognizer::kInt32x4Shuffle) ||
1771 (getter == MethodRecognizer::kUint32x4ShuffleMix)) { 1771 (getter == MethodRecognizer::kInt32x4ShuffleMix)) {
1772 // Extract shuffle mask. 1772 // Extract shuffle mask.
1773 Definition* mask_definition = NULL; 1773 Definition* mask_definition = NULL;
1774 if (getter == MethodRecognizer::kUint32x4Shuffle) { 1774 if (getter == MethodRecognizer::kInt32x4Shuffle) {
1775 ASSERT(call->ArgumentCount() == 2); 1775 ASSERT(call->ArgumentCount() == 2);
1776 mask_definition = call->ArgumentAt(1); 1776 mask_definition = call->ArgumentAt(1);
1777 } else { 1777 } else {
1778 ASSERT(getter == MethodRecognizer::kUint32x4ShuffleMix); 1778 ASSERT(getter == MethodRecognizer::kInt32x4ShuffleMix);
1779 ASSERT(call->ArgumentCount() == 3); 1779 ASSERT(call->ArgumentCount() == 3);
1780 mask_definition = call->ArgumentAt(2); 1780 mask_definition = call->ArgumentAt(2);
1781 } 1781 }
1782 if (!mask_definition->IsConstant()) { 1782 if (!mask_definition->IsConstant()) {
1783 return false; 1783 return false;
1784 } 1784 }
1785 ASSERT(mask_definition->IsConstant()); 1785 ASSERT(mask_definition->IsConstant());
1786 ConstantInstr* constant_instruction = mask_definition->AsConstant(); 1786 ConstantInstr* constant_instruction = mask_definition->AsConstant();
1787 const Object& constant_mask = constant_instruction->value(); 1787 const Object& constant_mask = constant_instruction->value();
1788 if (!constant_mask.IsSmi()) { 1788 if (!constant_mask.IsSmi()) {
1789 return false; 1789 return false;
1790 } 1790 }
1791 ASSERT(constant_mask.IsSmi()); 1791 ASSERT(constant_mask.IsSmi());
1792 mask = Smi::Cast(constant_mask).Value(); 1792 mask = Smi::Cast(constant_mask).Value();
1793 if ((mask < 0) || (mask > 255)) { 1793 if ((mask < 0) || (mask > 255)) {
1794 // Not a valid mask. 1794 // Not a valid mask.
1795 return false; 1795 return false;
1796 } 1796 }
1797 } 1797 }
1798 if (getter == MethodRecognizer::kUint32x4GetSignMask) { 1798 if (getter == MethodRecognizer::kInt32x4GetSignMask) {
1799 Simd32x4GetSignMaskInstr* instr = new Simd32x4GetSignMaskInstr( 1799 Simd32x4GetSignMaskInstr* instr = new Simd32x4GetSignMaskInstr(
1800 getter, 1800 getter,
1801 new Value(call->ArgumentAt(0)), 1801 new Value(call->ArgumentAt(0)),
1802 call->deopt_id()); 1802 call->deopt_id());
1803 ReplaceCall(call, instr); 1803 ReplaceCall(call, instr);
1804 return true; 1804 return true;
1805 } else if (getter == MethodRecognizer::kUint32x4ShuffleMix) { 1805 } else if (getter == MethodRecognizer::kInt32x4ShuffleMix) {
1806 Simd32x4ShuffleMixInstr* instr = new Simd32x4ShuffleMixInstr( 1806 Simd32x4ShuffleMixInstr* instr = new Simd32x4ShuffleMixInstr(
1807 getter, 1807 getter,
1808 new Value(call->ArgumentAt(0)), 1808 new Value(call->ArgumentAt(0)),
1809 new Value(call->ArgumentAt(1)), 1809 new Value(call->ArgumentAt(1)),
1810 mask, 1810 mask,
1811 call->deopt_id()); 1811 call->deopt_id());
1812 ReplaceCall(call, instr); 1812 ReplaceCall(call, instr);
1813 return true; 1813 return true;
1814 } else if (getter == MethodRecognizer::kUint32x4Shuffle) { 1814 } else if (getter == MethodRecognizer::kInt32x4Shuffle) {
1815 Simd32x4ShuffleInstr* instr = new Simd32x4ShuffleInstr( 1815 Simd32x4ShuffleInstr* instr = new Simd32x4ShuffleInstr(
1816 getter, 1816 getter,
1817 new Value(call->ArgumentAt(0)), 1817 new Value(call->ArgumentAt(0)),
1818 mask, 1818 mask,
1819 call->deopt_id()); 1819 call->deopt_id());
1820 ReplaceCall(call, instr); 1820 ReplaceCall(call, instr);
1821 return true; 1821 return true;
1822 } else { 1822 } else {
1823 Uint32x4GetFlagInstr* instr = new Uint32x4GetFlagInstr( 1823 Int32x4GetFlagInstr* instr = new Int32x4GetFlagInstr(
1824 getter, 1824 getter,
1825 new Value(call->ArgumentAt(0)), 1825 new Value(call->ArgumentAt(0)),
1826 call->deopt_id()); 1826 call->deopt_id());
1827 ReplaceCall(call, instr); 1827 ReplaceCall(call, instr);
1828 return true; 1828 return true;
1829 } 1829 }
1830 } 1830 }
1831 1831
1832 1832
1833 bool FlowGraphOptimizer::InlineFloat32x4BinaryOp(InstanceCallInstr* call, 1833 bool FlowGraphOptimizer::InlineFloat32x4BinaryOp(InstanceCallInstr* call,
(...skipping 21 matching lines...) Expand all
1855 // Replace call. 1855 // Replace call.
1856 BinaryFloat32x4OpInstr* float32x4_bin_op = 1856 BinaryFloat32x4OpInstr* float32x4_bin_op =
1857 new BinaryFloat32x4OpInstr(op_kind, new Value(left), new Value(right), 1857 new BinaryFloat32x4OpInstr(op_kind, new Value(left), new Value(right),
1858 call->deopt_id()); 1858 call->deopt_id());
1859 ReplaceCall(call, float32x4_bin_op); 1859 ReplaceCall(call, float32x4_bin_op);
1860 1860
1861 return true; 1861 return true;
1862 } 1862 }
1863 1863
1864 1864
1865 bool FlowGraphOptimizer::InlineUint32x4BinaryOp(InstanceCallInstr* call, 1865 bool FlowGraphOptimizer::InlineInt32x4BinaryOp(InstanceCallInstr* call,
1866 Token::Kind op_kind) { 1866 Token::Kind op_kind) {
1867 if (!ShouldInlineSimd()) { 1867 if (!ShouldInlineSimd()) {
1868 return false; 1868 return false;
1869 } 1869 }
1870 ASSERT(call->ArgumentCount() == 2); 1870 ASSERT(call->ArgumentCount() == 2);
1871 Definition* left = call->ArgumentAt(0); 1871 Definition* left = call->ArgumentAt(0);
1872 Definition* right = call->ArgumentAt(1); 1872 Definition* right = call->ArgumentAt(1);
1873 // Type check left. 1873 // Type check left.
1874 AddCheckClass(left, 1874 AddCheckClass(left,
1875 ICData::ZoneHandle( 1875 ICData::ZoneHandle(
1876 call->ic_data()->AsUnaryClassChecksForArgNr(0)), 1876 call->ic_data()->AsUnaryClassChecksForArgNr(0)),
1877 call->deopt_id(), 1877 call->deopt_id(),
1878 call->env(), 1878 call->env(),
1879 call); 1879 call);
1880 // Type check right. 1880 // Type check right.
1881 AddCheckClass(right, 1881 AddCheckClass(right,
1882 ICData::ZoneHandle( 1882 ICData::ZoneHandle(
1883 call->ic_data()->AsUnaryClassChecksForArgNr(1)), 1883 call->ic_data()->AsUnaryClassChecksForArgNr(1)),
1884 call->deopt_id(), 1884 call->deopt_id(),
1885 call->env(), 1885 call->env(),
1886 call); 1886 call);
1887 // Replace call. 1887 // Replace call.
1888 BinaryUint32x4OpInstr* uint32x4_bin_op = 1888 BinaryInt32x4OpInstr* int32x4_bin_op =
1889 new BinaryUint32x4OpInstr(op_kind, new Value(left), new Value(right), 1889 new BinaryInt32x4OpInstr(op_kind, new Value(left), new Value(right),
1890 call->deopt_id()); 1890 call->deopt_id());
1891 ReplaceCall(call, uint32x4_bin_op); 1891 ReplaceCall(call, int32x4_bin_op);
1892 return true; 1892 return true;
1893 } 1893 }
1894 1894
1895 1895
1896 // Only unique implicit instance getters can be currently handled. 1896 // Only unique implicit instance getters can be currently handled.
1897 bool FlowGraphOptimizer::TryInlineInstanceGetter(InstanceCallInstr* call) { 1897 bool FlowGraphOptimizer::TryInlineInstanceGetter(InstanceCallInstr* call) {
1898 ASSERT(call->HasICData()); 1898 ASSERT(call->HasICData());
1899 const ICData& ic_data = *call->ic_data(); 1899 const ICData& ic_data = *call->ic_data();
1900 if (ic_data.NumberOfChecks() == 0) { 1900 if (ic_data.NumberOfChecks() == 0) {
1901 // No type feedback collected. 1901 // No type feedback collected.
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1980 case kExternalTypedDataUint8ArrayCid: 1980 case kExternalTypedDataUint8ArrayCid:
1981 case kTypedDataUint8ClampedArrayCid: 1981 case kTypedDataUint8ClampedArrayCid:
1982 case kExternalTypedDataUint8ClampedArrayCid: 1982 case kExternalTypedDataUint8ClampedArrayCid:
1983 case kTypedDataInt16ArrayCid: 1983 case kTypedDataInt16ArrayCid:
1984 case kTypedDataUint16ArrayCid: 1984 case kTypedDataUint16ArrayCid:
1985 case kTypedDataInt32ArrayCid: 1985 case kTypedDataInt32ArrayCid:
1986 case kTypedDataUint32ArrayCid: 1986 case kTypedDataUint32ArrayCid:
1987 case kTypedDataFloat32ArrayCid: 1987 case kTypedDataFloat32ArrayCid:
1988 case kTypedDataFloat64ArrayCid: 1988 case kTypedDataFloat64ArrayCid:
1989 case kTypedDataFloat32x4ArrayCid: 1989 case kTypedDataFloat32x4ArrayCid:
1990 case kTypedDataUint32x4ArrayCid: 1990 case kTypedDataInt32x4ArrayCid:
1991 return true; 1991 return true;
1992 default: 1992 default:
1993 return false; 1993 return false;
1994 } 1994 }
1995 } 1995 }
1996 1996
1997 1997
1998 // Inline only simple, frequently called core library methods. 1998 // Inline only simple, frequently called core library methods.
1999 bool FlowGraphOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) { 1999 bool FlowGraphOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) {
2000 ASSERT(call->HasICData()); 2000 ASSERT(call->HasICData());
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
2154 case MethodRecognizer::kByteArrayBaseGetInt32: 2154 case MethodRecognizer::kByteArrayBaseGetInt32:
2155 return BuildByteArrayViewLoad(call, kTypedDataInt32ArrayCid); 2155 return BuildByteArrayViewLoad(call, kTypedDataInt32ArrayCid);
2156 case MethodRecognizer::kByteArrayBaseGetUint32: 2156 case MethodRecognizer::kByteArrayBaseGetUint32:
2157 return BuildByteArrayViewLoad(call, kTypedDataUint32ArrayCid); 2157 return BuildByteArrayViewLoad(call, kTypedDataUint32ArrayCid);
2158 case MethodRecognizer::kByteArrayBaseGetFloat32: 2158 case MethodRecognizer::kByteArrayBaseGetFloat32:
2159 return BuildByteArrayViewLoad(call, kTypedDataFloat32ArrayCid); 2159 return BuildByteArrayViewLoad(call, kTypedDataFloat32ArrayCid);
2160 case MethodRecognizer::kByteArrayBaseGetFloat64: 2160 case MethodRecognizer::kByteArrayBaseGetFloat64:
2161 return BuildByteArrayViewLoad(call, kTypedDataFloat64ArrayCid); 2161 return BuildByteArrayViewLoad(call, kTypedDataFloat64ArrayCid);
2162 case MethodRecognizer::kByteArrayBaseGetFloat32x4: 2162 case MethodRecognizer::kByteArrayBaseGetFloat32x4:
2163 return BuildByteArrayViewLoad(call, kTypedDataFloat32x4ArrayCid); 2163 return BuildByteArrayViewLoad(call, kTypedDataFloat32x4ArrayCid);
2164 case MethodRecognizer::kByteArrayBaseGetUint32x4: 2164 case MethodRecognizer::kByteArrayBaseGetInt32x4:
2165 return BuildByteArrayViewLoad(call, kTypedDataUint32x4ArrayCid); 2165 return BuildByteArrayViewLoad(call, kTypedDataInt32x4ArrayCid);
2166 2166
2167 // ByteArray setters. 2167 // ByteArray setters.
2168 case MethodRecognizer::kByteArrayBaseSetInt8: 2168 case MethodRecognizer::kByteArrayBaseSetInt8:
2169 return BuildByteArrayViewStore(call, kTypedDataInt8ArrayCid); 2169 return BuildByteArrayViewStore(call, kTypedDataInt8ArrayCid);
2170 case MethodRecognizer::kByteArrayBaseSetUint8: 2170 case MethodRecognizer::kByteArrayBaseSetUint8:
2171 return BuildByteArrayViewStore(call, kTypedDataUint8ArrayCid); 2171 return BuildByteArrayViewStore(call, kTypedDataUint8ArrayCid);
2172 case MethodRecognizer::kByteArrayBaseSetInt16: 2172 case MethodRecognizer::kByteArrayBaseSetInt16:
2173 return BuildByteArrayViewStore(call, kTypedDataInt16ArrayCid); 2173 return BuildByteArrayViewStore(call, kTypedDataInt16ArrayCid);
2174 case MethodRecognizer::kByteArrayBaseSetUint16: 2174 case MethodRecognizer::kByteArrayBaseSetUint16:
2175 return BuildByteArrayViewStore(call, kTypedDataUint16ArrayCid); 2175 return BuildByteArrayViewStore(call, kTypedDataUint16ArrayCid);
2176 case MethodRecognizer::kByteArrayBaseSetInt32: 2176 case MethodRecognizer::kByteArrayBaseSetInt32:
2177 return BuildByteArrayViewStore(call, kTypedDataInt32ArrayCid); 2177 return BuildByteArrayViewStore(call, kTypedDataInt32ArrayCid);
2178 case MethodRecognizer::kByteArrayBaseSetUint32: 2178 case MethodRecognizer::kByteArrayBaseSetUint32:
2179 return BuildByteArrayViewStore(call, kTypedDataUint32ArrayCid); 2179 return BuildByteArrayViewStore(call, kTypedDataUint32ArrayCid);
2180 case MethodRecognizer::kByteArrayBaseSetFloat32: 2180 case MethodRecognizer::kByteArrayBaseSetFloat32:
2181 return BuildByteArrayViewStore(call, kTypedDataFloat32ArrayCid); 2181 return BuildByteArrayViewStore(call, kTypedDataFloat32ArrayCid);
2182 case MethodRecognizer::kByteArrayBaseSetFloat64: 2182 case MethodRecognizer::kByteArrayBaseSetFloat64:
2183 return BuildByteArrayViewStore(call, kTypedDataFloat64ArrayCid); 2183 return BuildByteArrayViewStore(call, kTypedDataFloat64ArrayCid);
2184 case MethodRecognizer::kByteArrayBaseSetFloat32x4: 2184 case MethodRecognizer::kByteArrayBaseSetFloat32x4:
2185 return BuildByteArrayViewStore(call, kTypedDataFloat32x4ArrayCid); 2185 return BuildByteArrayViewStore(call, kTypedDataFloat32x4ArrayCid);
2186 case MethodRecognizer::kByteArrayBaseSetUint32x4: 2186 case MethodRecognizer::kByteArrayBaseSetInt32x4:
2187 return BuildByteArrayViewStore(call, kTypedDataUint32x4ArrayCid); 2187 return BuildByteArrayViewStore(call, kTypedDataInt32x4ArrayCid);
2188 default: 2188 default:
2189 // Unsupported method. 2189 // Unsupported method.
2190 return false; 2190 return false;
2191 } 2191 }
2192 } 2192 }
2193 2193
2194 if ((class_ids[0] == kFloat32x4Cid) && (ic_data.NumberOfChecks() == 1)) { 2194 if ((class_ids[0] == kFloat32x4Cid) && (ic_data.NumberOfChecks() == 1)) {
2195 return TryInlineFloat32x4Method(call, recognized_kind); 2195 return TryInlineFloat32x4Method(call, recognized_kind);
2196 } 2196 }
2197 2197
2198 if ((class_ids[0] == kUint32x4Cid) && (ic_data.NumberOfChecks() == 1)) { 2198 if ((class_ids[0] == kInt32x4Cid) && (ic_data.NumberOfChecks() == 1)) {
2199 return TryInlineUint32x4Method(call, recognized_kind); 2199 return TryInlineInt32x4Method(call, recognized_kind);
2200 } 2200 }
2201 2201
2202 if (recognized_kind == MethodRecognizer::kIntegerLeftShiftWithMask32) { 2202 if (recognized_kind == MethodRecognizer::kIntegerLeftShiftWithMask32) {
2203 ASSERT(call->ArgumentCount() == 3); 2203 ASSERT(call->ArgumentCount() == 3);
2204 ASSERT(ic_data.num_args_tested() == 2); 2204 ASSERT(ic_data.num_args_tested() == 2);
2205 Definition* value = call->ArgumentAt(0); 2205 Definition* value = call->ArgumentAt(0);
2206 Definition* count = call->ArgumentAt(1); 2206 Definition* count = call->ArgumentAt(1);
2207 Definition* int32_mask = call->ArgumentAt(2); 2207 Definition* int32_mask = call->ArgumentAt(2);
2208 if (HasOnlyTwoOf(ic_data, kSmiCid)) { 2208 if (HasOnlyTwoOf(ic_data, kSmiCid)) {
2209 if (ic_data.deopt_reason() == kDeoptShiftMintOp) { 2209 if (ic_data.deopt_reason() == kDeoptShiftMintOp) {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
2281 return true; 2281 return true;
2282 } else if (recognized_kind == MethodRecognizer::kFloat32x4Constructor) { 2282 } else if (recognized_kind == MethodRecognizer::kFloat32x4Constructor) {
2283 Float32x4ConstructorInstr* con = 2283 Float32x4ConstructorInstr* con =
2284 new Float32x4ConstructorInstr(new Value(call->ArgumentAt(1)), 2284 new Float32x4ConstructorInstr(new Value(call->ArgumentAt(1)),
2285 new Value(call->ArgumentAt(2)), 2285 new Value(call->ArgumentAt(2)),
2286 new Value(call->ArgumentAt(3)), 2286 new Value(call->ArgumentAt(3)),
2287 new Value(call->ArgumentAt(4)), 2287 new Value(call->ArgumentAt(4)),
2288 call->deopt_id()); 2288 call->deopt_id());
2289 ReplaceCall(call, con); 2289 ReplaceCall(call, con);
2290 return true; 2290 return true;
2291 } else if (recognized_kind == MethodRecognizer::kFloat32x4FromUint32x4Bits) { 2291 } else if (recognized_kind == MethodRecognizer::kFloat32x4FromInt32x4Bits) {
2292 Uint32x4ToFloat32x4Instr* cast = 2292 Int32x4ToFloat32x4Instr* cast =
2293 new Uint32x4ToFloat32x4Instr(new Value(call->ArgumentAt(1)), 2293 new Int32x4ToFloat32x4Instr(new Value(call->ArgumentAt(1)),
2294 call->deopt_id()); 2294 call->deopt_id());
2295 ReplaceCall(call, cast); 2295 ReplaceCall(call, cast);
2296 return true; 2296 return true;
2297 } 2297 }
2298 return false; 2298 return false;
2299 } 2299 }
2300 2300
2301 2301
2302 bool FlowGraphOptimizer::TryInlineUint32x4Constructor( 2302 bool FlowGraphOptimizer::TryInlineInt32x4Constructor(
2303 StaticCallInstr* call, 2303 StaticCallInstr* call,
2304 MethodRecognizer::Kind recognized_kind) { 2304 MethodRecognizer::Kind recognized_kind) {
2305 if (!ShouldInlineSimd()) { 2305 if (!ShouldInlineSimd()) {
2306 return false; 2306 return false;
2307 } 2307 }
2308 if (recognized_kind == MethodRecognizer::kUint32x4BoolConstructor) { 2308 if (recognized_kind == MethodRecognizer::kInt32x4BoolConstructor) {
2309 Uint32x4BoolConstructorInstr* con = new Uint32x4BoolConstructorInstr( 2309 Int32x4BoolConstructorInstr* con = new Int32x4BoolConstructorInstr(
2310 new Value(call->ArgumentAt(1)), 2310 new Value(call->ArgumentAt(1)),
2311 new Value(call->ArgumentAt(2)), 2311 new Value(call->ArgumentAt(2)),
2312 new Value(call->ArgumentAt(3)), 2312 new Value(call->ArgumentAt(3)),
2313 new Value(call->ArgumentAt(4)), 2313 new Value(call->ArgumentAt(4)),
2314 call->deopt_id()); 2314 call->deopt_id());
2315 ReplaceCall(call, con); 2315 ReplaceCall(call, con);
2316 return true; 2316 return true;
2317 } else if (recognized_kind == MethodRecognizer::kUint32x4FromFloat32x4Bits) { 2317 } else if (recognized_kind == MethodRecognizer::kInt32x4FromFloat32x4Bits) {
2318 Float32x4ToUint32x4Instr* cast = 2318 Float32x4ToInt32x4Instr* cast =
2319 new Float32x4ToUint32x4Instr(new Value(call->ArgumentAt(1)), 2319 new Float32x4ToInt32x4Instr(new Value(call->ArgumentAt(1)),
2320 call->deopt_id()); 2320 call->deopt_id());
2321 ReplaceCall(call, cast); 2321 ReplaceCall(call, cast);
2322 return true; 2322 return true;
2323 } 2323 }
2324 return false; 2324 return false;
2325 } 2325 }
2326 2326
2327 2327
2328 bool FlowGraphOptimizer::TryInlineFloat32x4Method( 2328 bool FlowGraphOptimizer::TryInlineFloat32x4Method(
2329 InstanceCallInstr* call, 2329 InstanceCallInstr* call,
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
2473 case MethodRecognizer::kFloat32x4ShuffleMix: 2473 case MethodRecognizer::kFloat32x4ShuffleMix:
2474 case MethodRecognizer::kFloat32x4Shuffle: { 2474 case MethodRecognizer::kFloat32x4Shuffle: {
2475 return InlineFloat32x4Getter(call, recognized_kind); 2475 return InlineFloat32x4Getter(call, recognized_kind);
2476 } 2476 }
2477 default: 2477 default:
2478 return false; 2478 return false;
2479 } 2479 }
2480 } 2480 }
2481 2481
2482 2482
2483 bool FlowGraphOptimizer::TryInlineUint32x4Method( 2483 bool FlowGraphOptimizer::TryInlineInt32x4Method(
2484 InstanceCallInstr* call, 2484 InstanceCallInstr* call,
2485 MethodRecognizer::Kind recognized_kind) { 2485 MethodRecognizer::Kind recognized_kind) {
2486 if (!ShouldInlineSimd()) { 2486 if (!ShouldInlineSimd()) {
2487 return false; 2487 return false;
2488 } 2488 }
2489 ASSERT(call->HasICData()); 2489 ASSERT(call->HasICData());
2490 switch (recognized_kind) { 2490 switch (recognized_kind) {
2491 case MethodRecognizer::kUint32x4ShuffleMix: 2491 case MethodRecognizer::kInt32x4ShuffleMix:
2492 case MethodRecognizer::kUint32x4Shuffle: 2492 case MethodRecognizer::kInt32x4Shuffle:
2493 case MethodRecognizer::kUint32x4GetFlagX: 2493 case MethodRecognizer::kInt32x4GetFlagX:
2494 case MethodRecognizer::kUint32x4GetFlagY: 2494 case MethodRecognizer::kInt32x4GetFlagY:
2495 case MethodRecognizer::kUint32x4GetFlagZ: 2495 case MethodRecognizer::kInt32x4GetFlagZ:
2496 case MethodRecognizer::kUint32x4GetFlagW: 2496 case MethodRecognizer::kInt32x4GetFlagW:
2497 case MethodRecognizer::kUint32x4GetSignMask: 2497 case MethodRecognizer::kInt32x4GetSignMask:
2498 ASSERT(call->ic_data()->HasReceiverClassId(kUint32x4Cid)); 2498 ASSERT(call->ic_data()->HasReceiverClassId(kInt32x4Cid));
2499 ASSERT(call->ic_data()->HasOneTarget()); 2499 ASSERT(call->ic_data()->HasOneTarget());
2500 return InlineUint32x4Getter(call, recognized_kind); 2500 return InlineInt32x4Getter(call, recognized_kind);
2501 2501
2502 case MethodRecognizer::kUint32x4Select: { 2502 case MethodRecognizer::kInt32x4Select: {
2503 Definition* mask = call->ArgumentAt(0); 2503 Definition* mask = call->ArgumentAt(0);
2504 Definition* trueValue = call->ArgumentAt(1); 2504 Definition* trueValue = call->ArgumentAt(1);
2505 Definition* falseValue = call->ArgumentAt(2); 2505 Definition* falseValue = call->ArgumentAt(2);
2506 // Type check left. 2506 // Type check left.
2507 AddCheckClass(mask, 2507 AddCheckClass(mask,
2508 ICData::ZoneHandle( 2508 ICData::ZoneHandle(
2509 call->ic_data()->AsUnaryClassChecksForArgNr(0)), 2509 call->ic_data()->AsUnaryClassChecksForArgNr(0)),
2510 call->deopt_id(), 2510 call->deopt_id(),
2511 call->env(), 2511 call->env(),
2512 call); 2512 call);
2513 Uint32x4SelectInstr* select = new Uint32x4SelectInstr( 2513 Int32x4SelectInstr* select = new Int32x4SelectInstr(
2514 new Value(mask), 2514 new Value(mask),
2515 new Value(trueValue), 2515 new Value(trueValue),
2516 new Value(falseValue), 2516 new Value(falseValue),
2517 call->deopt_id()); 2517 call->deopt_id());
2518 ReplaceCall(call, select); 2518 ReplaceCall(call, select);
2519 return true; 2519 return true;
2520 } 2520 }
2521 case MethodRecognizer::kUint32x4WithFlagX: 2521 case MethodRecognizer::kInt32x4WithFlagX:
2522 case MethodRecognizer::kUint32x4WithFlagY: 2522 case MethodRecognizer::kInt32x4WithFlagY:
2523 case MethodRecognizer::kUint32x4WithFlagZ: 2523 case MethodRecognizer::kInt32x4WithFlagZ:
2524 case MethodRecognizer::kUint32x4WithFlagW: { 2524 case MethodRecognizer::kInt32x4WithFlagW: {
2525 Definition* left = call->ArgumentAt(0); 2525 Definition* left = call->ArgumentAt(0);
2526 Definition* flag = call->ArgumentAt(1); 2526 Definition* flag = call->ArgumentAt(1);
2527 // Type check left. 2527 // Type check left.
2528 AddCheckClass(left, 2528 AddCheckClass(left,
2529 ICData::ZoneHandle( 2529 ICData::ZoneHandle(
2530 call->ic_data()->AsUnaryClassChecksForArgNr(0)), 2530 call->ic_data()->AsUnaryClassChecksForArgNr(0)),
2531 call->deopt_id(), 2531 call->deopt_id(),
2532 call->env(), 2532 call->env(),
2533 call); 2533 call);
2534 Uint32x4SetFlagInstr* setFlag = new Uint32x4SetFlagInstr( 2534 Int32x4SetFlagInstr* setFlag = new Int32x4SetFlagInstr(
2535 recognized_kind, 2535 recognized_kind,
2536 new Value(left), 2536 new Value(left),
2537 new Value(flag), 2537 new Value(flag),
2538 call->deopt_id()); 2538 call->deopt_id());
2539 ReplaceCall(call, setFlag); 2539 ReplaceCall(call, setFlag);
2540 return true; 2540 return true;
2541 } 2541 }
2542 default: 2542 default:
2543 return false; 2543 return false;
2544 } 2544 }
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
2668 Definition::kValue); 2668 Definition::kValue);
2669 *array = elements; 2669 *array = elements;
2670 } 2670 }
2671 return array_cid; 2671 return array_cid;
2672 } 2672 }
2673 2673
2674 2674
2675 bool FlowGraphOptimizer::BuildByteArrayViewLoad(InstanceCallInstr* call, 2675 bool FlowGraphOptimizer::BuildByteArrayViewLoad(InstanceCallInstr* call,
2676 intptr_t view_cid) { 2676 intptr_t view_cid) {
2677 bool simd_view = (view_cid == kTypedDataFloat32x4ArrayCid) || 2677 bool simd_view = (view_cid == kTypedDataFloat32x4ArrayCid) ||
2678 (view_cid == kTypedDataUint32x4ArrayCid); 2678 (view_cid == kTypedDataInt32x4ArrayCid);
2679 if (simd_view && !ShouldInlineSimd()) { 2679 if (simd_view && !ShouldInlineSimd()) {
2680 return false; 2680 return false;
2681 } 2681 }
2682 2682
2683 ASSERT(call->HasICData()); 2683 ASSERT(call->HasICData());
2684 Function& target = Function::Handle(); 2684 Function& target = Function::Handle();
2685 GrowableArray<intptr_t> class_ids; 2685 GrowableArray<intptr_t> class_ids;
2686 call->ic_data()->GetCheckAt(0, &class_ids, &target); 2686 call->ic_data()->GetCheckAt(0, &class_ids, &target);
2687 const intptr_t receiver_cid = class_ids[0]; 2687 const intptr_t receiver_cid = class_ids[0];
2688 2688
(...skipping 29 matching lines...) Expand all
2718 current_iterator()->RemoveCurrentFromGraph(); 2718 current_iterator()->RemoveCurrentFromGraph();
2719 call->set_previous(NULL); 2719 call->set_previous(NULL);
2720 call->set_next(NULL); 2720 call->set_next(NULL);
2721 return true; 2721 return true;
2722 } 2722 }
2723 2723
2724 2724
2725 bool FlowGraphOptimizer::BuildByteArrayViewStore(InstanceCallInstr* call, 2725 bool FlowGraphOptimizer::BuildByteArrayViewStore(InstanceCallInstr* call,
2726 intptr_t view_cid) { 2726 intptr_t view_cid) {
2727 bool simd_view = (view_cid == kTypedDataFloat32x4ArrayCid) || 2727 bool simd_view = (view_cid == kTypedDataFloat32x4ArrayCid) ||
2728 (view_cid == kTypedDataUint32x4ArrayCid); 2728 (view_cid == kTypedDataInt32x4ArrayCid);
2729 if (simd_view && !ShouldInlineSimd()) { 2729 if (simd_view && !ShouldInlineSimd()) {
2730 return false; 2730 return false;
2731 } 2731 }
2732 ASSERT(call->HasICData()); 2732 ASSERT(call->HasICData());
2733 Function& target = Function::Handle(); 2733 Function& target = Function::Handle();
2734 GrowableArray<intptr_t> class_ids; 2734 GrowableArray<intptr_t> class_ids;
2735 call->ic_data()->GetCheckAt(0, &class_ids, &target); 2735 call->ic_data()->GetCheckAt(0, &class_ids, &target);
2736 const intptr_t receiver_cid = class_ids[0]; 2736 const intptr_t receiver_cid = class_ids[0];
2737 2737
2738 Definition* array = call->ArgumentAt(0); 2738 Definition* array = call->ArgumentAt(0);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2773 case kTypedDataFloat64ArrayCid: { 2773 case kTypedDataFloat64ArrayCid: {
2774 // Check that value is always double. 2774 // Check that value is always double.
2775 value_check = ICData::New(flow_graph_->parsed_function().function(), 2775 value_check = ICData::New(flow_graph_->parsed_function().function(),
2776 call->function_name(), 2776 call->function_name(),
2777 Object::empty_array(), // Dummy args. descr. 2777 Object::empty_array(), // Dummy args. descr.
2778 Isolate::kNoDeoptId, 2778 Isolate::kNoDeoptId,
2779 1); 2779 1);
2780 value_check.AddReceiverCheck(kDoubleCid, target); 2780 value_check.AddReceiverCheck(kDoubleCid, target);
2781 break; 2781 break;
2782 } 2782 }
2783 case kTypedDataUint32x4ArrayCid: { 2783 case kTypedDataInt32x4ArrayCid: {
2784 // Check that value is always Uint32x4. 2784 // Check that value is always Int32x4.
2785 value_check = ICData::New(flow_graph_->parsed_function().function(), 2785 value_check = ICData::New(flow_graph_->parsed_function().function(),
2786 call->function_name(), 2786 call->function_name(),
2787 Object::empty_array(), // Dummy args. descr. 2787 Object::empty_array(), // Dummy args. descr.
2788 Isolate::kNoDeoptId, 2788 Isolate::kNoDeoptId,
2789 1); 2789 1);
2790 value_check.AddReceiverCheck(kUint32x4Cid, target); 2790 value_check.AddReceiverCheck(kInt32x4Cid, target);
2791 break; 2791 break;
2792 } 2792 }
2793 case kTypedDataFloat32x4ArrayCid: { 2793 case kTypedDataFloat32x4ArrayCid: {
2794 // Check that value is always Float32x4. 2794 // Check that value is always Float32x4.
2795 value_check = ICData::New(flow_graph_->parsed_function().function(), 2795 value_check = ICData::New(flow_graph_->parsed_function().function(),
2796 call->function_name(), 2796 call->function_name(),
2797 Object::empty_array(), // Dummy args. descr. 2797 Object::empty_array(), // Dummy args. descr.
2798 Isolate::kNoDeoptId, 2798 Isolate::kNoDeoptId,
2799 1); 2799 1);
2800 value_check.AddReceiverCheck(kFloat32x4Cid, target); 2800 value_check.AddReceiverCheck(kFloat32x4Cid, target);
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
3129 (recognized_kind == MethodRecognizer::kMathCos)) { 3129 (recognized_kind == MethodRecognizer::kMathCos)) {
3130 MathUnaryInstr* math_unary = 3130 MathUnaryInstr* math_unary =
3131 new MathUnaryInstr(recognized_kind, 3131 new MathUnaryInstr(recognized_kind,
3132 new Value(call->ArgumentAt(0)), 3132 new Value(call->ArgumentAt(0)),
3133 call->deopt_id()); 3133 call->deopt_id());
3134 ReplaceCall(call, math_unary); 3134 ReplaceCall(call, math_unary);
3135 } else if ((recognized_kind == MethodRecognizer::kFloat32x4Zero) || 3135 } else if ((recognized_kind == MethodRecognizer::kFloat32x4Zero) ||
3136 (recognized_kind == MethodRecognizer::kFloat32x4Splat) || 3136 (recognized_kind == MethodRecognizer::kFloat32x4Splat) ||
3137 (recognized_kind == MethodRecognizer::kFloat32x4Constructor)) { 3137 (recognized_kind == MethodRecognizer::kFloat32x4Constructor)) {
3138 TryInlineFloat32x4Constructor(call, recognized_kind); 3138 TryInlineFloat32x4Constructor(call, recognized_kind);
3139 } else if (recognized_kind == MethodRecognizer::kUint32x4BoolConstructor) { 3139 } else if (recognized_kind == MethodRecognizer::kInt32x4BoolConstructor) {
3140 TryInlineUint32x4Constructor(call, recognized_kind); 3140 TryInlineInt32x4Constructor(call, recognized_kind);
3141 } else if (recognized_kind == MethodRecognizer::kObjectConstructor) { 3141 } else if (recognized_kind == MethodRecognizer::kObjectConstructor) {
3142 // Remove the original push arguments. 3142 // Remove the original push arguments.
3143 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { 3143 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) {
3144 PushArgumentInstr* push = call->PushArgumentAt(i); 3144 PushArgumentInstr* push = call->PushArgumentAt(i);
3145 push->ReplaceUsesWith(push->value()->definition()); 3145 push->ReplaceUsesWith(push->value()->definition());
3146 push->RemoveFromGraph(); 3146 push->RemoveFromGraph();
3147 } 3147 }
3148 // Manually replace call with global null constant. ReplaceCall can't 3148 // Manually replace call with global null constant. ReplaceCall can't
3149 // be used for definitions that are already in the graph. 3149 // be used for definitions that are already in the graph.
3150 call->ReplaceUsesWith(flow_graph_->constant_null()); 3150 call->ReplaceUsesWith(flow_graph_->constant_null());
(...skipping 3834 matching lines...) Expand 10 before | Expand all | Expand 10 after
6985 void ConstantPropagator::VisitFloat32x4Clamp(Float32x4ClampInstr* instr) { 6985 void ConstantPropagator::VisitFloat32x4Clamp(Float32x4ClampInstr* instr) {
6986 SetValue(instr, non_constant_); 6986 SetValue(instr, non_constant_);
6987 } 6987 }
6988 6988
6989 6989
6990 void ConstantPropagator::VisitFloat32x4With(Float32x4WithInstr* instr) { 6990 void ConstantPropagator::VisitFloat32x4With(Float32x4WithInstr* instr) {
6991 SetValue(instr, non_constant_); 6991 SetValue(instr, non_constant_);
6992 } 6992 }
6993 6993
6994 6994
6995 void ConstantPropagator::VisitFloat32x4ToUint32x4( 6995 void ConstantPropagator::VisitFloat32x4ToInt32x4(
6996 Float32x4ToUint32x4Instr* instr) { 6996 Float32x4ToInt32x4Instr* instr) {
6997 SetValue(instr, non_constant_); 6997 SetValue(instr, non_constant_);
6998 } 6998 }
6999 6999
7000 7000
7001 void ConstantPropagator::VisitUint32x4BoolConstructor( 7001 void ConstantPropagator::VisitInt32x4BoolConstructor(
7002 Uint32x4BoolConstructorInstr* instr) { 7002 Int32x4BoolConstructorInstr* instr) {
7003 SetValue(instr, non_constant_); 7003 SetValue(instr, non_constant_);
7004 } 7004 }
7005 7005
7006 7006
7007 void ConstantPropagator::VisitUint32x4GetFlag(Uint32x4GetFlagInstr* instr) { 7007 void ConstantPropagator::VisitInt32x4GetFlag(Int32x4GetFlagInstr* instr) {
7008 SetValue(instr, non_constant_); 7008 SetValue(instr, non_constant_);
7009 } 7009 }
7010 7010
7011 7011
7012 void ConstantPropagator::VisitUint32x4SetFlag(Uint32x4SetFlagInstr* instr) { 7012 void ConstantPropagator::VisitInt32x4SetFlag(Int32x4SetFlagInstr* instr) {
7013 SetValue(instr, non_constant_); 7013 SetValue(instr, non_constant_);
7014 } 7014 }
7015 7015
7016 7016
7017 void ConstantPropagator::VisitUint32x4Select(Uint32x4SelectInstr* instr) { 7017 void ConstantPropagator::VisitInt32x4Select(Int32x4SelectInstr* instr) {
7018 SetValue(instr, non_constant_); 7018 SetValue(instr, non_constant_);
7019 } 7019 }
7020 7020
7021 7021
7022 void ConstantPropagator::VisitUint32x4ToFloat32x4( 7022 void ConstantPropagator::VisitInt32x4ToFloat32x4(
7023 Uint32x4ToFloat32x4Instr* instr) { 7023 Int32x4ToFloat32x4Instr* instr) {
7024 SetValue(instr, non_constant_); 7024 SetValue(instr, non_constant_);
7025 } 7025 }
7026 7026
7027 7027
7028 void ConstantPropagator::VisitBinaryUint32x4Op(BinaryUint32x4OpInstr* instr) { 7028 void ConstantPropagator::VisitBinaryInt32x4Op(BinaryInt32x4OpInstr* instr) {
7029 SetValue(instr, non_constant_); 7029 SetValue(instr, non_constant_);
7030 } 7030 }
7031 7031
7032 7032
7033 void ConstantPropagator::VisitMathUnary(MathUnaryInstr* instr) { 7033 void ConstantPropagator::VisitMathUnary(MathUnaryInstr* instr) {
7034 const Object& value = instr->value()->definition()->constant_value(); 7034 const Object& value = instr->value()->definition()->constant_value();
7035 if (IsNonConstant(value)) { 7035 if (IsNonConstant(value)) {
7036 SetValue(instr, non_constant_); 7036 SetValue(instr, non_constant_);
7037 } else if (IsConstant(value)) { 7037 } else if (IsConstant(value)) {
7038 // TODO(kmillikin): Handle Math's unary operations (sqrt, cos, sin). 7038 // TODO(kmillikin): Handle Math's unary operations (sqrt, cos, sin).
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
7090 const Object& value = instr->value()->definition()->constant_value(); 7090 const Object& value = instr->value()->definition()->constant_value();
7091 if (IsNonConstant(value)) { 7091 if (IsNonConstant(value)) {
7092 SetValue(instr, non_constant_); 7092 SetValue(instr, non_constant_);
7093 } else if (IsConstant(value)) { 7093 } else if (IsConstant(value)) {
7094 // TODO(kmillikin): Handle conversion. 7094 // TODO(kmillikin): Handle conversion.
7095 SetValue(instr, non_constant_); 7095 SetValue(instr, non_constant_);
7096 } 7096 }
7097 } 7097 }
7098 7098
7099 7099
7100 void ConstantPropagator::VisitUnboxUint32x4(UnboxUint32x4Instr* instr) { 7100 void ConstantPropagator::VisitUnboxInt32x4(UnboxInt32x4Instr* instr) {
7101 const Object& value = instr->value()->definition()->constant_value(); 7101 const Object& value = instr->value()->definition()->constant_value();
7102 if (IsNonConstant(value)) { 7102 if (IsNonConstant(value)) {
7103 SetValue(instr, non_constant_); 7103 SetValue(instr, non_constant_);
7104 } else if (IsConstant(value)) { 7104 } else if (IsConstant(value)) {
7105 // TODO(kmillikin): Handle conversion. 7105 // TODO(kmillikin): Handle conversion.
7106 SetValue(instr, non_constant_); 7106 SetValue(instr, non_constant_);
7107 } 7107 }
7108 } 7108 }
7109 7109
7110 7110
7111 void ConstantPropagator::VisitBoxUint32x4(BoxUint32x4Instr* instr) { 7111 void ConstantPropagator::VisitBoxInt32x4(BoxInt32x4Instr* instr) {
7112 const Object& value = instr->value()->definition()->constant_value(); 7112 const Object& value = instr->value()->definition()->constant_value();
7113 if (IsNonConstant(value)) { 7113 if (IsNonConstant(value)) {
7114 SetValue(instr, non_constant_); 7114 SetValue(instr, non_constant_);
7115 } else if (IsConstant(value)) { 7115 } else if (IsConstant(value)) {
7116 // TODO(kmillikin): Handle conversion. 7116 // TODO(kmillikin): Handle conversion.
7117 SetValue(instr, non_constant_); 7117 SetValue(instr, non_constant_);
7118 } 7118 }
7119 } 7119 }
7120 7120
7121 7121
(...skipping 845 matching lines...) Expand 10 before | Expand all | Expand 10 after
7967 } 7967 }
7968 7968
7969 // Insert materializations at environment uses. 7969 // Insert materializations at environment uses.
7970 for (intptr_t i = 0; i < exits.length(); i++) { 7970 for (intptr_t i = 0; i < exits.length(); i++) {
7971 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); 7971 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields);
7972 } 7972 }
7973 } 7973 }
7974 7974
7975 7975
7976 } // namespace dart 7976 } // namespace dart
OLDNEW
« no previous file with comments | « dart/runtime/vm/flow_graph_optimizer.h ('k') | dart/runtime/vm/flow_graph_type_propagator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698