| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/flow_graph_optimizer.h" | 5 #include "vm/flow_graph_optimizer.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/cha.h" | 8 #include "vm/cha.h" |
| 9 #include "vm/dart_entry.h" | 9 #include "vm/dart_entry.h" |
| 10 #include "vm/flow_graph_builder.h" | 10 #include "vm/flow_graph_builder.h" |
| (...skipping 375 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |