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_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/block_scheduler.h" | 8 #include "vm/block_scheduler.h" |
9 #include "vm/branch_optimizer.h" | 9 #include "vm/branch_optimizer.h" |
10 #include "vm/compiler.h" | 10 #include "vm/compiler.h" |
(...skipping 811 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
822 param_stubs); | 822 param_stubs); |
823 DEBUG_ASSERT(callee_graph->VerifyUseLists()); | 823 DEBUG_ASSERT(callee_graph->VerifyUseLists()); |
824 } | 824 } |
825 | 825 |
826 { | 826 { |
827 CSTAT_TIMER_SCOPE(thread(), graphinliner_opt_timer); | 827 CSTAT_TIMER_SCOPE(thread(), graphinliner_opt_timer); |
828 // TODO(fschneider): Improve suppression of speculative inlining. | 828 // TODO(fschneider): Improve suppression of speculative inlining. |
829 // Deopt-ids overlap between caller and callee. | 829 // Deopt-ids overlap between caller and callee. |
830 if (FLAG_precompiled_mode) { | 830 if (FLAG_precompiled_mode) { |
831 #ifdef DART_PRECOMPILER | 831 #ifdef DART_PRECOMPILER |
832 AotOptimizer optimizer(callee_graph, | 832 AotOptimizer optimizer(inliner_->precompiler_, |
833 callee_graph, | |
833 inliner_->use_speculative_inlining_, | 834 inliner_->use_speculative_inlining_, |
834 inliner_->inlining_black_list_); | 835 inliner_->inlining_black_list_); |
835 optimizer.PopulateWithICData(); | 836 optimizer.PopulateWithICData(); |
836 | 837 |
837 optimizer.ApplyClassIds(); | 838 optimizer.ApplyClassIds(); |
838 DEBUG_ASSERT(callee_graph->VerifyUseLists()); | 839 DEBUG_ASSERT(callee_graph->VerifyUseLists()); |
839 | 840 |
840 FlowGraphTypePropagator::Propagate(callee_graph); | 841 FlowGraphTypePropagator::Propagate(callee_graph); |
841 DEBUG_ASSERT(callee_graph->VerifyUseLists()); | 842 DEBUG_ASSERT(callee_graph->VerifyUseLists()); |
842 | 843 |
(...skipping 1028 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1871 return FLAG_trace_inlining && FlowGraphPrinter::ShouldPrint(top); | 1872 return FLAG_trace_inlining && FlowGraphPrinter::ShouldPrint(top); |
1872 } | 1873 } |
1873 | 1874 |
1874 | 1875 |
1875 FlowGraphInliner::FlowGraphInliner( | 1876 FlowGraphInliner::FlowGraphInliner( |
1876 FlowGraph* flow_graph, | 1877 FlowGraph* flow_graph, |
1877 GrowableArray<const Function*>* inline_id_to_function, | 1878 GrowableArray<const Function*>* inline_id_to_function, |
1878 GrowableArray<TokenPosition>* inline_id_to_token_pos, | 1879 GrowableArray<TokenPosition>* inline_id_to_token_pos, |
1879 GrowableArray<intptr_t>* caller_inline_id, | 1880 GrowableArray<intptr_t>* caller_inline_id, |
1880 bool use_speculative_inlining, | 1881 bool use_speculative_inlining, |
1881 GrowableArray<intptr_t>* inlining_black_list) | 1882 GrowableArray<intptr_t>* inlining_black_list, |
1883 Precompiler* precompiler) | |
1882 : flow_graph_(flow_graph), | 1884 : flow_graph_(flow_graph), |
1883 inline_id_to_function_(inline_id_to_function), | 1885 inline_id_to_function_(inline_id_to_function), |
1884 inline_id_to_token_pos_(inline_id_to_token_pos), | 1886 inline_id_to_token_pos_(inline_id_to_token_pos), |
1885 caller_inline_id_(caller_inline_id), | 1887 caller_inline_id_(caller_inline_id), |
1886 trace_inlining_(ShouldTraceInlining(flow_graph)), | 1888 trace_inlining_(ShouldTraceInlining(flow_graph)), |
1887 use_speculative_inlining_(use_speculative_inlining), | 1889 use_speculative_inlining_(use_speculative_inlining), |
1888 inlining_black_list_(inlining_black_list) { | 1890 inlining_black_list_(inlining_black_list), |
1891 precompiler_(precompiler) { | |
1889 ASSERT(!use_speculative_inlining || (inlining_black_list != NULL)); | 1892 ASSERT(!use_speculative_inlining || (inlining_black_list != NULL)); |
1890 } | 1893 } |
1891 | 1894 |
1892 | 1895 |
1893 void FlowGraphInliner::CollectGraphInfo(FlowGraph* flow_graph, bool force) { | 1896 void FlowGraphInliner::CollectGraphInfo(FlowGraph* flow_graph, bool force) { |
1894 const Function& function = flow_graph->function(); | 1897 const Function& function = flow_graph->function(); |
1895 if (force || (function.optimized_instruction_count() == 0)) { | 1898 if (force || (function.optimized_instruction_count() == 0)) { |
1896 GraphInfoCollector info; | 1899 GraphInfoCollector info; |
1897 info.Collect(*flow_graph); | 1900 info.Collect(*flow_graph); |
1898 | 1901 |
(...skipping 1852 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3751 flow_graph->AppendTo(*entry, *last, | 3754 flow_graph->AppendTo(*entry, *last, |
3752 call->deopt_id() != Thread::kNoDeoptId ? | 3755 call->deopt_id() != Thread::kNoDeoptId ? |
3753 call->env() : NULL, | 3756 call->env() : NULL, |
3754 FlowGraph::kValue); | 3757 FlowGraph::kValue); |
3755 return true; | 3758 return true; |
3756 } | 3759 } |
3757 } | 3760 } |
3758 return false; | 3761 return false; |
3759 } | 3762 } |
3760 | 3763 |
3764 case MethodRecognizer::kObjectRuntimeType: { | |
3765 Type& type = Type::Handle(Z); | |
3766 if (RawObject::IsStringClassId(receiver_cid)) { | |
3767 type = Type::StringType(); | |
3768 } else if (receiver_cid == kDoubleCid) { | |
3769 type = Type::Double(); | |
3770 } else if (RawObject::IsIntegerClassId(receiver_cid)) { | |
3771 type = Type::IntType(); | |
3772 } else if (receiver_cid != kClosureCid) { | |
3773 const Class& cls = Class::Handle(Z, | |
3774 flow_graph->isolate()->class_table()->At(receiver_cid)); | |
3775 if (!cls.IsGeneric()) { | |
3776 type = cls.CanonicalType(); | |
3777 } | |
3778 } | |
3779 | |
3780 if (!type.IsNull()) { | |
3781 *entry = new(Z) TargetEntryInstr(flow_graph->allocate_block_id(), | |
3782 call->GetBlock()->try_index()); | |
3783 (*entry)->InheritDeoptTarget(Z, call); | |
3784 *last = new(Z) ConstantInstr(type); | |
3785 flow_graph->AppendTo(*entry, *last, | |
3786 call->deopt_id() != Thread::kNoDeoptId ? | |
Florian Schneider
2016/10/06 18:03:19
Can call ever have Thread::kNoDeoptId?
Vyacheslav Egorov (Google)
2016/10/24 20:23:03
That's an interesting question. In JIT it should n
| |
3787 call->env() : NULL, | |
3788 FlowGraph::kValue); | |
3789 return true; | |
3790 } | |
3791 return false; | |
3792 } | |
3793 | |
3761 case MethodRecognizer::kOneByteStringSetAt: { | 3794 case MethodRecognizer::kOneByteStringSetAt: { |
3762 // This is an internal method, no need to check argument types nor | 3795 // This is an internal method, no need to check argument types nor |
3763 // range. | 3796 // range. |
3764 *entry = new(Z) TargetEntryInstr(flow_graph->allocate_block_id(), | 3797 *entry = new(Z) TargetEntryInstr(flow_graph->allocate_block_id(), |
3765 call->GetBlock()->try_index()); | 3798 call->GetBlock()->try_index()); |
3766 (*entry)->InheritDeoptTarget(Z, call); | 3799 (*entry)->InheritDeoptTarget(Z, call); |
3767 Definition* str = call->ArgumentAt(0); | 3800 Definition* str = call->ArgumentAt(0); |
3768 Definition* index = call->ArgumentAt(1); | 3801 Definition* index = call->ArgumentAt(1); |
3769 Definition* value = call->ArgumentAt(2); | 3802 Definition* value = call->ArgumentAt(2); |
3770 *last = new(Z) StoreIndexedInstr( | 3803 *last = new(Z) StoreIndexedInstr( |
(...skipping 13 matching lines...) Expand all Loading... | |
3784 return true; | 3817 return true; |
3785 } | 3818 } |
3786 | 3819 |
3787 default: | 3820 default: |
3788 return false; | 3821 return false; |
3789 } | 3822 } |
3790 } | 3823 } |
3791 | 3824 |
3792 | 3825 |
3793 } // namespace dart | 3826 } // namespace dart |
OLD | NEW |