| 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/aot_optimizer.h" | 5 #include "vm/aot_optimizer.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/branch_optimizer.h" | 8 #include "vm/branch_optimizer.h" |
| 9 #include "vm/cha.h" | 9 #include "vm/cha.h" |
| 10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
| (...skipping 1656 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1667 default: | 1667 default: |
| 1668 return false; | 1668 return false; |
| 1669 } | 1669 } |
| 1670 } | 1670 } |
| 1671 | 1671 |
| 1672 | 1672 |
| 1673 // Inline only simple, frequently called core library methods. | 1673 // Inline only simple, frequently called core library methods. |
| 1674 bool AotOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) { | 1674 bool AotOptimizer::TryInlineInstanceMethod(InstanceCallInstr* call) { |
| 1675 ASSERT(call->HasICData()); | 1675 ASSERT(call->HasICData()); |
| 1676 const ICData& ic_data = *call->ic_data(); | 1676 const ICData& ic_data = *call->ic_data(); |
| 1677 if ((ic_data.NumberOfUsedChecks() == 0) || !ic_data.HasOneTarget()) { | 1677 if (ic_data.NumberOfUsedChecks() != 1) { |
| 1678 // No type feedback collected or multiple targets found. | 1678 // No type feedback collected or multiple receivers/targets found. |
| 1679 return false; | 1679 return false; |
| 1680 } | 1680 } |
| 1681 | 1681 |
| 1682 Function& target = Function::Handle(Z); | 1682 Function& target = Function::Handle(Z); |
| 1683 GrowableArray<intptr_t> class_ids; | 1683 GrowableArray<intptr_t> class_ids; |
| 1684 ic_data.GetCheckAt(0, &class_ids, &target); | 1684 ic_data.GetCheckAt(0, &class_ids, &target); |
| 1685 MethodRecognizer::Kind recognized_kind = | 1685 MethodRecognizer::Kind recognized_kind = |
| 1686 MethodRecognizer::RecognizeKind(target); | 1686 MethodRecognizer::RecognizeKind(target); |
| 1687 | 1687 |
| 1688 if ((recognized_kind == MethodRecognizer::kOneByteStringCodeUnitAt) || | 1688 if ((recognized_kind == MethodRecognizer::kOneByteStringCodeUnitAt) || |
| 1689 (recognized_kind == MethodRecognizer::kTwoByteStringCodeUnitAt) || | 1689 (recognized_kind == MethodRecognizer::kTwoByteStringCodeUnitAt) || |
| 1690 (recognized_kind == MethodRecognizer::kExternalOneByteStringCodeUnitAt) || | 1690 (recognized_kind == MethodRecognizer::kExternalOneByteStringCodeUnitAt) || |
| 1691 (recognized_kind == MethodRecognizer::kExternalTwoByteStringCodeUnitAt) || | 1691 (recognized_kind == MethodRecognizer::kExternalTwoByteStringCodeUnitAt) || |
| 1692 (recognized_kind == MethodRecognizer::kGrowableArraySetData) || | 1692 (recognized_kind == MethodRecognizer::kGrowableArraySetData) || |
| 1693 (recognized_kind == MethodRecognizer::kGrowableArraySetLength)) { | 1693 (recognized_kind == MethodRecognizer::kGrowableArraySetLength) || |
| 1694 ASSERT(ic_data.NumberOfChecks() == 1); | 1694 (recognized_kind == MethodRecognizer::kSmi_bitAndFromSmi)) { |
| 1695 return FlowGraphInliner::TryReplaceInstanceCallWithInline( | 1695 return FlowGraphInliner::TryReplaceInstanceCallWithInline( |
| 1696 flow_graph_, current_iterator(), call); | 1696 flow_graph_, current_iterator(), call); |
| 1697 } | 1697 } |
| 1698 | 1698 |
| 1699 if ((recognized_kind == MethodRecognizer::kStringBaseCharAt) && | 1699 if (recognized_kind == MethodRecognizer::kStringBaseCharAt) { |
| 1700 (ic_data.NumberOfChecks() == 1)) { | |
| 1701 ASSERT((class_ids[0] == kOneByteStringCid) || | 1700 ASSERT((class_ids[0] == kOneByteStringCid) || |
| 1702 (class_ids[0] == kTwoByteStringCid) || | 1701 (class_ids[0] == kTwoByteStringCid) || |
| 1703 (class_ids[0] == kExternalOneByteStringCid) || | 1702 (class_ids[0] == kExternalOneByteStringCid) || |
| 1704 (class_ids[0] == kExternalTwoByteStringCid)); | 1703 (class_ids[0] == kExternalTwoByteStringCid)); |
| 1705 return FlowGraphInliner::TryReplaceInstanceCallWithInline( | 1704 return FlowGraphInliner::TryReplaceInstanceCallWithInline( |
| 1706 flow_graph_, current_iterator(), call); | 1705 flow_graph_, current_iterator(), call); |
| 1707 } | 1706 } |
| 1708 | 1707 |
| 1709 if ((class_ids[0] == kOneByteStringCid) && (ic_data.NumberOfChecks() == 1)) { | 1708 if (class_ids[0] == kOneByteStringCid) { |
| 1710 if (recognized_kind == MethodRecognizer::kOneByteStringSetAt) { | 1709 if (recognized_kind == MethodRecognizer::kOneByteStringSetAt) { |
| 1711 // This is an internal method, no need to check argument types nor | 1710 // This is an internal method, no need to check argument types nor |
| 1712 // range. | 1711 // range. |
| 1713 Definition* str = call->ArgumentAt(0); | 1712 Definition* str = call->ArgumentAt(0); |
| 1714 Definition* index = call->ArgumentAt(1); | 1713 Definition* index = call->ArgumentAt(1); |
| 1715 Definition* value = call->ArgumentAt(2); | 1714 Definition* value = call->ArgumentAt(2); |
| 1716 StoreIndexedInstr* store_op = new(Z) StoreIndexedInstr( | 1715 StoreIndexedInstr* store_op = new(Z) StoreIndexedInstr( |
| 1717 new(Z) Value(str), | 1716 new(Z) Value(str), |
| 1718 new(Z) Value(index), | 1717 new(Z) Value(index), |
| 1719 new(Z) Value(value), | 1718 new(Z) Value(value), |
| 1720 kNoStoreBarrier, | 1719 kNoStoreBarrier, |
| 1721 1, // Index scale | 1720 1, // Index scale |
| 1722 kOneByteStringCid, | 1721 kOneByteStringCid, |
| 1723 call->deopt_id(), | 1722 call->deopt_id(), |
| 1724 call->token_pos()); | 1723 call->token_pos()); |
| 1725 ReplaceCall(call, store_op); | 1724 ReplaceCall(call, store_op); |
| 1726 return true; | 1725 return true; |
| 1727 } | 1726 } |
| 1728 return false; | 1727 return false; |
| 1729 } | 1728 } |
| 1730 | 1729 |
| 1731 if (CanUnboxDouble() && | 1730 if (CanUnboxDouble() && |
| 1732 (recognized_kind == MethodRecognizer::kIntegerToDouble) && | 1731 (recognized_kind == MethodRecognizer::kIntegerToDouble)) { |
| 1733 (ic_data.NumberOfChecks() == 1)) { | |
| 1734 if (class_ids[0] == kSmiCid) { | 1732 if (class_ids[0] == kSmiCid) { |
| 1735 AddReceiverCheck(call); | 1733 AddReceiverCheck(call); |
| 1736 ReplaceCall(call, | 1734 ReplaceCall(call, |
| 1737 new(Z) SmiToDoubleInstr( | 1735 new(Z) SmiToDoubleInstr( |
| 1738 new(Z) Value(call->ArgumentAt(0)), | 1736 new(Z) Value(call->ArgumentAt(0)), |
| 1739 call->token_pos())); | 1737 call->token_pos())); |
| 1740 return true; | 1738 return true; |
| 1741 } else if ((class_ids[0] == kMintCid) && CanConvertUnboxedMintToDouble()) { | 1739 } else if ((class_ids[0] == kMintCid) && CanConvertUnboxedMintToDouble()) { |
| 1742 AddReceiverCheck(call); | 1740 AddReceiverCheck(call); |
| 1743 ReplaceCall(call, | 1741 ReplaceCall(call, |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1792 case MethodRecognizer::kDoubleMul: | 1790 case MethodRecognizer::kDoubleMul: |
| 1793 case MethodRecognizer::kDoubleDiv: | 1791 case MethodRecognizer::kDoubleDiv: |
| 1794 return FlowGraphInliner::TryReplaceInstanceCallWithInline( | 1792 return FlowGraphInliner::TryReplaceInstanceCallWithInline( |
| 1795 flow_graph_, current_iterator(), call); | 1793 flow_graph_, current_iterator(), call); |
| 1796 default: | 1794 default: |
| 1797 // Unsupported method. | 1795 // Unsupported method. |
| 1798 return false; | 1796 return false; |
| 1799 } | 1797 } |
| 1800 } | 1798 } |
| 1801 | 1799 |
| 1802 if (IsSupportedByteArrayViewCid(class_ids[0]) && | 1800 if (IsSupportedByteArrayViewCid(class_ids[0])) { |
| 1803 (ic_data.NumberOfChecks() == 1)) { | |
| 1804 return FlowGraphInliner::TryReplaceInstanceCallWithInline( | 1801 return FlowGraphInliner::TryReplaceInstanceCallWithInline( |
| 1805 flow_graph_, current_iterator(), call); | 1802 flow_graph_, current_iterator(), call); |
| 1806 } | 1803 } |
| 1807 | 1804 |
| 1808 if ((class_ids[0] == kFloat32x4Cid) && (ic_data.NumberOfChecks() == 1)) { | 1805 if (class_ids[0] == kFloat32x4Cid) { |
| 1809 return TryInlineFloat32x4Method(call, recognized_kind); | 1806 return TryInlineFloat32x4Method(call, recognized_kind); |
| 1810 } | 1807 } |
| 1811 | 1808 |
| 1812 if ((class_ids[0] == kInt32x4Cid) && (ic_data.NumberOfChecks() == 1)) { | 1809 if (class_ids[0] == kInt32x4Cid) { |
| 1813 return TryInlineInt32x4Method(call, recognized_kind); | 1810 return TryInlineInt32x4Method(call, recognized_kind); |
| 1814 } | 1811 } |
| 1815 | 1812 |
| 1816 if ((class_ids[0] == kFloat64x2Cid) && (ic_data.NumberOfChecks() == 1)) { | 1813 if (class_ids[0] == kFloat64x2Cid) { |
| 1817 return TryInlineFloat64x2Method(call, recognized_kind); | 1814 return TryInlineFloat64x2Method(call, recognized_kind); |
| 1818 } | 1815 } |
| 1819 | 1816 |
| 1820 return false; | 1817 return false; |
| 1821 } | 1818 } |
| 1822 | 1819 |
| 1823 | 1820 |
| 1824 bool AotOptimizer::TryInlineFloat32x4Constructor( | 1821 bool AotOptimizer::TryInlineFloat32x4Constructor( |
| 1825 StaticCallInstr* call, | 1822 StaticCallInstr* call, |
| 1826 MethodRecognizer::Kind recognized_kind) { | 1823 MethodRecognizer::Kind recognized_kind) { |
| (...skipping 913 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2740 | 2737 |
| 2741 // Discard the environment from the original instruction because the store | 2738 // Discard the environment from the original instruction because the store |
| 2742 // can't deoptimize. | 2739 // can't deoptimize. |
| 2743 instr->RemoveEnvironment(); | 2740 instr->RemoveEnvironment(); |
| 2744 ReplaceCall(instr, store); | 2741 ReplaceCall(instr, store); |
| 2745 return true; | 2742 return true; |
| 2746 } | 2743 } |
| 2747 | 2744 |
| 2748 | 2745 |
| 2749 } // namespace dart | 2746 } // namespace dart |
| OLD | NEW |