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

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

Issue 56023004: Replace Uint32x4/Uint32x4List with Int32x4/Int32x4List (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/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 319 matching lines...) Expand 10 before | Expand all | Expand 10 after
1458 } else if (HasTwoMintOrSmi(ic_data) && 1458 } else if (HasTwoMintOrSmi(ic_data) &&
1459 FlowGraphCompiler::SupportsUnboxedMints()) { 1459 FlowGraphCompiler::SupportsUnboxedMints()) {
1460 // Don't generate mint code if the IC data is marked because of an 1460 // Don't generate mint code if the IC data is marked because of an
1461 // overflow. 1461 // overflow.
1462 if (ic_data.deopt_reason() == kDeoptBinaryMintOp) return false; 1462 if (ic_data.deopt_reason() == kDeoptBinaryMintOp) return false;
1463 operands_type = kMintCid; 1463 operands_type = kMintCid;
1464 } else if (ShouldSpecializeForDouble(ic_data)) { 1464 } else if (ShouldSpecializeForDouble(ic_data)) {
1465 operands_type = kDoubleCid; 1465 operands_type = kDoubleCid;
1466 } else if (HasOnlyTwoOf(ic_data, kFloat32x4Cid)) { 1466 } else if (HasOnlyTwoOf(ic_data, kFloat32x4Cid)) {
1467 operands_type = kFloat32x4Cid; 1467 operands_type = kFloat32x4Cid;
1468 } else if (HasOnlyTwoOf(ic_data, kUint32x4Cid)) { 1468 } else if (HasOnlyTwoOf(ic_data, kInt32x4Cid)) {
1469 operands_type = kUint32x4Cid; 1469 operands_type = kInt32x4Cid;
1470 } else { 1470 } else {
1471 return false; 1471 return false;
1472 } 1472 }
1473 break; 1473 break;
1474 case Token::kMUL: 1474 case Token::kMUL:
1475 if (HasOnlyTwoOf(ic_data, kSmiCid)) { 1475 if (HasOnlyTwoOf(ic_data, kSmiCid)) {
1476 // Don't generate smi code if the IC data is marked because of an 1476 // Don't generate smi code if the IC data is marked because of an
1477 // overflow. 1477 // overflow.
1478 // TODO(fschneider): Add unboxed mint multiplication. 1478 // TODO(fschneider): Add unboxed mint multiplication.
1479 if (ic_data.deopt_reason() == kDeoptBinarySmiOp) return false; 1479 if (ic_data.deopt_reason() == kDeoptBinarySmiOp) return false;
(...skipping 23 matching lines...) Expand all
1503 return false; 1503 return false;
1504 } 1504 }
1505 break; 1505 break;
1506 case Token::kBIT_AND: 1506 case Token::kBIT_AND:
1507 case Token::kBIT_OR: 1507 case Token::kBIT_OR:
1508 case Token::kBIT_XOR: 1508 case Token::kBIT_XOR:
1509 if (HasOnlyTwoOf(ic_data, kSmiCid)) { 1509 if (HasOnlyTwoOf(ic_data, kSmiCid)) {
1510 operands_type = kSmiCid; 1510 operands_type = kSmiCid;
1511 } else if (HasTwoMintOrSmi(ic_data)) { 1511 } else if (HasTwoMintOrSmi(ic_data)) {
1512 operands_type = kMintCid; 1512 operands_type = kMintCid;
1513 } else if (HasOnlyTwoOf(ic_data, kUint32x4Cid)) { 1513 } else if (HasOnlyTwoOf(ic_data, kInt32x4Cid)) {
1514 operands_type = kUint32x4Cid; 1514 operands_type = kInt32x4Cid;
1515 } else { 1515 } else {
1516 return false; 1516 return false;
1517 } 1517 }
1518 break; 1518 break;
1519 case Token::kSHR: 1519 case Token::kSHR:
1520 case Token::kSHL: 1520 case Token::kSHL:
1521 if (HasOnlyTwoOf(ic_data, kSmiCid)) { 1521 if (HasOnlyTwoOf(ic_data, kSmiCid)) {
1522 // Left shift may overflow from smi into mint or big ints. 1522 // Left shift may overflow from smi into mint or big ints.
1523 // Don't generate smi code if the IC data is marked because 1523 // Don't generate smi code if the IC data is marked because
1524 // of an overflow. 1524 // of an overflow.
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
1578 call->deopt_id()); 1578 call->deopt_id());
1579 ReplaceCall(call, shift_op); 1579 ReplaceCall(call, shift_op);
1580 } else { 1580 } else {
1581 BinaryMintOpInstr* bin_op = 1581 BinaryMintOpInstr* bin_op =
1582 new BinaryMintOpInstr(op_kind, new Value(left), new Value(right), 1582 new BinaryMintOpInstr(op_kind, new Value(left), new Value(right),
1583 call->deopt_id()); 1583 call->deopt_id());
1584 ReplaceCall(call, bin_op); 1584 ReplaceCall(call, bin_op);
1585 } 1585 }
1586 } else if (operands_type == kFloat32x4Cid) { 1586 } else if (operands_type == kFloat32x4Cid) {
1587 return InlineFloat32x4BinaryOp(call, op_kind); 1587 return InlineFloat32x4BinaryOp(call, op_kind);
1588 } else if (operands_type == kUint32x4Cid) { 1588 } else if (operands_type == kInt32x4Cid) {
1589 return InlineUint32x4BinaryOp(call, op_kind); 1589 return InlineInt32x4BinaryOp(call, op_kind);
1590 } else if (op_kind == Token::kMOD) { 1590 } else if (op_kind == Token::kMOD) {
1591 // TODO(vegorov): implement fast path code for modulo. 1591 // TODO(vegorov): implement fast path code for modulo.
1592 ASSERT(operands_type == kSmiCid); 1592 ASSERT(operands_type == kSmiCid);
1593 if (!right->IsConstant()) return false; 1593 if (!right->IsConstant()) return false;
1594 const Object& obj = right->AsConstant()->value(); 1594 const Object& obj = right->AsConstant()->value();
1595 if (!obj.IsSmi()) return false; 1595 if (!obj.IsSmi()) return false;
1596 const intptr_t value = Smi::Cast(obj).Value(); 1596 const intptr_t value = Smi::Cast(obj).Value();
1597 if (!Utils::IsPowerOfTwo(value)) return false; 1597 if (!Utils::IsPowerOfTwo(value)) return false;
1598 1598
1599 // Insert smi check and attach a copy of the original environment 1599 // Insert smi check and attach a copy of the original environment
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
1843 mask, 1843 mask,
1844 call->deopt_id()); 1844 call->deopt_id());
1845 ReplaceCall(call, instr); 1845 ReplaceCall(call, instr);
1846 return true; 1846 return true;
1847 } 1847 }
1848 UNREACHABLE(); 1848 UNREACHABLE();
1849 return false; 1849 return false;
1850 } 1850 }
1851 1851
1852 1852
1853 bool FlowGraphOptimizer::InlineUint32x4Getter(InstanceCallInstr* call, 1853 bool FlowGraphOptimizer::InlineInt32x4Getter(InstanceCallInstr* call,
1854 MethodRecognizer::Kind getter) { 1854 MethodRecognizer::Kind getter) {
1855 if (!ShouldInlineSimd()) { 1855 if (!ShouldInlineSimd()) {
1856 return false; 1856 return false;
1857 } 1857 }
1858 AddCheckClass(call->ArgumentAt(0), 1858 AddCheckClass(call->ArgumentAt(0),
1859 ICData::ZoneHandle( 1859 ICData::ZoneHandle(
1860 call->ic_data()->AsUnaryClassChecksForArgNr(0)), 1860 call->ic_data()->AsUnaryClassChecksForArgNr(0)),
1861 call->deopt_id(), 1861 call->deopt_id(),
1862 call->env(), 1862 call->env(),
1863 call); 1863 call);
1864 intptr_t mask = 0; 1864 intptr_t mask = 0;
1865 if ((getter == MethodRecognizer::kUint32x4Shuffle) || 1865 if ((getter == MethodRecognizer::kInt32x4Shuffle) ||
1866 (getter == MethodRecognizer::kUint32x4ShuffleMix)) { 1866 (getter == MethodRecognizer::kInt32x4ShuffleMix)) {
1867 // Extract shuffle mask. 1867 // Extract shuffle mask.
1868 Definition* mask_definition = NULL; 1868 Definition* mask_definition = NULL;
1869 if (getter == MethodRecognizer::kUint32x4Shuffle) { 1869 if (getter == MethodRecognizer::kInt32x4Shuffle) {
1870 ASSERT(call->ArgumentCount() == 2); 1870 ASSERT(call->ArgumentCount() == 2);
1871 mask_definition = call->ArgumentAt(1); 1871 mask_definition = call->ArgumentAt(1);
1872 } else { 1872 } else {
1873 ASSERT(getter == MethodRecognizer::kUint32x4ShuffleMix); 1873 ASSERT(getter == MethodRecognizer::kInt32x4ShuffleMix);
1874 ASSERT(call->ArgumentCount() == 3); 1874 ASSERT(call->ArgumentCount() == 3);
1875 mask_definition = call->ArgumentAt(2); 1875 mask_definition = call->ArgumentAt(2);
1876 } 1876 }
1877 if (!mask_definition->IsConstant()) { 1877 if (!mask_definition->IsConstant()) {
1878 return false; 1878 return false;
1879 } 1879 }
1880 ASSERT(mask_definition->IsConstant()); 1880 ASSERT(mask_definition->IsConstant());
1881 ConstantInstr* constant_instruction = mask_definition->AsConstant(); 1881 ConstantInstr* constant_instruction = mask_definition->AsConstant();
1882 const Object& constant_mask = constant_instruction->value(); 1882 const Object& constant_mask = constant_instruction->value();
1883 if (!constant_mask.IsSmi()) { 1883 if (!constant_mask.IsSmi()) {
1884 return false; 1884 return false;
1885 } 1885 }
1886 ASSERT(constant_mask.IsSmi()); 1886 ASSERT(constant_mask.IsSmi());
1887 mask = Smi::Cast(constant_mask).Value(); 1887 mask = Smi::Cast(constant_mask).Value();
1888 if ((mask < 0) || (mask > 255)) { 1888 if ((mask < 0) || (mask > 255)) {
1889 // Not a valid mask. 1889 // Not a valid mask.
1890 return false; 1890 return false;
1891 } 1891 }
1892 } 1892 }
1893 if (getter == MethodRecognizer::kUint32x4GetSignMask) { 1893 if (getter == MethodRecognizer::kInt32x4GetSignMask) {
1894 Simd32x4GetSignMaskInstr* instr = new Simd32x4GetSignMaskInstr( 1894 Simd32x4GetSignMaskInstr* instr = new Simd32x4GetSignMaskInstr(
1895 getter, 1895 getter,
1896 new Value(call->ArgumentAt(0)), 1896 new Value(call->ArgumentAt(0)),
1897 call->deopt_id()); 1897 call->deopt_id());
1898 ReplaceCall(call, instr); 1898 ReplaceCall(call, instr);
1899 return true; 1899 return true;
1900 } else if (getter == MethodRecognizer::kUint32x4ShuffleMix) { 1900 } else if (getter == MethodRecognizer::kInt32x4ShuffleMix) {
1901 Simd32x4ShuffleMixInstr* instr = new Simd32x4ShuffleMixInstr( 1901 Simd32x4ShuffleMixInstr* instr = new Simd32x4ShuffleMixInstr(
1902 getter, 1902 getter,
1903 new Value(call->ArgumentAt(0)), 1903 new Value(call->ArgumentAt(0)),
1904 new Value(call->ArgumentAt(1)), 1904 new Value(call->ArgumentAt(1)),
1905 mask, 1905 mask,
1906 call->deopt_id()); 1906 call->deopt_id());
1907 ReplaceCall(call, instr); 1907 ReplaceCall(call, instr);
1908 return true; 1908 return true;
1909 } else if (getter == MethodRecognizer::kUint32x4Shuffle) { 1909 } else if (getter == MethodRecognizer::kInt32x4Shuffle) {
1910 Simd32x4ShuffleInstr* instr = new Simd32x4ShuffleInstr( 1910 Simd32x4ShuffleInstr* instr = new Simd32x4ShuffleInstr(
1911 getter, 1911 getter,
1912 new Value(call->ArgumentAt(0)), 1912 new Value(call->ArgumentAt(0)),
1913 mask, 1913 mask,
1914 call->deopt_id()); 1914 call->deopt_id());
1915 ReplaceCall(call, instr); 1915 ReplaceCall(call, instr);
1916 return true; 1916 return true;
1917 } else { 1917 } else {
1918 Uint32x4GetFlagInstr* instr = new Uint32x4GetFlagInstr( 1918 Int32x4GetFlagInstr* instr = new Int32x4GetFlagInstr(
1919 getter, 1919 getter,
1920 new Value(call->ArgumentAt(0)), 1920 new Value(call->ArgumentAt(0)),
1921 call->deopt_id()); 1921 call->deopt_id());
1922 ReplaceCall(call, instr); 1922 ReplaceCall(call, instr);
1923 return true; 1923 return true;
1924 } 1924 }
1925 } 1925 }
1926 1926
1927 1927
1928 bool FlowGraphOptimizer::InlineFloat32x4BinaryOp(InstanceCallInstr* call, 1928 bool FlowGraphOptimizer::InlineFloat32x4BinaryOp(InstanceCallInstr* call,
(...skipping 21 matching lines...) Expand all
1950 // Replace call. 1950 // Replace call.
1951 BinaryFloat32x4OpInstr* float32x4_bin_op = 1951 BinaryFloat32x4OpInstr* float32x4_bin_op =
1952 new BinaryFloat32x4OpInstr(op_kind, new Value(left), new Value(right), 1952 new BinaryFloat32x4OpInstr(op_kind, new Value(left), new Value(right),
1953 call->deopt_id()); 1953 call->deopt_id());
1954 ReplaceCall(call, float32x4_bin_op); 1954 ReplaceCall(call, float32x4_bin_op);
1955 1955
1956 return true; 1956 return true;
1957 } 1957 }
1958 1958
1959 1959
1960 bool FlowGraphOptimizer::InlineUint32x4BinaryOp(InstanceCallInstr* call, 1960 bool FlowGraphOptimizer::InlineInt32x4BinaryOp(InstanceCallInstr* call,
1961 Token::Kind op_kind) { 1961 Token::Kind op_kind) {
1962 if (!ShouldInlineSimd()) { 1962 if (!ShouldInlineSimd()) {
1963 return false; 1963 return false;
1964 } 1964 }
1965 ASSERT(call->ArgumentCount() == 2); 1965 ASSERT(call->ArgumentCount() == 2);
1966 Definition* left = call->ArgumentAt(0); 1966 Definition* left = call->ArgumentAt(0);
1967 Definition* right = call->ArgumentAt(1); 1967 Definition* right = call->ArgumentAt(1);
1968 // Type check left. 1968 // Type check left.
1969 AddCheckClass(left, 1969 AddCheckClass(left,
1970 ICData::ZoneHandle( 1970 ICData::ZoneHandle(
1971 call->ic_data()->AsUnaryClassChecksForArgNr(0)), 1971 call->ic_data()->AsUnaryClassChecksForArgNr(0)),
1972 call->deopt_id(), 1972 call->deopt_id(),
1973 call->env(), 1973 call->env(),
1974 call); 1974 call);
1975 // Type check right. 1975 // Type check right.
1976 AddCheckClass(right, 1976 AddCheckClass(right,
1977 ICData::ZoneHandle( 1977 ICData::ZoneHandle(
1978 call->ic_data()->AsUnaryClassChecksForArgNr(1)), 1978 call->ic_data()->AsUnaryClassChecksForArgNr(1)),
1979 call->deopt_id(), 1979 call->deopt_id(),
1980 call->env(), 1980 call->env(),
1981 call); 1981 call);
1982 // Replace call. 1982 // Replace call.
1983 BinaryUint32x4OpInstr* uint32x4_bin_op = 1983 BinaryInt32x4OpInstr* int32x4_bin_op =
1984 new BinaryUint32x4OpInstr(op_kind, new Value(left), new Value(right), 1984 new BinaryInt32x4OpInstr(op_kind, new Value(left), new Value(right),
1985 call->deopt_id()); 1985 call->deopt_id());
1986 ReplaceCall(call, uint32x4_bin_op); 1986 ReplaceCall(call, int32x4_bin_op);
1987 return true; 1987 return true;
1988 } 1988 }
1989 1989
1990 1990
1991 // Only unique implicit instance getters can be currently handled. 1991 // Only unique implicit instance getters can be currently handled.
1992 bool FlowGraphOptimizer::TryInlineInstanceGetter(InstanceCallInstr* call) { 1992 bool FlowGraphOptimizer::TryInlineInstanceGetter(InstanceCallInstr* call) {
1993 ASSERT(call->HasICData()); 1993 ASSERT(call->HasICData());
1994 const ICData& ic_data = *call->ic_data(); 1994 const ICData& ic_data = *call->ic_data();
1995 if (ic_data.NumberOfChecks() == 0) { 1995 if (ic_data.NumberOfChecks() == 0) {
1996 // No type feedback collected. 1996 // No type feedback collected.
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
2075 case kExternalTypedDataUint8ArrayCid: 2075 case kExternalTypedDataUint8ArrayCid:
2076 case kTypedDataUint8ClampedArrayCid: 2076 case kTypedDataUint8ClampedArrayCid:
2077 case kExternalTypedDataUint8ClampedArrayCid: 2077 case kExternalTypedDataUint8ClampedArrayCid:
2078 case kTypedDataInt16ArrayCid: 2078 case kTypedDataInt16ArrayCid:
2079 case kTypedDataUint16ArrayCid: 2079 case kTypedDataUint16ArrayCid:
2080 case kTypedDataInt32ArrayCid: 2080 case kTypedDataInt32ArrayCid:
2081 case kTypedDataUint32ArrayCid: 2081 case kTypedDataUint32ArrayCid:
2082 case kTypedDataFloat32ArrayCid: 2082 case kTypedDataFloat32ArrayCid:
2083 case kTypedDataFloat64ArrayCid: 2083 case kTypedDataFloat64ArrayCid:
2084 case kTypedDataFloat32x4ArrayCid: 2084 case kTypedDataFloat32x4ArrayCid:
2085 case kTypedDataUint32x4ArrayCid: 2085 case kTypedDataInt32x4ArrayCid:
2086 return true; 2086 return true;
2087 default: 2087 default:
2088 return false; 2088 return false;
2089 } 2089 }
2090 } 2090 }
2091 2091
2092 2092
2093 // Inline only simple, frequently called core library methods. 2093 // Inline only simple, frequently called core library methods.
2094 bool FlowGraphOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) { 2094 bool FlowGraphOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) {
2095 ASSERT(call->HasICData()); 2095 ASSERT(call->HasICData());
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
2249 case MethodRecognizer::kByteArrayBaseGetInt32: 2249 case MethodRecognizer::kByteArrayBaseGetInt32:
2250 return BuildByteArrayViewLoad(call, kTypedDataInt32ArrayCid); 2250 return BuildByteArrayViewLoad(call, kTypedDataInt32ArrayCid);
2251 case MethodRecognizer::kByteArrayBaseGetUint32: 2251 case MethodRecognizer::kByteArrayBaseGetUint32:
2252 return BuildByteArrayViewLoad(call, kTypedDataUint32ArrayCid); 2252 return BuildByteArrayViewLoad(call, kTypedDataUint32ArrayCid);
2253 case MethodRecognizer::kByteArrayBaseGetFloat32: 2253 case MethodRecognizer::kByteArrayBaseGetFloat32:
2254 return BuildByteArrayViewLoad(call, kTypedDataFloat32ArrayCid); 2254 return BuildByteArrayViewLoad(call, kTypedDataFloat32ArrayCid);
2255 case MethodRecognizer::kByteArrayBaseGetFloat64: 2255 case MethodRecognizer::kByteArrayBaseGetFloat64:
2256 return BuildByteArrayViewLoad(call, kTypedDataFloat64ArrayCid); 2256 return BuildByteArrayViewLoad(call, kTypedDataFloat64ArrayCid);
2257 case MethodRecognizer::kByteArrayBaseGetFloat32x4: 2257 case MethodRecognizer::kByteArrayBaseGetFloat32x4:
2258 return BuildByteArrayViewLoad(call, kTypedDataFloat32x4ArrayCid); 2258 return BuildByteArrayViewLoad(call, kTypedDataFloat32x4ArrayCid);
2259 case MethodRecognizer::kByteArrayBaseGetUint32x4: 2259 case MethodRecognizer::kByteArrayBaseGetInt32x4:
2260 return BuildByteArrayViewLoad(call, kTypedDataUint32x4ArrayCid); 2260 return BuildByteArrayViewLoad(call, kTypedDataInt32x4ArrayCid);
2261 2261
2262 // ByteArray setters. 2262 // ByteArray setters.
2263 case MethodRecognizer::kByteArrayBaseSetInt8: 2263 case MethodRecognizer::kByteArrayBaseSetInt8:
2264 return BuildByteArrayViewStore(call, kTypedDataInt8ArrayCid); 2264 return BuildByteArrayViewStore(call, kTypedDataInt8ArrayCid);
2265 case MethodRecognizer::kByteArrayBaseSetUint8: 2265 case MethodRecognizer::kByteArrayBaseSetUint8:
2266 return BuildByteArrayViewStore(call, kTypedDataUint8ArrayCid); 2266 return BuildByteArrayViewStore(call, kTypedDataUint8ArrayCid);
2267 case MethodRecognizer::kByteArrayBaseSetInt16: 2267 case MethodRecognizer::kByteArrayBaseSetInt16:
2268 return BuildByteArrayViewStore(call, kTypedDataInt16ArrayCid); 2268 return BuildByteArrayViewStore(call, kTypedDataInt16ArrayCid);
2269 case MethodRecognizer::kByteArrayBaseSetUint16: 2269 case MethodRecognizer::kByteArrayBaseSetUint16:
2270 return BuildByteArrayViewStore(call, kTypedDataUint16ArrayCid); 2270 return BuildByteArrayViewStore(call, kTypedDataUint16ArrayCid);
2271 case MethodRecognizer::kByteArrayBaseSetInt32: 2271 case MethodRecognizer::kByteArrayBaseSetInt32:
2272 return BuildByteArrayViewStore(call, kTypedDataInt32ArrayCid); 2272 return BuildByteArrayViewStore(call, kTypedDataInt32ArrayCid);
2273 case MethodRecognizer::kByteArrayBaseSetUint32: 2273 case MethodRecognizer::kByteArrayBaseSetUint32:
2274 return BuildByteArrayViewStore(call, kTypedDataUint32ArrayCid); 2274 return BuildByteArrayViewStore(call, kTypedDataUint32ArrayCid);
2275 case MethodRecognizer::kByteArrayBaseSetFloat32: 2275 case MethodRecognizer::kByteArrayBaseSetFloat32:
2276 return BuildByteArrayViewStore(call, kTypedDataFloat32ArrayCid); 2276 return BuildByteArrayViewStore(call, kTypedDataFloat32ArrayCid);
2277 case MethodRecognizer::kByteArrayBaseSetFloat64: 2277 case MethodRecognizer::kByteArrayBaseSetFloat64:
2278 return BuildByteArrayViewStore(call, kTypedDataFloat64ArrayCid); 2278 return BuildByteArrayViewStore(call, kTypedDataFloat64ArrayCid);
2279 case MethodRecognizer::kByteArrayBaseSetFloat32x4: 2279 case MethodRecognizer::kByteArrayBaseSetFloat32x4:
2280 return BuildByteArrayViewStore(call, kTypedDataFloat32x4ArrayCid); 2280 return BuildByteArrayViewStore(call, kTypedDataFloat32x4ArrayCid);
2281 case MethodRecognizer::kByteArrayBaseSetUint32x4: 2281 case MethodRecognizer::kByteArrayBaseSetInt32x4:
2282 return BuildByteArrayViewStore(call, kTypedDataUint32x4ArrayCid); 2282 return BuildByteArrayViewStore(call, kTypedDataInt32x4ArrayCid);
2283 default: 2283 default:
2284 // Unsupported method. 2284 // Unsupported method.
2285 return false; 2285 return false;
2286 } 2286 }
2287 } 2287 }
2288 2288
2289 if ((class_ids[0] == kFloat32x4Cid) && (ic_data.NumberOfChecks() == 1)) { 2289 if ((class_ids[0] == kFloat32x4Cid) && (ic_data.NumberOfChecks() == 1)) {
2290 return TryInlineFloat32x4Method(call, recognized_kind); 2290 return TryInlineFloat32x4Method(call, recognized_kind);
2291 } 2291 }
2292 2292
2293 if ((class_ids[0] == kUint32x4Cid) && (ic_data.NumberOfChecks() == 1)) { 2293 if ((class_ids[0] == kInt32x4Cid) && (ic_data.NumberOfChecks() == 1)) {
2294 return TryInlineUint32x4Method(call, recognized_kind); 2294 return TryInlineInt32x4Method(call, recognized_kind);
2295 } 2295 }
2296 2296
2297 if (recognized_kind == MethodRecognizer::kIntegerLeftShiftWithMask32) { 2297 if (recognized_kind == MethodRecognizer::kIntegerLeftShiftWithMask32) {
2298 ASSERT(call->ArgumentCount() == 3); 2298 ASSERT(call->ArgumentCount() == 3);
2299 ASSERT(ic_data.num_args_tested() == 2); 2299 ASSERT(ic_data.num_args_tested() == 2);
2300 Definition* value = call->ArgumentAt(0); 2300 Definition* value = call->ArgumentAt(0);
2301 Definition* count = call->ArgumentAt(1); 2301 Definition* count = call->ArgumentAt(1);
2302 Definition* int32_mask = call->ArgumentAt(2); 2302 Definition* int32_mask = call->ArgumentAt(2);
2303 if (HasOnlyTwoOf(ic_data, kSmiCid)) { 2303 if (HasOnlyTwoOf(ic_data, kSmiCid)) {
2304 if (ic_data.deopt_reason() == kDeoptShiftMintOp) { 2304 if (ic_data.deopt_reason() == kDeoptShiftMintOp) {
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
2376 return true; 2376 return true;
2377 } else if (recognized_kind == MethodRecognizer::kFloat32x4Constructor) { 2377 } else if (recognized_kind == MethodRecognizer::kFloat32x4Constructor) {
2378 Float32x4ConstructorInstr* con = 2378 Float32x4ConstructorInstr* con =
2379 new Float32x4ConstructorInstr(new Value(call->ArgumentAt(1)), 2379 new Float32x4ConstructorInstr(new Value(call->ArgumentAt(1)),
2380 new Value(call->ArgumentAt(2)), 2380 new Value(call->ArgumentAt(2)),
2381 new Value(call->ArgumentAt(3)), 2381 new Value(call->ArgumentAt(3)),
2382 new Value(call->ArgumentAt(4)), 2382 new Value(call->ArgumentAt(4)),
2383 call->deopt_id()); 2383 call->deopt_id());
2384 ReplaceCall(call, con); 2384 ReplaceCall(call, con);
2385 return true; 2385 return true;
2386 } else if (recognized_kind == MethodRecognizer::kFloat32x4FromUint32x4Bits) { 2386 } else if (recognized_kind == MethodRecognizer::kFloat32x4FromInt32x4Bits) {
2387 Uint32x4ToFloat32x4Instr* cast = 2387 Int32x4ToFloat32x4Instr* cast =
2388 new Uint32x4ToFloat32x4Instr(new Value(call->ArgumentAt(1)), 2388 new Int32x4ToFloat32x4Instr(new Value(call->ArgumentAt(1)),
2389 call->deopt_id()); 2389 call->deopt_id());
2390 ReplaceCall(call, cast); 2390 ReplaceCall(call, cast);
2391 return true; 2391 return true;
2392 } 2392 }
2393 return false; 2393 return false;
2394 } 2394 }
2395 2395
2396 2396
2397 bool FlowGraphOptimizer::TryInlineUint32x4Constructor( 2397 bool FlowGraphOptimizer::TryInlineInt32x4Constructor(
2398 StaticCallInstr* call, 2398 StaticCallInstr* call,
2399 MethodRecognizer::Kind recognized_kind) { 2399 MethodRecognizer::Kind recognized_kind) {
2400 if (!ShouldInlineSimd()) { 2400 if (!ShouldInlineSimd()) {
2401 return false; 2401 return false;
2402 } 2402 }
2403 if (recognized_kind == MethodRecognizer::kUint32x4BoolConstructor) { 2403 if (recognized_kind == MethodRecognizer::kInt32x4BoolConstructor) {
2404 Uint32x4BoolConstructorInstr* con = new Uint32x4BoolConstructorInstr( 2404 Int32x4BoolConstructorInstr* con = new Int32x4BoolConstructorInstr(
2405 new Value(call->ArgumentAt(1)), 2405 new Value(call->ArgumentAt(1)),
2406 new Value(call->ArgumentAt(2)), 2406 new Value(call->ArgumentAt(2)),
2407 new Value(call->ArgumentAt(3)), 2407 new Value(call->ArgumentAt(3)),
2408 new Value(call->ArgumentAt(4)), 2408 new Value(call->ArgumentAt(4)),
2409 call->deopt_id()); 2409 call->deopt_id());
2410 ReplaceCall(call, con); 2410 ReplaceCall(call, con);
2411 return true; 2411 return true;
2412 } else if (recognized_kind == MethodRecognizer::kUint32x4FromFloat32x4Bits) { 2412 } else if (recognized_kind == MethodRecognizer::kInt32x4FromFloat32x4Bits) {
2413 Float32x4ToUint32x4Instr* cast = 2413 Float32x4ToInt32x4Instr* cast =
2414 new Float32x4ToUint32x4Instr(new Value(call->ArgumentAt(1)), 2414 new Float32x4ToInt32x4Instr(new Value(call->ArgumentAt(1)),
2415 call->deopt_id()); 2415 call->deopt_id());
2416 ReplaceCall(call, cast); 2416 ReplaceCall(call, cast);
2417 return true; 2417 return true;
2418 } 2418 }
2419 return false; 2419 return false;
2420 } 2420 }
2421 2421
2422 2422
2423 bool FlowGraphOptimizer::TryInlineFloat32x4Method( 2423 bool FlowGraphOptimizer::TryInlineFloat32x4Method(
2424 InstanceCallInstr* call, 2424 InstanceCallInstr* call,
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
2568 case MethodRecognizer::kFloat32x4ShuffleMix: 2568 case MethodRecognizer::kFloat32x4ShuffleMix:
2569 case MethodRecognizer::kFloat32x4Shuffle: { 2569 case MethodRecognizer::kFloat32x4Shuffle: {
2570 return InlineFloat32x4Getter(call, recognized_kind); 2570 return InlineFloat32x4Getter(call, recognized_kind);
2571 } 2571 }
2572 default: 2572 default:
2573 return false; 2573 return false;
2574 } 2574 }
2575 } 2575 }
2576 2576
2577 2577
2578 bool FlowGraphOptimizer::TryInlineUint32x4Method( 2578 bool FlowGraphOptimizer::TryInlineInt32x4Method(
2579 InstanceCallInstr* call, 2579 InstanceCallInstr* call,
2580 MethodRecognizer::Kind recognized_kind) { 2580 MethodRecognizer::Kind recognized_kind) {
2581 if (!ShouldInlineSimd()) { 2581 if (!ShouldInlineSimd()) {
2582 return false; 2582 return false;
2583 } 2583 }
2584 ASSERT(call->HasICData()); 2584 ASSERT(call->HasICData());
2585 switch (recognized_kind) { 2585 switch (recognized_kind) {
2586 case MethodRecognizer::kUint32x4ShuffleMix: 2586 case MethodRecognizer::kInt32x4ShuffleMix:
2587 case MethodRecognizer::kUint32x4Shuffle: 2587 case MethodRecognizer::kInt32x4Shuffle:
2588 case MethodRecognizer::kUint32x4GetFlagX: 2588 case MethodRecognizer::kInt32x4GetFlagX:
2589 case MethodRecognizer::kUint32x4GetFlagY: 2589 case MethodRecognizer::kInt32x4GetFlagY:
2590 case MethodRecognizer::kUint32x4GetFlagZ: 2590 case MethodRecognizer::kInt32x4GetFlagZ:
2591 case MethodRecognizer::kUint32x4GetFlagW: 2591 case MethodRecognizer::kInt32x4GetFlagW:
2592 case MethodRecognizer::kUint32x4GetSignMask: 2592 case MethodRecognizer::kInt32x4GetSignMask:
2593 ASSERT(call->ic_data()->HasReceiverClassId(kUint32x4Cid)); 2593 ASSERT(call->ic_data()->HasReceiverClassId(kInt32x4Cid));
2594 ASSERT(call->ic_data()->HasOneTarget()); 2594 ASSERT(call->ic_data()->HasOneTarget());
2595 return InlineUint32x4Getter(call, recognized_kind); 2595 return InlineInt32x4Getter(call, recognized_kind);
2596 2596
2597 case MethodRecognizer::kUint32x4Select: { 2597 case MethodRecognizer::kInt32x4Select: {
2598 Definition* mask = call->ArgumentAt(0); 2598 Definition* mask = call->ArgumentAt(0);
2599 Definition* trueValue = call->ArgumentAt(1); 2599 Definition* trueValue = call->ArgumentAt(1);
2600 Definition* falseValue = call->ArgumentAt(2); 2600 Definition* falseValue = call->ArgumentAt(2);
2601 // Type check left. 2601 // Type check left.
2602 AddCheckClass(mask, 2602 AddCheckClass(mask,
2603 ICData::ZoneHandle( 2603 ICData::ZoneHandle(
2604 call->ic_data()->AsUnaryClassChecksForArgNr(0)), 2604 call->ic_data()->AsUnaryClassChecksForArgNr(0)),
2605 call->deopt_id(), 2605 call->deopt_id(),
2606 call->env(), 2606 call->env(),
2607 call); 2607 call);
2608 Uint32x4SelectInstr* select = new Uint32x4SelectInstr( 2608 Int32x4SelectInstr* select = new Int32x4SelectInstr(
2609 new Value(mask), 2609 new Value(mask),
2610 new Value(trueValue), 2610 new Value(trueValue),
2611 new Value(falseValue), 2611 new Value(falseValue),
2612 call->deopt_id()); 2612 call->deopt_id());
2613 ReplaceCall(call, select); 2613 ReplaceCall(call, select);
2614 return true; 2614 return true;
2615 } 2615 }
2616 case MethodRecognizer::kUint32x4WithFlagX: 2616 case MethodRecognizer::kInt32x4WithFlagX:
2617 case MethodRecognizer::kUint32x4WithFlagY: 2617 case MethodRecognizer::kInt32x4WithFlagY:
2618 case MethodRecognizer::kUint32x4WithFlagZ: 2618 case MethodRecognizer::kInt32x4WithFlagZ:
2619 case MethodRecognizer::kUint32x4WithFlagW: { 2619 case MethodRecognizer::kInt32x4WithFlagW: {
2620 Definition* left = call->ArgumentAt(0); 2620 Definition* left = call->ArgumentAt(0);
2621 Definition* flag = call->ArgumentAt(1); 2621 Definition* flag = call->ArgumentAt(1);
2622 // Type check left. 2622 // Type check left.
2623 AddCheckClass(left, 2623 AddCheckClass(left,
2624 ICData::ZoneHandle( 2624 ICData::ZoneHandle(
2625 call->ic_data()->AsUnaryClassChecksForArgNr(0)), 2625 call->ic_data()->AsUnaryClassChecksForArgNr(0)),
2626 call->deopt_id(), 2626 call->deopt_id(),
2627 call->env(), 2627 call->env(),
2628 call); 2628 call);
2629 Uint32x4SetFlagInstr* setFlag = new Uint32x4SetFlagInstr( 2629 Int32x4SetFlagInstr* setFlag = new Int32x4SetFlagInstr(
2630 recognized_kind, 2630 recognized_kind,
2631 new Value(left), 2631 new Value(left),
2632 new Value(flag), 2632 new Value(flag),
2633 call->deopt_id()); 2633 call->deopt_id());
2634 ReplaceCall(call, setFlag); 2634 ReplaceCall(call, setFlag);
2635 return true; 2635 return true;
2636 } 2636 }
2637 default: 2637 default:
2638 return false; 2638 return false;
2639 } 2639 }
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
2763 Definition::kValue); 2763 Definition::kValue);
2764 *array = elements; 2764 *array = elements;
2765 } 2765 }
2766 return array_cid; 2766 return array_cid;
2767 } 2767 }
2768 2768
2769 2769
2770 bool FlowGraphOptimizer::BuildByteArrayViewLoad(InstanceCallInstr* call, 2770 bool FlowGraphOptimizer::BuildByteArrayViewLoad(InstanceCallInstr* call,
2771 intptr_t view_cid) { 2771 intptr_t view_cid) {
2772 bool simd_view = (view_cid == kTypedDataFloat32x4ArrayCid) || 2772 bool simd_view = (view_cid == kTypedDataFloat32x4ArrayCid) ||
2773 (view_cid == kTypedDataUint32x4ArrayCid); 2773 (view_cid == kTypedDataInt32x4ArrayCid);
2774 if (simd_view && !ShouldInlineSimd()) { 2774 if (simd_view && !ShouldInlineSimd()) {
2775 return false; 2775 return false;
2776 } 2776 }
2777 2777
2778 ASSERT(call->HasICData()); 2778 ASSERT(call->HasICData());
2779 Function& target = Function::Handle(); 2779 Function& target = Function::Handle();
2780 GrowableArray<intptr_t> class_ids; 2780 GrowableArray<intptr_t> class_ids;
2781 call->ic_data()->GetCheckAt(0, &class_ids, &target); 2781 call->ic_data()->GetCheckAt(0, &class_ids, &target);
2782 const intptr_t receiver_cid = class_ids[0]; 2782 const intptr_t receiver_cid = class_ids[0];
2783 2783
(...skipping 29 matching lines...) Expand all
2813 current_iterator()->RemoveCurrentFromGraph(); 2813 current_iterator()->RemoveCurrentFromGraph();
2814 call->set_previous(NULL); 2814 call->set_previous(NULL);
2815 call->set_next(NULL); 2815 call->set_next(NULL);
2816 return true; 2816 return true;
2817 } 2817 }
2818 2818
2819 2819
2820 bool FlowGraphOptimizer::BuildByteArrayViewStore(InstanceCallInstr* call, 2820 bool FlowGraphOptimizer::BuildByteArrayViewStore(InstanceCallInstr* call,
2821 intptr_t view_cid) { 2821 intptr_t view_cid) {
2822 bool simd_view = (view_cid == kTypedDataFloat32x4ArrayCid) || 2822 bool simd_view = (view_cid == kTypedDataFloat32x4ArrayCid) ||
2823 (view_cid == kTypedDataUint32x4ArrayCid); 2823 (view_cid == kTypedDataInt32x4ArrayCid);
2824 if (simd_view && !ShouldInlineSimd()) { 2824 if (simd_view && !ShouldInlineSimd()) {
2825 return false; 2825 return false;
2826 } 2826 }
2827 ASSERT(call->HasICData()); 2827 ASSERT(call->HasICData());
2828 Function& target = Function::Handle(); 2828 Function& target = Function::Handle();
2829 GrowableArray<intptr_t> class_ids; 2829 GrowableArray<intptr_t> class_ids;
2830 call->ic_data()->GetCheckAt(0, &class_ids, &target); 2830 call->ic_data()->GetCheckAt(0, &class_ids, &target);
2831 const intptr_t receiver_cid = class_ids[0]; 2831 const intptr_t receiver_cid = class_ids[0];
2832 2832
2833 Definition* array = call->ArgumentAt(0); 2833 Definition* array = call->ArgumentAt(0);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
2868 case kTypedDataFloat64ArrayCid: { 2868 case kTypedDataFloat64ArrayCid: {
2869 // Check that value is always double. 2869 // Check that value is always double.
2870 value_check = ICData::New(flow_graph_->parsed_function().function(), 2870 value_check = ICData::New(flow_graph_->parsed_function().function(),
2871 call->function_name(), 2871 call->function_name(),
2872 Object::empty_array(), // Dummy args. descr. 2872 Object::empty_array(), // Dummy args. descr.
2873 Isolate::kNoDeoptId, 2873 Isolate::kNoDeoptId,
2874 1); 2874 1);
2875 value_check.AddReceiverCheck(kDoubleCid, target); 2875 value_check.AddReceiverCheck(kDoubleCid, target);
2876 break; 2876 break;
2877 } 2877 }
2878 case kTypedDataUint32x4ArrayCid: { 2878 case kTypedDataInt32x4ArrayCid: {
2879 // Check that value is always Uint32x4. 2879 // Check that value is always Int32x4.
2880 value_check = ICData::New(flow_graph_->parsed_function().function(), 2880 value_check = ICData::New(flow_graph_->parsed_function().function(),
2881 call->function_name(), 2881 call->function_name(),
2882 Object::empty_array(), // Dummy args. descr. 2882 Object::empty_array(), // Dummy args. descr.
2883 Isolate::kNoDeoptId, 2883 Isolate::kNoDeoptId,
2884 1); 2884 1);
2885 value_check.AddReceiverCheck(kUint32x4Cid, target); 2885 value_check.AddReceiverCheck(kInt32x4Cid, target);
2886 break; 2886 break;
2887 } 2887 }
2888 case kTypedDataFloat32x4ArrayCid: { 2888 case kTypedDataFloat32x4ArrayCid: {
2889 // Check that value is always Float32x4. 2889 // Check that value is always Float32x4.
2890 value_check = ICData::New(flow_graph_->parsed_function().function(), 2890 value_check = ICData::New(flow_graph_->parsed_function().function(),
2891 call->function_name(), 2891 call->function_name(),
2892 Object::empty_array(), // Dummy args. descr. 2892 Object::empty_array(), // Dummy args. descr.
2893 Isolate::kNoDeoptId, 2893 Isolate::kNoDeoptId,
2894 1); 2894 1);
2895 value_check.AddReceiverCheck(kFloat32x4Cid, target); 2895 value_check.AddReceiverCheck(kFloat32x4Cid, target);
(...skipping 347 matching lines...) Expand 10 before | Expand all | Expand 10 after
3243 (recognized_kind == MethodRecognizer::kMathCos)) { 3243 (recognized_kind == MethodRecognizer::kMathCos)) {
3244 MathUnaryInstr* math_unary = 3244 MathUnaryInstr* math_unary =
3245 new MathUnaryInstr(recognized_kind, 3245 new MathUnaryInstr(recognized_kind,
3246 new Value(call->ArgumentAt(0)), 3246 new Value(call->ArgumentAt(0)),
3247 call->deopt_id()); 3247 call->deopt_id());
3248 ReplaceCall(call, math_unary); 3248 ReplaceCall(call, math_unary);
3249 } else if ((recognized_kind == MethodRecognizer::kFloat32x4Zero) || 3249 } else if ((recognized_kind == MethodRecognizer::kFloat32x4Zero) ||
3250 (recognized_kind == MethodRecognizer::kFloat32x4Splat) || 3250 (recognized_kind == MethodRecognizer::kFloat32x4Splat) ||
3251 (recognized_kind == MethodRecognizer::kFloat32x4Constructor)) { 3251 (recognized_kind == MethodRecognizer::kFloat32x4Constructor)) {
3252 TryInlineFloat32x4Constructor(call, recognized_kind); 3252 TryInlineFloat32x4Constructor(call, recognized_kind);
3253 } else if (recognized_kind == MethodRecognizer::kUint32x4BoolConstructor) { 3253 } else if (recognized_kind == MethodRecognizer::kInt32x4BoolConstructor) {
3254 TryInlineUint32x4Constructor(call, recognized_kind); 3254 TryInlineInt32x4Constructor(call, recognized_kind);
3255 } else if (recognized_kind == MethodRecognizer::kObjectConstructor) { 3255 } else if (recognized_kind == MethodRecognizer::kObjectConstructor) {
3256 // Remove the original push arguments. 3256 // Remove the original push arguments.
3257 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { 3257 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) {
3258 PushArgumentInstr* push = call->PushArgumentAt(i); 3258 PushArgumentInstr* push = call->PushArgumentAt(i);
3259 push->ReplaceUsesWith(push->value()->definition()); 3259 push->ReplaceUsesWith(push->value()->definition());
3260 push->RemoveFromGraph(); 3260 push->RemoveFromGraph();
3261 } 3261 }
3262 // Manually replace call with global null constant. ReplaceCall can't 3262 // Manually replace call with global null constant. ReplaceCall can't
3263 // be used for definitions that are already in the graph. 3263 // be used for definitions that are already in the graph.
3264 call->ReplaceUsesWith(flow_graph_->constant_null()); 3264 call->ReplaceUsesWith(flow_graph_->constant_null());
(...skipping 3605 matching lines...) Expand 10 before | Expand all | Expand 10 after
6870 void ConstantPropagator::VisitFloat32x4Clamp(Float32x4ClampInstr* instr) { 6870 void ConstantPropagator::VisitFloat32x4Clamp(Float32x4ClampInstr* instr) {
6871 SetValue(instr, non_constant_); 6871 SetValue(instr, non_constant_);
6872 } 6872 }
6873 6873
6874 6874
6875 void ConstantPropagator::VisitFloat32x4With(Float32x4WithInstr* instr) { 6875 void ConstantPropagator::VisitFloat32x4With(Float32x4WithInstr* instr) {
6876 SetValue(instr, non_constant_); 6876 SetValue(instr, non_constant_);
6877 } 6877 }
6878 6878
6879 6879
6880 void ConstantPropagator::VisitFloat32x4ToUint32x4( 6880 void ConstantPropagator::VisitFloat32x4ToInt32x4(
6881 Float32x4ToUint32x4Instr* instr) { 6881 Float32x4ToInt32x4Instr* instr) {
6882 SetValue(instr, non_constant_); 6882 SetValue(instr, non_constant_);
6883 } 6883 }
6884 6884
6885 6885
6886 void ConstantPropagator::VisitUint32x4BoolConstructor( 6886 void ConstantPropagator::VisitInt32x4BoolConstructor(
6887 Uint32x4BoolConstructorInstr* instr) { 6887 Int32x4BoolConstructorInstr* instr) {
6888 SetValue(instr, non_constant_); 6888 SetValue(instr, non_constant_);
6889 } 6889 }
6890 6890
6891 6891
6892 void ConstantPropagator::VisitUint32x4GetFlag(Uint32x4GetFlagInstr* instr) { 6892 void ConstantPropagator::VisitInt32x4GetFlag(Int32x4GetFlagInstr* instr) {
6893 SetValue(instr, non_constant_); 6893 SetValue(instr, non_constant_);
6894 } 6894 }
6895 6895
6896 6896
6897 void ConstantPropagator::VisitUint32x4SetFlag(Uint32x4SetFlagInstr* instr) { 6897 void ConstantPropagator::VisitInt32x4SetFlag(Int32x4SetFlagInstr* instr) {
6898 SetValue(instr, non_constant_); 6898 SetValue(instr, non_constant_);
6899 } 6899 }
6900 6900
6901 6901
6902 void ConstantPropagator::VisitUint32x4Select(Uint32x4SelectInstr* instr) { 6902 void ConstantPropagator::VisitInt32x4Select(Int32x4SelectInstr* instr) {
6903 SetValue(instr, non_constant_); 6903 SetValue(instr, non_constant_);
6904 } 6904 }
6905 6905
6906 6906
6907 void ConstantPropagator::VisitUint32x4ToFloat32x4( 6907 void ConstantPropagator::VisitInt32x4ToFloat32x4(
6908 Uint32x4ToFloat32x4Instr* instr) { 6908 Int32x4ToFloat32x4Instr* instr) {
6909 SetValue(instr, non_constant_); 6909 SetValue(instr, non_constant_);
6910 } 6910 }
6911 6911
6912 6912
6913 void ConstantPropagator::VisitBinaryUint32x4Op(BinaryUint32x4OpInstr* instr) { 6913 void ConstantPropagator::VisitBinaryInt32x4Op(BinaryInt32x4OpInstr* instr) {
6914 SetValue(instr, non_constant_); 6914 SetValue(instr, non_constant_);
6915 } 6915 }
6916 6916
6917 6917
6918 void ConstantPropagator::VisitMathUnary(MathUnaryInstr* instr) { 6918 void ConstantPropagator::VisitMathUnary(MathUnaryInstr* instr) {
6919 const Object& value = instr->value()->definition()->constant_value(); 6919 const Object& value = instr->value()->definition()->constant_value();
6920 if (IsNonConstant(value)) { 6920 if (IsNonConstant(value)) {
6921 SetValue(instr, non_constant_); 6921 SetValue(instr, non_constant_);
6922 } else if (IsConstant(value)) { 6922 } else if (IsConstant(value)) {
6923 // TODO(kmillikin): Handle Math's unary operations (sqrt, cos, sin). 6923 // TODO(kmillikin): Handle Math's unary operations (sqrt, cos, sin).
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
6975 const Object& value = instr->value()->definition()->constant_value(); 6975 const Object& value = instr->value()->definition()->constant_value();
6976 if (IsNonConstant(value)) { 6976 if (IsNonConstant(value)) {
6977 SetValue(instr, non_constant_); 6977 SetValue(instr, non_constant_);
6978 } else if (IsConstant(value)) { 6978 } else if (IsConstant(value)) {
6979 // TODO(kmillikin): Handle conversion. 6979 // TODO(kmillikin): Handle conversion.
6980 SetValue(instr, non_constant_); 6980 SetValue(instr, non_constant_);
6981 } 6981 }
6982 } 6982 }
6983 6983
6984 6984
6985 void ConstantPropagator::VisitUnboxUint32x4(UnboxUint32x4Instr* instr) { 6985 void ConstantPropagator::VisitUnboxInt32x4(UnboxInt32x4Instr* instr) {
6986 const Object& value = instr->value()->definition()->constant_value(); 6986 const Object& value = instr->value()->definition()->constant_value();
6987 if (IsNonConstant(value)) { 6987 if (IsNonConstant(value)) {
6988 SetValue(instr, non_constant_); 6988 SetValue(instr, non_constant_);
6989 } else if (IsConstant(value)) { 6989 } else if (IsConstant(value)) {
6990 // TODO(kmillikin): Handle conversion. 6990 // TODO(kmillikin): Handle conversion.
6991 SetValue(instr, non_constant_); 6991 SetValue(instr, non_constant_);
6992 } 6992 }
6993 } 6993 }
6994 6994
6995 6995
6996 void ConstantPropagator::VisitBoxUint32x4(BoxUint32x4Instr* instr) { 6996 void ConstantPropagator::VisitBoxInt32x4(BoxInt32x4Instr* instr) {
6997 const Object& value = instr->value()->definition()->constant_value(); 6997 const Object& value = instr->value()->definition()->constant_value();
6998 if (IsNonConstant(value)) { 6998 if (IsNonConstant(value)) {
6999 SetValue(instr, non_constant_); 6999 SetValue(instr, non_constant_);
7000 } else if (IsConstant(value)) { 7000 } else if (IsConstant(value)) {
7001 // TODO(kmillikin): Handle conversion. 7001 // TODO(kmillikin): Handle conversion.
7002 SetValue(instr, non_constant_); 7002 SetValue(instr, non_constant_);
7003 } 7003 }
7004 } 7004 }
7005 7005
7006 7006
(...skipping 844 matching lines...) Expand 10 before | Expand all | Expand 10 after
7851 } 7851 }
7852 7852
7853 // Insert materializations at environment uses. 7853 // Insert materializations at environment uses.
7854 for (intptr_t i = 0; i < exits.length(); i++) { 7854 for (intptr_t i = 0; i < exits.length(); i++) {
7855 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); 7855 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields);
7856 } 7856 }
7857 } 7857 }
7858 7858
7859 7859
7860 } // namespace dart 7860 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/flow_graph_type_propagator.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698