| 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 converted = new UnboxFloat32x4Instr(use->CopyWithType(), deopt_id); |
| 372 } else if ((from == kUnboxedFloat32x4) && (to == kTagged)) { |
| 373 converted = new BoxFloat32x4Instr(use->CopyWithType()); |
| 366 } | 374 } |
| 367 ASSERT(converted != NULL); | 375 ASSERT(converted != NULL); |
| 368 use->BindTo(converted); | 376 use->BindTo(converted); |
| 369 InsertBefore(insert_before, converted, use->instruction()->env(), | 377 InsertBefore(insert_before, converted, use->instruction()->env(), |
| 370 Definition::kValue); | 378 Definition::kValue); |
| 371 } | 379 } |
| 372 | 380 |
| 373 | 381 |
| 374 void FlowGraphOptimizer::InsertConversionsFor(Definition* def) { | 382 void FlowGraphOptimizer::InsertConversionsFor(Definition* def) { |
| 375 const Representation from_rep = def->representation(); | 383 const Representation from_rep = def->representation(); |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 756 case kTypedDataFloat32ArrayCid: | 764 case kTypedDataFloat32ArrayCid: |
| 757 case kTypedDataFloat64ArrayCid: { | 765 case kTypedDataFloat64ArrayCid: { |
| 758 // Check that value is always double. | 766 // Check that value is always double. |
| 759 value_check = call->ic_data()->AsUnaryClassChecksForArgNr(2); | 767 value_check = call->ic_data()->AsUnaryClassChecksForArgNr(2); |
| 760 if ((value_check.NumberOfChecks() != 1) || | 768 if ((value_check.NumberOfChecks() != 1) || |
| 761 (value_check.GetReceiverClassIdAt(0) != kDoubleCid)) { | 769 (value_check.GetReceiverClassIdAt(0) != kDoubleCid)) { |
| 762 return false; | 770 return false; |
| 763 } | 771 } |
| 764 break; | 772 break; |
| 765 } | 773 } |
| 774 case kTypedDataFloat32x4ArrayCid: { |
| 775 // Check that value is always a Float32x4. |
| 776 value_check = call->ic_data()->AsUnaryClassChecksForArgNr(2); |
| 777 if ((value_check.NumberOfChecks() != 1) || |
| 778 (value_check.GetReceiverClassIdAt(0) != kFloat32x4Cid)) { |
| 779 return false; |
| 780 } |
| 781 } |
| 782 break; |
| 766 default: | 783 default: |
| 767 // TODO(fschneider): Add support for other array types. | 784 // TODO(fschneider): Add support for other array types. |
| 768 return false; | 785 return false; |
| 769 } | 786 } |
| 770 | 787 |
| 771 BuildStoreIndexed(call, value_check, class_id); | 788 BuildStoreIndexed(call, value_check, class_id); |
| 772 return true; | 789 return true; |
| 773 } | 790 } |
| 774 | 791 |
| 775 | 792 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 817 // Fall through. | 834 // Fall through. |
| 818 case kTypedDataFloat32ArrayCid: | 835 case kTypedDataFloat32ArrayCid: |
| 819 case kTypedDataFloat64ArrayCid: { | 836 case kTypedDataFloat64ArrayCid: { |
| 820 type_args = instantiator = flow_graph_->constant_null(); | 837 type_args = instantiator = flow_graph_->constant_null(); |
| 821 ASSERT((class_id != kTypedDataFloat32ArrayCid && | 838 ASSERT((class_id != kTypedDataFloat32ArrayCid && |
| 822 class_id != kTypedDataFloat64ArrayCid) || | 839 class_id != kTypedDataFloat64ArrayCid) || |
| 823 value_type.IsDoubleType()); | 840 value_type.IsDoubleType()); |
| 824 ASSERT(value_type.IsInstantiated()); | 841 ASSERT(value_type.IsInstantiated()); |
| 825 break; | 842 break; |
| 826 } | 843 } |
| 844 case kTypedDataFloat32x4ArrayCid: { |
| 845 type_args = instantiator = flow_graph_->constant_null(); |
| 846 ASSERT((class_id != kTypedDataFloat32x4ArrayCid) || |
| 847 value_type.IsFloat32x4Type()); |
| 848 ASSERT(value_type.IsInstantiated()); |
| 849 break; |
| 850 } |
| 827 default: | 851 default: |
| 828 // TODO(fschneider): Add support for other array types. | 852 // TODO(fschneider): Add support for other array types. |
| 829 UNREACHABLE(); | 853 UNREACHABLE(); |
| 830 } | 854 } |
| 831 AssertAssignableInstr* assert_value = | 855 AssertAssignableInstr* assert_value = |
| 832 new AssertAssignableInstr(call->token_pos(), | 856 new AssertAssignableInstr(call->token_pos(), |
| 833 new Value(stored_value), | 857 new Value(stored_value), |
| 834 new Value(instantiator), | 858 new Value(instantiator), |
| 835 new Value(type_args), | 859 new Value(type_args), |
| 836 value_type, | 860 value_type, |
| 837 Symbols::Value()); | 861 Symbols::Value()); |
| 838 // Newly inserted instructions that can deoptimize or throw an exception | 862 // Newly inserted instructions that can deoptimize or throw an exception |
| 839 // must have a deoptimization id that is valid for lookup in the unoptimized | 863 // must have a deoptimization id that is valid for lookup in the unoptimized |
| 840 // code. | 864 // code. |
| 841 assert_value->deopt_id_ = call->deopt_id(); | 865 assert_value->deopt_id_ = call->deopt_id(); |
| 842 InsertBefore(call, assert_value, call->env(), Definition::kValue); | 866 InsertBefore(call, assert_value, call->env(), Definition::kValue); |
| 843 } | 867 } |
| 844 | 868 |
| 845 intptr_t array_cid = PrepareIndexedOp(call, class_id, &array, &index); | 869 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. | 870 // Check if store barrier is needed. Byte arrays don't need a store barrier. |
| 847 StoreBarrierType needs_store_barrier = | 871 StoreBarrierType needs_store_barrier = |
| 848 (RawObject::IsTypedDataClassId(array_cid) || | 872 (RawObject::IsTypedDataClassId(array_cid) || |
| 849 RawObject::IsTypedDataViewClassId(array_cid) || | 873 RawObject::IsTypedDataViewClassId(array_cid) || |
| 850 RawObject::IsExternalTypedDataClassId(array_cid)) ? kNoStoreBarrier | 874 RawObject::IsExternalTypedDataClassId(array_cid)) ? kNoStoreBarrier |
| 851 : kEmitStoreBarrier; | 875 : kEmitStoreBarrier; |
| 852 if (!value_check.IsNull()) { | 876 if (!value_check.IsNull()) { |
| 853 // No store barrier needed because checked value is a smi, an unboxed mint | 877 // No store barrier needed because checked value is a smi, an unboxed mint, |
| 854 // or unboxed double. | 878 // an unboxed double, an unboxed Float32x4, or unboxed Uint32x4. |
| 855 needs_store_barrier = kNoStoreBarrier; | 879 needs_store_barrier = kNoStoreBarrier; |
| 856 AddCheckClass(stored_value, value_check, call->deopt_id(), call->env(), | 880 AddCheckClass(stored_value, value_check, call->deopt_id(), call->env(), |
| 857 call); | 881 call); |
| 858 } | 882 } |
| 859 | 883 |
| 860 intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(array_cid); | 884 intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(array_cid); |
| 861 Definition* array_op = new StoreIndexedInstr(new Value(array), | 885 Definition* array_op = new StoreIndexedInstr(new Value(array), |
| 862 new Value(index), | 886 new Value(index), |
| 863 new Value(stored_value), | 887 new Value(stored_value), |
| 864 needs_store_barrier, | 888 needs_store_barrier, |
| 865 index_scale, | 889 index_scale, |
| 866 array_cid, | 890 array_cid, |
| 867 call->deopt_id()); | 891 call->deopt_id()); |
| 868 ReplaceCall(call, array_op); | 892 ReplaceCall(call, array_op); |
| 869 } | 893 } |
| 870 | 894 |
| 871 | 895 |
| 872 | 896 |
| 873 bool FlowGraphOptimizer::TryReplaceWithLoadIndexed(InstanceCallInstr* call) { | 897 bool FlowGraphOptimizer::TryReplaceWithLoadIndexed(InstanceCallInstr* call) { |
| 874 const intptr_t class_id = ReceiverClassId(call); | 898 const intptr_t class_id = ReceiverClassId(call); |
| 875 // Set deopt_id to a valid id if the LoadIndexedInstr can cause deopt. | 899 // Set deopt_id to a valid id if the LoadIndexedInstr can cause deopt. |
| 876 intptr_t deopt_id = Isolate::kNoDeoptId; | 900 intptr_t deopt_id = Isolate::kNoDeoptId; |
| 877 switch (class_id) { | 901 switch (class_id) { |
| 878 case kArrayCid: | 902 case kArrayCid: |
| 879 case kImmutableArrayCid: | 903 case kImmutableArrayCid: |
| 880 case kGrowableObjectArrayCid: | 904 case kGrowableObjectArrayCid: |
| 881 case kTypedDataFloat32ArrayCid: | 905 case kTypedDataFloat32ArrayCid: |
| 882 case kTypedDataFloat64ArrayCid: | 906 case kTypedDataFloat64ArrayCid: |
| 907 case kTypedDataFloat32x4ArrayCid: |
| 883 case kTypedDataInt8ArrayCid: | 908 case kTypedDataInt8ArrayCid: |
| 884 case kTypedDataUint8ArrayCid: | 909 case kTypedDataUint8ArrayCid: |
| 885 case kTypedDataUint8ClampedArrayCid: | 910 case kTypedDataUint8ClampedArrayCid: |
| 886 case kExternalTypedDataUint8ArrayCid: | 911 case kExternalTypedDataUint8ArrayCid: |
| 887 case kExternalTypedDataUint8ClampedArrayCid: | 912 case kExternalTypedDataUint8ClampedArrayCid: |
| 888 case kTypedDataInt16ArrayCid: | 913 case kTypedDataInt16ArrayCid: |
| 889 case kTypedDataUint16ArrayCid: | 914 case kTypedDataUint16ArrayCid: |
| 890 break; | 915 break; |
| 891 case kTypedDataInt32ArrayCid: | 916 case kTypedDataInt32ArrayCid: |
| 892 case kTypedDataUint32ArrayCid: { | 917 case kTypedDataUint32ArrayCid: { |
| (...skipping 570 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1463 case kTypedDataUint8ArrayCid: | 1488 case kTypedDataUint8ArrayCid: |
| 1464 case kExternalTypedDataUint8ArrayCid: | 1489 case kExternalTypedDataUint8ArrayCid: |
| 1465 case kTypedDataUint8ClampedArrayCid: | 1490 case kTypedDataUint8ClampedArrayCid: |
| 1466 case kExternalTypedDataUint8ClampedArrayCid: | 1491 case kExternalTypedDataUint8ClampedArrayCid: |
| 1467 case kTypedDataInt16ArrayCid: | 1492 case kTypedDataInt16ArrayCid: |
| 1468 case kTypedDataUint16ArrayCid: | 1493 case kTypedDataUint16ArrayCid: |
| 1469 case kTypedDataInt32ArrayCid: | 1494 case kTypedDataInt32ArrayCid: |
| 1470 case kTypedDataUint32ArrayCid: | 1495 case kTypedDataUint32ArrayCid: |
| 1471 case kTypedDataFloat32ArrayCid: | 1496 case kTypedDataFloat32ArrayCid: |
| 1472 case kTypedDataFloat64ArrayCid: | 1497 case kTypedDataFloat64ArrayCid: |
| 1498 case kTypedDataFloat32x4ArrayCid: |
| 1473 return true; | 1499 return true; |
| 1474 default: | 1500 default: |
| 1475 return false; | 1501 return false; |
| 1476 } | 1502 } |
| 1477 } | 1503 } |
| 1478 | 1504 |
| 1479 | 1505 |
| 1480 // Inline only simple, frequently called core library methods. | 1506 // Inline only simple, frequently called core library methods. |
| 1481 bool FlowGraphOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) { | 1507 bool FlowGraphOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) { |
| 1482 ASSERT(call->HasICData()); | 1508 ASSERT(call->HasICData()); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1596 call, class_ids[0], kTypedDataInt32ArrayCid); | 1622 call, class_ids[0], kTypedDataInt32ArrayCid); |
| 1597 case MethodRecognizer::kByteArrayBaseGetUint32: | 1623 case MethodRecognizer::kByteArrayBaseGetUint32: |
| 1598 return BuildByteArrayViewLoad( | 1624 return BuildByteArrayViewLoad( |
| 1599 call, class_ids[0], kTypedDataUint32ArrayCid); | 1625 call, class_ids[0], kTypedDataUint32ArrayCid); |
| 1600 case MethodRecognizer::kByteArrayBaseGetFloat32: | 1626 case MethodRecognizer::kByteArrayBaseGetFloat32: |
| 1601 return BuildByteArrayViewLoad( | 1627 return BuildByteArrayViewLoad( |
| 1602 call, class_ids[0], kTypedDataFloat32ArrayCid); | 1628 call, class_ids[0], kTypedDataFloat32ArrayCid); |
| 1603 case MethodRecognizer::kByteArrayBaseGetFloat64: | 1629 case MethodRecognizer::kByteArrayBaseGetFloat64: |
| 1604 return BuildByteArrayViewLoad( | 1630 return BuildByteArrayViewLoad( |
| 1605 call, class_ids[0], kTypedDataFloat64ArrayCid); | 1631 call, class_ids[0], kTypedDataFloat64ArrayCid); |
| 1632 case MethodRecognizer::kByteArrayBaseGetFloat32x4: |
| 1633 return BuildByteArrayViewLoad( |
| 1634 call, class_ids[0], kTypedDataFloat32x4ArrayCid); |
| 1606 | 1635 |
| 1607 // ByteArray setters. | 1636 // ByteArray setters. |
| 1608 case MethodRecognizer::kByteArrayBaseSetInt8: | 1637 case MethodRecognizer::kByteArrayBaseSetInt8: |
| 1609 return BuildByteArrayViewStore( | 1638 return BuildByteArrayViewStore( |
| 1610 call, class_ids[0], kTypedDataInt8ArrayCid); | 1639 call, class_ids[0], kTypedDataInt8ArrayCid); |
| 1611 case MethodRecognizer::kByteArrayBaseSetUint8: | 1640 case MethodRecognizer::kByteArrayBaseSetUint8: |
| 1612 return BuildByteArrayViewStore( | 1641 return BuildByteArrayViewStore( |
| 1613 call, class_ids[0], kTypedDataUint8ArrayCid); | 1642 call, class_ids[0], kTypedDataUint8ArrayCid); |
| 1614 case MethodRecognizer::kByteArrayBaseSetInt16: | 1643 case MethodRecognizer::kByteArrayBaseSetInt16: |
| 1615 return BuildByteArrayViewStore( | 1644 return BuildByteArrayViewStore( |
| 1616 call, class_ids[0], kTypedDataInt16ArrayCid); | 1645 call, class_ids[0], kTypedDataInt16ArrayCid); |
| 1617 case MethodRecognizer::kByteArrayBaseSetUint16: | 1646 case MethodRecognizer::kByteArrayBaseSetUint16: |
| 1618 return BuildByteArrayViewStore( | 1647 return BuildByteArrayViewStore( |
| 1619 call, class_ids[0], kTypedDataUint16ArrayCid); | 1648 call, class_ids[0], kTypedDataUint16ArrayCid); |
| 1620 case MethodRecognizer::kByteArrayBaseSetInt32: | 1649 case MethodRecognizer::kByteArrayBaseSetInt32: |
| 1621 return BuildByteArrayViewStore( | 1650 return BuildByteArrayViewStore( |
| 1622 call, class_ids[0], kTypedDataInt32ArrayCid); | 1651 call, class_ids[0], kTypedDataInt32ArrayCid); |
| 1623 case MethodRecognizer::kByteArrayBaseSetUint32: | 1652 case MethodRecognizer::kByteArrayBaseSetUint32: |
| 1624 return BuildByteArrayViewStore( | 1653 return BuildByteArrayViewStore( |
| 1625 call, class_ids[0], kTypedDataUint32ArrayCid); | 1654 call, class_ids[0], kTypedDataUint32ArrayCid); |
| 1626 case MethodRecognizer::kByteArrayBaseSetFloat32: | 1655 case MethodRecognizer::kByteArrayBaseSetFloat32: |
| 1627 return BuildByteArrayViewStore( | 1656 return BuildByteArrayViewStore( |
| 1628 call, class_ids[0], kTypedDataFloat32ArrayCid); | 1657 call, class_ids[0], kTypedDataFloat32ArrayCid); |
| 1629 case MethodRecognizer::kByteArrayBaseSetFloat64: | 1658 case MethodRecognizer::kByteArrayBaseSetFloat64: |
| 1630 return BuildByteArrayViewStore( | 1659 return BuildByteArrayViewStore( |
| 1631 call, class_ids[0], kTypedDataFloat64ArrayCid); | 1660 call, class_ids[0], kTypedDataFloat64ArrayCid); |
| 1661 case MethodRecognizer::kByteArrayBaseSetFloat32x4: |
| 1662 return BuildByteArrayViewStore( |
| 1663 call, class_ids[0], kTypedDataFloat32x4ArrayCid); |
| 1632 default: | 1664 default: |
| 1633 // Unsupported method. | 1665 // Unsupported method. |
| 1634 return false; | 1666 return false; |
| 1635 } | 1667 } |
| 1636 } | 1668 } |
| 1637 return false; | 1669 return false; |
| 1638 } | 1670 } |
| 1639 | 1671 |
| 1640 | 1672 |
| 1641 bool FlowGraphOptimizer::BuildByteArrayViewLoad( | 1673 bool FlowGraphOptimizer::BuildByteArrayViewLoad( |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1704 case kTypedDataFloat32ArrayCid: | 1736 case kTypedDataFloat32ArrayCid: |
| 1705 case kTypedDataFloat64ArrayCid: { | 1737 case kTypedDataFloat64ArrayCid: { |
| 1706 // Check that value is always double. | 1738 // Check that value is always double. |
| 1707 value_check = ICData::New(Function::Handle(), | 1739 value_check = ICData::New(Function::Handle(), |
| 1708 String::Handle(), | 1740 String::Handle(), |
| 1709 Isolate::kNoDeoptId, | 1741 Isolate::kNoDeoptId, |
| 1710 1); | 1742 1); |
| 1711 value_check.AddReceiverCheck(kDoubleCid, Function::Handle()); | 1743 value_check.AddReceiverCheck(kDoubleCid, Function::Handle()); |
| 1712 break; | 1744 break; |
| 1713 } | 1745 } |
| 1746 case kTypedDataFloat32x4ArrayCid: { |
| 1747 // Check that value is always Float32x4. |
| 1748 value_check = ICData::New(Function::Handle(), |
| 1749 String::Handle(), |
| 1750 Isolate::kNoDeoptId, |
| 1751 1); |
| 1752 value_check.AddReceiverCheck(kFloat32x4Cid, Function::Handle()); |
| 1753 break; |
| 1754 } |
| 1714 default: | 1755 default: |
| 1715 // Array cids are already checked in the caller. | 1756 // Array cids are already checked in the caller. |
| 1716 UNREACHABLE(); | 1757 UNREACHABLE(); |
| 1717 return NULL; | 1758 return NULL; |
| 1718 } | 1759 } |
| 1719 | 1760 |
| 1720 Definition* index = call->ArgumentAt(1); | 1761 Definition* index = call->ArgumentAt(1); |
| 1721 Definition* stored_value = call->ArgumentAt(2); | 1762 Definition* stored_value = call->ArgumentAt(2); |
| 1722 if (!value_check.IsNull()) { | 1763 if (!value_check.IsNull()) { |
| 1723 AddCheckClass(stored_value, value_check, call->deopt_id(), call->env(), | 1764 AddCheckClass(stored_value, value_check, call->deopt_id(), call->env(), |
| (...skipping 2656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4380 const Object& value = instr->value()->definition()->constant_value(); | 4421 const Object& value = instr->value()->definition()->constant_value(); |
| 4381 if (IsNonConstant(value)) { | 4422 if (IsNonConstant(value)) { |
| 4382 SetValue(instr, non_constant_); | 4423 SetValue(instr, non_constant_); |
| 4383 } else if (IsConstant(value)) { | 4424 } else if (IsConstant(value)) { |
| 4384 // TODO(kmillikin): Handle conversion. | 4425 // TODO(kmillikin): Handle conversion. |
| 4385 SetValue(instr, non_constant_); | 4426 SetValue(instr, non_constant_); |
| 4386 } | 4427 } |
| 4387 } | 4428 } |
| 4388 | 4429 |
| 4389 | 4430 |
| 4431 void ConstantPropagator::VisitUnboxFloat32x4(UnboxFloat32x4Instr* instr) { |
| 4432 const Object& value = instr->value()->definition()->constant_value(); |
| 4433 if (IsNonConstant(value)) { |
| 4434 SetValue(instr, non_constant_); |
| 4435 } else if (IsConstant(value)) { |
| 4436 // TODO(kmillikin): Handle conversion. |
| 4437 SetValue(instr, non_constant_); |
| 4438 } |
| 4439 } |
| 4440 |
| 4441 |
| 4442 void ConstantPropagator::VisitBoxFloat32x4(BoxFloat32x4Instr* instr) { |
| 4443 const Object& value = instr->value()->definition()->constant_value(); |
| 4444 if (IsNonConstant(value)) { |
| 4445 SetValue(instr, non_constant_); |
| 4446 } else if (IsConstant(value)) { |
| 4447 // TODO(kmillikin): Handle conversion. |
| 4448 SetValue(instr, non_constant_); |
| 4449 } |
| 4450 } |
| 4451 |
| 4452 |
| 4390 void ConstantPropagator::Analyze() { | 4453 void ConstantPropagator::Analyze() { |
| 4391 GraphEntryInstr* entry = graph_->graph_entry(); | 4454 GraphEntryInstr* entry = graph_->graph_entry(); |
| 4392 reachable_->Add(entry->preorder_number()); | 4455 reachable_->Add(entry->preorder_number()); |
| 4393 block_worklist_.Add(entry); | 4456 block_worklist_.Add(entry); |
| 4394 | 4457 |
| 4395 while (true) { | 4458 while (true) { |
| 4396 if (block_worklist_.is_empty()) { | 4459 if (block_worklist_.is_empty()) { |
| 4397 if (definition_worklist_.is_empty()) break; | 4460 if (definition_worklist_.is_empty()) break; |
| 4398 Definition* definition = definition_worklist_.RemoveLast(); | 4461 Definition* definition = definition_worklist_.RemoveLast(); |
| 4399 definition_marks_->Remove(definition->ssa_temp_index()); | 4462 definition_marks_->Remove(definition->ssa_temp_index()); |
| (...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4905 if (changed) { | 4968 if (changed) { |
| 4906 // We may have changed the block order and the dominator tree. | 4969 // We may have changed the block order and the dominator tree. |
| 4907 flow_graph->DiscoverBlocks(); | 4970 flow_graph->DiscoverBlocks(); |
| 4908 GrowableArray<BitVector*> dominance_frontier; | 4971 GrowableArray<BitVector*> dominance_frontier; |
| 4909 flow_graph->ComputeDominators(&dominance_frontier); | 4972 flow_graph->ComputeDominators(&dominance_frontier); |
| 4910 } | 4973 } |
| 4911 } | 4974 } |
| 4912 | 4975 |
| 4913 | 4976 |
| 4914 } // namespace dart | 4977 } // namespace dart |
| OLD | NEW |