| 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/flow_graph_builder.h" | 9 #include "vm/flow_graph_builder.h" |
| 10 #include "vm/flow_graph_compiler.h" | 10 #include "vm/flow_graph_compiler.h" |
| (...skipping 327 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 // TODO(fschneider): Implement direct unboxed mint-to-double conversion. | 338 // TODO(fschneider): Implement direct unboxed mint-to-double conversion. |
| 339 BoxIntegerInstr* boxed = new BoxIntegerInstr(use->CopyWithType()); | 339 BoxIntegerInstr* boxed = new BoxIntegerInstr(use->CopyWithType()); |
| 340 use->BindTo(boxed); | 340 use->BindTo(boxed); |
| 341 InsertBefore(insert_before, boxed, NULL, Definition::kValue); | 341 InsertBefore(insert_before, boxed, NULL, Definition::kValue); |
| 342 | 342 |
| 343 const intptr_t deopt_id = (deopt_target != NULL) ? | 343 const intptr_t deopt_id = (deopt_target != NULL) ? |
| 344 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; | 344 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; |
| 345 converted = new UnboxDoubleInstr(new Value(boxed), deopt_id); | 345 converted = new UnboxDoubleInstr(new Value(boxed), deopt_id); |
| 346 | 346 |
| 347 } else if ((from == kUnboxedDouble) && (to == kTagged)) { | 347 } else if ((from == kUnboxedDouble) && (to == kTagged)) { |
| 348 converted = new BoxDoubleInstr(use->CopyWithType(), NULL); | 348 converted = new BoxDoubleInstr(use->CopyWithType()); |
| 349 | 349 |
| 350 } else if ((from == kTagged) && (to == kUnboxedDouble)) { | 350 } else if ((from == kTagged) && (to == kUnboxedDouble)) { |
| 351 ASSERT((deopt_target != NULL) || | 351 ASSERT((deopt_target != NULL) || |
| 352 (use->Type()->ToCid() == kDoubleCid)); | 352 (use->Type()->ToCid() == kDoubleCid)); |
| 353 const intptr_t deopt_id = (deopt_target != NULL) ? | 353 const intptr_t deopt_id = (deopt_target != NULL) ? |
| 354 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; | 354 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; |
| 355 ConstantInstr* constant = use->definition()->AsConstant(); | 355 ConstantInstr* constant = use->definition()->AsConstant(); |
| 356 if ((constant != NULL) && constant->value().IsSmi()) { | 356 if ((constant != NULL) && constant->value().IsSmi()) { |
| 357 const double dbl_val = Smi::Cast(constant->value()).AsDoubleValue(); | 357 const double dbl_val = Smi::Cast(constant->value()).AsDoubleValue(); |
| 358 const Double& dbl_obj = | 358 const Double& dbl_obj = |
| 359 Double::ZoneHandle(Double::New(dbl_val, Heap::kOld)); | 359 Double::ZoneHandle(Double::New(dbl_val, Heap::kOld)); |
| 360 ConstantInstr* double_const = new ConstantInstr(dbl_obj); | 360 ConstantInstr* double_const = new ConstantInstr(dbl_obj); |
| 361 InsertBefore(insert_before, double_const, NULL, Definition::kValue); | 361 InsertBefore(insert_before, double_const, NULL, Definition::kValue); |
| 362 converted = new UnboxDoubleInstr(new Value(double_const), deopt_id); | 362 converted = new UnboxDoubleInstr(new Value(double_const), deopt_id); |
| 363 } else { | 363 } else { |
| 364 converted = new UnboxDoubleInstr(use->CopyWithType(), deopt_id); | 364 converted = new UnboxDoubleInstr(use->CopyWithType(), deopt_id); |
| 365 } | 365 } |
| 366 } else if ((from == kTagged) && (to == kUnboxedFloat32x4)) { |
| 367 ASSERT((deopt_target != NULL) || |
| 368 (use->Type()->ToCid() == kFloat32x4Cid)); |
| 369 const intptr_t deopt_id = (deopt_target != NULL) ? |
| 370 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; |
| 371 CheckNonSmiInstr* non_smi = new CheckNonSmiInstr(use->CopyWithType(), |
| 372 deopt_id); |
| 373 // Check that value is not a Smi. |
| 374 InsertBefore(insert_before, non_smi, use->instruction()->env(), |
| 375 Definition::kEffect); |
| 376 converted = new UnboxFloat32x4Instr(use->CopyWithType(), deopt_id); |
| 377 } else if ((from == kUnboxedFloat32x4) && (to == kTagged)) { |
| 378 converted = new BoxFloat32x4Instr(use->CopyWithType()); |
| 366 } | 379 } |
| 367 ASSERT(converted != NULL); | 380 ASSERT(converted != NULL); |
| 368 use->BindTo(converted); | 381 use->BindTo(converted); |
| 369 InsertBefore(insert_before, converted, use->instruction()->env(), | 382 InsertBefore(insert_before, converted, use->instruction()->env(), |
| 370 Definition::kValue); | 383 Definition::kValue); |
| 371 } | 384 } |
| 372 | 385 |
| 373 | 386 |
| 374 void FlowGraphOptimizer::InsertConversionsFor(Definition* def) { | 387 void FlowGraphOptimizer::InsertConversionsFor(Definition* def) { |
| 375 const Representation from_rep = def->representation(); | 388 const Representation from_rep = def->representation(); |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 756 case kTypedDataFloat32ArrayCid: | 769 case kTypedDataFloat32ArrayCid: |
| 757 case kTypedDataFloat64ArrayCid: { | 770 case kTypedDataFloat64ArrayCid: { |
| 758 // Check that value is always double. | 771 // Check that value is always double. |
| 759 value_check = call->ic_data()->AsUnaryClassChecksForArgNr(2); | 772 value_check = call->ic_data()->AsUnaryClassChecksForArgNr(2); |
| 760 if ((value_check.NumberOfChecks() != 1) || | 773 if ((value_check.NumberOfChecks() != 1) || |
| 761 (value_check.GetReceiverClassIdAt(0) != kDoubleCid)) { | 774 (value_check.GetReceiverClassIdAt(0) != kDoubleCid)) { |
| 762 return false; | 775 return false; |
| 763 } | 776 } |
| 764 break; | 777 break; |
| 765 } | 778 } |
| 779 case kTypedDataFloat32x4ArrayCid: { |
| 780 // Check that value is always a Float32x4. |
| 781 value_check = call->ic_data()->AsUnaryClassChecksForArgNr(2); |
| 782 if ((value_check.NumberOfChecks() != 1) || |
| 783 (value_check.GetReceiverClassIdAt(0) != kFloat32x4Cid)) { |
| 784 return false; |
| 785 } |
| 786 } |
| 787 break; |
| 766 default: | 788 default: |
| 767 // TODO(fschneider): Add support for other array types. | 789 // TODO(fschneider): Add support for other array types. |
| 768 return false; | 790 return false; |
| 769 } | 791 } |
| 770 | 792 |
| 771 BuildStoreIndexed(call, value_check, class_id); | 793 BuildStoreIndexed(call, value_check, class_id); |
| 772 return true; | 794 return true; |
| 773 } | 795 } |
| 774 | 796 |
| 775 | 797 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 817 // Fall through. | 839 // Fall through. |
| 818 case kTypedDataFloat32ArrayCid: | 840 case kTypedDataFloat32ArrayCid: |
| 819 case kTypedDataFloat64ArrayCid: { | 841 case kTypedDataFloat64ArrayCid: { |
| 820 type_args = instantiator = flow_graph_->constant_null(); | 842 type_args = instantiator = flow_graph_->constant_null(); |
| 821 ASSERT((class_id != kTypedDataFloat32ArrayCid && | 843 ASSERT((class_id != kTypedDataFloat32ArrayCid && |
| 822 class_id != kTypedDataFloat64ArrayCid) || | 844 class_id != kTypedDataFloat64ArrayCid) || |
| 823 value_type.IsDoubleType()); | 845 value_type.IsDoubleType()); |
| 824 ASSERT(value_type.IsInstantiated()); | 846 ASSERT(value_type.IsInstantiated()); |
| 825 break; | 847 break; |
| 826 } | 848 } |
| 849 case kTypedDataFloat32x4ArrayCid: { |
| 850 type_args = instantiator = flow_graph_->constant_null(); |
| 851 ASSERT((class_id != kTypedDataFloat32x4ArrayCid) || |
| 852 value_type.IsFloat32x4Type()); |
| 853 ASSERT(value_type.IsInstantiated()); |
| 854 break; |
| 855 } |
| 827 default: | 856 default: |
| 828 // TODO(fschneider): Add support for other array types. | 857 // TODO(fschneider): Add support for other array types. |
| 829 UNREACHABLE(); | 858 UNREACHABLE(); |
| 830 } | 859 } |
| 831 AssertAssignableInstr* assert_value = | 860 AssertAssignableInstr* assert_value = |
| 832 new AssertAssignableInstr(call->token_pos(), | 861 new AssertAssignableInstr(call->token_pos(), |
| 833 new Value(stored_value), | 862 new Value(stored_value), |
| 834 new Value(instantiator), | 863 new Value(instantiator), |
| 835 new Value(type_args), | 864 new Value(type_args), |
| 836 value_type, | 865 value_type, |
| 837 Symbols::Value()); | 866 Symbols::Value()); |
| 838 // Newly inserted instructions that can deoptimize or throw an exception | 867 // Newly inserted instructions that can deoptimize or throw an exception |
| 839 // must have a deoptimization id that is valid for lookup in the unoptimized | 868 // must have a deoptimization id that is valid for lookup in the unoptimized |
| 840 // code. | 869 // code. |
| 841 assert_value->deopt_id_ = call->deopt_id(); | 870 assert_value->deopt_id_ = call->deopt_id(); |
| 842 InsertBefore(call, assert_value, call->env(), Definition::kValue); | 871 InsertBefore(call, assert_value, call->env(), Definition::kValue); |
| 843 } | 872 } |
| 844 | 873 |
| 845 intptr_t array_cid = PrepareIndexedOp(call, class_id, &array, &index); | 874 intptr_t array_cid = PrepareIndexedOp(call, class_id, &array, &index); |
| 846 // Check if store barrier is needed. Byte arrays don't need a store barrier. | 875 // Check if store barrier is needed. Byte arrays don't need a store barrier. |
| 847 StoreBarrierType needs_store_barrier = | 876 StoreBarrierType needs_store_barrier = |
| 848 (RawObject::IsTypedDataClassId(array_cid) || | 877 (RawObject::IsTypedDataClassId(array_cid) || |
| 849 RawObject::IsTypedDataViewClassId(array_cid) || | 878 RawObject::IsTypedDataViewClassId(array_cid) || |
| 850 RawObject::IsExternalTypedDataClassId(array_cid)) ? kNoStoreBarrier | 879 RawObject::IsExternalTypedDataClassId(array_cid)) ? kNoStoreBarrier |
| 851 : kEmitStoreBarrier; | 880 : kEmitStoreBarrier; |
| 852 if (!value_check.IsNull()) { | 881 if (!value_check.IsNull()) { |
| 853 // No store barrier needed because checked value is a smi, an unboxed mint | 882 // No store barrier needed because checked value is a smi, an unboxed mint, |
| 854 // or unboxed double. | 883 // an unboxed double, an unboxed Float32x4, or unboxed Uint32x4. |
| 855 needs_store_barrier = kNoStoreBarrier; | 884 needs_store_barrier = kNoStoreBarrier; |
| 856 AddCheckClass(stored_value, value_check, call->deopt_id(), call->env(), | 885 AddCheckClass(stored_value, value_check, call->deopt_id(), call->env(), |
| 857 call); | 886 call); |
| 858 } | 887 } |
| 859 | 888 |
| 860 intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(array_cid); | 889 intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(array_cid); |
| 861 Definition* array_op = new StoreIndexedInstr(new Value(array), | 890 Definition* array_op = new StoreIndexedInstr(new Value(array), |
| 862 new Value(index), | 891 new Value(index), |
| 863 new Value(stored_value), | 892 new Value(stored_value), |
| 864 needs_store_barrier, | 893 needs_store_barrier, |
| 865 index_scale, | 894 index_scale, |
| 866 array_cid, | 895 array_cid, |
| 867 call->deopt_id()); | 896 call->deopt_id()); |
| 868 ReplaceCall(call, array_op); | 897 ReplaceCall(call, array_op); |
| 869 } | 898 } |
| 870 | 899 |
| 871 | 900 |
| 872 | 901 |
| 873 bool FlowGraphOptimizer::TryReplaceWithLoadIndexed(InstanceCallInstr* call) { | 902 bool FlowGraphOptimizer::TryReplaceWithLoadIndexed(InstanceCallInstr* call) { |
| 874 const intptr_t class_id = ReceiverClassId(call); | 903 const intptr_t class_id = ReceiverClassId(call); |
| 875 // Set deopt_id to a valid id if the LoadIndexedInstr can cause deopt. | 904 // Set deopt_id to a valid id if the LoadIndexedInstr can cause deopt. |
| 876 intptr_t deopt_id = Isolate::kNoDeoptId; | 905 intptr_t deopt_id = Isolate::kNoDeoptId; |
| 877 switch (class_id) { | 906 switch (class_id) { |
| 878 case kArrayCid: | 907 case kArrayCid: |
| 879 case kImmutableArrayCid: | 908 case kImmutableArrayCid: |
| 880 case kGrowableObjectArrayCid: | 909 case kGrowableObjectArrayCid: |
| 881 case kTypedDataFloat32ArrayCid: | 910 case kTypedDataFloat32ArrayCid: |
| 882 case kTypedDataFloat64ArrayCid: | 911 case kTypedDataFloat64ArrayCid: |
| 912 case kTypedDataFloat32x4ArrayCid: |
| 883 case kTypedDataInt8ArrayCid: | 913 case kTypedDataInt8ArrayCid: |
| 884 case kTypedDataUint8ArrayCid: | 914 case kTypedDataUint8ArrayCid: |
| 885 case kTypedDataUint8ClampedArrayCid: | 915 case kTypedDataUint8ClampedArrayCid: |
| 886 case kExternalTypedDataUint8ArrayCid: | 916 case kExternalTypedDataUint8ArrayCid: |
| 887 case kExternalTypedDataUint8ClampedArrayCid: | 917 case kExternalTypedDataUint8ClampedArrayCid: |
| 888 case kTypedDataInt16ArrayCid: | 918 case kTypedDataInt16ArrayCid: |
| 889 case kTypedDataUint16ArrayCid: | 919 case kTypedDataUint16ArrayCid: |
| 890 break; | 920 break; |
| 891 case kTypedDataInt32ArrayCid: | 921 case kTypedDataInt32ArrayCid: |
| 892 case kTypedDataUint32ArrayCid: { | 922 case kTypedDataUint32ArrayCid: { |
| (...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1463 case kTypedDataUint8ArrayCid: | 1493 case kTypedDataUint8ArrayCid: |
| 1464 case kExternalTypedDataUint8ArrayCid: | 1494 case kExternalTypedDataUint8ArrayCid: |
| 1465 case kTypedDataUint8ClampedArrayCid: | 1495 case kTypedDataUint8ClampedArrayCid: |
| 1466 case kExternalTypedDataUint8ClampedArrayCid: | 1496 case kExternalTypedDataUint8ClampedArrayCid: |
| 1467 case kTypedDataInt16ArrayCid: | 1497 case kTypedDataInt16ArrayCid: |
| 1468 case kTypedDataUint16ArrayCid: | 1498 case kTypedDataUint16ArrayCid: |
| 1469 case kTypedDataInt32ArrayCid: | 1499 case kTypedDataInt32ArrayCid: |
| 1470 case kTypedDataUint32ArrayCid: | 1500 case kTypedDataUint32ArrayCid: |
| 1471 case kTypedDataFloat32ArrayCid: | 1501 case kTypedDataFloat32ArrayCid: |
| 1472 case kTypedDataFloat64ArrayCid: | 1502 case kTypedDataFloat64ArrayCid: |
| 1503 case kTypedDataFloat32x4ArrayCid: |
| 1473 return true; | 1504 return true; |
| 1474 default: | 1505 default: |
| 1475 return false; | 1506 return false; |
| 1476 } | 1507 } |
| 1477 } | 1508 } |
| 1478 | 1509 |
| 1479 | 1510 |
| 1480 // Inline only simple, frequently called core library methods. | 1511 // Inline only simple, frequently called core library methods. |
| 1481 bool FlowGraphOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) { | 1512 bool FlowGraphOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) { |
| 1482 ASSERT(call->HasICData()); | 1513 ASSERT(call->HasICData()); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1596 call, class_ids[0], kTypedDataInt32ArrayCid); | 1627 call, class_ids[0], kTypedDataInt32ArrayCid); |
| 1597 case MethodRecognizer::kByteArrayBaseGetUint32: | 1628 case MethodRecognizer::kByteArrayBaseGetUint32: |
| 1598 return BuildByteArrayViewLoad( | 1629 return BuildByteArrayViewLoad( |
| 1599 call, class_ids[0], kTypedDataUint32ArrayCid); | 1630 call, class_ids[0], kTypedDataUint32ArrayCid); |
| 1600 case MethodRecognizer::kByteArrayBaseGetFloat32: | 1631 case MethodRecognizer::kByteArrayBaseGetFloat32: |
| 1601 return BuildByteArrayViewLoad( | 1632 return BuildByteArrayViewLoad( |
| 1602 call, class_ids[0], kTypedDataFloat32ArrayCid); | 1633 call, class_ids[0], kTypedDataFloat32ArrayCid); |
| 1603 case MethodRecognizer::kByteArrayBaseGetFloat64: | 1634 case MethodRecognizer::kByteArrayBaseGetFloat64: |
| 1604 return BuildByteArrayViewLoad( | 1635 return BuildByteArrayViewLoad( |
| 1605 call, class_ids[0], kTypedDataFloat64ArrayCid); | 1636 call, class_ids[0], kTypedDataFloat64ArrayCid); |
| 1637 case MethodRecognizer::kByteArrayBaseGetFloat32x4: |
| 1638 return BuildByteArrayViewLoad( |
| 1639 call, class_ids[0], kTypedDataFloat32x4ArrayCid); |
| 1606 | 1640 |
| 1607 // ByteArray setters. | 1641 // ByteArray setters. |
| 1608 case MethodRecognizer::kByteArrayBaseSetInt8: | 1642 case MethodRecognizer::kByteArrayBaseSetInt8: |
| 1609 return BuildByteArrayViewStore( | 1643 return BuildByteArrayViewStore( |
| 1610 call, class_ids[0], kTypedDataInt8ArrayCid); | 1644 call, class_ids[0], kTypedDataInt8ArrayCid); |
| 1611 case MethodRecognizer::kByteArrayBaseSetUint8: | 1645 case MethodRecognizer::kByteArrayBaseSetUint8: |
| 1612 return BuildByteArrayViewStore( | 1646 return BuildByteArrayViewStore( |
| 1613 call, class_ids[0], kTypedDataUint8ArrayCid); | 1647 call, class_ids[0], kTypedDataUint8ArrayCid); |
| 1614 case MethodRecognizer::kByteArrayBaseSetInt16: | 1648 case MethodRecognizer::kByteArrayBaseSetInt16: |
| 1615 return BuildByteArrayViewStore( | 1649 return BuildByteArrayViewStore( |
| 1616 call, class_ids[0], kTypedDataInt16ArrayCid); | 1650 call, class_ids[0], kTypedDataInt16ArrayCid); |
| 1617 case MethodRecognizer::kByteArrayBaseSetUint16: | 1651 case MethodRecognizer::kByteArrayBaseSetUint16: |
| 1618 return BuildByteArrayViewStore( | 1652 return BuildByteArrayViewStore( |
| 1619 call, class_ids[0], kTypedDataUint16ArrayCid); | 1653 call, class_ids[0], kTypedDataUint16ArrayCid); |
| 1620 case MethodRecognizer::kByteArrayBaseSetInt32: | 1654 case MethodRecognizer::kByteArrayBaseSetInt32: |
| 1621 return BuildByteArrayViewStore( | 1655 return BuildByteArrayViewStore( |
| 1622 call, class_ids[0], kTypedDataInt32ArrayCid); | 1656 call, class_ids[0], kTypedDataInt32ArrayCid); |
| 1623 case MethodRecognizer::kByteArrayBaseSetUint32: | 1657 case MethodRecognizer::kByteArrayBaseSetUint32: |
| 1624 return BuildByteArrayViewStore( | 1658 return BuildByteArrayViewStore( |
| 1625 call, class_ids[0], kTypedDataUint32ArrayCid); | 1659 call, class_ids[0], kTypedDataUint32ArrayCid); |
| 1626 case MethodRecognizer::kByteArrayBaseSetFloat32: | 1660 case MethodRecognizer::kByteArrayBaseSetFloat32: |
| 1627 return BuildByteArrayViewStore( | 1661 return BuildByteArrayViewStore( |
| 1628 call, class_ids[0], kTypedDataFloat32ArrayCid); | 1662 call, class_ids[0], kTypedDataFloat32ArrayCid); |
| 1629 case MethodRecognizer::kByteArrayBaseSetFloat64: | 1663 case MethodRecognizer::kByteArrayBaseSetFloat64: |
| 1630 return BuildByteArrayViewStore( | 1664 return BuildByteArrayViewStore( |
| 1631 call, class_ids[0], kTypedDataFloat64ArrayCid); | 1665 call, class_ids[0], kTypedDataFloat64ArrayCid); |
| 1666 case MethodRecognizer::kByteArrayBaseSetFloat32x4: |
| 1667 return BuildByteArrayViewStore( |
| 1668 call, class_ids[0], kTypedDataFloat32x4ArrayCid); |
| 1632 default: | 1669 default: |
| 1633 // Unsupported method. | 1670 // Unsupported method. |
| 1634 return false; | 1671 return false; |
| 1635 } | 1672 } |
| 1636 } | 1673 } |
| 1637 return false; | 1674 return false; |
| 1638 } | 1675 } |
| 1639 | 1676 |
| 1640 | 1677 |
| 1641 bool FlowGraphOptimizer::BuildByteArrayViewLoad( | 1678 bool FlowGraphOptimizer::BuildByteArrayViewLoad( |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1704 case kTypedDataFloat32ArrayCid: | 1741 case kTypedDataFloat32ArrayCid: |
| 1705 case kTypedDataFloat64ArrayCid: { | 1742 case kTypedDataFloat64ArrayCid: { |
| 1706 // Check that value is always double. | 1743 // Check that value is always double. |
| 1707 value_check = ICData::New(Function::Handle(), | 1744 value_check = ICData::New(Function::Handle(), |
| 1708 String::Handle(), | 1745 String::Handle(), |
| 1709 Isolate::kNoDeoptId, | 1746 Isolate::kNoDeoptId, |
| 1710 1); | 1747 1); |
| 1711 value_check.AddReceiverCheck(kDoubleCid, Function::Handle()); | 1748 value_check.AddReceiverCheck(kDoubleCid, Function::Handle()); |
| 1712 break; | 1749 break; |
| 1713 } | 1750 } |
| 1751 case kTypedDataFloat32x4ArrayCid: { |
| 1752 // Check that value is always Float32x4. |
| 1753 value_check = ICData::New(Function::Handle(), |
| 1754 String::Handle(), |
| 1755 Isolate::kNoDeoptId, |
| 1756 1); |
| 1757 value_check.AddReceiverCheck(kFloat32x4Cid, Function::Handle()); |
| 1758 break; |
| 1759 } |
| 1714 default: | 1760 default: |
| 1715 // Array cids are already checked in the caller. | 1761 // Array cids are already checked in the caller. |
| 1716 UNREACHABLE(); | 1762 UNREACHABLE(); |
| 1717 return NULL; | 1763 return NULL; |
| 1718 } | 1764 } |
| 1719 | 1765 |
| 1720 Definition* index = call->ArgumentAt(1); | 1766 Definition* index = call->ArgumentAt(1); |
| 1721 Definition* stored_value = call->ArgumentAt(2); | 1767 Definition* stored_value = call->ArgumentAt(2); |
| 1722 if (!value_check.IsNull()) { | 1768 if (!value_check.IsNull()) { |
| 1723 AddCheckClass(stored_value, value_check, call->deopt_id(), call->env(), | 1769 AddCheckClass(stored_value, value_check, call->deopt_id(), call->env(), |
| (...skipping 2094 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3818 void ConstantPropagator::VisitCheckStackOverflow( | 3864 void ConstantPropagator::VisitCheckStackOverflow( |
| 3819 CheckStackOverflowInstr* instr) { } | 3865 CheckStackOverflowInstr* instr) { } |
| 3820 | 3866 |
| 3821 | 3867 |
| 3822 void ConstantPropagator::VisitCheckClass(CheckClassInstr* instr) { } | 3868 void ConstantPropagator::VisitCheckClass(CheckClassInstr* instr) { } |
| 3823 | 3869 |
| 3824 void ConstantPropagator::VisitGuardField(GuardFieldInstr* instr) { } | 3870 void ConstantPropagator::VisitGuardField(GuardFieldInstr* instr) { } |
| 3825 | 3871 |
| 3826 void ConstantPropagator::VisitCheckSmi(CheckSmiInstr* instr) { } | 3872 void ConstantPropagator::VisitCheckSmi(CheckSmiInstr* instr) { } |
| 3827 | 3873 |
| 3874 void ConstantPropagator::VisitCheckNonSmi(CheckNonSmiInstr* instr) { } |
| 3875 |
| 3828 | 3876 |
| 3829 void ConstantPropagator::VisitCheckEitherNonSmi( | 3877 void ConstantPropagator::VisitCheckEitherNonSmi( |
| 3830 CheckEitherNonSmiInstr* instr) { } | 3878 CheckEitherNonSmiInstr* instr) { } |
| 3831 | 3879 |
| 3832 | 3880 |
| 3833 void ConstantPropagator::VisitCheckArrayBound(CheckArrayBoundInstr* instr) { } | 3881 void ConstantPropagator::VisitCheckArrayBound(CheckArrayBoundInstr* instr) { } |
| 3834 | 3882 |
| 3835 | 3883 |
| 3836 // -------------------------------------------------------------------------- | 3884 // -------------------------------------------------------------------------- |
| 3837 // Analysis of definitions. Compute the constant value. If it has changed | 3885 // Analysis of definitions. Compute the constant value. If it has changed |
| (...skipping 509 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4347 const Object& value = instr->value()->definition()->constant_value(); | 4395 const Object& value = instr->value()->definition()->constant_value(); |
| 4348 if (IsNonConstant(value)) { | 4396 if (IsNonConstant(value)) { |
| 4349 SetValue(instr, non_constant_); | 4397 SetValue(instr, non_constant_); |
| 4350 } else if (IsConstant(value)) { | 4398 } else if (IsConstant(value)) { |
| 4351 // TODO(kmillikin): Handle conversion. | 4399 // TODO(kmillikin): Handle conversion. |
| 4352 SetValue(instr, non_constant_); | 4400 SetValue(instr, non_constant_); |
| 4353 } | 4401 } |
| 4354 } | 4402 } |
| 4355 | 4403 |
| 4356 | 4404 |
| 4405 void ConstantPropagator::VisitUnboxFloat32x4(UnboxFloat32x4Instr* instr) { |
| 4406 const Object& value = instr->value()->definition()->constant_value(); |
| 4407 if (IsNonConstant(value)) { |
| 4408 SetValue(instr, non_constant_); |
| 4409 } else if (IsConstant(value)) { |
| 4410 // TODO(kmillikin): Handle conversion. |
| 4411 SetValue(instr, non_constant_); |
| 4412 } |
| 4413 } |
| 4414 |
| 4415 |
| 4416 void ConstantPropagator::VisitBoxFloat32x4(BoxFloat32x4Instr* instr) { |
| 4417 const Object& value = instr->value()->definition()->constant_value(); |
| 4418 if (IsNonConstant(value)) { |
| 4419 SetValue(instr, non_constant_); |
| 4420 } else if (IsConstant(value)) { |
| 4421 // TODO(kmillikin): Handle conversion. |
| 4422 SetValue(instr, non_constant_); |
| 4423 } |
| 4424 } |
| 4425 |
| 4426 |
| 4357 void ConstantPropagator::Analyze() { | 4427 void ConstantPropagator::Analyze() { |
| 4358 GraphEntryInstr* entry = graph_->graph_entry(); | 4428 GraphEntryInstr* entry = graph_->graph_entry(); |
| 4359 reachable_->Add(entry->preorder_number()); | 4429 reachable_->Add(entry->preorder_number()); |
| 4360 block_worklist_.Add(entry); | 4430 block_worklist_.Add(entry); |
| 4361 | 4431 |
| 4362 while (true) { | 4432 while (true) { |
| 4363 if (block_worklist_.is_empty()) { | 4433 if (block_worklist_.is_empty()) { |
| 4364 if (definition_worklist_.is_empty()) break; | 4434 if (definition_worklist_.is_empty()) break; |
| 4365 Definition* definition = definition_worklist_.RemoveLast(); | 4435 Definition* definition = definition_worklist_.RemoveLast(); |
| 4366 definition_marks_->Remove(definition->ssa_temp_index()); | 4436 definition_marks_->Remove(definition->ssa_temp_index()); |
| (...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4743 if (changed) { | 4813 if (changed) { |
| 4744 // We may have changed the block order and the dominator tree. | 4814 // We may have changed the block order and the dominator tree. |
| 4745 flow_graph->DiscoverBlocks(); | 4815 flow_graph->DiscoverBlocks(); |
| 4746 GrowableArray<BitVector*> dominance_frontier; | 4816 GrowableArray<BitVector*> dominance_frontier; |
| 4747 flow_graph->ComputeDominators(&dominance_frontier); | 4817 flow_graph->ComputeDominators(&dominance_frontier); |
| 4748 } | 4818 } |
| 4749 } | 4819 } |
| 4750 | 4820 |
| 4751 | 4821 |
| 4752 } // namespace dart | 4822 } // namespace dart |
| OLD | NEW |