Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(61)

Side by Side Diff: runtime/vm/flow_graph_inliner.cc

Issue 2896903002: Shuffle around deopt id allocation to give the flow graph builder a chance to record other data as … (Closed)
Patch Set: format Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 #if !defined(DART_PRECOMPILED_RUNTIME) 4 #if !defined(DART_PRECOMPILED_RUNTIME)
5 #include "vm/flow_graph_inliner.h" 5 #include "vm/flow_graph_inliner.h"
6 6
7 #include "vm/aot_optimizer.h" 7 #include "vm/aot_optimizer.h"
8 #include "vm/precompiler.h" 8 #include "vm/precompiler.h"
9 #include "vm/block_scheduler.h" 9 #include "vm/block_scheduler.h"
10 #include "vm/branch_optimizer.h" 10 #include "vm/branch_optimizer.h"
(...skipping 1497 matching lines...) Expand 10 before | Expand all | Expand 10 after
1508 1508
1509 JoinEntryInstr* new_join = 1509 JoinEntryInstr* new_join =
1510 BranchSimplifier::ToJoinEntry(zone(), old_target); 1510 BranchSimplifier::ToJoinEntry(zone(), old_target);
1511 old_target->ReplaceAsPredecessorWith(new_join); 1511 old_target->ReplaceAsPredecessorWith(new_join);
1512 for (intptr_t j = 0; j < old_target->dominated_blocks().length(); ++j) { 1512 for (intptr_t j = 0; j < old_target->dominated_blocks().length(); ++j) {
1513 BlockEntryInstr* block = old_target->dominated_blocks()[j]; 1513 BlockEntryInstr* block = old_target->dominated_blocks()[j];
1514 new_join->AddDominatedBlock(block); 1514 new_join->AddDominatedBlock(block);
1515 } 1515 }
1516 // Create a new target with the join as unconditional successor. 1516 // Create a new target with the join as unconditional successor.
1517 TargetEntryInstr* new_target = 1517 TargetEntryInstr* new_target =
1518 new TargetEntryInstr(AllocateBlockId(), old_target->try_index()); 1518 new TargetEntryInstr(AllocateBlockId(), old_target->try_index(),
1519 Thread::Current()->GetNextDeoptId());
Vyacheslav Egorov (Google) 2017/05/23 12:00:02 kNoDeoptId because InheritDeoptTarget below.
1519 new_target->InheritDeoptTarget(zone(), new_join); 1520 new_target->InheritDeoptTarget(zone(), new_join);
1520 GotoInstr* new_goto = new (Z) GotoInstr(new_join); 1521 GotoInstr* new_goto =
1522 new (Z) GotoInstr(new_join, Thread::Current()->GetNextDeoptId());
Vyacheslav Egorov (Google) 2017/05/23 12:00:02 ditto
1521 new_goto->InheritDeoptTarget(zone(), new_join); 1523 new_goto->InheritDeoptTarget(zone(), new_join);
1522 new_target->LinkTo(new_goto); 1524 new_target->LinkTo(new_goto);
1523 new_target->set_last_instruction(new_goto); 1525 new_target->set_last_instruction(new_goto);
1524 new_join->predecessors_.Add(new_target); 1526 new_join->predecessors_.Add(new_target);
1525 1527
1526 // Record the new target for the first variant. 1528 // Record the new target for the first variant.
1527 inlined_entries_[i] = new_target; 1529 inlined_entries_[i] = new_target;
1528 } 1530 }
1529 ASSERT(inlined_entries_[i]->IsTargetEntry()); 1531 ASSERT(inlined_entries_[i]->IsTargetEntry());
1530 // Record the shared join for this variant. 1532 // Record the shared join for this variant.
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
1650 if (FlowGraphInliner::TryInlineRecognizedMethod( 1652 if (FlowGraphInliner::TryInlineRecognizedMethod(
1651 owner_->caller_graph(), receiver_cid, target, call_, redefinition, 1653 owner_->caller_graph(), receiver_cid, target, call_, redefinition,
1652 call_->instance_call()->token_pos(), 1654 call_->instance_call()->token_pos(),
1653 *call_->instance_call()->ic_data(), &entry, &last)) { 1655 *call_->instance_call()->ic_data(), &entry, &last)) {
1654 // Create a graph fragment. 1656 // Create a graph fragment.
1655 redefinition->InsertAfter(entry); 1657 redefinition->InsertAfter(entry);
1656 InlineExitCollector* exit_collector = 1658 InlineExitCollector* exit_collector =
1657 new (Z) InlineExitCollector(owner_->caller_graph(), call_); 1659 new (Z) InlineExitCollector(owner_->caller_graph(), call_);
1658 1660
1659 ReturnInstr* result = new (Z) 1661 ReturnInstr* result = new (Z)
1660 ReturnInstr(call_->instance_call()->token_pos(), new (Z) Value(last)); 1662 ReturnInstr(call_->instance_call()->token_pos(), new (Z) Value(last),
1663 Thread::Current()->GetNextDeoptId());
Vyacheslav Egorov (Google) 2017/05/23 12:00:02 should be call_->deopt_id() I think because we use
1661 owner_->caller_graph()->AppendTo( 1664 owner_->caller_graph()->AppendTo(
1662 last, result, 1665 last, result,
1663 call_->env(), // Return can become deoptimization target. 1666 call_->env(), // Return can become deoptimization target.
1664 FlowGraph::kEffect); 1667 FlowGraph::kEffect);
1665 entry->set_last_instruction(result); 1668 entry->set_last_instruction(result);
1666 exit_collector->AddExit(result); 1669 exit_collector->AddExit(result);
1667 ParsedFunction* temp_parsed_function = 1670 ParsedFunction* temp_parsed_function =
1668 new ParsedFunction(Thread::Current(), target); 1671 new ParsedFunction(Thread::Current(), target);
1669 GraphEntryInstr* graph_entry = new (Z) 1672 GraphEntryInstr* graph_entry = new (Z)
1670 GraphEntryInstr(*temp_parsed_function, entry, Compiler::kNoOSRDeoptId); 1673 GraphEntryInstr(*temp_parsed_function, entry, Compiler::kNoOSRDeoptId);
1671 // Update polymorphic inliner state. 1674 // Update polymorphic inliner state.
1672 inlined_entries_.Add(graph_entry); 1675 inlined_entries_.Add(graph_entry);
1673 exit_collector_->Union(exit_collector); 1676 exit_collector_->Union(exit_collector);
1674 return true; 1677 return true;
1675 } 1678 }
1676 return false; 1679 return false;
1677 } 1680 }
1678 1681
1679 1682
1680 // Build a DAG to dispatch to the inlined function bodies. Load the class 1683 // Build a DAG to dispatch to the inlined function bodies. Load the class
1681 // id of the receiver and make explicit comparisons for each inlined body, 1684 // id of the receiver and make explicit comparisons for each inlined body,
1682 // in frequency order. If all variants are inlined, the entry to the last 1685 // in frequency order. If all variants are inlined, the entry to the last
1683 // inlined body is guarded by a CheckClassId instruction which can deopt. 1686 // inlined body is guarded by a CheckClassId instruction which can deopt.
1684 // If not all variants are inlined, we add a PolymorphicInstanceCall 1687 // If not all variants are inlined, we add a PolymorphicInstanceCall
1685 // instruction to handle the non-inlined variants. 1688 // instruction to handle the non-inlined variants.
1686 TargetEntryInstr* PolymorphicInliner::BuildDecisionGraph() { 1689 TargetEntryInstr* PolymorphicInliner::BuildDecisionGraph() {
1687 const intptr_t try_idx = call_->GetBlock()->try_index(); 1690 const intptr_t try_idx = call_->GetBlock()->try_index();
1688 1691
1689 // Start with a fresh target entry. 1692 // Start with a fresh target entry.
1690 TargetEntryInstr* entry = 1693 TargetEntryInstr* entry = new (Z) TargetEntryInstr(
1691 new (Z) TargetEntryInstr(AllocateBlockId(), try_idx); 1694 AllocateBlockId(), try_idx, Thread::Current()->GetNextDeoptId());
Vyacheslav Egorov (Google) 2017/05/23 12:00:02 kNoDeoptId because InheritDeoptTarget below.
1692 entry->InheritDeoptTarget(zone(), call_); 1695 entry->InheritDeoptTarget(zone(), call_);
1693 1696
1694 // This function uses a cursor (a pointer to the 'current' instruction) to 1697 // This function uses a cursor (a pointer to the 'current' instruction) to
1695 // build the graph. The next instruction will be inserted after the 1698 // build the graph. The next instruction will be inserted after the
1696 // cursor. 1699 // cursor.
1697 BlockEntryInstr* current_block = entry; 1700 BlockEntryInstr* current_block = entry;
1698 Instruction* cursor = entry; 1701 Instruction* cursor = entry;
1699 1702
1700 Definition* receiver = call_->ArgumentAt(0); 1703 Definition* receiver = call_->ArgumentAt(0);
1701 // There are at least two variants including non-inlined ones, so we have 1704 // There are at least two variants including non-inlined ones, so we have
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1752 for (intptr_t j = 0; j < target->dominated_blocks().length(); ++j) { 1755 for (intptr_t j = 0; j < target->dominated_blocks().length(); ++j) {
1753 BlockEntryInstr* block = target->dominated_blocks()[j]; 1756 BlockEntryInstr* block = target->dominated_blocks()[j];
1754 current_block->AddDominatedBlock(block); 1757 current_block->AddDominatedBlock(block);
1755 } 1758 }
1756 } else if (callee_entry->IsJoinEntry()) { 1759 } else if (callee_entry->IsJoinEntry()) {
1757 // Shared inlined body and this is a subsequent entry. We have 1760 // Shared inlined body and this is a subsequent entry. We have
1758 // already constructed a join and set its dominator. Add a jump to 1761 // already constructed a join and set its dominator. Add a jump to
1759 // the join. 1762 // the join.
1760 JoinEntryInstr* join = callee_entry->AsJoinEntry(); 1763 JoinEntryInstr* join = callee_entry->AsJoinEntry();
1761 ASSERT(join->dominator() != NULL); 1764 ASSERT(join->dominator() != NULL);
1762 GotoInstr* goto_join = new GotoInstr(join); 1765 GotoInstr* goto_join =
1766 new GotoInstr(join, Thread::Current()->GetNextDeoptId());
Vyacheslav Egorov (Google) 2017/05/23 12:00:02 kNoDeoptId because InheritDeoptTarget below.
1763 goto_join->InheritDeoptTarget(zone(), join); 1767 goto_join->InheritDeoptTarget(zone(), join);
1764 cursor->LinkTo(goto_join); 1768 cursor->LinkTo(goto_join);
1765 current_block->set_last_instruction(goto_join); 1769 current_block->set_last_instruction(goto_join);
1766 } else { 1770 } else {
1767 // There is no possibility of a TargetEntry (the first entry to a 1771 // There is no possibility of a TargetEntry (the first entry to a
1768 // shared inlined body) because this is the last inlined entry. 1772 // shared inlined body) because this is the last inlined entry.
1769 UNREACHABLE(); 1773 UNREACHABLE();
1770 } 1774 }
1771 cursor = NULL; 1775 cursor = NULL;
1772 } else { 1776 } else {
(...skipping 10 matching lines...) Expand all
1783 // special instruction that uses subtraction and unsigned comparison to 1787 // special instruction that uses subtraction and unsigned comparison to
1784 // do this with a single branch. 1788 // do this with a single branch.
1785 const Smi& cid_end = Smi::ZoneHandle(Smi::New(variant.cid_end)); 1789 const Smi& cid_end = Smi::ZoneHandle(Smi::New(variant.cid_end));
1786 ConstantInstr* cid_constant_end = 1790 ConstantInstr* cid_constant_end =
1787 owner_->caller_graph()->GetConstant(cid_end); 1791 owner_->caller_graph()->GetConstant(cid_end);
1788 RelationalOpInstr* compare_top = new RelationalOpInstr( 1792 RelationalOpInstr* compare_top = new RelationalOpInstr(
1789 call_->instance_call()->token_pos(), Token::kLTE, 1793 call_->instance_call()->token_pos(), Token::kLTE,
1790 new Value(load_cid), new Value(cid_constant_end), kSmiCid, 1794 new Value(load_cid), new Value(cid_constant_end), kSmiCid,
1791 call_->deopt_id()); 1795 call_->deopt_id());
1792 BranchInstr* branch_top = upper_limit_branch = 1796 BranchInstr* branch_top = upper_limit_branch =
1793 new BranchInstr(compare_top); 1797 new BranchInstr(compare_top, Thread::Current()->GetNextDeoptId());
Vyacheslav Egorov (Google) 2017/05/23 12:00:03 kNoDeoptId because InheritDeoptTarget below.
1794 branch_top->InheritDeoptTarget(zone(), call_); 1798 branch_top->InheritDeoptTarget(zone(), call_);
1795 cursor = AppendInstruction(cursor, branch_top); 1799 cursor = AppendInstruction(cursor, branch_top);
1796 current_block->set_last_instruction(branch_top); 1800 current_block->set_last_instruction(branch_top);
1797 1801
1798 TargetEntryInstr* below_target = 1802 TargetEntryInstr* below_target = new TargetEntryInstr(
1799 new TargetEntryInstr(AllocateBlockId(), try_idx); 1803 AllocateBlockId(), try_idx, Thread::Current()->GetNextDeoptId());
Vyacheslav Egorov (Google) 2017/05/23 12:00:02 kNoDeoptId because InheritDeoptTarget below.
1800 below_target->InheritDeoptTarget(zone(), call_); 1804 below_target->InheritDeoptTarget(zone(), call_);
1801 current_block->AddDominatedBlock(below_target); 1805 current_block->AddDominatedBlock(below_target);
1802 cursor = current_block = below_target; 1806 cursor = current_block = below_target;
1803 *branch_top->true_successor_address() = below_target; 1807 *branch_top->true_successor_address() = below_target;
1804 1808
1805 RelationalOpInstr* compare_bottom = new RelationalOpInstr( 1809 RelationalOpInstr* compare_bottom = new RelationalOpInstr(
1806 call_->instance_call()->token_pos(), Token::kGTE, 1810 call_->instance_call()->token_pos(), Token::kGTE,
1807 new Value(load_cid), new Value(cid_constant), kSmiCid, 1811 new Value(load_cid), new Value(cid_constant), kSmiCid,
1808 call_->deopt_id()); 1812 call_->deopt_id());
1809 branch = new BranchInstr(compare_bottom); 1813 branch = new BranchInstr(compare_bottom,
1814 Thread::Current()->GetNextDeoptId());
Vyacheslav Egorov (Google) 2017/05/23 12:00:02 kNoDeoptId because InheritDeoptTarget below.
1810 } else { 1815 } else {
1811 StrictCompareInstr* compare = new StrictCompareInstr( 1816 StrictCompareInstr* compare = new StrictCompareInstr(
1812 call_->instance_call()->token_pos(), Token::kEQ_STRICT, 1817 call_->instance_call()->token_pos(), Token::kEQ_STRICT,
1813 new Value(load_cid), new Value(cid_constant), 1818 new Value(load_cid), new Value(cid_constant), false,
Vyacheslav Egorov (Google) 2017/05/23 12:00:02 /* number_check = */ false because comment moved
1814 false); // No number check. 1819 Thread::Current()->GetNextDeoptId()); // No number check.
Vyacheslav Egorov (Google) 2017/05/23 12:00:02 kNoDeoptId because StrictCompareInstr never deopts
1815 branch = new BranchInstr(compare); 1820 branch = new BranchInstr(compare, Thread::Current()->GetNextDeoptId());
Vyacheslav Egorov (Google) 2017/05/23 12:00:03 kNoDeoptId because InheritDeoptTarget below.
1816 } 1821 }
1817 1822
1818 branch->InheritDeoptTarget(zone(), call_); 1823 branch->InheritDeoptTarget(zone(), call_);
1819 cursor = AppendInstruction(cursor, branch); 1824 cursor = AppendInstruction(cursor, branch);
1820 current_block->set_last_instruction(branch); 1825 current_block->set_last_instruction(branch);
1821 cursor = NULL; 1826 cursor = NULL;
1822 1827
1823 // 2. Handle a match by linking to the inlined body. There are three 1828 // 2. Handle a match by linking to the inlined body. There are three
1824 // cases (unshared, shared first predecessor, and shared subsequent 1829 // cases (unshared, shared first predecessor, and shared subsequent
1825 // predecessors). 1830 // predecessors).
(...skipping 10 matching lines...) Expand all
1836 true_target = callee_entry->AsTargetEntry(); 1841 true_target = callee_entry->AsTargetEntry();
1837 BlockEntryInstr* join = true_target->last_instruction()->SuccessorAt(0); 1842 BlockEntryInstr* join = true_target->last_instruction()->SuccessorAt(0);
1838 current_block->AddDominatedBlock(join); 1843 current_block->AddDominatedBlock(join);
1839 } else { 1844 } else {
1840 // Shared inlined body and this is a subsequent entry. We have 1845 // Shared inlined body and this is a subsequent entry. We have
1841 // already constructed a join. We need a fresh target that jumps to 1846 // already constructed a join. We need a fresh target that jumps to
1842 // the join. 1847 // the join.
1843 JoinEntryInstr* join = callee_entry->AsJoinEntry(); 1848 JoinEntryInstr* join = callee_entry->AsJoinEntry();
1844 ASSERT(join != NULL); 1849 ASSERT(join != NULL);
1845 ASSERT(join->dominator() != NULL); 1850 ASSERT(join->dominator() != NULL);
1846 true_target = new TargetEntryInstr(AllocateBlockId(), try_idx); 1851 true_target = new TargetEntryInstr(AllocateBlockId(), try_idx,
1852 Thread::Current()->GetNextDeoptId());
Vyacheslav Egorov (Google) 2017/05/23 12:00:03 kNoDeoptId because InheritDeoptTarget below.
1847 true_target->InheritDeoptTarget(zone(), join); 1853 true_target->InheritDeoptTarget(zone(), join);
1848 GotoInstr* goto_join = new GotoInstr(join); 1854 GotoInstr* goto_join =
1855 new GotoInstr(join, Thread::Current()->GetNextDeoptId());
Vyacheslav Egorov (Google) 2017/05/23 12:00:02 kNoDeoptId because InheritDeoptTarget below.
1849 goto_join->InheritDeoptTarget(zone(), join); 1856 goto_join->InheritDeoptTarget(zone(), join);
1850 true_target->LinkTo(goto_join); 1857 true_target->LinkTo(goto_join);
1851 true_target->set_last_instruction(goto_join); 1858 true_target->set_last_instruction(goto_join);
1852 } 1859 }
1853 *branch->true_successor_address() = true_target; 1860 *branch->true_successor_address() = true_target;
1854 current_block->AddDominatedBlock(true_target); 1861 current_block->AddDominatedBlock(true_target);
1855 1862
1856 // 3. Prepare to handle a match failure on the next iteration or the 1863 // 3. Prepare to handle a match failure on the next iteration or the
1857 // fall-through code below for non-inlined variants. 1864 // fall-through code below for non-inlined variants.
1858 1865
1859 TargetEntryInstr* false_target = 1866 TargetEntryInstr* false_target = new TargetEntryInstr(
1860 new TargetEntryInstr(AllocateBlockId(), try_idx); 1867 AllocateBlockId(), try_idx, Thread::Current()->GetNextDeoptId());
Vyacheslav Egorov (Google) 2017/05/23 12:00:02 kNoDeoptId because InheritDeoptTarget below.
1861 false_target->InheritDeoptTarget(zone(), call_); 1868 false_target->InheritDeoptTarget(zone(), call_);
1862 *branch->false_successor_address() = false_target; 1869 *branch->false_successor_address() = false_target;
1863 cid_test_entry_block->AddDominatedBlock(false_target); 1870 cid_test_entry_block->AddDominatedBlock(false_target);
1864 1871
1865 cursor = current_block = false_target; 1872 cursor = current_block = false_target;
1866 1873
1867 if (test_is_range) { 1874 if (test_is_range) {
1868 // If we tested against a range of Cids there are two different tests 1875 // If we tested against a range of Cids there are two different tests
1869 // that can go to the no-cid-match target. 1876 // that can go to the no-cid-match target.
1870 JoinEntryInstr* join = new JoinEntryInstr(AllocateBlockId(), try_idx); 1877 JoinEntryInstr* join = new JoinEntryInstr(
1871 TargetEntryInstr* false_target2 = 1878 AllocateBlockId(), try_idx, Thread::Current()->GetNextDeoptId());
Vyacheslav Egorov (Google) 2017/05/23 12:00:02 kNoDeoptId because InheritDeoptTarget below.
1872 new TargetEntryInstr(AllocateBlockId(), try_idx); 1879 TargetEntryInstr* false_target2 = new TargetEntryInstr(
1880 AllocateBlockId(), try_idx, Thread::Current()->GetNextDeoptId());
Vyacheslav Egorov (Google) 2017/05/23 12:00:03 kNoDeoptId because InheritDeoptTarget below.
1873 *upper_limit_branch->false_successor_address() = false_target2; 1881 *upper_limit_branch->false_successor_address() = false_target2;
1874 cid_test_entry_block->AddDominatedBlock(false_target2); 1882 cid_test_entry_block->AddDominatedBlock(false_target2);
1875 cid_test_entry_block->AddDominatedBlock(join); 1883 cid_test_entry_block->AddDominatedBlock(join);
1876 GotoInstr* goto_1 = new GotoInstr(join); 1884 GotoInstr* goto_1 =
1877 GotoInstr* goto_2 = new GotoInstr(join); 1885 new GotoInstr(join, Thread::Current()->GetNextDeoptId());
Vyacheslav Egorov (Google) 2017/05/23 12:00:02 kNoDeoptId because InheritDeoptTarget below.
1886 GotoInstr* goto_2 =
1887 new GotoInstr(join, Thread::Current()->GetNextDeoptId());
Vyacheslav Egorov (Google) 2017/05/23 12:00:02 kNoDeoptId because InheritDeoptTarget below.
1878 false_target->LinkTo(goto_1); 1888 false_target->LinkTo(goto_1);
1879 false_target2->LinkTo(goto_2); 1889 false_target2->LinkTo(goto_2);
1880 false_target->set_last_instruction(goto_1); 1890 false_target->set_last_instruction(goto_1);
1881 false_target2->set_last_instruction(goto_2); 1891 false_target2->set_last_instruction(goto_2);
1882 1892
1883 join->InheritDeoptTarget(zone(), call_); 1893 join->InheritDeoptTarget(zone(), call_);
1884 false_target2->InheritDeoptTarget(zone(), call_); 1894 false_target2->InheritDeoptTarget(zone(), call_);
1885 goto_1->InheritDeoptTarget(zone(), call_); 1895 goto_1->InheritDeoptTarget(zone(), call_);
1886 goto_2->InheritDeoptTarget(zone(), call_); 1896 goto_2->InheritDeoptTarget(zone(), call_);
1887 1897
(...skipping 14 matching lines...) Expand all
1902 } 1912 }
1903 PolymorphicInstanceCallInstr* fallback_call = 1913 PolymorphicInstanceCallInstr* fallback_call =
1904 new PolymorphicInstanceCallInstr( 1914 new PolymorphicInstanceCallInstr(
1905 call_->instance_call(), *non_inlined_variants_, 1915 call_->instance_call(), *non_inlined_variants_,
1906 /* with_checks = */ true, call_->complete()); 1916 /* with_checks = */ true, call_->complete());
1907 fallback_call->set_ssa_temp_index( 1917 fallback_call->set_ssa_temp_index(
1908 owner_->caller_graph()->alloc_ssa_temp_index()); 1918 owner_->caller_graph()->alloc_ssa_temp_index());
1909 fallback_call->InheritDeoptTarget(zone(), call_); 1919 fallback_call->InheritDeoptTarget(zone(), call_);
1910 fallback_call->set_total_call_count(call_->CallCount()); 1920 fallback_call->set_total_call_count(call_->CallCount());
1911 ReturnInstr* fallback_return = new ReturnInstr( 1921 ReturnInstr* fallback_return = new ReturnInstr(
1912 call_->instance_call()->token_pos(), new Value(fallback_call)); 1922 call_->instance_call()->token_pos(), new Value(fallback_call),
1923 Thread::Current()->GetNextDeoptId());
Vyacheslav Egorov (Google) 2017/05/23 12:00:02 kNoDeoptId because InheritDeoptTarget below.
1913 fallback_return->InheritDeoptTargetAfter(owner_->caller_graph(), call_, 1924 fallback_return->InheritDeoptTargetAfter(owner_->caller_graph(), call_,
1914 fallback_call); 1925 fallback_call);
1915 AppendInstruction(AppendInstruction(cursor, fallback_call), 1926 AppendInstruction(AppendInstruction(cursor, fallback_call),
1916 fallback_return); 1927 fallback_return);
1917 exit_collector_->AddExit(fallback_return); 1928 exit_collector_->AddExit(fallback_return);
1918 cursor = NULL; 1929 cursor = NULL;
1919 } else { 1930 } else {
1920 if (follow_with_deopt) { 1931 if (follow_with_deopt) {
1921 DeoptimizeInstr* deopt = new DeoptimizeInstr( 1932 DeoptimizeInstr* deopt = new DeoptimizeInstr(
1922 ICData::kDeoptPolymorphicInstanceCallTestFail, call_->deopt_id()); 1933 ICData::kDeoptPolymorphicInstanceCallTestFail, call_->deopt_id());
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
2287 MethodRecognizer::Kind kind, 2298 MethodRecognizer::Kind kind,
2288 Instruction* call, 2299 Instruction* call,
2289 Definition* receiver, 2300 Definition* receiver,
2290 TargetEntryInstr** entry, 2301 TargetEntryInstr** entry,
2291 Definition** last) { 2302 Definition** last) {
2292 intptr_t array_cid = MethodRecognizer::MethodKindToReceiverCid(kind); 2303 intptr_t array_cid = MethodRecognizer::MethodKindToReceiverCid(kind);
2293 2304
2294 Definition* array = receiver; 2305 Definition* array = receiver;
2295 Definition* index = call->ArgumentAt(1); 2306 Definition* index = call->ArgumentAt(1);
2296 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), 2307 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(),
2297 call->GetBlock()->try_index()); 2308 call->GetBlock()->try_index(),
2309 Thread::Current()->GetNextDeoptId());
Vyacheslav Egorov (Google) 2017/05/23 12:00:01 kNoDeoptId because InheritDeoptTarget below.
2298 (*entry)->InheritDeoptTarget(Z, call); 2310 (*entry)->InheritDeoptTarget(Z, call);
2299 Instruction* cursor = *entry; 2311 Instruction* cursor = *entry;
2300 2312
2301 array_cid = PrepareInlineIndexedOp(flow_graph, call, array_cid, &array, index, 2313 array_cid = PrepareInlineIndexedOp(flow_graph, call, array_cid, &array, index,
2302 &cursor); 2314 &cursor);
2303 2315
2304 intptr_t deopt_id = Thread::kNoDeoptId; 2316 intptr_t deopt_id = Thread::kNoDeoptId;
2305 if ((array_cid == kTypedDataInt32ArrayCid) || 2317 if ((array_cid == kTypedDataInt32ArrayCid) ||
2306 (array_cid == kTypedDataUint32ArrayCid)) { 2318 (array_cid == kTypedDataUint32ArrayCid)) {
2307 // Deoptimization may be needed if result does not always fit in a Smi. 2319 // Deoptimization may be needed if result does not always fit in a Smi.
(...skipping 28 matching lines...) Expand all
2336 const Cids* value_check, 2348 const Cids* value_check,
2337 TargetEntryInstr** entry, 2349 TargetEntryInstr** entry,
2338 Definition** last) { 2350 Definition** last) {
2339 intptr_t array_cid = MethodRecognizer::MethodKindToReceiverCid(kind); 2351 intptr_t array_cid = MethodRecognizer::MethodKindToReceiverCid(kind);
2340 2352
2341 Definition* array = receiver; 2353 Definition* array = receiver;
2342 Definition* index = call->ArgumentAt(1); 2354 Definition* index = call->ArgumentAt(1);
2343 Definition* stored_value = call->ArgumentAt(2); 2355 Definition* stored_value = call->ArgumentAt(2);
2344 2356
2345 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), 2357 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(),
2346 call->GetBlock()->try_index()); 2358 call->GetBlock()->try_index(),
2359 Thread::Current()->GetNextDeoptId());
Vyacheslav Egorov (Google) 2017/05/23 12:00:02 kNoDeoptId because InheritDeoptTarget below.
2347 (*entry)->InheritDeoptTarget(Z, call); 2360 (*entry)->InheritDeoptTarget(Z, call);
2348 Instruction* cursor = *entry; 2361 Instruction* cursor = *entry;
2349 if (flow_graph->isolate()->type_checks()) { 2362 if (flow_graph->isolate()->type_checks()) {
2350 // Only type check for the value. A type check for the index is not 2363 // Only type check for the value. A type check for the index is not
2351 // needed here because we insert a deoptimizing smi-check for the case 2364 // needed here because we insert a deoptimizing smi-check for the case
2352 // the index is not a smi. 2365 // the index is not a smi.
2353 const AbstractType& value_type = 2366 const AbstractType& value_type =
2354 AbstractType::ZoneHandle(Z, target.ParameterTypeAt(2)); 2367 AbstractType::ZoneHandle(Z, target.ParameterTypeAt(2));
2355 Definition* type_args = NULL; 2368 Definition* type_args = NULL;
2356 switch (array_cid) { 2369 switch (array_cid) {
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
2473 Definition* receiver, 2486 Definition* receiver,
2474 TargetEntryInstr** entry, 2487 TargetEntryInstr** entry,
2475 Definition** last) { 2488 Definition** last) {
2476 if (!CanUnboxDouble()) { 2489 if (!CanUnboxDouble()) {
2477 return false; 2490 return false;
2478 } 2491 }
2479 Definition* left = receiver; 2492 Definition* left = receiver;
2480 Definition* right = call->ArgumentAt(1); 2493 Definition* right = call->ArgumentAt(1);
2481 2494
2482 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), 2495 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(),
2483 call->GetBlock()->try_index()); 2496 call->GetBlock()->try_index(),
2497 Thread::Current()->GetNextDeoptId());
Vyacheslav Egorov (Google) 2017/05/23 12:00:02 kNoDeoptId because InheritDeoptTarget below.
2484 (*entry)->InheritDeoptTarget(Z, call); 2498 (*entry)->InheritDeoptTarget(Z, call);
2485 // Arguments are checked. No need for class check. 2499 // Arguments are checked. No need for class check.
2486 BinaryDoubleOpInstr* double_bin_op = new (Z) 2500 BinaryDoubleOpInstr* double_bin_op = new (Z)
2487 BinaryDoubleOpInstr(op_kind, new (Z) Value(left), new (Z) Value(right), 2501 BinaryDoubleOpInstr(op_kind, new (Z) Value(left), new (Z) Value(right),
2488 call->deopt_id(), call->token_pos()); 2502 call->deopt_id(), call->token_pos());
2489 flow_graph->AppendTo(*entry, double_bin_op, call->env(), FlowGraph::kValue); 2503 flow_graph->AppendTo(*entry, double_bin_op, call->env(), FlowGraph::kValue);
2490 *last = double_bin_op; 2504 *last = double_bin_op;
2491 2505
2492 return true; 2506 return true;
2493 } 2507 }
2494 2508
2495 2509
2496 static bool InlineDoubleTestOp(FlowGraph* flow_graph, 2510 static bool InlineDoubleTestOp(FlowGraph* flow_graph,
2497 Instruction* call, 2511 Instruction* call,
2498 Definition* receiver, 2512 Definition* receiver,
2499 MethodRecognizer::Kind kind, 2513 MethodRecognizer::Kind kind,
2500 TargetEntryInstr** entry, 2514 TargetEntryInstr** entry,
2501 Definition** last) { 2515 Definition** last) {
2502 if (!CanUnboxDouble()) { 2516 if (!CanUnboxDouble()) {
2503 return false; 2517 return false;
2504 } 2518 }
2505 2519
2506 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), 2520 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(),
2507 call->GetBlock()->try_index()); 2521 call->GetBlock()->try_index(),
2522 Thread::Current()->GetNextDeoptId());
Vyacheslav Egorov (Google) 2017/05/23 12:00:03 kNoDeoptId because InheritDeoptTarget below.
2508 (*entry)->InheritDeoptTarget(Z, call); 2523 (*entry)->InheritDeoptTarget(Z, call);
2509 // Arguments are checked. No need for class check. 2524 // Arguments are checked. No need for class check.
2510 2525
2511 DoubleTestOpInstr* double_test_op = new (Z) DoubleTestOpInstr( 2526 DoubleTestOpInstr* double_test_op = new (Z) DoubleTestOpInstr(
2512 kind, new (Z) Value(receiver), call->deopt_id(), call->token_pos()); 2527 kind, new (Z) Value(receiver), call->deopt_id(), call->token_pos());
2513 flow_graph->AppendTo(*entry, double_test_op, call->env(), FlowGraph::kValue); 2528 flow_graph->AppendTo(*entry, double_test_op, call->env(), FlowGraph::kValue);
2514 *last = double_test_op; 2529 *last = double_test_op;
2515 2530
2516 return true; 2531 return true;
2517 } 2532 }
2518 2533
2519 2534
2520 static bool InlineSmiBitAndFromSmi(FlowGraph* flow_graph, 2535 static bool InlineSmiBitAndFromSmi(FlowGraph* flow_graph,
2521 Instruction* call, 2536 Instruction* call,
2522 Definition* receiver, 2537 Definition* receiver,
2523 TargetEntryInstr** entry, 2538 TargetEntryInstr** entry,
2524 Definition** last) { 2539 Definition** last) {
2525 Definition* left = receiver; 2540 Definition* left = receiver;
2526 Definition* right = call->ArgumentAt(1); 2541 Definition* right = call->ArgumentAt(1);
2527 2542
2528 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), 2543 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(),
2529 call->GetBlock()->try_index()); 2544 call->GetBlock()->try_index(),
2545 Thread::Current()->GetNextDeoptId());
Vyacheslav Egorov (Google) 2017/05/23 12:00:01 kNoDeoptId because InheritDeoptTarget below.
2530 (*entry)->InheritDeoptTarget(Z, call); 2546 (*entry)->InheritDeoptTarget(Z, call);
2531 // Right arguments is known to be smi: other._bitAndFromSmi(this); 2547 // Right arguments is known to be smi: other._bitAndFromSmi(this);
2532 BinarySmiOpInstr* smi_op = 2548 BinarySmiOpInstr* smi_op =
2533 new (Z) BinarySmiOpInstr(Token::kBIT_AND, new (Z) Value(left), 2549 new (Z) BinarySmiOpInstr(Token::kBIT_AND, new (Z) Value(left),
2534 new (Z) Value(right), call->deopt_id()); 2550 new (Z) Value(right), call->deopt_id());
2535 flow_graph->AppendTo(*entry, smi_op, call->env(), FlowGraph::kValue); 2551 flow_graph->AppendTo(*entry, smi_op, call->env(), FlowGraph::kValue);
2536 *last = smi_op; 2552 *last = smi_op;
2537 2553
2538 return true; 2554 return true;
2539 } 2555 }
2540 2556
2541 2557
2542 static bool InlineGrowableArraySetter(FlowGraph* flow_graph, 2558 static bool InlineGrowableArraySetter(FlowGraph* flow_graph,
2543 intptr_t offset, 2559 intptr_t offset,
2544 StoreBarrierType store_barrier_type, 2560 StoreBarrierType store_barrier_type,
2545 Instruction* call, 2561 Instruction* call,
2546 Definition* receiver, 2562 Definition* receiver,
2547 TargetEntryInstr** entry, 2563 TargetEntryInstr** entry,
2548 Definition** last) { 2564 Definition** last) {
2549 Definition* array = receiver; 2565 Definition* array = receiver;
2550 Definition* value = call->ArgumentAt(1); 2566 Definition* value = call->ArgumentAt(1);
2551 2567
2552 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), 2568 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(),
2553 call->GetBlock()->try_index()); 2569 call->GetBlock()->try_index(),
2570 Thread::Current()->GetNextDeoptId());
Vyacheslav Egorov (Google) 2017/05/23 12:00:03 kNoDeoptId because InheritDeoptTarget below.
2554 (*entry)->InheritDeoptTarget(Z, call); 2571 (*entry)->InheritDeoptTarget(Z, call);
2555 2572
2556 // This is an internal method, no need to check argument types. 2573 // This is an internal method, no need to check argument types.
2557 StoreInstanceFieldInstr* store = new (Z) StoreInstanceFieldInstr( 2574 StoreInstanceFieldInstr* store = new (Z) StoreInstanceFieldInstr(
2558 offset, new (Z) Value(array), new (Z) Value(value), store_barrier_type, 2575 offset, new (Z) Value(array), new (Z) Value(value), store_barrier_type,
2559 call->token_pos()); 2576 call->token_pos());
2560 flow_graph->AppendTo(*entry, store, call->env(), FlowGraph::kEffect); 2577 flow_graph->AppendTo(*entry, store, call->env(), FlowGraph::kEffect);
2561 *last = store; 2578 *last = store;
2562 2579
2563 return true; 2580 return true;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
2629 Instruction* call, 2646 Instruction* call,
2630 Definition* receiver, 2647 Definition* receiver,
2631 intptr_t array_cid, 2648 intptr_t array_cid,
2632 intptr_t view_cid, 2649 intptr_t view_cid,
2633 TargetEntryInstr** entry, 2650 TargetEntryInstr** entry,
2634 Definition** last) { 2651 Definition** last) {
2635 ASSERT(array_cid != kIllegalCid); 2652 ASSERT(array_cid != kIllegalCid);
2636 Definition* array = receiver; 2653 Definition* array = receiver;
2637 Definition* index = call->ArgumentAt(1); 2654 Definition* index = call->ArgumentAt(1);
2638 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), 2655 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(),
2639 call->GetBlock()->try_index()); 2656 call->GetBlock()->try_index(),
2657 Thread::Current()->GetNextDeoptId());
Vyacheslav Egorov (Google) 2017/05/23 12:00:02 kNoDeoptId because InheritDeoptTarget below.
2640 (*entry)->InheritDeoptTarget(Z, call); 2658 (*entry)->InheritDeoptTarget(Z, call);
2641 Instruction* cursor = *entry; 2659 Instruction* cursor = *entry;
2642 2660
2643 PrepareInlineByteArrayBaseOp(flow_graph, call, array_cid, view_cid, &array, 2661 PrepareInlineByteArrayBaseOp(flow_graph, call, array_cid, view_cid, &array,
2644 index, &cursor); 2662 index, &cursor);
2645 2663
2646 intptr_t deopt_id = Thread::kNoDeoptId; 2664 intptr_t deopt_id = Thread::kNoDeoptId;
2647 if ((array_cid == kTypedDataInt32ArrayCid) || 2665 if ((array_cid == kTypedDataInt32ArrayCid) ||
2648 (array_cid == kTypedDataUint32ArrayCid)) { 2666 (array_cid == kTypedDataUint32ArrayCid)) {
2649 // Deoptimization may be needed if result does not always fit in a Smi. 2667 // Deoptimization may be needed if result does not always fit in a Smi.
(...skipping 22 matching lines...) Expand all
2672 Instruction* call, 2690 Instruction* call,
2673 Definition* receiver, 2691 Definition* receiver,
2674 intptr_t array_cid, 2692 intptr_t array_cid,
2675 intptr_t view_cid, 2693 intptr_t view_cid,
2676 TargetEntryInstr** entry, 2694 TargetEntryInstr** entry,
2677 Definition** last) { 2695 Definition** last) {
2678 ASSERT(array_cid != kIllegalCid); 2696 ASSERT(array_cid != kIllegalCid);
2679 Definition* array = receiver; 2697 Definition* array = receiver;
2680 Definition* index = call->ArgumentAt(1); 2698 Definition* index = call->ArgumentAt(1);
2681 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), 2699 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(),
2682 call->GetBlock()->try_index()); 2700 call->GetBlock()->try_index(),
2701 Thread::Current()->GetNextDeoptId());
Vyacheslav Egorov (Google) 2017/05/23 12:00:02 kNoDeoptId because InheritDeoptTarget below.
2683 (*entry)->InheritDeoptTarget(Z, call); 2702 (*entry)->InheritDeoptTarget(Z, call);
2684 Instruction* cursor = *entry; 2703 Instruction* cursor = *entry;
2685 2704
2686 PrepareInlineByteArrayBaseOp(flow_graph, call, array_cid, view_cid, &array, 2705 PrepareInlineByteArrayBaseOp(flow_graph, call, array_cid, view_cid, &array,
2687 index, &cursor); 2706 index, &cursor);
2688 2707
2689 // Extract the instance call so we can use the function_name in the stored 2708 // Extract the instance call so we can use the function_name in the stored
2690 // value check ICData. 2709 // value check ICData.
2691 InstanceCallInstr* i_call = NULL; 2710 InstanceCallInstr* i_call = NULL;
2692 if (call->IsPolymorphicInstanceCall()) { 2711 if (call->IsPolymorphicInstanceCall()) {
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
2838 intptr_t cid, 2857 intptr_t cid,
2839 TargetEntryInstr** entry, 2858 TargetEntryInstr** entry,
2840 Definition** last) { 2859 Definition** last) {
2841 if ((cid != kOneByteStringCid) && (cid != kExternalOneByteStringCid)) { 2860 if ((cid != kOneByteStringCid) && (cid != kExternalOneByteStringCid)) {
2842 return false; 2861 return false;
2843 } 2862 }
2844 Definition* str = receiver; 2863 Definition* str = receiver;
2845 Definition* index = call->ArgumentAt(1); 2864 Definition* index = call->ArgumentAt(1);
2846 2865
2847 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), 2866 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(),
2848 call->GetBlock()->try_index()); 2867 call->GetBlock()->try_index(),
2868 Thread::Current()->GetNextDeoptId());
Vyacheslav Egorov (Google) 2017/05/23 12:00:01 kNoDeoptId because InheritDeoptTarget below.
2849 (*entry)->InheritDeoptTarget(Z, call); 2869 (*entry)->InheritDeoptTarget(Z, call);
2850 2870
2851 *last = PrepareInlineStringIndexOp(flow_graph, call, cid, str, index, *entry); 2871 *last = PrepareInlineStringIndexOp(flow_graph, call, cid, str, index, *entry);
2852 2872
2853 OneByteStringFromCharCodeInstr* char_at = 2873 OneByteStringFromCharCodeInstr* char_at =
2854 new (Z) OneByteStringFromCharCodeInstr(new (Z) Value(*last)); 2874 new (Z) OneByteStringFromCharCodeInstr(new (Z) Value(*last));
2855 2875
2856 flow_graph->AppendTo(*last, char_at, NULL, FlowGraph::kValue); 2876 flow_graph->AppendTo(*last, char_at, NULL, FlowGraph::kValue);
2857 *last = char_at; 2877 *last = char_at;
2858 2878
2859 return true; 2879 return true;
2860 } 2880 }
2861 2881
2862 2882
2863 static bool InlineStringCodeUnitAt(FlowGraph* flow_graph, 2883 static bool InlineStringCodeUnitAt(FlowGraph* flow_graph,
2864 Instruction* call, 2884 Instruction* call,
2865 Definition* receiver, 2885 Definition* receiver,
2866 intptr_t cid, 2886 intptr_t cid,
2867 TargetEntryInstr** entry, 2887 TargetEntryInstr** entry,
2868 Definition** last) { 2888 Definition** last) {
2869 ASSERT((cid == kOneByteStringCid) || (cid == kTwoByteStringCid) || 2889 ASSERT((cid == kOneByteStringCid) || (cid == kTwoByteStringCid) ||
2870 (cid == kExternalOneByteStringCid) || 2890 (cid == kExternalOneByteStringCid) ||
2871 (cid == kExternalTwoByteStringCid)); 2891 (cid == kExternalTwoByteStringCid));
2872 Definition* str = receiver; 2892 Definition* str = receiver;
2873 Definition* index = call->ArgumentAt(1); 2893 Definition* index = call->ArgumentAt(1);
2874 2894
2875 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), 2895 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(),
2876 call->GetBlock()->try_index()); 2896 call->GetBlock()->try_index(),
2897 Thread::Current()->GetNextDeoptId());
Vyacheslav Egorov (Google) 2017/05/23 12:00:02 kNoDeoptId because InheritDeoptTarget below.
2877 (*entry)->InheritDeoptTarget(Z, call); 2898 (*entry)->InheritDeoptTarget(Z, call);
2878 2899
2879 *last = PrepareInlineStringIndexOp(flow_graph, call, cid, str, index, *entry); 2900 *last = PrepareInlineStringIndexOp(flow_graph, call, cid, str, index, *entry);
2880 2901
2881 return true; 2902 return true;
2882 } 2903 }
2883 2904
2884 2905
2885 // Only used for monomorphic calls. 2906 // Only used for monomorphic calls.
2886 bool FlowGraphInliner::TryReplaceInstanceCallWithInline( 2907 bool FlowGraphInliner::TryReplaceInstanceCallWithInline(
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
2979 Instruction* call, 3000 Instruction* call,
2980 Definition* receiver, 3001 Definition* receiver,
2981 MethodRecognizer::Kind kind, 3002 MethodRecognizer::Kind kind,
2982 TargetEntryInstr** entry, 3003 TargetEntryInstr** entry,
2983 Definition** last) { 3004 Definition** last) {
2984 if (!ShouldInlineSimd()) { 3005 if (!ShouldInlineSimd()) {
2985 return false; 3006 return false;
2986 } 3007 }
2987 3008
2988 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), 3009 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(),
2989 call->GetBlock()->try_index()); 3010 call->GetBlock()->try_index(),
3011 Thread::Current()->GetNextDeoptId());
Vyacheslav Egorov (Google) 2017/05/23 12:00:03 kNoDeoptId because InheritDeoptTarget below.
2990 (*entry)->InheritDeoptTarget(Z, call); 3012 (*entry)->InheritDeoptTarget(Z, call);
2991 Instruction* cursor = *entry; 3013 Instruction* cursor = *entry;
2992 switch (kind) { 3014 switch (kind) {
2993 case MethodRecognizer::kFloat32x4ShuffleX: 3015 case MethodRecognizer::kFloat32x4ShuffleX:
2994 case MethodRecognizer::kFloat32x4ShuffleY: 3016 case MethodRecognizer::kFloat32x4ShuffleY:
2995 case MethodRecognizer::kFloat32x4ShuffleZ: 3017 case MethodRecognizer::kFloat32x4ShuffleZ:
2996 case MethodRecognizer::kFloat32x4ShuffleW: { 3018 case MethodRecognizer::kFloat32x4ShuffleW: {
2997 *last = new (Z) Simd32x4ShuffleInstr(kind, new (Z) Value(receiver), 3019 *last = new (Z) Simd32x4ShuffleInstr(kind, new (Z) Value(receiver),
2998 0, // mask ignored. 3020 0, // mask ignored.
2999 call->deopt_id()); 3021 call->deopt_id());
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
3097 static bool InlineSimdShuffleMethod(FlowGraph* flow_graph, 3119 static bool InlineSimdShuffleMethod(FlowGraph* flow_graph,
3098 Instruction* call, 3120 Instruction* call,
3099 Definition* receiver, 3121 Definition* receiver,
3100 MethodRecognizer::Kind kind, 3122 MethodRecognizer::Kind kind,
3101 TargetEntryInstr** entry, 3123 TargetEntryInstr** entry,
3102 Definition** last) { 3124 Definition** last) {
3103 if (!ShouldInlineSimd()) { 3125 if (!ShouldInlineSimd()) {
3104 return false; 3126 return false;
3105 } 3127 }
3106 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), 3128 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(),
3107 call->GetBlock()->try_index()); 3129 call->GetBlock()->try_index(),
3130 Thread::Current()->GetNextDeoptId());
Vyacheslav Egorov (Google) 2017/05/23 12:00:03 kNoDeoptId because InheritDeoptTarget below.
3108 (*entry)->InheritDeoptTarget(Z, call); 3131 (*entry)->InheritDeoptTarget(Z, call);
3109 Instruction* cursor = *entry; 3132 Instruction* cursor = *entry;
3110 Definition* mask_definition = call->ArgumentAt(1); 3133 Definition* mask_definition = call->ArgumentAt(1);
3111 intptr_t mask = 0; 3134 intptr_t mask = 0;
3112 if (!CheckMask(mask_definition, &mask)) { 3135 if (!CheckMask(mask_definition, &mask)) {
3113 return false; 3136 return false;
3114 } 3137 }
3115 *last = new (Z) Simd32x4ShuffleInstr(kind, new (Z) Value(call->ArgumentAt(0)), 3138 *last = new (Z) Simd32x4ShuffleInstr(kind, new (Z) Value(call->ArgumentAt(0)),
3116 mask, call->deopt_id()); 3139 mask, call->deopt_id());
3117 flow_graph->AppendTo( 3140 flow_graph->AppendTo(
3118 cursor, *last, 3141 cursor, *last,
3119 call->deopt_id() != Thread::kNoDeoptId ? call->env() : NULL, 3142 call->deopt_id() != Thread::kNoDeoptId ? call->env() : NULL,
3120 FlowGraph::kValue); 3143 FlowGraph::kValue);
3121 return true; 3144 return true;
3122 } 3145 }
3123 3146
3124 3147
3125 static bool InlineSimdShuffleMixMethod(FlowGraph* flow_graph, 3148 static bool InlineSimdShuffleMixMethod(FlowGraph* flow_graph,
3126 Instruction* call, 3149 Instruction* call,
3127 Definition* receiver, 3150 Definition* receiver,
3128 MethodRecognizer::Kind kind, 3151 MethodRecognizer::Kind kind,
3129 TargetEntryInstr** entry, 3152 TargetEntryInstr** entry,
3130 Definition** last) { 3153 Definition** last) {
3131 if (!ShouldInlineSimd()) { 3154 if (!ShouldInlineSimd()) {
3132 return false; 3155 return false;
3133 } 3156 }
3134 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), 3157 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(),
3135 call->GetBlock()->try_index()); 3158 call->GetBlock()->try_index(),
3159 Thread::Current()->GetNextDeoptId());
Vyacheslav Egorov (Google) 2017/05/23 12:00:01 kNoDeoptId because InheritDeoptTarget below.
3136 (*entry)->InheritDeoptTarget(Z, call); 3160 (*entry)->InheritDeoptTarget(Z, call);
3137 Instruction* cursor = *entry; 3161 Instruction* cursor = *entry;
3138 Definition* mask_definition = call->ArgumentAt(2); 3162 Definition* mask_definition = call->ArgumentAt(2);
3139 intptr_t mask = 0; 3163 intptr_t mask = 0;
3140 if (!CheckMask(mask_definition, &mask)) { 3164 if (!CheckMask(mask_definition, &mask)) {
3141 return false; 3165 return false;
3142 } 3166 }
3143 *last = new (Z) Simd32x4ShuffleMixInstr(kind, new (Z) Value(receiver), 3167 *last = new (Z) Simd32x4ShuffleMixInstr(kind, new (Z) Value(receiver),
3144 new (Z) Value(call->ArgumentAt(1)), 3168 new (Z) Value(call->ArgumentAt(1)),
3145 mask, call->deopt_id()); 3169 mask, call->deopt_id());
3146 flow_graph->AppendTo( 3170 flow_graph->AppendTo(
3147 cursor, *last, 3171 cursor, *last,
3148 call->deopt_id() != Thread::kNoDeoptId ? call->env() : NULL, 3172 call->deopt_id() != Thread::kNoDeoptId ? call->env() : NULL,
3149 FlowGraph::kValue); 3173 FlowGraph::kValue);
3150 return true; 3174 return true;
3151 } 3175 }
3152 3176
3153 3177
3154 static bool InlineInt32x4Method(FlowGraph* flow_graph, 3178 static bool InlineInt32x4Method(FlowGraph* flow_graph,
3155 Instruction* call, 3179 Instruction* call,
3156 Definition* receiver, 3180 Definition* receiver,
3157 MethodRecognizer::Kind kind, 3181 MethodRecognizer::Kind kind,
3158 TargetEntryInstr** entry, 3182 TargetEntryInstr** entry,
3159 Definition** last) { 3183 Definition** last) {
3160 if (!ShouldInlineSimd()) { 3184 if (!ShouldInlineSimd()) {
3161 return false; 3185 return false;
3162 } 3186 }
3163 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), 3187 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(),
3164 call->GetBlock()->try_index()); 3188 call->GetBlock()->try_index(),
3189 Thread::Current()->GetNextDeoptId());
Vyacheslav Egorov (Google) 2017/05/23 12:00:01 kNoDeoptId because InheritDeoptTarget below.
3165 (*entry)->InheritDeoptTarget(Z, call); 3190 (*entry)->InheritDeoptTarget(Z, call);
3166 Instruction* cursor = *entry; 3191 Instruction* cursor = *entry;
3167 switch (kind) { 3192 switch (kind) {
3168 case MethodRecognizer::kInt32x4GetFlagX: 3193 case MethodRecognizer::kInt32x4GetFlagX:
3169 case MethodRecognizer::kInt32x4GetFlagY: 3194 case MethodRecognizer::kInt32x4GetFlagY:
3170 case MethodRecognizer::kInt32x4GetFlagZ: 3195 case MethodRecognizer::kInt32x4GetFlagZ:
3171 case MethodRecognizer::kInt32x4GetFlagW: { 3196 case MethodRecognizer::kInt32x4GetFlagW: {
3172 *last = new (Z) 3197 *last = new (Z)
3173 Int32x4GetFlagInstr(kind, new (Z) Value(receiver), call->deopt_id()); 3198 Int32x4GetFlagInstr(kind, new (Z) Value(receiver), call->deopt_id());
3174 break; 3199 break;
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
3210 static bool InlineFloat64x2Method(FlowGraph* flow_graph, 3235 static bool InlineFloat64x2Method(FlowGraph* flow_graph,
3211 Instruction* call, 3236 Instruction* call,
3212 Definition* receiver, 3237 Definition* receiver,
3213 MethodRecognizer::Kind kind, 3238 MethodRecognizer::Kind kind,
3214 TargetEntryInstr** entry, 3239 TargetEntryInstr** entry,
3215 Definition** last) { 3240 Definition** last) {
3216 if (!ShouldInlineSimd()) { 3241 if (!ShouldInlineSimd()) {
3217 return false; 3242 return false;
3218 } 3243 }
3219 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), 3244 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(),
3220 call->GetBlock()->try_index()); 3245 call->GetBlock()->try_index(),
3246 Thread::Current()->GetNextDeoptId());
Vyacheslav Egorov (Google) 2017/05/23 12:00:03 kNoDeoptId because InheritDeoptTarget below.
3221 (*entry)->InheritDeoptTarget(Z, call); 3247 (*entry)->InheritDeoptTarget(Z, call);
3222 Instruction* cursor = *entry; 3248 Instruction* cursor = *entry;
3223 switch (kind) { 3249 switch (kind) {
3224 case MethodRecognizer::kFloat64x2GetX: 3250 case MethodRecognizer::kFloat64x2GetX:
3225 case MethodRecognizer::kFloat64x2GetY: { 3251 case MethodRecognizer::kFloat64x2GetY: {
3226 *last = new (Z) Simd64x2ShuffleInstr(kind, new (Z) Value(receiver), 3252 *last = new (Z) Simd64x2ShuffleInstr(kind, new (Z) Value(receiver),
3227 0, // mask is ignored. 3253 0, // mask is ignored.
3228 call->deopt_id()); 3254 call->deopt_id());
3229 break; 3255 break;
3230 } 3256 }
(...skipping 30 matching lines...) Expand all
3261 3287
3262 static bool InlineSimdConstructor(FlowGraph* flow_graph, 3288 static bool InlineSimdConstructor(FlowGraph* flow_graph,
3263 Instruction* call, 3289 Instruction* call,
3264 MethodRecognizer::Kind kind, 3290 MethodRecognizer::Kind kind,
3265 TargetEntryInstr** entry, 3291 TargetEntryInstr** entry,
3266 Definition** last) { 3292 Definition** last) {
3267 if (!ShouldInlineSimd()) { 3293 if (!ShouldInlineSimd()) {
3268 return false; 3294 return false;
3269 } 3295 }
3270 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), 3296 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(),
3271 call->GetBlock()->try_index()); 3297 call->GetBlock()->try_index(),
3298 Thread::Current()->GetNextDeoptId());
Vyacheslav Egorov (Google) 2017/05/23 12:00:02 kNoDeoptId because InheritDeoptTarget below. same
3272 (*entry)->InheritDeoptTarget(Z, call); 3299 (*entry)->InheritDeoptTarget(Z, call);
3273 Instruction* cursor = *entry; 3300 Instruction* cursor = *entry;
3274 switch (kind) { 3301 switch (kind) {
3275 case MethodRecognizer::kFloat32x4Zero: 3302 case MethodRecognizer::kFloat32x4Zero:
3276 *last = new (Z) Float32x4ZeroInstr(); 3303 *last = new (Z) Float32x4ZeroInstr();
3277 break; 3304 break;
3278 case MethodRecognizer::kFloat32x4Splat: 3305 case MethodRecognizer::kFloat32x4Splat:
3279 *last = new (Z) Float32x4SplatInstr(new (Z) Value(call->ArgumentAt(1)), 3306 *last = new (Z) Float32x4SplatInstr(new (Z) Value(call->ArgumentAt(1)),
3280 call->deopt_id()); 3307 call->deopt_id());
3281 break; 3308 break;
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
3342 3369
3343 static bool InlineMathCFunction(FlowGraph* flow_graph, 3370 static bool InlineMathCFunction(FlowGraph* flow_graph,
3344 Instruction* call, 3371 Instruction* call,
3345 MethodRecognizer::Kind kind, 3372 MethodRecognizer::Kind kind,
3346 TargetEntryInstr** entry, 3373 TargetEntryInstr** entry,
3347 Definition** last) { 3374 Definition** last) {
3348 if (!CanUnboxDouble()) { 3375 if (!CanUnboxDouble()) {
3349 return false; 3376 return false;
3350 } 3377 }
3351 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), 3378 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(),
3352 call->GetBlock()->try_index()); 3379 call->GetBlock()->try_index(),
3380 Thread::Current()->GetNextDeoptId());
3353 (*entry)->InheritDeoptTarget(Z, call); 3381 (*entry)->InheritDeoptTarget(Z, call);
3354 Instruction* cursor = *entry; 3382 Instruction* cursor = *entry;
3355 3383
3356 switch (kind) { 3384 switch (kind) {
3357 case MethodRecognizer::kMathSqrt: { 3385 case MethodRecognizer::kMathSqrt: {
3358 *last = new (Z) 3386 *last = new (Z)
3359 MathUnaryInstr(MathUnaryInstr::kSqrt, 3387 MathUnaryInstr(MathUnaryInstr::kSqrt,
3360 new (Z) Value(call->ArgumentAt(0)), call->deopt_id()); 3388 new (Z) Value(call->ArgumentAt(0)), call->deopt_id());
3361 break; 3389 break;
3362 } 3390 }
(...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
3704 case MethodRecognizer::kMathCos: 3732 case MethodRecognizer::kMathCos:
3705 case MethodRecognizer::kMathTan: 3733 case MethodRecognizer::kMathTan:
3706 case MethodRecognizer::kMathAsin: 3734 case MethodRecognizer::kMathAsin:
3707 case MethodRecognizer::kMathAcos: 3735 case MethodRecognizer::kMathAcos:
3708 case MethodRecognizer::kMathAtan: 3736 case MethodRecognizer::kMathAtan:
3709 case MethodRecognizer::kMathAtan2: 3737 case MethodRecognizer::kMathAtan2:
3710 return InlineMathCFunction(flow_graph, call, kind, entry, last); 3738 return InlineMathCFunction(flow_graph, call, kind, entry, last);
3711 3739
3712 case MethodRecognizer::kObjectConstructor: { 3740 case MethodRecognizer::kObjectConstructor: {
3713 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), 3741 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(),
3714 call->GetBlock()->try_index()); 3742 call->GetBlock()->try_index(),
3743 Thread::Current()->GetNextDeoptId());
3715 (*entry)->InheritDeoptTarget(Z, call); 3744 (*entry)->InheritDeoptTarget(Z, call);
3716 ASSERT(!call->HasUses()); 3745 ASSERT(!call->HasUses());
3717 *last = NULL; // Empty body. 3746 *last = NULL; // Empty body.
3718 return true; 3747 return true;
3719 } 3748 }
3720 3749
3721 case MethodRecognizer::kObjectArrayAllocate: { 3750 case MethodRecognizer::kObjectArrayAllocate: {
3722 Value* num_elements = new (Z) Value(call->ArgumentAt(1)); 3751 Value* num_elements = new (Z) Value(call->ArgumentAt(1));
3723 if (num_elements->BindsToConstant() && 3752 if (num_elements->BindsToConstant() &&
3724 num_elements->BoundConstant().IsSmi()) { 3753 num_elements->BoundConstant().IsSmi()) {
3725 intptr_t length = Smi::Cast(num_elements->BoundConstant()).Value(); 3754 intptr_t length = Smi::Cast(num_elements->BoundConstant()).Value();
3726 if (length >= 0 && length <= Array::kMaxElements) { 3755 if (length >= 0 && length <= Array::kMaxElements) {
3727 Value* type = new (Z) Value(call->ArgumentAt(0)); 3756 Value* type = new (Z) Value(call->ArgumentAt(0));
3728 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), 3757 *entry = new (Z) TargetEntryInstr(
3729 call->GetBlock()->try_index()); 3758 flow_graph->allocate_block_id(), call->GetBlock()->try_index(),
3759 Thread::Current()->GetNextDeoptId());
3730 (*entry)->InheritDeoptTarget(Z, call); 3760 (*entry)->InheritDeoptTarget(Z, call);
3731 *last = 3761 *last =
3732 new (Z) CreateArrayInstr(call->token_pos(), type, num_elements); 3762 new (Z) CreateArrayInstr(call->token_pos(), type, num_elements,
3763 Thread::Current()->GetNextDeoptId());
3733 flow_graph->AppendTo( 3764 flow_graph->AppendTo(
3734 *entry, *last, 3765 *entry, *last,
3735 call->deopt_id() != Thread::kNoDeoptId ? call->env() : NULL, 3766 call->deopt_id() != Thread::kNoDeoptId ? call->env() : NULL,
3736 FlowGraph::kValue); 3767 FlowGraph::kValue);
3737 return true; 3768 return true;
3738 } 3769 }
3739 } 3770 }
3740 return false; 3771 return false;
3741 } 3772 }
3742 3773
3743 case MethodRecognizer::kObjectRuntimeType: { 3774 case MethodRecognizer::kObjectRuntimeType: {
3744 Type& type = Type::ZoneHandle(Z); 3775 Type& type = Type::ZoneHandle(Z);
3745 if (RawObject::IsStringClassId(receiver_cid)) { 3776 if (RawObject::IsStringClassId(receiver_cid)) {
3746 type = Type::StringType(); 3777 type = Type::StringType();
3747 } else if (receiver_cid == kDoubleCid) { 3778 } else if (receiver_cid == kDoubleCid) {
3748 type = Type::Double(); 3779 type = Type::Double();
3749 } else if (RawObject::IsIntegerClassId(receiver_cid)) { 3780 } else if (RawObject::IsIntegerClassId(receiver_cid)) {
3750 type = Type::IntType(); 3781 type = Type::IntType();
3751 } else if (receiver_cid != kClosureCid) { 3782 } else if (receiver_cid != kClosureCid) {
3752 const Class& cls = Class::Handle( 3783 const Class& cls = Class::Handle(
3753 Z, flow_graph->isolate()->class_table()->At(receiver_cid)); 3784 Z, flow_graph->isolate()->class_table()->At(receiver_cid));
3754 if (!cls.IsGeneric()) { 3785 if (!cls.IsGeneric()) {
3755 type = cls.CanonicalType(); 3786 type = cls.CanonicalType();
3756 } 3787 }
3757 } 3788 }
3758 3789
3759 if (!type.IsNull()) { 3790 if (!type.IsNull()) {
3760 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), 3791 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(),
3761 call->GetBlock()->try_index()); 3792 call->GetBlock()->try_index(),
3793 Thread::Current()->GetNextDeoptId());
3762 (*entry)->InheritDeoptTarget(Z, call); 3794 (*entry)->InheritDeoptTarget(Z, call);
3763 *last = new (Z) ConstantInstr(type); 3795 *last = new (Z) ConstantInstr(type);
3764 flow_graph->AppendTo( 3796 flow_graph->AppendTo(
3765 *entry, *last, 3797 *entry, *last,
3766 call->deopt_id() != Thread::kNoDeoptId ? call->env() : NULL, 3798 call->deopt_id() != Thread::kNoDeoptId ? call->env() : NULL,
3767 FlowGraph::kValue); 3799 FlowGraph::kValue);
3768 return true; 3800 return true;
3769 } 3801 }
3770 return false; 3802 return false;
3771 } 3803 }
3772 3804
3773 case MethodRecognizer::kOneByteStringSetAt: { 3805 case MethodRecognizer::kOneByteStringSetAt: {
3774 // This is an internal method, no need to check argument types nor 3806 // This is an internal method, no need to check argument types nor
3775 // range. 3807 // range.
3776 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(), 3808 *entry = new (Z) TargetEntryInstr(flow_graph->allocate_block_id(),
3777 call->GetBlock()->try_index()); 3809 call->GetBlock()->try_index(),
3810 Thread::Current()->GetNextDeoptId());
3778 (*entry)->InheritDeoptTarget(Z, call); 3811 (*entry)->InheritDeoptTarget(Z, call);
3779 Definition* str = call->ArgumentAt(0); 3812 Definition* str = call->ArgumentAt(0);
3780 Definition* index = call->ArgumentAt(1); 3813 Definition* index = call->ArgumentAt(1);
3781 Definition* value = call->ArgumentAt(2); 3814 Definition* value = call->ArgumentAt(2);
3782 *last = 3815 *last =
3783 new (Z) StoreIndexedInstr(new (Z) Value(str), new (Z) Value(index), 3816 new (Z) StoreIndexedInstr(new (Z) Value(str), new (Z) Value(index),
3784 new (Z) Value(value), kNoStoreBarrier, 3817 new (Z) Value(value), kNoStoreBarrier,
3785 1, // Index scale 3818 1, // Index scale
3786 kOneByteStringCid, kAlignedAccess, 3819 kOneByteStringCid, kAlignedAccess,
3787 call->deopt_id(), call->token_pos()); 3820 call->deopt_id(), call->token_pos());
3788 flow_graph->AppendTo( 3821 flow_graph->AppendTo(
3789 *entry, *last, 3822 *entry, *last,
3790 call->deopt_id() != Thread::kNoDeoptId ? call->env() : NULL, 3823 call->deopt_id() != Thread::kNoDeoptId ? call->env() : NULL,
3791 FlowGraph::kEffect); 3824 FlowGraph::kEffect);
3792 return true; 3825 return true;
3793 } 3826 }
3794 3827
3795 default: 3828 default:
3796 return false; 3829 return false;
3797 } 3830 }
3798 } 3831 }
3799 3832
3800 3833
3801 } // namespace dart 3834 } // namespace dart
3802 #endif // !defined(DART_PRECOMPILED_RUNTIME) 3835 #endif // !defined(DART_PRECOMPILED_RUNTIME)
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698