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/cpu.h" | 9 #include "vm/cpu.h" |
10 #include "vm/dart_entry.h" | 10 #include "vm/dart_entry.h" |
(...skipping 178 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 call->function_name(), | 189 call->function_name(), |
190 args_desc)); | 190 args_desc)); |
191 if (function.IsNull()) { | 191 if (function.IsNull()) { |
192 return false; | 192 return false; |
193 } | 193 } |
194 // Create new ICData, do not modify the one attached to the instruction | 194 // Create new ICData, do not modify the one attached to the instruction |
195 // since it is attached to the assembly instruction itself. | 195 // since it is attached to the assembly instruction itself. |
196 // TODO(srdjan): Prevent modification of ICData object that is | 196 // TODO(srdjan): Prevent modification of ICData object that is |
197 // referenced in assembly code. | 197 // referenced in assembly code. |
198 ICData& ic_data = ICData::ZoneHandle(Z, ICData::New( | 198 ICData& ic_data = ICData::ZoneHandle(Z, ICData::New( |
199 flow_graph_->parsed_function()->function(), | 199 flow_graph_->function(), |
200 call->function_name(), | 200 call->function_name(), |
201 args_desc_array, | 201 args_desc_array, |
202 call->deopt_id(), | 202 call->deopt_id(), |
203 class_ids.length())); | 203 class_ids.length())); |
204 if (class_ids.length() > 1) { | 204 if (class_ids.length() > 1) { |
205 ic_data.AddCheck(class_ids, function); | 205 ic_data.AddCheck(class_ids, function); |
206 } else { | 206 } else { |
207 ASSERT(class_ids.length() == 1); | 207 ASSERT(class_ids.length() == 1); |
208 ic_data.AddReceiverCheck(class_ids[0], function); | 208 ic_data.AddReceiverCheck(class_ids[0], function); |
209 } | 209 } |
(...skipping 2046 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2256 | 2256 |
2257 | 2257 |
2258 // Use CHA to determine if the call needs a class check: if the callee's | 2258 // Use CHA to determine if the call needs a class check: if the callee's |
2259 // receiver is the same as the caller's receiver and there are no overriden | 2259 // receiver is the same as the caller's receiver and there are no overriden |
2260 // callee functions, then no class check is needed. | 2260 // callee functions, then no class check is needed. |
2261 bool FlowGraphOptimizer::InstanceCallNeedsClassCheck( | 2261 bool FlowGraphOptimizer::InstanceCallNeedsClassCheck( |
2262 InstanceCallInstr* call, RawFunction::Kind kind) const { | 2262 InstanceCallInstr* call, RawFunction::Kind kind) const { |
2263 if (!FLAG_use_cha) return true; | 2263 if (!FLAG_use_cha) return true; |
2264 Definition* callee_receiver = call->ArgumentAt(0); | 2264 Definition* callee_receiver = call->ArgumentAt(0); |
2265 ASSERT(callee_receiver != NULL); | 2265 ASSERT(callee_receiver != NULL); |
2266 const Function& function = flow_graph_->parsed_function()->function(); | 2266 const Function& function = flow_graph_->function(); |
2267 if (function.IsDynamicFunction() && | 2267 if (function.IsDynamicFunction() && |
2268 callee_receiver->IsParameter() && | 2268 callee_receiver->IsParameter() && |
2269 (callee_receiver->AsParameter()->index() == 0)) { | 2269 (callee_receiver->AsParameter()->index() == 0)) { |
2270 const String& name = (kind == RawFunction::kMethodExtractor) | 2270 const String& name = (kind == RawFunction::kMethodExtractor) |
2271 ? String::Handle(Z, Field::NameFromGetter(call->function_name())) | 2271 ? String::Handle(Z, Field::NameFromGetter(call->function_name())) |
2272 : call->function_name(); | 2272 : call->function_name(); |
2273 return isolate()->cha()->HasOverride(Class::Handle(Z, function.Owner()), | 2273 return isolate()->cha()->HasOverride(Class::Handle(Z, function.Owner()), |
2274 name); | 2274 name); |
2275 } | 2275 } |
2276 return true; | 2276 return true; |
(...skipping 1351 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3628 ICData& value_check = ICData::ZoneHandle(Z); | 3628 ICData& value_check = ICData::ZoneHandle(Z); |
3629 switch (view_cid) { | 3629 switch (view_cid) { |
3630 case kTypedDataInt8ArrayCid: | 3630 case kTypedDataInt8ArrayCid: |
3631 case kTypedDataUint8ArrayCid: | 3631 case kTypedDataUint8ArrayCid: |
3632 case kTypedDataUint8ClampedArrayCid: | 3632 case kTypedDataUint8ClampedArrayCid: |
3633 case kExternalTypedDataUint8ArrayCid: | 3633 case kExternalTypedDataUint8ArrayCid: |
3634 case kExternalTypedDataUint8ClampedArrayCid: | 3634 case kExternalTypedDataUint8ClampedArrayCid: |
3635 case kTypedDataInt16ArrayCid: | 3635 case kTypedDataInt16ArrayCid: |
3636 case kTypedDataUint16ArrayCid: { | 3636 case kTypedDataUint16ArrayCid: { |
3637 // Check that value is always smi. | 3637 // Check that value is always smi. |
3638 value_check = ICData::New(flow_graph_->parsed_function()->function(), | 3638 value_check = ICData::New(flow_graph_->function(), |
3639 i_call->function_name(), | 3639 i_call->function_name(), |
3640 Object::empty_array(), // Dummy args. descr. | 3640 Object::empty_array(), // Dummy args. descr. |
3641 Isolate::kNoDeoptId, | 3641 Isolate::kNoDeoptId, |
3642 1); | 3642 1); |
3643 value_check.AddReceiverCheck(kSmiCid, target); | 3643 value_check.AddReceiverCheck(kSmiCid, target); |
3644 break; | 3644 break; |
3645 } | 3645 } |
3646 case kTypedDataInt32ArrayCid: | 3646 case kTypedDataInt32ArrayCid: |
3647 case kTypedDataUint32ArrayCid: | 3647 case kTypedDataUint32ArrayCid: |
3648 // On 64-bit platforms assume that stored value is always a smi. | 3648 // On 64-bit platforms assume that stored value is always a smi. |
3649 if (kSmiBits >= 32) { | 3649 if (kSmiBits >= 32) { |
3650 value_check = ICData::New(flow_graph_->parsed_function()->function(), | 3650 value_check = ICData::New(flow_graph_->function(), |
3651 i_call->function_name(), | 3651 i_call->function_name(), |
3652 Object::empty_array(), // Dummy args. descr. | 3652 Object::empty_array(), // Dummy args. descr. |
3653 Isolate::kNoDeoptId, | 3653 Isolate::kNoDeoptId, |
3654 1); | 3654 1); |
3655 value_check.AddReceiverCheck(kSmiCid, target); | 3655 value_check.AddReceiverCheck(kSmiCid, target); |
3656 } | 3656 } |
3657 break; | 3657 break; |
3658 case kTypedDataFloat32ArrayCid: | 3658 case kTypedDataFloat32ArrayCid: |
3659 case kTypedDataFloat64ArrayCid: { | 3659 case kTypedDataFloat64ArrayCid: { |
3660 // Check that value is always double. | 3660 // Check that value is always double. |
3661 value_check = ICData::New(flow_graph_->parsed_function()->function(), | 3661 value_check = ICData::New(flow_graph_->function(), |
3662 i_call->function_name(), | 3662 i_call->function_name(), |
3663 Object::empty_array(), // Dummy args. descr. | 3663 Object::empty_array(), // Dummy args. descr. |
3664 Isolate::kNoDeoptId, | 3664 Isolate::kNoDeoptId, |
3665 1); | 3665 1); |
3666 value_check.AddReceiverCheck(kDoubleCid, target); | 3666 value_check.AddReceiverCheck(kDoubleCid, target); |
3667 break; | 3667 break; |
3668 } | 3668 } |
3669 case kTypedDataInt32x4ArrayCid: { | 3669 case kTypedDataInt32x4ArrayCid: { |
3670 // Check that value is always Int32x4. | 3670 // Check that value is always Int32x4. |
3671 value_check = ICData::New(flow_graph_->parsed_function()->function(), | 3671 value_check = ICData::New(flow_graph_->function(), |
3672 i_call->function_name(), | 3672 i_call->function_name(), |
3673 Object::empty_array(), // Dummy args. descr. | 3673 Object::empty_array(), // Dummy args. descr. |
3674 Isolate::kNoDeoptId, | 3674 Isolate::kNoDeoptId, |
3675 1); | 3675 1); |
3676 value_check.AddReceiverCheck(kInt32x4Cid, target); | 3676 value_check.AddReceiverCheck(kInt32x4Cid, target); |
3677 break; | 3677 break; |
3678 } | 3678 } |
3679 case kTypedDataFloat32x4ArrayCid: { | 3679 case kTypedDataFloat32x4ArrayCid: { |
3680 // Check that value is always Float32x4. | 3680 // Check that value is always Float32x4. |
3681 value_check = ICData::New(flow_graph_->parsed_function()->function(), | 3681 value_check = ICData::New(flow_graph_->function(), |
3682 i_call->function_name(), | 3682 i_call->function_name(), |
3683 Object::empty_array(), // Dummy args. descr. | 3683 Object::empty_array(), // Dummy args. descr. |
3684 Isolate::kNoDeoptId, | 3684 Isolate::kNoDeoptId, |
3685 1); | 3685 1); |
3686 value_check.AddReceiverCheck(kFloat32x4Cid, target); | 3686 value_check.AddReceiverCheck(kFloat32x4Cid, target); |
3687 break; | 3687 break; |
3688 } | 3688 } |
3689 default: | 3689 default: |
3690 // Array cids are already checked in the caller. | 3690 // Array cids are already checked in the caller. |
3691 UNREACHABLE(); | 3691 UNREACHABLE(); |
(...skipping 1295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4987 Instruction* instr) { | 4987 Instruction* instr) { |
4988 return IsLoadEliminationCandidate(instr) && | 4988 return IsLoadEliminationCandidate(instr) && |
4989 (sets != NULL) && | 4989 (sets != NULL) && |
4990 instr->HasPlaceId() && | 4990 instr->HasPlaceId() && |
4991 ((*sets)[loop_header_index] != NULL) && | 4991 ((*sets)[loop_header_index] != NULL) && |
4992 (*sets)[loop_header_index]->Contains(instr->place_id()); | 4992 (*sets)[loop_header_index]->Contains(instr->place_id()); |
4993 } | 4993 } |
4994 | 4994 |
4995 | 4995 |
4996 void LICM::OptimisticallySpecializeSmiPhis() { | 4996 void LICM::OptimisticallySpecializeSmiPhis() { |
4997 if (!flow_graph()->parsed_function()->function(). | 4997 if (!flow_graph()->function().allows_hoisting_check_class()) { |
4998 allows_hoisting_check_class()) { | |
4999 // Do not hoist any. | 4998 // Do not hoist any. |
5000 return; | 4999 return; |
5001 } | 5000 } |
5002 | 5001 |
5003 const ZoneGrowableArray<BlockEntryInstr*>& loop_headers = | 5002 const ZoneGrowableArray<BlockEntryInstr*>& loop_headers = |
5004 flow_graph()->LoopHeaders(); | 5003 flow_graph()->LoopHeaders(); |
5005 | 5004 |
5006 for (intptr_t i = 0; i < loop_headers.length(); ++i) { | 5005 for (intptr_t i = 0; i < loop_headers.length(); ++i) { |
5007 JoinEntryInstr* header = loop_headers[i]->AsJoinEntry(); | 5006 JoinEntryInstr* header = loop_headers[i]->AsJoinEntry(); |
5008 // Skip loop that don't have a pre-header block. | 5007 // Skip loop that don't have a pre-header block. |
5009 BlockEntryInstr* pre_header = header->ImmediateDominator(); | 5008 BlockEntryInstr* pre_header = header->ImmediateDominator(); |
5010 if (pre_header == NULL) continue; | 5009 if (pre_header == NULL) continue; |
5011 | 5010 |
5012 for (PhiIterator it(header); !it.Done(); it.Advance()) { | 5011 for (PhiIterator it(header); !it.Done(); it.Advance()) { |
5013 TrySpecializeSmiPhi(it.Current(), header, pre_header); | 5012 TrySpecializeSmiPhi(it.Current(), header, pre_header); |
5014 } | 5013 } |
5015 } | 5014 } |
5016 } | 5015 } |
5017 | 5016 |
5018 | 5017 |
5019 void LICM::Optimize() { | 5018 void LICM::Optimize() { |
5020 if (!flow_graph()->parsed_function()->function(). | 5019 if (!flow_graph()->function().allows_hoisting_check_class()) { |
5021 allows_hoisting_check_class()) { | |
5022 // Do not hoist any. | 5020 // Do not hoist any. |
5023 return; | 5021 return; |
5024 } | 5022 } |
5025 | 5023 |
5026 const ZoneGrowableArray<BlockEntryInstr*>& loop_headers = | 5024 const ZoneGrowableArray<BlockEntryInstr*>& loop_headers = |
5027 flow_graph()->LoopHeaders(); | 5025 flow_graph()->LoopHeaders(); |
5028 | 5026 |
5029 ZoneGrowableArray<BitVector*>* loop_invariant_loads = | 5027 ZoneGrowableArray<BitVector*>* loop_invariant_loads = |
5030 flow_graph()->loop_invariant_loads(); | 5028 flow_graph()->loop_invariant_loads(); |
5031 | 5029 |
(...skipping 3578 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8610 | 8608 |
8611 // Insert materializations at environment uses. | 8609 // Insert materializations at environment uses. |
8612 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { | 8610 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { |
8613 CreateMaterializationAt( | 8611 CreateMaterializationAt( |
8614 exits_collector_.exits()[i], alloc, *slots); | 8612 exits_collector_.exits()[i], alloc, *slots); |
8615 } | 8613 } |
8616 } | 8614 } |
8617 | 8615 |
8618 | 8616 |
8619 } // namespace dart | 8617 } // namespace dart |
OLD | NEW |