| 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 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1363 } else if (HasTwoMintOrSmi(ic_data) && | 1363 } else if (HasTwoMintOrSmi(ic_data) && |
| 1364 FlowGraphCompiler::SupportsUnboxedMints()) { | 1364 FlowGraphCompiler::SupportsUnboxedMints()) { |
| 1365 // Don't generate mint code if the IC data is marked because of an | 1365 // Don't generate mint code if the IC data is marked because of an |
| 1366 // overflow. | 1366 // overflow. |
| 1367 if (ic_data.deopt_reason() == kDeoptBinaryMintOp) return false; | 1367 if (ic_data.deopt_reason() == kDeoptBinaryMintOp) return false; |
| 1368 operands_type = kMintCid; | 1368 operands_type = kMintCid; |
| 1369 } else if (ShouldSpecializeForDouble(ic_data)) { | 1369 } else if (ShouldSpecializeForDouble(ic_data)) { |
| 1370 operands_type = kDoubleCid; | 1370 operands_type = kDoubleCid; |
| 1371 } else if (HasOnlyTwoOf(ic_data, kFloat32x4Cid)) { | 1371 } else if (HasOnlyTwoOf(ic_data, kFloat32x4Cid)) { |
| 1372 operands_type = kFloat32x4Cid; | 1372 operands_type = kFloat32x4Cid; |
| 1373 } else if (HasOnlyTwoOf(ic_data, kUint32x4Cid)) { | 1373 } else if (HasOnlyTwoOf(ic_data, kInt32x4Cid)) { |
| 1374 operands_type = kUint32x4Cid; | 1374 operands_type = kInt32x4Cid; |
| 1375 } else { | 1375 } else { |
| 1376 return false; | 1376 return false; |
| 1377 } | 1377 } |
| 1378 break; | 1378 break; |
| 1379 case Token::kMUL: | 1379 case Token::kMUL: |
| 1380 if (HasOnlyTwoOf(ic_data, kSmiCid)) { | 1380 if (HasOnlyTwoOf(ic_data, kSmiCid)) { |
| 1381 // Don't generate smi code if the IC data is marked because of an | 1381 // Don't generate smi code if the IC data is marked because of an |
| 1382 // overflow. | 1382 // overflow. |
| 1383 // TODO(fschneider): Add unboxed mint multiplication. | 1383 // TODO(fschneider): Add unboxed mint multiplication. |
| 1384 if (ic_data.deopt_reason() == kDeoptBinarySmiOp) return false; | 1384 if (ic_data.deopt_reason() == kDeoptBinarySmiOp) return false; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1408 return false; | 1408 return false; |
| 1409 } | 1409 } |
| 1410 break; | 1410 break; |
| 1411 case Token::kBIT_AND: | 1411 case Token::kBIT_AND: |
| 1412 case Token::kBIT_OR: | 1412 case Token::kBIT_OR: |
| 1413 case Token::kBIT_XOR: | 1413 case Token::kBIT_XOR: |
| 1414 if (HasOnlyTwoOf(ic_data, kSmiCid)) { | 1414 if (HasOnlyTwoOf(ic_data, kSmiCid)) { |
| 1415 operands_type = kSmiCid; | 1415 operands_type = kSmiCid; |
| 1416 } else if (HasTwoMintOrSmi(ic_data)) { | 1416 } else if (HasTwoMintOrSmi(ic_data)) { |
| 1417 operands_type = kMintCid; | 1417 operands_type = kMintCid; |
| 1418 } else if (HasOnlyTwoOf(ic_data, kUint32x4Cid)) { | 1418 } else if (HasOnlyTwoOf(ic_data, kInt32x4Cid)) { |
| 1419 operands_type = kUint32x4Cid; | 1419 operands_type = kInt32x4Cid; |
| 1420 } else { | 1420 } else { |
| 1421 return false; | 1421 return false; |
| 1422 } | 1422 } |
| 1423 break; | 1423 break; |
| 1424 case Token::kSHR: | 1424 case Token::kSHR: |
| 1425 case Token::kSHL: | 1425 case Token::kSHL: |
| 1426 if (HasOnlyTwoOf(ic_data, kSmiCid)) { | 1426 if (HasOnlyTwoOf(ic_data, kSmiCid)) { |
| 1427 // Left shift may overflow from smi into mint or big ints. | 1427 // Left shift may overflow from smi into mint or big ints. |
| 1428 // Don't generate smi code if the IC data is marked because | 1428 // Don't generate smi code if the IC data is marked because |
| 1429 // of an overflow. | 1429 // of an overflow. |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1483 call->deopt_id()); | 1483 call->deopt_id()); |
| 1484 ReplaceCall(call, shift_op); | 1484 ReplaceCall(call, shift_op); |
| 1485 } else { | 1485 } else { |
| 1486 BinaryMintOpInstr* bin_op = | 1486 BinaryMintOpInstr* bin_op = |
| 1487 new BinaryMintOpInstr(op_kind, new Value(left), new Value(right), | 1487 new BinaryMintOpInstr(op_kind, new Value(left), new Value(right), |
| 1488 call->deopt_id()); | 1488 call->deopt_id()); |
| 1489 ReplaceCall(call, bin_op); | 1489 ReplaceCall(call, bin_op); |
| 1490 } | 1490 } |
| 1491 } else if (operands_type == kFloat32x4Cid) { | 1491 } else if (operands_type == kFloat32x4Cid) { |
| 1492 return InlineFloat32x4BinaryOp(call, op_kind); | 1492 return InlineFloat32x4BinaryOp(call, op_kind); |
| 1493 } else if (operands_type == kUint32x4Cid) { | 1493 } else if (operands_type == kInt32x4Cid) { |
| 1494 return InlineUint32x4BinaryOp(call, op_kind); | 1494 return InlineInt32x4BinaryOp(call, op_kind); |
| 1495 } else if (op_kind == Token::kMOD) { | 1495 } else if (op_kind == Token::kMOD) { |
| 1496 // TODO(vegorov): implement fast path code for modulo. | 1496 // TODO(vegorov): implement fast path code for modulo. |
| 1497 ASSERT(operands_type == kSmiCid); | 1497 ASSERT(operands_type == kSmiCid); |
| 1498 if (!right->IsConstant()) return false; | 1498 if (!right->IsConstant()) return false; |
| 1499 const Object& obj = right->AsConstant()->value(); | 1499 const Object& obj = right->AsConstant()->value(); |
| 1500 if (!obj.IsSmi()) return false; | 1500 if (!obj.IsSmi()) return false; |
| 1501 const intptr_t value = Smi::Cast(obj).Value(); | 1501 const intptr_t value = Smi::Cast(obj).Value(); |
| 1502 if (!Utils::IsPowerOfTwo(value)) return false; | 1502 if (!Utils::IsPowerOfTwo(value)) return false; |
| 1503 | 1503 |
| 1504 // Insert smi check and attach a copy of the original environment | 1504 // Insert smi check and attach a copy of the original environment |
| (...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1748 mask, | 1748 mask, |
| 1749 call->deopt_id()); | 1749 call->deopt_id()); |
| 1750 ReplaceCall(call, instr); | 1750 ReplaceCall(call, instr); |
| 1751 return true; | 1751 return true; |
| 1752 } | 1752 } |
| 1753 UNREACHABLE(); | 1753 UNREACHABLE(); |
| 1754 return false; | 1754 return false; |
| 1755 } | 1755 } |
| 1756 | 1756 |
| 1757 | 1757 |
| 1758 bool FlowGraphOptimizer::InlineUint32x4Getter(InstanceCallInstr* call, | 1758 bool FlowGraphOptimizer::InlineInt32x4Getter(InstanceCallInstr* call, |
| 1759 MethodRecognizer::Kind getter) { | 1759 MethodRecognizer::Kind getter) { |
| 1760 if (!ShouldInlineSimd()) { | 1760 if (!ShouldInlineSimd()) { |
| 1761 return false; | 1761 return false; |
| 1762 } | 1762 } |
| 1763 AddCheckClass(call->ArgumentAt(0), | 1763 AddCheckClass(call->ArgumentAt(0), |
| 1764 ICData::ZoneHandle( | 1764 ICData::ZoneHandle( |
| 1765 call->ic_data()->AsUnaryClassChecksForArgNr(0)), | 1765 call->ic_data()->AsUnaryClassChecksForArgNr(0)), |
| 1766 call->deopt_id(), | 1766 call->deopt_id(), |
| 1767 call->env(), | 1767 call->env(), |
| 1768 call); | 1768 call); |
| 1769 intptr_t mask = 0; | 1769 intptr_t mask = 0; |
| 1770 if ((getter == MethodRecognizer::kUint32x4Shuffle) || | 1770 if ((getter == MethodRecognizer::kInt32x4Shuffle) || |
| 1771 (getter == MethodRecognizer::kUint32x4ShuffleMix)) { | 1771 (getter == MethodRecognizer::kInt32x4ShuffleMix)) { |
| 1772 // Extract shuffle mask. | 1772 // Extract shuffle mask. |
| 1773 Definition* mask_definition = NULL; | 1773 Definition* mask_definition = NULL; |
| 1774 if (getter == MethodRecognizer::kUint32x4Shuffle) { | 1774 if (getter == MethodRecognizer::kInt32x4Shuffle) { |
| 1775 ASSERT(call->ArgumentCount() == 2); | 1775 ASSERT(call->ArgumentCount() == 2); |
| 1776 mask_definition = call->ArgumentAt(1); | 1776 mask_definition = call->ArgumentAt(1); |
| 1777 } else { | 1777 } else { |
| 1778 ASSERT(getter == MethodRecognizer::kUint32x4ShuffleMix); | 1778 ASSERT(getter == MethodRecognizer::kInt32x4ShuffleMix); |
| 1779 ASSERT(call->ArgumentCount() == 3); | 1779 ASSERT(call->ArgumentCount() == 3); |
| 1780 mask_definition = call->ArgumentAt(2); | 1780 mask_definition = call->ArgumentAt(2); |
| 1781 } | 1781 } |
| 1782 if (!mask_definition->IsConstant()) { | 1782 if (!mask_definition->IsConstant()) { |
| 1783 return false; | 1783 return false; |
| 1784 } | 1784 } |
| 1785 ASSERT(mask_definition->IsConstant()); | 1785 ASSERT(mask_definition->IsConstant()); |
| 1786 ConstantInstr* constant_instruction = mask_definition->AsConstant(); | 1786 ConstantInstr* constant_instruction = mask_definition->AsConstant(); |
| 1787 const Object& constant_mask = constant_instruction->value(); | 1787 const Object& constant_mask = constant_instruction->value(); |
| 1788 if (!constant_mask.IsSmi()) { | 1788 if (!constant_mask.IsSmi()) { |
| 1789 return false; | 1789 return false; |
| 1790 } | 1790 } |
| 1791 ASSERT(constant_mask.IsSmi()); | 1791 ASSERT(constant_mask.IsSmi()); |
| 1792 mask = Smi::Cast(constant_mask).Value(); | 1792 mask = Smi::Cast(constant_mask).Value(); |
| 1793 if ((mask < 0) || (mask > 255)) { | 1793 if ((mask < 0) || (mask > 255)) { |
| 1794 // Not a valid mask. | 1794 // Not a valid mask. |
| 1795 return false; | 1795 return false; |
| 1796 } | 1796 } |
| 1797 } | 1797 } |
| 1798 if (getter == MethodRecognizer::kUint32x4GetSignMask) { | 1798 if (getter == MethodRecognizer::kInt32x4GetSignMask) { |
| 1799 Simd32x4GetSignMaskInstr* instr = new Simd32x4GetSignMaskInstr( | 1799 Simd32x4GetSignMaskInstr* instr = new Simd32x4GetSignMaskInstr( |
| 1800 getter, | 1800 getter, |
| 1801 new Value(call->ArgumentAt(0)), | 1801 new Value(call->ArgumentAt(0)), |
| 1802 call->deopt_id()); | 1802 call->deopt_id()); |
| 1803 ReplaceCall(call, instr); | 1803 ReplaceCall(call, instr); |
| 1804 return true; | 1804 return true; |
| 1805 } else if (getter == MethodRecognizer::kUint32x4ShuffleMix) { | 1805 } else if (getter == MethodRecognizer::kInt32x4ShuffleMix) { |
| 1806 Simd32x4ShuffleMixInstr* instr = new Simd32x4ShuffleMixInstr( | 1806 Simd32x4ShuffleMixInstr* instr = new Simd32x4ShuffleMixInstr( |
| 1807 getter, | 1807 getter, |
| 1808 new Value(call->ArgumentAt(0)), | 1808 new Value(call->ArgumentAt(0)), |
| 1809 new Value(call->ArgumentAt(1)), | 1809 new Value(call->ArgumentAt(1)), |
| 1810 mask, | 1810 mask, |
| 1811 call->deopt_id()); | 1811 call->deopt_id()); |
| 1812 ReplaceCall(call, instr); | 1812 ReplaceCall(call, instr); |
| 1813 return true; | 1813 return true; |
| 1814 } else if (getter == MethodRecognizer::kUint32x4Shuffle) { | 1814 } else if (getter == MethodRecognizer::kInt32x4Shuffle) { |
| 1815 Simd32x4ShuffleInstr* instr = new Simd32x4ShuffleInstr( | 1815 Simd32x4ShuffleInstr* instr = new Simd32x4ShuffleInstr( |
| 1816 getter, | 1816 getter, |
| 1817 new Value(call->ArgumentAt(0)), | 1817 new Value(call->ArgumentAt(0)), |
| 1818 mask, | 1818 mask, |
| 1819 call->deopt_id()); | 1819 call->deopt_id()); |
| 1820 ReplaceCall(call, instr); | 1820 ReplaceCall(call, instr); |
| 1821 return true; | 1821 return true; |
| 1822 } else { | 1822 } else { |
| 1823 Uint32x4GetFlagInstr* instr = new Uint32x4GetFlagInstr( | 1823 Int32x4GetFlagInstr* instr = new Int32x4GetFlagInstr( |
| 1824 getter, | 1824 getter, |
| 1825 new Value(call->ArgumentAt(0)), | 1825 new Value(call->ArgumentAt(0)), |
| 1826 call->deopt_id()); | 1826 call->deopt_id()); |
| 1827 ReplaceCall(call, instr); | 1827 ReplaceCall(call, instr); |
| 1828 return true; | 1828 return true; |
| 1829 } | 1829 } |
| 1830 } | 1830 } |
| 1831 | 1831 |
| 1832 | 1832 |
| 1833 bool FlowGraphOptimizer::InlineFloat32x4BinaryOp(InstanceCallInstr* call, | 1833 bool FlowGraphOptimizer::InlineFloat32x4BinaryOp(InstanceCallInstr* call, |
| (...skipping 21 matching lines...) Expand all Loading... |
| 1855 // Replace call. | 1855 // Replace call. |
| 1856 BinaryFloat32x4OpInstr* float32x4_bin_op = | 1856 BinaryFloat32x4OpInstr* float32x4_bin_op = |
| 1857 new BinaryFloat32x4OpInstr(op_kind, new Value(left), new Value(right), | 1857 new BinaryFloat32x4OpInstr(op_kind, new Value(left), new Value(right), |
| 1858 call->deopt_id()); | 1858 call->deopt_id()); |
| 1859 ReplaceCall(call, float32x4_bin_op); | 1859 ReplaceCall(call, float32x4_bin_op); |
| 1860 | 1860 |
| 1861 return true; | 1861 return true; |
| 1862 } | 1862 } |
| 1863 | 1863 |
| 1864 | 1864 |
| 1865 bool FlowGraphOptimizer::InlineUint32x4BinaryOp(InstanceCallInstr* call, | 1865 bool FlowGraphOptimizer::InlineInt32x4BinaryOp(InstanceCallInstr* call, |
| 1866 Token::Kind op_kind) { | 1866 Token::Kind op_kind) { |
| 1867 if (!ShouldInlineSimd()) { | 1867 if (!ShouldInlineSimd()) { |
| 1868 return false; | 1868 return false; |
| 1869 } | 1869 } |
| 1870 ASSERT(call->ArgumentCount() == 2); | 1870 ASSERT(call->ArgumentCount() == 2); |
| 1871 Definition* left = call->ArgumentAt(0); | 1871 Definition* left = call->ArgumentAt(0); |
| 1872 Definition* right = call->ArgumentAt(1); | 1872 Definition* right = call->ArgumentAt(1); |
| 1873 // Type check left. | 1873 // Type check left. |
| 1874 AddCheckClass(left, | 1874 AddCheckClass(left, |
| 1875 ICData::ZoneHandle( | 1875 ICData::ZoneHandle( |
| 1876 call->ic_data()->AsUnaryClassChecksForArgNr(0)), | 1876 call->ic_data()->AsUnaryClassChecksForArgNr(0)), |
| 1877 call->deopt_id(), | 1877 call->deopt_id(), |
| 1878 call->env(), | 1878 call->env(), |
| 1879 call); | 1879 call); |
| 1880 // Type check right. | 1880 // Type check right. |
| 1881 AddCheckClass(right, | 1881 AddCheckClass(right, |
| 1882 ICData::ZoneHandle( | 1882 ICData::ZoneHandle( |
| 1883 call->ic_data()->AsUnaryClassChecksForArgNr(1)), | 1883 call->ic_data()->AsUnaryClassChecksForArgNr(1)), |
| 1884 call->deopt_id(), | 1884 call->deopt_id(), |
| 1885 call->env(), | 1885 call->env(), |
| 1886 call); | 1886 call); |
| 1887 // Replace call. | 1887 // Replace call. |
| 1888 BinaryUint32x4OpInstr* uint32x4_bin_op = | 1888 BinaryInt32x4OpInstr* int32x4_bin_op = |
| 1889 new BinaryUint32x4OpInstr(op_kind, new Value(left), new Value(right), | 1889 new BinaryInt32x4OpInstr(op_kind, new Value(left), new Value(right), |
| 1890 call->deopt_id()); | 1890 call->deopt_id()); |
| 1891 ReplaceCall(call, uint32x4_bin_op); | 1891 ReplaceCall(call, int32x4_bin_op); |
| 1892 return true; | 1892 return true; |
| 1893 } | 1893 } |
| 1894 | 1894 |
| 1895 | 1895 |
| 1896 // Only unique implicit instance getters can be currently handled. | 1896 // Only unique implicit instance getters can be currently handled. |
| 1897 bool FlowGraphOptimizer::TryInlineInstanceGetter(InstanceCallInstr* call) { | 1897 bool FlowGraphOptimizer::TryInlineInstanceGetter(InstanceCallInstr* call) { |
| 1898 ASSERT(call->HasICData()); | 1898 ASSERT(call->HasICData()); |
| 1899 const ICData& ic_data = *call->ic_data(); | 1899 const ICData& ic_data = *call->ic_data(); |
| 1900 if (ic_data.NumberOfChecks() == 0) { | 1900 if (ic_data.NumberOfChecks() == 0) { |
| 1901 // No type feedback collected. | 1901 // No type feedback collected. |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1980 case kExternalTypedDataUint8ArrayCid: | 1980 case kExternalTypedDataUint8ArrayCid: |
| 1981 case kTypedDataUint8ClampedArrayCid: | 1981 case kTypedDataUint8ClampedArrayCid: |
| 1982 case kExternalTypedDataUint8ClampedArrayCid: | 1982 case kExternalTypedDataUint8ClampedArrayCid: |
| 1983 case kTypedDataInt16ArrayCid: | 1983 case kTypedDataInt16ArrayCid: |
| 1984 case kTypedDataUint16ArrayCid: | 1984 case kTypedDataUint16ArrayCid: |
| 1985 case kTypedDataInt32ArrayCid: | 1985 case kTypedDataInt32ArrayCid: |
| 1986 case kTypedDataUint32ArrayCid: | 1986 case kTypedDataUint32ArrayCid: |
| 1987 case kTypedDataFloat32ArrayCid: | 1987 case kTypedDataFloat32ArrayCid: |
| 1988 case kTypedDataFloat64ArrayCid: | 1988 case kTypedDataFloat64ArrayCid: |
| 1989 case kTypedDataFloat32x4ArrayCid: | 1989 case kTypedDataFloat32x4ArrayCid: |
| 1990 case kTypedDataUint32x4ArrayCid: | 1990 case kTypedDataInt32x4ArrayCid: |
| 1991 return true; | 1991 return true; |
| 1992 default: | 1992 default: |
| 1993 return false; | 1993 return false; |
| 1994 } | 1994 } |
| 1995 } | 1995 } |
| 1996 | 1996 |
| 1997 | 1997 |
| 1998 // Inline only simple, frequently called core library methods. | 1998 // Inline only simple, frequently called core library methods. |
| 1999 bool FlowGraphOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) { | 1999 bool FlowGraphOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) { |
| 2000 ASSERT(call->HasICData()); | 2000 ASSERT(call->HasICData()); |
| (...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2154 case MethodRecognizer::kByteArrayBaseGetInt32: | 2154 case MethodRecognizer::kByteArrayBaseGetInt32: |
| 2155 return BuildByteArrayViewLoad(call, kTypedDataInt32ArrayCid); | 2155 return BuildByteArrayViewLoad(call, kTypedDataInt32ArrayCid); |
| 2156 case MethodRecognizer::kByteArrayBaseGetUint32: | 2156 case MethodRecognizer::kByteArrayBaseGetUint32: |
| 2157 return BuildByteArrayViewLoad(call, kTypedDataUint32ArrayCid); | 2157 return BuildByteArrayViewLoad(call, kTypedDataUint32ArrayCid); |
| 2158 case MethodRecognizer::kByteArrayBaseGetFloat32: | 2158 case MethodRecognizer::kByteArrayBaseGetFloat32: |
| 2159 return BuildByteArrayViewLoad(call, kTypedDataFloat32ArrayCid); | 2159 return BuildByteArrayViewLoad(call, kTypedDataFloat32ArrayCid); |
| 2160 case MethodRecognizer::kByteArrayBaseGetFloat64: | 2160 case MethodRecognizer::kByteArrayBaseGetFloat64: |
| 2161 return BuildByteArrayViewLoad(call, kTypedDataFloat64ArrayCid); | 2161 return BuildByteArrayViewLoad(call, kTypedDataFloat64ArrayCid); |
| 2162 case MethodRecognizer::kByteArrayBaseGetFloat32x4: | 2162 case MethodRecognizer::kByteArrayBaseGetFloat32x4: |
| 2163 return BuildByteArrayViewLoad(call, kTypedDataFloat32x4ArrayCid); | 2163 return BuildByteArrayViewLoad(call, kTypedDataFloat32x4ArrayCid); |
| 2164 case MethodRecognizer::kByteArrayBaseGetUint32x4: | 2164 case MethodRecognizer::kByteArrayBaseGetInt32x4: |
| 2165 return BuildByteArrayViewLoad(call, kTypedDataUint32x4ArrayCid); | 2165 return BuildByteArrayViewLoad(call, kTypedDataInt32x4ArrayCid); |
| 2166 | 2166 |
| 2167 // ByteArray setters. | 2167 // ByteArray setters. |
| 2168 case MethodRecognizer::kByteArrayBaseSetInt8: | 2168 case MethodRecognizer::kByteArrayBaseSetInt8: |
| 2169 return BuildByteArrayViewStore(call, kTypedDataInt8ArrayCid); | 2169 return BuildByteArrayViewStore(call, kTypedDataInt8ArrayCid); |
| 2170 case MethodRecognizer::kByteArrayBaseSetUint8: | 2170 case MethodRecognizer::kByteArrayBaseSetUint8: |
| 2171 return BuildByteArrayViewStore(call, kTypedDataUint8ArrayCid); | 2171 return BuildByteArrayViewStore(call, kTypedDataUint8ArrayCid); |
| 2172 case MethodRecognizer::kByteArrayBaseSetInt16: | 2172 case MethodRecognizer::kByteArrayBaseSetInt16: |
| 2173 return BuildByteArrayViewStore(call, kTypedDataInt16ArrayCid); | 2173 return BuildByteArrayViewStore(call, kTypedDataInt16ArrayCid); |
| 2174 case MethodRecognizer::kByteArrayBaseSetUint16: | 2174 case MethodRecognizer::kByteArrayBaseSetUint16: |
| 2175 return BuildByteArrayViewStore(call, kTypedDataUint16ArrayCid); | 2175 return BuildByteArrayViewStore(call, kTypedDataUint16ArrayCid); |
| 2176 case MethodRecognizer::kByteArrayBaseSetInt32: | 2176 case MethodRecognizer::kByteArrayBaseSetInt32: |
| 2177 return BuildByteArrayViewStore(call, kTypedDataInt32ArrayCid); | 2177 return BuildByteArrayViewStore(call, kTypedDataInt32ArrayCid); |
| 2178 case MethodRecognizer::kByteArrayBaseSetUint32: | 2178 case MethodRecognizer::kByteArrayBaseSetUint32: |
| 2179 return BuildByteArrayViewStore(call, kTypedDataUint32ArrayCid); | 2179 return BuildByteArrayViewStore(call, kTypedDataUint32ArrayCid); |
| 2180 case MethodRecognizer::kByteArrayBaseSetFloat32: | 2180 case MethodRecognizer::kByteArrayBaseSetFloat32: |
| 2181 return BuildByteArrayViewStore(call, kTypedDataFloat32ArrayCid); | 2181 return BuildByteArrayViewStore(call, kTypedDataFloat32ArrayCid); |
| 2182 case MethodRecognizer::kByteArrayBaseSetFloat64: | 2182 case MethodRecognizer::kByteArrayBaseSetFloat64: |
| 2183 return BuildByteArrayViewStore(call, kTypedDataFloat64ArrayCid); | 2183 return BuildByteArrayViewStore(call, kTypedDataFloat64ArrayCid); |
| 2184 case MethodRecognizer::kByteArrayBaseSetFloat32x4: | 2184 case MethodRecognizer::kByteArrayBaseSetFloat32x4: |
| 2185 return BuildByteArrayViewStore(call, kTypedDataFloat32x4ArrayCid); | 2185 return BuildByteArrayViewStore(call, kTypedDataFloat32x4ArrayCid); |
| 2186 case MethodRecognizer::kByteArrayBaseSetUint32x4: | 2186 case MethodRecognizer::kByteArrayBaseSetInt32x4: |
| 2187 return BuildByteArrayViewStore(call, kTypedDataUint32x4ArrayCid); | 2187 return BuildByteArrayViewStore(call, kTypedDataInt32x4ArrayCid); |
| 2188 default: | 2188 default: |
| 2189 // Unsupported method. | 2189 // Unsupported method. |
| 2190 return false; | 2190 return false; |
| 2191 } | 2191 } |
| 2192 } | 2192 } |
| 2193 | 2193 |
| 2194 if ((class_ids[0] == kFloat32x4Cid) && (ic_data.NumberOfChecks() == 1)) { | 2194 if ((class_ids[0] == kFloat32x4Cid) && (ic_data.NumberOfChecks() == 1)) { |
| 2195 return TryInlineFloat32x4Method(call, recognized_kind); | 2195 return TryInlineFloat32x4Method(call, recognized_kind); |
| 2196 } | 2196 } |
| 2197 | 2197 |
| 2198 if ((class_ids[0] == kUint32x4Cid) && (ic_data.NumberOfChecks() == 1)) { | 2198 if ((class_ids[0] == kInt32x4Cid) && (ic_data.NumberOfChecks() == 1)) { |
| 2199 return TryInlineUint32x4Method(call, recognized_kind); | 2199 return TryInlineInt32x4Method(call, recognized_kind); |
| 2200 } | 2200 } |
| 2201 | 2201 |
| 2202 if (recognized_kind == MethodRecognizer::kIntegerLeftShiftWithMask32) { | 2202 if (recognized_kind == MethodRecognizer::kIntegerLeftShiftWithMask32) { |
| 2203 ASSERT(call->ArgumentCount() == 3); | 2203 ASSERT(call->ArgumentCount() == 3); |
| 2204 ASSERT(ic_data.num_args_tested() == 2); | 2204 ASSERT(ic_data.num_args_tested() == 2); |
| 2205 Definition* value = call->ArgumentAt(0); | 2205 Definition* value = call->ArgumentAt(0); |
| 2206 Definition* count = call->ArgumentAt(1); | 2206 Definition* count = call->ArgumentAt(1); |
| 2207 Definition* int32_mask = call->ArgumentAt(2); | 2207 Definition* int32_mask = call->ArgumentAt(2); |
| 2208 if (HasOnlyTwoOf(ic_data, kSmiCid)) { | 2208 if (HasOnlyTwoOf(ic_data, kSmiCid)) { |
| 2209 if (ic_data.deopt_reason() == kDeoptShiftMintOp) { | 2209 if (ic_data.deopt_reason() == kDeoptShiftMintOp) { |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2281 return true; | 2281 return true; |
| 2282 } else if (recognized_kind == MethodRecognizer::kFloat32x4Constructor) { | 2282 } else if (recognized_kind == MethodRecognizer::kFloat32x4Constructor) { |
| 2283 Float32x4ConstructorInstr* con = | 2283 Float32x4ConstructorInstr* con = |
| 2284 new Float32x4ConstructorInstr(new Value(call->ArgumentAt(1)), | 2284 new Float32x4ConstructorInstr(new Value(call->ArgumentAt(1)), |
| 2285 new Value(call->ArgumentAt(2)), | 2285 new Value(call->ArgumentAt(2)), |
| 2286 new Value(call->ArgumentAt(3)), | 2286 new Value(call->ArgumentAt(3)), |
| 2287 new Value(call->ArgumentAt(4)), | 2287 new Value(call->ArgumentAt(4)), |
| 2288 call->deopt_id()); | 2288 call->deopt_id()); |
| 2289 ReplaceCall(call, con); | 2289 ReplaceCall(call, con); |
| 2290 return true; | 2290 return true; |
| 2291 } else if (recognized_kind == MethodRecognizer::kFloat32x4FromUint32x4Bits) { | 2291 } else if (recognized_kind == MethodRecognizer::kFloat32x4FromInt32x4Bits) { |
| 2292 Uint32x4ToFloat32x4Instr* cast = | 2292 Int32x4ToFloat32x4Instr* cast = |
| 2293 new Uint32x4ToFloat32x4Instr(new Value(call->ArgumentAt(1)), | 2293 new Int32x4ToFloat32x4Instr(new Value(call->ArgumentAt(1)), |
| 2294 call->deopt_id()); | 2294 call->deopt_id()); |
| 2295 ReplaceCall(call, cast); | 2295 ReplaceCall(call, cast); |
| 2296 return true; | 2296 return true; |
| 2297 } | 2297 } |
| 2298 return false; | 2298 return false; |
| 2299 } | 2299 } |
| 2300 | 2300 |
| 2301 | 2301 |
| 2302 bool FlowGraphOptimizer::TryInlineUint32x4Constructor( | 2302 bool FlowGraphOptimizer::TryInlineInt32x4Constructor( |
| 2303 StaticCallInstr* call, | 2303 StaticCallInstr* call, |
| 2304 MethodRecognizer::Kind recognized_kind) { | 2304 MethodRecognizer::Kind recognized_kind) { |
| 2305 if (!ShouldInlineSimd()) { | 2305 if (!ShouldInlineSimd()) { |
| 2306 return false; | 2306 return false; |
| 2307 } | 2307 } |
| 2308 if (recognized_kind == MethodRecognizer::kUint32x4BoolConstructor) { | 2308 if (recognized_kind == MethodRecognizer::kInt32x4BoolConstructor) { |
| 2309 Uint32x4BoolConstructorInstr* con = new Uint32x4BoolConstructorInstr( | 2309 Int32x4BoolConstructorInstr* con = new Int32x4BoolConstructorInstr( |
| 2310 new Value(call->ArgumentAt(1)), | 2310 new Value(call->ArgumentAt(1)), |
| 2311 new Value(call->ArgumentAt(2)), | 2311 new Value(call->ArgumentAt(2)), |
| 2312 new Value(call->ArgumentAt(3)), | 2312 new Value(call->ArgumentAt(3)), |
| 2313 new Value(call->ArgumentAt(4)), | 2313 new Value(call->ArgumentAt(4)), |
| 2314 call->deopt_id()); | 2314 call->deopt_id()); |
| 2315 ReplaceCall(call, con); | 2315 ReplaceCall(call, con); |
| 2316 return true; | 2316 return true; |
| 2317 } else if (recognized_kind == MethodRecognizer::kUint32x4FromFloat32x4Bits) { | 2317 } else if (recognized_kind == MethodRecognizer::kInt32x4FromFloat32x4Bits) { |
| 2318 Float32x4ToUint32x4Instr* cast = | 2318 Float32x4ToInt32x4Instr* cast = |
| 2319 new Float32x4ToUint32x4Instr(new Value(call->ArgumentAt(1)), | 2319 new Float32x4ToInt32x4Instr(new Value(call->ArgumentAt(1)), |
| 2320 call->deopt_id()); | 2320 call->deopt_id()); |
| 2321 ReplaceCall(call, cast); | 2321 ReplaceCall(call, cast); |
| 2322 return true; | 2322 return true; |
| 2323 } | 2323 } |
| 2324 return false; | 2324 return false; |
| 2325 } | 2325 } |
| 2326 | 2326 |
| 2327 | 2327 |
| 2328 bool FlowGraphOptimizer::TryInlineFloat32x4Method( | 2328 bool FlowGraphOptimizer::TryInlineFloat32x4Method( |
| 2329 InstanceCallInstr* call, | 2329 InstanceCallInstr* call, |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2473 case MethodRecognizer::kFloat32x4ShuffleMix: | 2473 case MethodRecognizer::kFloat32x4ShuffleMix: |
| 2474 case MethodRecognizer::kFloat32x4Shuffle: { | 2474 case MethodRecognizer::kFloat32x4Shuffle: { |
| 2475 return InlineFloat32x4Getter(call, recognized_kind); | 2475 return InlineFloat32x4Getter(call, recognized_kind); |
| 2476 } | 2476 } |
| 2477 default: | 2477 default: |
| 2478 return false; | 2478 return false; |
| 2479 } | 2479 } |
| 2480 } | 2480 } |
| 2481 | 2481 |
| 2482 | 2482 |
| 2483 bool FlowGraphOptimizer::TryInlineUint32x4Method( | 2483 bool FlowGraphOptimizer::TryInlineInt32x4Method( |
| 2484 InstanceCallInstr* call, | 2484 InstanceCallInstr* call, |
| 2485 MethodRecognizer::Kind recognized_kind) { | 2485 MethodRecognizer::Kind recognized_kind) { |
| 2486 if (!ShouldInlineSimd()) { | 2486 if (!ShouldInlineSimd()) { |
| 2487 return false; | 2487 return false; |
| 2488 } | 2488 } |
| 2489 ASSERT(call->HasICData()); | 2489 ASSERT(call->HasICData()); |
| 2490 switch (recognized_kind) { | 2490 switch (recognized_kind) { |
| 2491 case MethodRecognizer::kUint32x4ShuffleMix: | 2491 case MethodRecognizer::kInt32x4ShuffleMix: |
| 2492 case MethodRecognizer::kUint32x4Shuffle: | 2492 case MethodRecognizer::kInt32x4Shuffle: |
| 2493 case MethodRecognizer::kUint32x4GetFlagX: | 2493 case MethodRecognizer::kInt32x4GetFlagX: |
| 2494 case MethodRecognizer::kUint32x4GetFlagY: | 2494 case MethodRecognizer::kInt32x4GetFlagY: |
| 2495 case MethodRecognizer::kUint32x4GetFlagZ: | 2495 case MethodRecognizer::kInt32x4GetFlagZ: |
| 2496 case MethodRecognizer::kUint32x4GetFlagW: | 2496 case MethodRecognizer::kInt32x4GetFlagW: |
| 2497 case MethodRecognizer::kUint32x4GetSignMask: | 2497 case MethodRecognizer::kInt32x4GetSignMask: |
| 2498 ASSERT(call->ic_data()->HasReceiverClassId(kUint32x4Cid)); | 2498 ASSERT(call->ic_data()->HasReceiverClassId(kInt32x4Cid)); |
| 2499 ASSERT(call->ic_data()->HasOneTarget()); | 2499 ASSERT(call->ic_data()->HasOneTarget()); |
| 2500 return InlineUint32x4Getter(call, recognized_kind); | 2500 return InlineInt32x4Getter(call, recognized_kind); |
| 2501 | 2501 |
| 2502 case MethodRecognizer::kUint32x4Select: { | 2502 case MethodRecognizer::kInt32x4Select: { |
| 2503 Definition* mask = call->ArgumentAt(0); | 2503 Definition* mask = call->ArgumentAt(0); |
| 2504 Definition* trueValue = call->ArgumentAt(1); | 2504 Definition* trueValue = call->ArgumentAt(1); |
| 2505 Definition* falseValue = call->ArgumentAt(2); | 2505 Definition* falseValue = call->ArgumentAt(2); |
| 2506 // Type check left. | 2506 // Type check left. |
| 2507 AddCheckClass(mask, | 2507 AddCheckClass(mask, |
| 2508 ICData::ZoneHandle( | 2508 ICData::ZoneHandle( |
| 2509 call->ic_data()->AsUnaryClassChecksForArgNr(0)), | 2509 call->ic_data()->AsUnaryClassChecksForArgNr(0)), |
| 2510 call->deopt_id(), | 2510 call->deopt_id(), |
| 2511 call->env(), | 2511 call->env(), |
| 2512 call); | 2512 call); |
| 2513 Uint32x4SelectInstr* select = new Uint32x4SelectInstr( | 2513 Int32x4SelectInstr* select = new Int32x4SelectInstr( |
| 2514 new Value(mask), | 2514 new Value(mask), |
| 2515 new Value(trueValue), | 2515 new Value(trueValue), |
| 2516 new Value(falseValue), | 2516 new Value(falseValue), |
| 2517 call->deopt_id()); | 2517 call->deopt_id()); |
| 2518 ReplaceCall(call, select); | 2518 ReplaceCall(call, select); |
| 2519 return true; | 2519 return true; |
| 2520 } | 2520 } |
| 2521 case MethodRecognizer::kUint32x4WithFlagX: | 2521 case MethodRecognizer::kInt32x4WithFlagX: |
| 2522 case MethodRecognizer::kUint32x4WithFlagY: | 2522 case MethodRecognizer::kInt32x4WithFlagY: |
| 2523 case MethodRecognizer::kUint32x4WithFlagZ: | 2523 case MethodRecognizer::kInt32x4WithFlagZ: |
| 2524 case MethodRecognizer::kUint32x4WithFlagW: { | 2524 case MethodRecognizer::kInt32x4WithFlagW: { |
| 2525 Definition* left = call->ArgumentAt(0); | 2525 Definition* left = call->ArgumentAt(0); |
| 2526 Definition* flag = call->ArgumentAt(1); | 2526 Definition* flag = call->ArgumentAt(1); |
| 2527 // Type check left. | 2527 // Type check left. |
| 2528 AddCheckClass(left, | 2528 AddCheckClass(left, |
| 2529 ICData::ZoneHandle( | 2529 ICData::ZoneHandle( |
| 2530 call->ic_data()->AsUnaryClassChecksForArgNr(0)), | 2530 call->ic_data()->AsUnaryClassChecksForArgNr(0)), |
| 2531 call->deopt_id(), | 2531 call->deopt_id(), |
| 2532 call->env(), | 2532 call->env(), |
| 2533 call); | 2533 call); |
| 2534 Uint32x4SetFlagInstr* setFlag = new Uint32x4SetFlagInstr( | 2534 Int32x4SetFlagInstr* setFlag = new Int32x4SetFlagInstr( |
| 2535 recognized_kind, | 2535 recognized_kind, |
| 2536 new Value(left), | 2536 new Value(left), |
| 2537 new Value(flag), | 2537 new Value(flag), |
| 2538 call->deopt_id()); | 2538 call->deopt_id()); |
| 2539 ReplaceCall(call, setFlag); | 2539 ReplaceCall(call, setFlag); |
| 2540 return true; | 2540 return true; |
| 2541 } | 2541 } |
| 2542 default: | 2542 default: |
| 2543 return false; | 2543 return false; |
| 2544 } | 2544 } |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2668 Definition::kValue); | 2668 Definition::kValue); |
| 2669 *array = elements; | 2669 *array = elements; |
| 2670 } | 2670 } |
| 2671 return array_cid; | 2671 return array_cid; |
| 2672 } | 2672 } |
| 2673 | 2673 |
| 2674 | 2674 |
| 2675 bool FlowGraphOptimizer::BuildByteArrayViewLoad(InstanceCallInstr* call, | 2675 bool FlowGraphOptimizer::BuildByteArrayViewLoad(InstanceCallInstr* call, |
| 2676 intptr_t view_cid) { | 2676 intptr_t view_cid) { |
| 2677 bool simd_view = (view_cid == kTypedDataFloat32x4ArrayCid) || | 2677 bool simd_view = (view_cid == kTypedDataFloat32x4ArrayCid) || |
| 2678 (view_cid == kTypedDataUint32x4ArrayCid); | 2678 (view_cid == kTypedDataInt32x4ArrayCid); |
| 2679 if (simd_view && !ShouldInlineSimd()) { | 2679 if (simd_view && !ShouldInlineSimd()) { |
| 2680 return false; | 2680 return false; |
| 2681 } | 2681 } |
| 2682 | 2682 |
| 2683 ASSERT(call->HasICData()); | 2683 ASSERT(call->HasICData()); |
| 2684 Function& target = Function::Handle(); | 2684 Function& target = Function::Handle(); |
| 2685 GrowableArray<intptr_t> class_ids; | 2685 GrowableArray<intptr_t> class_ids; |
| 2686 call->ic_data()->GetCheckAt(0, &class_ids, &target); | 2686 call->ic_data()->GetCheckAt(0, &class_ids, &target); |
| 2687 const intptr_t receiver_cid = class_ids[0]; | 2687 const intptr_t receiver_cid = class_ids[0]; |
| 2688 | 2688 |
| (...skipping 29 matching lines...) Expand all Loading... |
| 2718 current_iterator()->RemoveCurrentFromGraph(); | 2718 current_iterator()->RemoveCurrentFromGraph(); |
| 2719 call->set_previous(NULL); | 2719 call->set_previous(NULL); |
| 2720 call->set_next(NULL); | 2720 call->set_next(NULL); |
| 2721 return true; | 2721 return true; |
| 2722 } | 2722 } |
| 2723 | 2723 |
| 2724 | 2724 |
| 2725 bool FlowGraphOptimizer::BuildByteArrayViewStore(InstanceCallInstr* call, | 2725 bool FlowGraphOptimizer::BuildByteArrayViewStore(InstanceCallInstr* call, |
| 2726 intptr_t view_cid) { | 2726 intptr_t view_cid) { |
| 2727 bool simd_view = (view_cid == kTypedDataFloat32x4ArrayCid) || | 2727 bool simd_view = (view_cid == kTypedDataFloat32x4ArrayCid) || |
| 2728 (view_cid == kTypedDataUint32x4ArrayCid); | 2728 (view_cid == kTypedDataInt32x4ArrayCid); |
| 2729 if (simd_view && !ShouldInlineSimd()) { | 2729 if (simd_view && !ShouldInlineSimd()) { |
| 2730 return false; | 2730 return false; |
| 2731 } | 2731 } |
| 2732 ASSERT(call->HasICData()); | 2732 ASSERT(call->HasICData()); |
| 2733 Function& target = Function::Handle(); | 2733 Function& target = Function::Handle(); |
| 2734 GrowableArray<intptr_t> class_ids; | 2734 GrowableArray<intptr_t> class_ids; |
| 2735 call->ic_data()->GetCheckAt(0, &class_ids, &target); | 2735 call->ic_data()->GetCheckAt(0, &class_ids, &target); |
| 2736 const intptr_t receiver_cid = class_ids[0]; | 2736 const intptr_t receiver_cid = class_ids[0]; |
| 2737 | 2737 |
| 2738 Definition* array = call->ArgumentAt(0); | 2738 Definition* array = call->ArgumentAt(0); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2773 case kTypedDataFloat64ArrayCid: { | 2773 case kTypedDataFloat64ArrayCid: { |
| 2774 // Check that value is always double. | 2774 // Check that value is always double. |
| 2775 value_check = ICData::New(flow_graph_->parsed_function().function(), | 2775 value_check = ICData::New(flow_graph_->parsed_function().function(), |
| 2776 call->function_name(), | 2776 call->function_name(), |
| 2777 Object::empty_array(), // Dummy args. descr. | 2777 Object::empty_array(), // Dummy args. descr. |
| 2778 Isolate::kNoDeoptId, | 2778 Isolate::kNoDeoptId, |
| 2779 1); | 2779 1); |
| 2780 value_check.AddReceiverCheck(kDoubleCid, target); | 2780 value_check.AddReceiverCheck(kDoubleCid, target); |
| 2781 break; | 2781 break; |
| 2782 } | 2782 } |
| 2783 case kTypedDataUint32x4ArrayCid: { | 2783 case kTypedDataInt32x4ArrayCid: { |
| 2784 // Check that value is always Uint32x4. | 2784 // Check that value is always Int32x4. |
| 2785 value_check = ICData::New(flow_graph_->parsed_function().function(), | 2785 value_check = ICData::New(flow_graph_->parsed_function().function(), |
| 2786 call->function_name(), | 2786 call->function_name(), |
| 2787 Object::empty_array(), // Dummy args. descr. | 2787 Object::empty_array(), // Dummy args. descr. |
| 2788 Isolate::kNoDeoptId, | 2788 Isolate::kNoDeoptId, |
| 2789 1); | 2789 1); |
| 2790 value_check.AddReceiverCheck(kUint32x4Cid, target); | 2790 value_check.AddReceiverCheck(kInt32x4Cid, target); |
| 2791 break; | 2791 break; |
| 2792 } | 2792 } |
| 2793 case kTypedDataFloat32x4ArrayCid: { | 2793 case kTypedDataFloat32x4ArrayCid: { |
| 2794 // Check that value is always Float32x4. | 2794 // Check that value is always Float32x4. |
| 2795 value_check = ICData::New(flow_graph_->parsed_function().function(), | 2795 value_check = ICData::New(flow_graph_->parsed_function().function(), |
| 2796 call->function_name(), | 2796 call->function_name(), |
| 2797 Object::empty_array(), // Dummy args. descr. | 2797 Object::empty_array(), // Dummy args. descr. |
| 2798 Isolate::kNoDeoptId, | 2798 Isolate::kNoDeoptId, |
| 2799 1); | 2799 1); |
| 2800 value_check.AddReceiverCheck(kFloat32x4Cid, target); | 2800 value_check.AddReceiverCheck(kFloat32x4Cid, target); |
| (...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3129 (recognized_kind == MethodRecognizer::kMathCos)) { | 3129 (recognized_kind == MethodRecognizer::kMathCos)) { |
| 3130 MathUnaryInstr* math_unary = | 3130 MathUnaryInstr* math_unary = |
| 3131 new MathUnaryInstr(recognized_kind, | 3131 new MathUnaryInstr(recognized_kind, |
| 3132 new Value(call->ArgumentAt(0)), | 3132 new Value(call->ArgumentAt(0)), |
| 3133 call->deopt_id()); | 3133 call->deopt_id()); |
| 3134 ReplaceCall(call, math_unary); | 3134 ReplaceCall(call, math_unary); |
| 3135 } else if ((recognized_kind == MethodRecognizer::kFloat32x4Zero) || | 3135 } else if ((recognized_kind == MethodRecognizer::kFloat32x4Zero) || |
| 3136 (recognized_kind == MethodRecognizer::kFloat32x4Splat) || | 3136 (recognized_kind == MethodRecognizer::kFloat32x4Splat) || |
| 3137 (recognized_kind == MethodRecognizer::kFloat32x4Constructor)) { | 3137 (recognized_kind == MethodRecognizer::kFloat32x4Constructor)) { |
| 3138 TryInlineFloat32x4Constructor(call, recognized_kind); | 3138 TryInlineFloat32x4Constructor(call, recognized_kind); |
| 3139 } else if (recognized_kind == MethodRecognizer::kUint32x4BoolConstructor) { | 3139 } else if (recognized_kind == MethodRecognizer::kInt32x4BoolConstructor) { |
| 3140 TryInlineUint32x4Constructor(call, recognized_kind); | 3140 TryInlineInt32x4Constructor(call, recognized_kind); |
| 3141 } else if (recognized_kind == MethodRecognizer::kObjectConstructor) { | 3141 } else if (recognized_kind == MethodRecognizer::kObjectConstructor) { |
| 3142 // Remove the original push arguments. | 3142 // Remove the original push arguments. |
| 3143 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { | 3143 for (intptr_t i = 0; i < call->ArgumentCount(); ++i) { |
| 3144 PushArgumentInstr* push = call->PushArgumentAt(i); | 3144 PushArgumentInstr* push = call->PushArgumentAt(i); |
| 3145 push->ReplaceUsesWith(push->value()->definition()); | 3145 push->ReplaceUsesWith(push->value()->definition()); |
| 3146 push->RemoveFromGraph(); | 3146 push->RemoveFromGraph(); |
| 3147 } | 3147 } |
| 3148 // Manually replace call with global null constant. ReplaceCall can't | 3148 // Manually replace call with global null constant. ReplaceCall can't |
| 3149 // be used for definitions that are already in the graph. | 3149 // be used for definitions that are already in the graph. |
| 3150 call->ReplaceUsesWith(flow_graph_->constant_null()); | 3150 call->ReplaceUsesWith(flow_graph_->constant_null()); |
| (...skipping 3834 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6985 void ConstantPropagator::VisitFloat32x4Clamp(Float32x4ClampInstr* instr) { | 6985 void ConstantPropagator::VisitFloat32x4Clamp(Float32x4ClampInstr* instr) { |
| 6986 SetValue(instr, non_constant_); | 6986 SetValue(instr, non_constant_); |
| 6987 } | 6987 } |
| 6988 | 6988 |
| 6989 | 6989 |
| 6990 void ConstantPropagator::VisitFloat32x4With(Float32x4WithInstr* instr) { | 6990 void ConstantPropagator::VisitFloat32x4With(Float32x4WithInstr* instr) { |
| 6991 SetValue(instr, non_constant_); | 6991 SetValue(instr, non_constant_); |
| 6992 } | 6992 } |
| 6993 | 6993 |
| 6994 | 6994 |
| 6995 void ConstantPropagator::VisitFloat32x4ToUint32x4( | 6995 void ConstantPropagator::VisitFloat32x4ToInt32x4( |
| 6996 Float32x4ToUint32x4Instr* instr) { | 6996 Float32x4ToInt32x4Instr* instr) { |
| 6997 SetValue(instr, non_constant_); | 6997 SetValue(instr, non_constant_); |
| 6998 } | 6998 } |
| 6999 | 6999 |
| 7000 | 7000 |
| 7001 void ConstantPropagator::VisitUint32x4BoolConstructor( | 7001 void ConstantPropagator::VisitInt32x4BoolConstructor( |
| 7002 Uint32x4BoolConstructorInstr* instr) { | 7002 Int32x4BoolConstructorInstr* instr) { |
| 7003 SetValue(instr, non_constant_); | 7003 SetValue(instr, non_constant_); |
| 7004 } | 7004 } |
| 7005 | 7005 |
| 7006 | 7006 |
| 7007 void ConstantPropagator::VisitUint32x4GetFlag(Uint32x4GetFlagInstr* instr) { | 7007 void ConstantPropagator::VisitInt32x4GetFlag(Int32x4GetFlagInstr* instr) { |
| 7008 SetValue(instr, non_constant_); | 7008 SetValue(instr, non_constant_); |
| 7009 } | 7009 } |
| 7010 | 7010 |
| 7011 | 7011 |
| 7012 void ConstantPropagator::VisitUint32x4SetFlag(Uint32x4SetFlagInstr* instr) { | 7012 void ConstantPropagator::VisitInt32x4SetFlag(Int32x4SetFlagInstr* instr) { |
| 7013 SetValue(instr, non_constant_); | 7013 SetValue(instr, non_constant_); |
| 7014 } | 7014 } |
| 7015 | 7015 |
| 7016 | 7016 |
| 7017 void ConstantPropagator::VisitUint32x4Select(Uint32x4SelectInstr* instr) { | 7017 void ConstantPropagator::VisitInt32x4Select(Int32x4SelectInstr* instr) { |
| 7018 SetValue(instr, non_constant_); | 7018 SetValue(instr, non_constant_); |
| 7019 } | 7019 } |
| 7020 | 7020 |
| 7021 | 7021 |
| 7022 void ConstantPropagator::VisitUint32x4ToFloat32x4( | 7022 void ConstantPropagator::VisitInt32x4ToFloat32x4( |
| 7023 Uint32x4ToFloat32x4Instr* instr) { | 7023 Int32x4ToFloat32x4Instr* instr) { |
| 7024 SetValue(instr, non_constant_); | 7024 SetValue(instr, non_constant_); |
| 7025 } | 7025 } |
| 7026 | 7026 |
| 7027 | 7027 |
| 7028 void ConstantPropagator::VisitBinaryUint32x4Op(BinaryUint32x4OpInstr* instr) { | 7028 void ConstantPropagator::VisitBinaryInt32x4Op(BinaryInt32x4OpInstr* instr) { |
| 7029 SetValue(instr, non_constant_); | 7029 SetValue(instr, non_constant_); |
| 7030 } | 7030 } |
| 7031 | 7031 |
| 7032 | 7032 |
| 7033 void ConstantPropagator::VisitMathUnary(MathUnaryInstr* instr) { | 7033 void ConstantPropagator::VisitMathUnary(MathUnaryInstr* instr) { |
| 7034 const Object& value = instr->value()->definition()->constant_value(); | 7034 const Object& value = instr->value()->definition()->constant_value(); |
| 7035 if (IsNonConstant(value)) { | 7035 if (IsNonConstant(value)) { |
| 7036 SetValue(instr, non_constant_); | 7036 SetValue(instr, non_constant_); |
| 7037 } else if (IsConstant(value)) { | 7037 } else if (IsConstant(value)) { |
| 7038 // TODO(kmillikin): Handle Math's unary operations (sqrt, cos, sin). | 7038 // TODO(kmillikin): Handle Math's unary operations (sqrt, cos, sin). |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7090 const Object& value = instr->value()->definition()->constant_value(); | 7090 const Object& value = instr->value()->definition()->constant_value(); |
| 7091 if (IsNonConstant(value)) { | 7091 if (IsNonConstant(value)) { |
| 7092 SetValue(instr, non_constant_); | 7092 SetValue(instr, non_constant_); |
| 7093 } else if (IsConstant(value)) { | 7093 } else if (IsConstant(value)) { |
| 7094 // TODO(kmillikin): Handle conversion. | 7094 // TODO(kmillikin): Handle conversion. |
| 7095 SetValue(instr, non_constant_); | 7095 SetValue(instr, non_constant_); |
| 7096 } | 7096 } |
| 7097 } | 7097 } |
| 7098 | 7098 |
| 7099 | 7099 |
| 7100 void ConstantPropagator::VisitUnboxUint32x4(UnboxUint32x4Instr* instr) { | 7100 void ConstantPropagator::VisitUnboxInt32x4(UnboxInt32x4Instr* instr) { |
| 7101 const Object& value = instr->value()->definition()->constant_value(); | 7101 const Object& value = instr->value()->definition()->constant_value(); |
| 7102 if (IsNonConstant(value)) { | 7102 if (IsNonConstant(value)) { |
| 7103 SetValue(instr, non_constant_); | 7103 SetValue(instr, non_constant_); |
| 7104 } else if (IsConstant(value)) { | 7104 } else if (IsConstant(value)) { |
| 7105 // TODO(kmillikin): Handle conversion. | 7105 // TODO(kmillikin): Handle conversion. |
| 7106 SetValue(instr, non_constant_); | 7106 SetValue(instr, non_constant_); |
| 7107 } | 7107 } |
| 7108 } | 7108 } |
| 7109 | 7109 |
| 7110 | 7110 |
| 7111 void ConstantPropagator::VisitBoxUint32x4(BoxUint32x4Instr* instr) { | 7111 void ConstantPropagator::VisitBoxInt32x4(BoxInt32x4Instr* instr) { |
| 7112 const Object& value = instr->value()->definition()->constant_value(); | 7112 const Object& value = instr->value()->definition()->constant_value(); |
| 7113 if (IsNonConstant(value)) { | 7113 if (IsNonConstant(value)) { |
| 7114 SetValue(instr, non_constant_); | 7114 SetValue(instr, non_constant_); |
| 7115 } else if (IsConstant(value)) { | 7115 } else if (IsConstant(value)) { |
| 7116 // TODO(kmillikin): Handle conversion. | 7116 // TODO(kmillikin): Handle conversion. |
| 7117 SetValue(instr, non_constant_); | 7117 SetValue(instr, non_constant_); |
| 7118 } | 7118 } |
| 7119 } | 7119 } |
| 7120 | 7120 |
| 7121 | 7121 |
| (...skipping 845 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7967 } | 7967 } |
| 7968 | 7968 |
| 7969 // Insert materializations at environment uses. | 7969 // Insert materializations at environment uses. |
| 7970 for (intptr_t i = 0; i < exits.length(); i++) { | 7970 for (intptr_t i = 0; i < exits.length(); i++) { |
| 7971 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); | 7971 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *fields); |
| 7972 } | 7972 } |
| 7973 } | 7973 } |
| 7974 | 7974 |
| 7975 | 7975 |
| 7976 } // namespace dart | 7976 } // namespace dart |
| OLD | NEW |