| 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 798 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 809 case kExternalTypedDataUint8ClampedArrayCid: | 809 case kExternalTypedDataUint8ClampedArrayCid: |
| 810 case kTypedDataInt16ArrayCid: | 810 case kTypedDataInt16ArrayCid: |
| 811 case kTypedDataUint16ArrayCid: | 811 case kTypedDataUint16ArrayCid: |
| 812 case kTypedDataInt32ArrayCid: | 812 case kTypedDataInt32ArrayCid: |
| 813 case kTypedDataUint32ArrayCid: | 813 case kTypedDataUint32ArrayCid: |
| 814 ASSERT(value_type.IsIntType()); | 814 ASSERT(value_type.IsIntType()); |
| 815 // Fall through. | 815 // Fall through. |
| 816 case kTypedDataFloat32ArrayCid: | 816 case kTypedDataFloat32ArrayCid: |
| 817 case kTypedDataFloat64ArrayCid: { | 817 case kTypedDataFloat64ArrayCid: { |
| 818 type_args = instantiator = flow_graph_->constant_null(); | 818 type_args = instantiator = flow_graph_->constant_null(); |
| 819 ASSERT((class_id != kFloat32ArrayCid && | 819 ASSERT((class_id != kTypedDataFloat32ArrayCid && |
| 820 class_id != kFloat64ArrayCid && | |
| 821 class_id != kTypedDataFloat32ArrayCid && | |
| 822 class_id != kTypedDataFloat64ArrayCid) || | 820 class_id != kTypedDataFloat64ArrayCid) || |
| 823 value_type.IsDoubleType()); | 821 value_type.IsDoubleType()); |
| 824 ASSERT(value_type.IsInstantiated()); | 822 ASSERT(value_type.IsInstantiated()); |
| 825 break; | 823 break; |
| 826 } | 824 } |
| 827 default: | 825 default: |
| 828 // TODO(fschneider): Add support for other array types. | 826 // TODO(fschneider): Add support for other array types. |
| 829 UNREACHABLE(); | 827 UNREACHABLE(); |
| 830 } | 828 } |
| 831 AssertAssignableInstr* assert_value = | 829 AssertAssignableInstr* assert_value = |
| 832 new AssertAssignableInstr(call->token_pos(), | 830 new AssertAssignableInstr(call->token_pos(), |
| 833 new Value(stored_value), | 831 new Value(stored_value), |
| 834 new Value(instantiator), | 832 new Value(instantiator), |
| 835 new Value(type_args), | 833 new Value(type_args), |
| 836 value_type, | 834 value_type, |
| 837 Symbols::Value()); | 835 Symbols::Value()); |
| 838 // Newly inserted instructions that can deoptimize or throw an exception | 836 // Newly inserted instructions that can deoptimize or throw an exception |
| 839 // must have a deoptimization id that is valid for lookup in the unoptimized | 837 // must have a deoptimization id that is valid for lookup in the unoptimized |
| 840 // code. | 838 // code. |
| 841 assert_value->deopt_id_ = call->deopt_id(); | 839 assert_value->deopt_id_ = call->deopt_id(); |
| 842 InsertBefore(call, assert_value, call->env(), Definition::kValue); | 840 InsertBefore(call, assert_value, call->env(), Definition::kValue); |
| 843 } | 841 } |
| 844 | 842 |
| 845 intptr_t array_cid = PrepareIndexedOp(call, class_id, &array, &index); | 843 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. | 844 // Check if store barrier is needed. Byte arrays don't need a store barrier. |
| 847 StoreBarrierType needs_store_barrier = | 845 StoreBarrierType needs_store_barrier = |
| 848 RawObject::IsByteArrayClassId(array_cid) | 846 (RawObject::IsTypedDataClassId(array_cid) || |
| 849 ? kNoStoreBarrier | 847 RawObject::IsTypedDataViewClassId(array_cid) || |
| 850 : kEmitStoreBarrier; | 848 RawObject::IsExternalTypedDataClassId(array_cid)) ? kNoStoreBarrier |
| 849 : kEmitStoreBarrier; |
| 851 if (!value_check.IsNull()) { | 850 if (!value_check.IsNull()) { |
| 852 // No store barrier needed because checked value is a smi, an unboxed mint | 851 // No store barrier needed because checked value is a smi, an unboxed mint |
| 853 // or unboxed double. | 852 // or unboxed double. |
| 854 needs_store_barrier = kNoStoreBarrier; | 853 needs_store_barrier = kNoStoreBarrier; |
| 855 AddCheckClass(stored_value, value_check, call->deopt_id(), call->env(), | 854 AddCheckClass(stored_value, value_check, call->deopt_id(), call->env(), |
| 856 call); | 855 call); |
| 857 } | 856 } |
| 858 | 857 |
| 859 intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(array_cid); | 858 intptr_t index_scale = FlowGraphCompiler::ElementSizeFor(array_cid); |
| 860 Definition* array_op = new StoreIndexedInstr(new Value(array), | 859 Definition* array_op = new StoreIndexedInstr(new Value(array), |
| (...skipping 755 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1616 InstanceCallInstr* call, | 1615 InstanceCallInstr* call, |
| 1617 intptr_t receiver_cid, | 1616 intptr_t receiver_cid, |
| 1618 intptr_t view_cid) { | 1617 intptr_t view_cid) { |
| 1619 Definition* array = call->ArgumentAt(0); | 1618 Definition* array = call->ArgumentAt(0); |
| 1620 PrepareByteArrayViewOp(call, receiver_cid, view_cid, &array); | 1619 PrepareByteArrayViewOp(call, receiver_cid, view_cid, &array); |
| 1621 | 1620 |
| 1622 // Optimistically build a smi-checked load for Int32 and Uint32 | 1621 // Optimistically build a smi-checked load for Int32 and Uint32 |
| 1623 // loads on ia32 like we do for normal array loads, and only revert to | 1622 // loads on ia32 like we do for normal array loads, and only revert to |
| 1624 // mint case after deoptimizing here. | 1623 // mint case after deoptimizing here. |
| 1625 intptr_t deopt_id = Isolate::kNoDeoptId; | 1624 intptr_t deopt_id = Isolate::kNoDeoptId; |
| 1626 if ((view_cid == kInt32ArrayCid || view_cid == kUint32ArrayCid) && | 1625 if ((view_cid == kTypedDataInt32ArrayCid || |
| 1626 view_cid == kTypedDataUint32ArrayCid) && |
| 1627 call->ic_data()->deopt_reason() == kDeoptUnknown) { | 1627 call->ic_data()->deopt_reason() == kDeoptUnknown) { |
| 1628 deopt_id = call->deopt_id(); | 1628 deopt_id = call->deopt_id(); |
| 1629 } | 1629 } |
| 1630 Definition* byte_index = call->ArgumentAt(1); | 1630 Definition* byte_index = call->ArgumentAt(1); |
| 1631 LoadIndexedInstr* array_op = new LoadIndexedInstr(new Value(array), | 1631 LoadIndexedInstr* array_op = new LoadIndexedInstr(new Value(array), |
| 1632 new Value(byte_index), | 1632 new Value(byte_index), |
| 1633 1, // Index scale. | 1633 1, // Index scale. |
| 1634 view_cid, | 1634 view_cid, |
| 1635 deopt_id); | 1635 deopt_id); |
| 1636 ReplaceCall(call, array_op); | 1636 ReplaceCall(call, array_op); |
| (...skipping 1471 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3108 // because only those values that are in the GEN set | 3108 // because only those values that are in the GEN set |
| 3109 // will ever be used. | 3109 // will ever be used. |
| 3110 gen->RemoveAll(kill_by_offset_[offset_in_words]); | 3110 gen->RemoveAll(kill_by_offset_[offset_in_words]); |
| 3111 | 3111 |
| 3112 // Only forward stores to normal arrays and float64 arrays | 3112 // Only forward stores to normal arrays and float64 arrays |
| 3113 // to loads because other array stores (intXX/uintXX/float32) | 3113 // to loads because other array stores (intXX/uintXX/float32) |
| 3114 // may implicitly convert the value stored. | 3114 // may implicitly convert the value stored. |
| 3115 StoreIndexedInstr* array_store = instr->AsStoreIndexed(); | 3115 StoreIndexedInstr* array_store = instr->AsStoreIndexed(); |
| 3116 if (array_store == NULL || | 3116 if (array_store == NULL || |
| 3117 array_store->class_id() == kArrayCid || | 3117 array_store->class_id() == kArrayCid || |
| 3118 array_store->class_id() == kFloat64ArrayCid) { | 3118 array_store->class_id() == kTypedDataFloat64ArrayCid) { |
| 3119 Definition* load = map_->Lookup(instr->AsDefinition()); | 3119 Definition* load = map_->Lookup(instr->AsDefinition()); |
| 3120 if (load != NULL) { | 3120 if (load != NULL) { |
| 3121 // Store has a corresponding numbered load. Try forwarding | 3121 // Store has a corresponding numbered load. Try forwarding |
| 3122 // stored value to it. | 3122 // stored value to it. |
| 3123 gen->Add(load->expr_id()); | 3123 gen->Add(load->expr_id()); |
| 3124 if (out_values == NULL) out_values = CreateBlockOutValues(); | 3124 if (out_values == NULL) out_values = CreateBlockOutValues(); |
| 3125 (*out_values)[load->expr_id()] = GetStoredValue(instr); | 3125 (*out_values)[load->expr_id()] = GetStoredValue(instr); |
| 3126 } | 3126 } |
| 3127 } | 3127 } |
| 3128 } | 3128 } |
| (...skipping 1485 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4614 if (changed) { | 4614 if (changed) { |
| 4615 // We may have changed the block order and the dominator tree. | 4615 // We may have changed the block order and the dominator tree. |
| 4616 flow_graph->DiscoverBlocks(); | 4616 flow_graph->DiscoverBlocks(); |
| 4617 GrowableArray<BitVector*> dominance_frontier; | 4617 GrowableArray<BitVector*> dominance_frontier; |
| 4618 flow_graph->ComputeDominators(&dominance_frontier); | 4618 flow_graph->ComputeDominators(&dominance_frontier); |
| 4619 } | 4619 } |
| 4620 } | 4620 } |
| 4621 | 4621 |
| 4622 | 4622 |
| 4623 } // namespace dart | 4623 } // namespace dart |
| OLD | NEW |