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/compiler.h" | 9 #include "vm/compiler.h" |
10 #include "vm/cpu.h" | 10 #include "vm/cpu.h" |
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
387 | 387 |
388 // Pattern recognized. | 388 // Pattern recognized. |
389 smi_shift_left->mark_truncating(); | 389 smi_shift_left->mark_truncating(); |
390 ASSERT(bit_and_instr->IsBinarySmiOp() || bit_and_instr->IsBinaryMintOp()); | 390 ASSERT(bit_and_instr->IsBinarySmiOp() || bit_and_instr->IsBinaryMintOp()); |
391 if (bit_and_instr->IsBinaryMintOp()) { | 391 if (bit_and_instr->IsBinaryMintOp()) { |
392 // Replace Mint op with Smi op. | 392 // Replace Mint op with Smi op. |
393 BinarySmiOpInstr* smi_op = new(Z) BinarySmiOpInstr( | 393 BinarySmiOpInstr* smi_op = new(Z) BinarySmiOpInstr( |
394 Token::kBIT_AND, | 394 Token::kBIT_AND, |
395 new(Z) Value(left_instr), | 395 new(Z) Value(left_instr), |
396 new(Z) Value(right_instr), | 396 new(Z) Value(right_instr), |
397 Isolate::kNoDeoptId); // BIT_AND cannot deoptimize. | 397 Thread::kNoDeoptId); // BIT_AND cannot deoptimize. |
398 bit_and_instr->ReplaceWith(smi_op, current_iterator()); | 398 bit_and_instr->ReplaceWith(smi_op, current_iterator()); |
399 } | 399 } |
400 } | 400 } |
401 | 401 |
402 | 402 |
403 | 403 |
404 // Used by TryMergeDivMod. | 404 // Used by TryMergeDivMod. |
405 // Inserts a load-indexed instruction between a TRUNCDIV or MOD instruction, | 405 // Inserts a load-indexed instruction between a TRUNCDIV or MOD instruction, |
406 // and the using instruction. This is an intermediate step before merging. | 406 // and the using instruction. This is an intermediate step before merging. |
407 void FlowGraphOptimizer::AppendLoadIndexedForMerged(Definition* instr, | 407 void FlowGraphOptimizer::AppendLoadIndexedForMerged(Definition* instr, |
408 intptr_t ix, | 408 intptr_t ix, |
409 intptr_t cid) { | 409 intptr_t cid) { |
410 const intptr_t index_scale = Instance::ElementSizeFor(cid); | 410 const intptr_t index_scale = Instance::ElementSizeFor(cid); |
411 ConstantInstr* index_instr = | 411 ConstantInstr* index_instr = |
412 flow_graph()->GetConstant(Smi::Handle(Z, Smi::New(ix))); | 412 flow_graph()->GetConstant(Smi::Handle(Z, Smi::New(ix))); |
413 LoadIndexedInstr* load = | 413 LoadIndexedInstr* load = |
414 new(Z) LoadIndexedInstr(new(Z) Value(instr), | 414 new(Z) LoadIndexedInstr(new(Z) Value(instr), |
415 new(Z) Value(index_instr), | 415 new(Z) Value(index_instr), |
416 index_scale, | 416 index_scale, |
417 cid, | 417 cid, |
418 Isolate::kNoDeoptId, | 418 Thread::kNoDeoptId, |
419 instr->token_pos()); | 419 instr->token_pos()); |
420 instr->ReplaceUsesWith(load); | 420 instr->ReplaceUsesWith(load); |
421 flow_graph()->InsertAfter(instr, load, NULL, FlowGraph::kValue); | 421 flow_graph()->InsertAfter(instr, load, NULL, FlowGraph::kValue); |
422 } | 422 } |
423 | 423 |
424 | 424 |
425 void FlowGraphOptimizer::AppendExtractNthOutputForMerged(Definition* instr, | 425 void FlowGraphOptimizer::AppendExtractNthOutputForMerged(Definition* instr, |
426 intptr_t index, | 426 intptr_t index, |
427 Representation rep, | 427 Representation rep, |
428 intptr_t cid) { | 428 intptr_t cid) { |
(...skipping 277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
706 insert_before = | 706 insert_before = |
707 phi->block()->PredecessorAt(use->use_index())->last_instruction(); | 707 phi->block()->PredecessorAt(use->use_index())->last_instruction(); |
708 deopt_target = NULL; | 708 deopt_target = NULL; |
709 } else { | 709 } else { |
710 deopt_target = insert_before = use->instruction(); | 710 deopt_target = insert_before = use->instruction(); |
711 } | 711 } |
712 | 712 |
713 Definition* converted = NULL; | 713 Definition* converted = NULL; |
714 if (IsUnboxedInteger(from) && IsUnboxedInteger(to)) { | 714 if (IsUnboxedInteger(from) && IsUnboxedInteger(to)) { |
715 const intptr_t deopt_id = (to == kUnboxedInt32) && (deopt_target != NULL) ? | 715 const intptr_t deopt_id = (to == kUnboxedInt32) && (deopt_target != NULL) ? |
716 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; | 716 deopt_target->DeoptimizationTarget() : Thread::kNoDeoptId; |
717 converted = new(Z) UnboxedIntConverterInstr(from, | 717 converted = new(Z) UnboxedIntConverterInstr(from, |
718 to, | 718 to, |
719 use->CopyWithType(), | 719 use->CopyWithType(), |
720 deopt_id); | 720 deopt_id); |
721 } else if ((from == kUnboxedInt32) && (to == kUnboxedDouble)) { | 721 } else if ((from == kUnboxedInt32) && (to == kUnboxedDouble)) { |
722 converted = new Int32ToDoubleInstr(use->CopyWithType()); | 722 converted = new Int32ToDoubleInstr(use->CopyWithType()); |
723 } else if ((from == kUnboxedMint) && | 723 } else if ((from == kUnboxedMint) && |
724 (to == kUnboxedDouble) && | 724 (to == kUnboxedDouble) && |
725 CanConvertUnboxedMintToDouble()) { | 725 CanConvertUnboxedMintToDouble()) { |
726 const intptr_t deopt_id = (deopt_target != NULL) ? | 726 const intptr_t deopt_id = (deopt_target != NULL) ? |
727 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; | 727 deopt_target->DeoptimizationTarget() : Thread::kNoDeoptId; |
728 ASSERT(CanUnboxDouble()); | 728 ASSERT(CanUnboxDouble()); |
729 converted = new MintToDoubleInstr(use->CopyWithType(), deopt_id); | 729 converted = new MintToDoubleInstr(use->CopyWithType(), deopt_id); |
730 } else if ((from == kTagged) && Boxing::Supports(to)) { | 730 } else if ((from == kTagged) && Boxing::Supports(to)) { |
731 const intptr_t deopt_id = (deopt_target != NULL) ? | 731 const intptr_t deopt_id = (deopt_target != NULL) ? |
732 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; | 732 deopt_target->DeoptimizationTarget() : Thread::kNoDeoptId; |
733 converted = UnboxInstr::Create(to, use->CopyWithType(), deopt_id); | 733 converted = UnboxInstr::Create(to, use->CopyWithType(), deopt_id); |
734 } else if ((to == kTagged) && Boxing::Supports(from)) { | 734 } else if ((to == kTagged) && Boxing::Supports(from)) { |
735 converted = BoxInstr::Create(from, use->CopyWithType()); | 735 converted = BoxInstr::Create(from, use->CopyWithType()); |
736 } else { | 736 } else { |
737 // We have failed to find a suitable conversion instruction. | 737 // We have failed to find a suitable conversion instruction. |
738 // Insert two "dummy" conversion instructions with the correct | 738 // Insert two "dummy" conversion instructions with the correct |
739 // "from" and "to" representation. The inserted instructions will | 739 // "from" and "to" representation. The inserted instructions will |
740 // trigger a deoptimization if executed. See #12417 for a discussion. | 740 // trigger a deoptimization if executed. See #12417 for a discussion. |
741 const intptr_t deopt_id = (deopt_target != NULL) ? | 741 const intptr_t deopt_id = (deopt_target != NULL) ? |
742 deopt_target->DeoptimizationTarget() : Isolate::kNoDeoptId; | 742 deopt_target->DeoptimizationTarget() : Thread::kNoDeoptId; |
743 ASSERT(Boxing::Supports(from)); | 743 ASSERT(Boxing::Supports(from)); |
744 ASSERT(Boxing::Supports(to)); | 744 ASSERT(Boxing::Supports(to)); |
745 Definition* boxed = BoxInstr::Create(from, use->CopyWithType()); | 745 Definition* boxed = BoxInstr::Create(from, use->CopyWithType()); |
746 use->BindTo(boxed); | 746 use->BindTo(boxed); |
747 InsertBefore(insert_before, boxed, NULL, FlowGraph::kValue); | 747 InsertBefore(insert_before, boxed, NULL, FlowGraph::kValue); |
748 converted = UnboxInstr::Create(to, new(Z) Value(boxed), deopt_id); | 748 converted = UnboxInstr::Create(to, new(Z) Value(boxed), deopt_id); |
749 } | 749 } |
750 ASSERT(converted != NULL); | 750 ASSERT(converted != NULL); |
751 InsertBefore(insert_before, converted, use->instruction()->env(), | 751 InsertBefore(insert_before, converted, use->instruction()->env(), |
752 FlowGraph::kValue); | 752 FlowGraph::kValue); |
(...skipping 994 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1747 call->GetBlock()->try_index()); | 1747 call->GetBlock()->try_index()); |
1748 (*entry)->InheritDeoptTarget(Z, call); | 1748 (*entry)->InheritDeoptTarget(Z, call); |
1749 Instruction* cursor = *entry; | 1749 Instruction* cursor = *entry; |
1750 | 1750 |
1751 array_cid = PrepareInlineIndexedOp(call, | 1751 array_cid = PrepareInlineIndexedOp(call, |
1752 array_cid, | 1752 array_cid, |
1753 &array, | 1753 &array, |
1754 index, | 1754 index, |
1755 &cursor); | 1755 &cursor); |
1756 | 1756 |
1757 intptr_t deopt_id = Isolate::kNoDeoptId; | 1757 intptr_t deopt_id = Thread::kNoDeoptId; |
1758 if ((array_cid == kTypedDataInt32ArrayCid) || | 1758 if ((array_cid == kTypedDataInt32ArrayCid) || |
1759 (array_cid == kTypedDataUint32ArrayCid)) { | 1759 (array_cid == kTypedDataUint32ArrayCid)) { |
1760 // Deoptimization may be needed if result does not always fit in a Smi. | 1760 // Deoptimization may be needed if result does not always fit in a Smi. |
1761 deopt_id = (kSmiBits >= 32) ? Isolate::kNoDeoptId : call->deopt_id(); | 1761 deopt_id = (kSmiBits >= 32) ? Thread::kNoDeoptId : call->deopt_id(); |
1762 } | 1762 } |
1763 | 1763 |
1764 // Array load and return. | 1764 // Array load and return. |
1765 intptr_t index_scale = Instance::ElementSizeFor(array_cid); | 1765 intptr_t index_scale = Instance::ElementSizeFor(array_cid); |
1766 *last = new(Z) LoadIndexedInstr(new(Z) Value(array), | 1766 *last = new(Z) LoadIndexedInstr(new(Z) Value(array), |
1767 new(Z) Value(index), | 1767 new(Z) Value(index), |
1768 index_scale, | 1768 index_scale, |
1769 array_cid, | 1769 array_cid, |
1770 deopt_id, | 1770 deopt_id, |
1771 call->token_pos()); | 1771 call->token_pos()); |
1772 cursor = flow_graph()->AppendTo( | 1772 cursor = flow_graph()->AppendTo( |
1773 cursor, | 1773 cursor, |
1774 *last, | 1774 *last, |
1775 deopt_id != Isolate::kNoDeoptId ? call->env() : NULL, | 1775 deopt_id != Thread::kNoDeoptId ? call->env() : NULL, |
1776 FlowGraph::kValue); | 1776 FlowGraph::kValue); |
1777 | 1777 |
1778 if (array_cid == kTypedDataFloat32ArrayCid) { | 1778 if (array_cid == kTypedDataFloat32ArrayCid) { |
1779 *last = new(Z) FloatToDoubleInstr(new(Z) Value(*last), deopt_id); | 1779 *last = new(Z) FloatToDoubleInstr(new(Z) Value(*last), deopt_id); |
1780 flow_graph()->AppendTo(cursor, | 1780 flow_graph()->AppendTo(cursor, |
1781 *last, | 1781 *last, |
1782 deopt_id != Isolate::kNoDeoptId ? call->env() : NULL, | 1782 deopt_id != Thread::kNoDeoptId ? call->env() : NULL, |
1783 FlowGraph::kValue); | 1783 FlowGraph::kValue); |
1784 } | 1784 } |
1785 return true; | 1785 return true; |
1786 } | 1786 } |
1787 | 1787 |
1788 | 1788 |
1789 // Return true if d is a string of length one (a constant or result from | 1789 // Return true if d is a string of length one (a constant or result from |
1790 // from string-from-char-code instruction. | 1790 // from string-from-char-code instruction. |
1791 static bool IsLengthOneString(Definition* d) { | 1791 static bool IsLengthOneString(Definition* d) { |
1792 if (d->IsConstant()) { | 1792 if (d->IsConstant()) { |
(...skipping 995 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2788 new(Z) Value(index), | 2788 new(Z) Value(index), |
2789 call->deopt_id()), | 2789 call->deopt_id()), |
2790 call->env(), | 2790 call->env(), |
2791 FlowGraph::kEffect); | 2791 FlowGraph::kEffect); |
2792 | 2792 |
2793 LoadIndexedInstr* load_indexed = new(Z) LoadIndexedInstr( | 2793 LoadIndexedInstr* load_indexed = new(Z) LoadIndexedInstr( |
2794 new(Z) Value(str), | 2794 new(Z) Value(str), |
2795 new(Z) Value(index), | 2795 new(Z) Value(index), |
2796 Instance::ElementSizeFor(cid), | 2796 Instance::ElementSizeFor(cid), |
2797 cid, | 2797 cid, |
2798 Isolate::kNoDeoptId, | 2798 Thread::kNoDeoptId, |
2799 call->token_pos()); | 2799 call->token_pos()); |
2800 | 2800 |
2801 cursor = flow_graph()->AppendTo(cursor, | 2801 cursor = flow_graph()->AppendTo(cursor, |
2802 load_indexed, | 2802 load_indexed, |
2803 NULL, | 2803 NULL, |
2804 FlowGraph::kValue); | 2804 FlowGraph::kValue); |
2805 ASSERT(cursor == load_indexed); | 2805 ASSERT(cursor == load_indexed); |
2806 return load_indexed; | 2806 return load_indexed; |
2807 } | 2807 } |
2808 | 2808 |
(...skipping 844 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3653 (*entry)->InheritDeoptTarget(Z, call); | 3653 (*entry)->InheritDeoptTarget(Z, call); |
3654 Instruction* cursor = *entry; | 3654 Instruction* cursor = *entry; |
3655 | 3655 |
3656 array_cid = PrepareInlineByteArrayBaseOp(call, | 3656 array_cid = PrepareInlineByteArrayBaseOp(call, |
3657 array_cid, | 3657 array_cid, |
3658 view_cid, | 3658 view_cid, |
3659 &array, | 3659 &array, |
3660 index, | 3660 index, |
3661 &cursor); | 3661 &cursor); |
3662 | 3662 |
3663 intptr_t deopt_id = Isolate::kNoDeoptId; | 3663 intptr_t deopt_id = Thread::kNoDeoptId; |
3664 if ((array_cid == kTypedDataInt32ArrayCid) || | 3664 if ((array_cid == kTypedDataInt32ArrayCid) || |
3665 (array_cid == kTypedDataUint32ArrayCid)) { | 3665 (array_cid == kTypedDataUint32ArrayCid)) { |
3666 // Deoptimization may be needed if result does not always fit in a Smi. | 3666 // Deoptimization may be needed if result does not always fit in a Smi. |
3667 deopt_id = (kSmiBits >= 32) ? Isolate::kNoDeoptId : call->deopt_id(); | 3667 deopt_id = (kSmiBits >= 32) ? Thread::kNoDeoptId : call->deopt_id(); |
3668 } | 3668 } |
3669 | 3669 |
3670 *last = new(Z) LoadIndexedInstr(new(Z) Value(array), | 3670 *last = new(Z) LoadIndexedInstr(new(Z) Value(array), |
3671 new(Z) Value(index), | 3671 new(Z) Value(index), |
3672 1, | 3672 1, |
3673 view_cid, | 3673 view_cid, |
3674 deopt_id, | 3674 deopt_id, |
3675 call->token_pos()); | 3675 call->token_pos()); |
3676 cursor = flow_graph()->AppendTo( | 3676 cursor = flow_graph()->AppendTo( |
3677 cursor, | 3677 cursor, |
3678 *last, | 3678 *last, |
3679 deopt_id != Isolate::kNoDeoptId ? call->env() : NULL, | 3679 deopt_id != Thread::kNoDeoptId ? call->env() : NULL, |
3680 FlowGraph::kValue); | 3680 FlowGraph::kValue); |
3681 | 3681 |
3682 if (view_cid == kTypedDataFloat32ArrayCid) { | 3682 if (view_cid == kTypedDataFloat32ArrayCid) { |
3683 *last = new(Z) FloatToDoubleInstr(new(Z) Value(*last), deopt_id); | 3683 *last = new(Z) FloatToDoubleInstr(new(Z) Value(*last), deopt_id); |
3684 flow_graph()->AppendTo(cursor, | 3684 flow_graph()->AppendTo(cursor, |
3685 *last, | 3685 *last, |
3686 deopt_id != Isolate::kNoDeoptId ? call->env() : NULL, | 3686 deopt_id != Thread::kNoDeoptId ? call->env() : NULL, |
3687 FlowGraph::kValue); | 3687 FlowGraph::kValue); |
3688 } | 3688 } |
3689 return true; | 3689 return true; |
3690 } | 3690 } |
3691 | 3691 |
3692 | 3692 |
3693 bool FlowGraphOptimizer::InlineByteArrayBaseStore(const Function& target, | 3693 bool FlowGraphOptimizer::InlineByteArrayBaseStore(const Function& target, |
3694 Instruction* call, | 3694 Instruction* call, |
3695 Definition* receiver, | 3695 Definition* receiver, |
3696 intptr_t array_cid, | 3696 intptr_t array_cid, |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3729 case kTypedDataUint8ArrayCid: | 3729 case kTypedDataUint8ArrayCid: |
3730 case kTypedDataUint8ClampedArrayCid: | 3730 case kTypedDataUint8ClampedArrayCid: |
3731 case kExternalTypedDataUint8ArrayCid: | 3731 case kExternalTypedDataUint8ArrayCid: |
3732 case kExternalTypedDataUint8ClampedArrayCid: | 3732 case kExternalTypedDataUint8ClampedArrayCid: |
3733 case kTypedDataInt16ArrayCid: | 3733 case kTypedDataInt16ArrayCid: |
3734 case kTypedDataUint16ArrayCid: { | 3734 case kTypedDataUint16ArrayCid: { |
3735 // Check that value is always smi. | 3735 // Check that value is always smi. |
3736 value_check = ICData::New(flow_graph_->function(), | 3736 value_check = ICData::New(flow_graph_->function(), |
3737 i_call->function_name(), | 3737 i_call->function_name(), |
3738 Object::empty_array(), // Dummy args. descr. | 3738 Object::empty_array(), // Dummy args. descr. |
3739 Isolate::kNoDeoptId, | 3739 Thread::kNoDeoptId, |
3740 1); | 3740 1); |
3741 value_check.AddReceiverCheck(kSmiCid, target); | 3741 value_check.AddReceiverCheck(kSmiCid, target); |
3742 break; | 3742 break; |
3743 } | 3743 } |
3744 case kTypedDataInt32ArrayCid: | 3744 case kTypedDataInt32ArrayCid: |
3745 case kTypedDataUint32ArrayCid: | 3745 case kTypedDataUint32ArrayCid: |
3746 // On 64-bit platforms assume that stored value is always a smi. | 3746 // On 64-bit platforms assume that stored value is always a smi. |
3747 if (kSmiBits >= 32) { | 3747 if (kSmiBits >= 32) { |
3748 value_check = ICData::New(flow_graph_->function(), | 3748 value_check = ICData::New(flow_graph_->function(), |
3749 i_call->function_name(), | 3749 i_call->function_name(), |
3750 Object::empty_array(), // Dummy args. descr. | 3750 Object::empty_array(), // Dummy args. descr. |
3751 Isolate::kNoDeoptId, | 3751 Thread::kNoDeoptId, |
3752 1); | 3752 1); |
3753 value_check.AddReceiverCheck(kSmiCid, target); | 3753 value_check.AddReceiverCheck(kSmiCid, target); |
3754 } | 3754 } |
3755 break; | 3755 break; |
3756 case kTypedDataFloat32ArrayCid: | 3756 case kTypedDataFloat32ArrayCid: |
3757 case kTypedDataFloat64ArrayCid: { | 3757 case kTypedDataFloat64ArrayCid: { |
3758 // Check that value is always double. | 3758 // Check that value is always double. |
3759 value_check = ICData::New(flow_graph_->function(), | 3759 value_check = ICData::New(flow_graph_->function(), |
3760 i_call->function_name(), | 3760 i_call->function_name(), |
3761 Object::empty_array(), // Dummy args. descr. | 3761 Object::empty_array(), // Dummy args. descr. |
3762 Isolate::kNoDeoptId, | 3762 Thread::kNoDeoptId, |
3763 1); | 3763 1); |
3764 value_check.AddReceiverCheck(kDoubleCid, target); | 3764 value_check.AddReceiverCheck(kDoubleCid, target); |
3765 break; | 3765 break; |
3766 } | 3766 } |
3767 case kTypedDataInt32x4ArrayCid: { | 3767 case kTypedDataInt32x4ArrayCid: { |
3768 // Check that value is always Int32x4. | 3768 // Check that value is always Int32x4. |
3769 value_check = ICData::New(flow_graph_->function(), | 3769 value_check = ICData::New(flow_graph_->function(), |
3770 i_call->function_name(), | 3770 i_call->function_name(), |
3771 Object::empty_array(), // Dummy args. descr. | 3771 Object::empty_array(), // Dummy args. descr. |
3772 Isolate::kNoDeoptId, | 3772 Thread::kNoDeoptId, |
3773 1); | 3773 1); |
3774 value_check.AddReceiverCheck(kInt32x4Cid, target); | 3774 value_check.AddReceiverCheck(kInt32x4Cid, target); |
3775 break; | 3775 break; |
3776 } | 3776 } |
3777 case kTypedDataFloat32x4ArrayCid: { | 3777 case kTypedDataFloat32x4ArrayCid: { |
3778 // Check that value is always Float32x4. | 3778 // Check that value is always Float32x4. |
3779 value_check = ICData::New(flow_graph_->function(), | 3779 value_check = ICData::New(flow_graph_->function(), |
3780 i_call->function_name(), | 3780 i_call->function_name(), |
3781 Object::empty_array(), // Dummy args. descr. | 3781 Object::empty_array(), // Dummy args. descr. |
3782 Isolate::kNoDeoptId, | 3782 Thread::kNoDeoptId, |
3783 1); | 3783 1); |
3784 value_check.AddReceiverCheck(kFloat32x4Cid, target); | 3784 value_check.AddReceiverCheck(kFloat32x4Cid, target); |
3785 break; | 3785 break; |
3786 } | 3786 } |
3787 default: | 3787 default: |
3788 // Array cids are already checked in the caller. | 3788 // Array cids are already checked in the caller. |
3789 UNREACHABLE(); | 3789 UNREACHABLE(); |
3790 } | 3790 } |
3791 | 3791 |
3792 Definition* stored_value = call->ArgumentAt(2); | 3792 Definition* stored_value = call->ArgumentAt(2); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3827 new(Z) Value(index), | 3827 new(Z) Value(index), |
3828 new(Z) Value(stored_value), | 3828 new(Z) Value(stored_value), |
3829 needs_store_barrier, | 3829 needs_store_barrier, |
3830 1, // Index scale | 3830 1, // Index scale |
3831 view_cid, | 3831 view_cid, |
3832 call->deopt_id(), | 3832 call->deopt_id(), |
3833 call->token_pos()); | 3833 call->token_pos()); |
3834 | 3834 |
3835 flow_graph()->AppendTo(cursor, | 3835 flow_graph()->AppendTo(cursor, |
3836 *last, | 3836 *last, |
3837 call->deopt_id() != Isolate::kNoDeoptId ? | 3837 call->deopt_id() != Thread::kNoDeoptId ? |
3838 call->env() : NULL, | 3838 call->env() : NULL, |
3839 FlowGraph::kEffect); | 3839 FlowGraph::kEffect); |
3840 return true; | 3840 return true; |
3841 } | 3841 } |
3842 | 3842 |
3843 | 3843 |
3844 | 3844 |
3845 intptr_t FlowGraphOptimizer::PrepareInlineByteArrayBaseOp( | 3845 intptr_t FlowGraphOptimizer::PrepareInlineByteArrayBaseOp( |
3846 Instruction* call, | 3846 Instruction* call, |
3847 intptr_t array_cid, | 3847 intptr_t array_cid, |
(...skipping 335 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4183 Bool& as_bool = | 4183 Bool& as_bool = |
4184 Bool::ZoneHandle(Z, InstanceOfAsBool(unary_checks, type, results)); | 4184 Bool::ZoneHandle(Z, InstanceOfAsBool(unary_checks, type, results)); |
4185 if (as_bool.IsNull()) { | 4185 if (as_bool.IsNull()) { |
4186 if (results->length() == unary_checks.NumberOfChecks() * 2) { | 4186 if (results->length() == unary_checks.NumberOfChecks() * 2) { |
4187 const bool can_deopt = TryExpandTestCidsResult(results, type); | 4187 const bool can_deopt = TryExpandTestCidsResult(results, type); |
4188 TestCidsInstr* test_cids = new(Z) TestCidsInstr( | 4188 TestCidsInstr* test_cids = new(Z) TestCidsInstr( |
4189 call->token_pos(), | 4189 call->token_pos(), |
4190 negate ? Token::kISNOT : Token::kIS, | 4190 negate ? Token::kISNOT : Token::kIS, |
4191 new(Z) Value(left), | 4191 new(Z) Value(left), |
4192 *results, | 4192 *results, |
4193 can_deopt ? call->deopt_id() : Isolate::kNoDeoptId); | 4193 can_deopt ? call->deopt_id() : Thread::kNoDeoptId); |
4194 // Remove type. | 4194 // Remove type. |
4195 ReplaceCall(call, test_cids); | 4195 ReplaceCall(call, test_cids); |
4196 return; | 4196 return; |
4197 } | 4197 } |
4198 } else { | 4198 } else { |
4199 // TODO(srdjan): Use TestCidsInstr also for this case. | 4199 // TODO(srdjan): Use TestCidsInstr also for this case. |
4200 // One result only. | 4200 // One result only. |
4201 AddReceiverCheck(call); | 4201 AddReceiverCheck(call); |
4202 if (negate) { | 4202 if (negate) { |
4203 as_bool = Bool::Get(!as_bool.value()).raw(); | 4203 as_bool = Bool::Get(!as_bool.value()).raw(); |
(...skipping 4588 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8792 | 8792 |
8793 // Insert materializations at environment uses. | 8793 // Insert materializations at environment uses. |
8794 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { | 8794 for (intptr_t i = 0; i < exits_collector_.exits().length(); i++) { |
8795 CreateMaterializationAt( | 8795 CreateMaterializationAt( |
8796 exits_collector_.exits()[i], alloc, *slots); | 8796 exits_collector_.exits()[i], alloc, *slots); |
8797 } | 8797 } |
8798 } | 8798 } |
8799 | 8799 |
8800 | 8800 |
8801 } // namespace dart | 8801 } // namespace dart |
OLD | NEW |