Chromium Code Reviews| Index: runtime/vm/flow_graph_inliner.cc |
| diff --git a/runtime/vm/flow_graph_inliner.cc b/runtime/vm/flow_graph_inliner.cc |
| index 062196160f0408a82922d383075660f6c1533cb1..6cf06842f01707baa7a29cfdaa9d44b312fe0e65 100644 |
| --- a/runtime/vm/flow_graph_inliner.cc |
| +++ b/runtime/vm/flow_graph_inliner.cc |
| @@ -5,6 +5,7 @@ |
| #include "vm/flow_graph_inliner.h" |
| #include "vm/aot_optimizer.h" |
| +#include "vm/precompiler.h" |
| #include "vm/block_scheduler.h" |
| #include "vm/branch_optimizer.h" |
| #include "vm/compiler.h" |
| @@ -213,8 +214,11 @@ struct InlinedInfo { |
| // A collection of call sites to consider for inlining. |
| class CallSites : public ValueObject { |
| public: |
| - explicit CallSites(FlowGraph* flow_graph) |
| - : static_calls_(), closure_calls_(), instance_calls_() {} |
| + explicit CallSites(FlowGraph* flow_graph, intptr_t threshold) |
| + : inlining_depth_threshold_(threshold), |
| + static_calls_(), |
| + closure_calls_(), |
| + instance_calls_() {} |
| struct InstanceCallInfo { |
| PolymorphicInstanceCallInstr* call; |
| @@ -357,7 +361,7 @@ class CallSites : public ValueObject { |
| intptr_t depth, |
| GrowableArray<InlinedInfo>* inlined_info) { |
| ASSERT(graph != NULL); |
| - if (depth > FLAG_inlining_depth_threshold) { |
| + if (depth > inlining_depth_threshold_) { |
| if (FLAG_print_inlining_tree) { |
| RecordAllNotInlinedFunction(graph, depth, inlined_info); |
| } |
| @@ -367,7 +371,7 @@ class CallSites : public ValueObject { |
| // Recognized methods are not treated as normal calls. They don't have |
| // calls in themselves, so we keep adding those even when at the threshold. |
| const bool inline_only_recognized_methods = |
| - (depth == FLAG_inlining_depth_threshold); |
| + (depth == inlining_depth_threshold_); |
| const intptr_t instance_call_start_ix = instance_calls_.length(); |
| const intptr_t static_call_start_ix = static_calls_.length(); |
| @@ -423,6 +427,7 @@ class CallSites : public ValueObject { |
| } |
| private: |
| + intptr_t inlining_depth_threshold_; |
| GrowableArray<StaticCallInfo> static_calls_; |
| GrowableArray<ClosureCallInfo> closure_calls_; |
| GrowableArray<InstanceCallInfo> instance_calls_; |
| @@ -513,7 +518,7 @@ static bool HasAnnotation(const Function& function, const char* annotation) { |
| class CallSiteInliner : public ValueObject { |
| public: |
| - explicit CallSiteInliner(FlowGraphInliner* inliner) |
| + explicit CallSiteInliner(FlowGraphInliner* inliner, intptr_t threshold) |
| : inliner_(inliner), |
| caller_graph_(inliner->flow_graph()), |
| inlined_(false), |
| @@ -522,6 +527,7 @@ class CallSiteInliner : public ValueObject { |
| inlined_recursive_call_(false), |
| inlining_depth_(1), |
| inlining_recursion_depth_(0), |
| + inlining_depth_threshold_(threshold), |
| collected_call_sites_(NULL), |
| inlining_call_sites_(NULL), |
| function_cache_(), |
| @@ -570,14 +576,14 @@ class CallSiteInliner : public ValueObject { |
| void InlineCalls() { |
| // If inlining depth is less then one abort. |
| - if (FLAG_inlining_depth_threshold < 1) return; |
| + if (inlining_depth_threshold_ < 1) return; |
| if (caller_graph_->function().deoptimization_counter() >= |
| FLAG_deoptimization_counter_inlining_threshold) { |
| return; |
| } |
| // Create two call site collections to swap between. |
| - CallSites sites1(caller_graph_); |
| - CallSites sites2(caller_graph_); |
| + CallSites sites1(caller_graph_, inlining_depth_threshold_); |
| + CallSites sites2(caller_graph_, inlining_depth_threshold_); |
| CallSites* call_sites_temp = NULL; |
| collected_call_sites_ = &sites1; |
| inlining_call_sites_ = &sites2; |
| @@ -669,6 +675,15 @@ class CallSiteInliner : public ValueObject { |
| return false; |
| } |
| + if ((inliner_->precompiler_ != NULL) && |
| + inliner_->precompiler_->HasFeedback() && |
| + (function.usage_counter() <= 0) && !inliner_->AlwaysInline(function)) { |
| + TRACE_INLINING(THR_Print(" Bailout: not compiled yet\n")); |
| + PRINT_INLINING_TREE("Not compiled", &call_data->caller, &function, |
| + call_data->call); |
| + return false; |
| + } |
| + |
| // Type feedback may have been cleared for this function (ClearICDataArray), |
| // but we need it for inlining. |
| if (!FLAG_precompiled_mode && (function.ic_data_array() == Array::null())) { |
| @@ -791,6 +806,16 @@ class CallSiteInliner : public ValueObject { |
| callee_graph = builder.BuildGraph(); |
| } |
| } |
| +#ifdef DART_PRECOMPILER |
| + if (FLAG_precompiled_mode) { |
|
rmacnak
2016/12/16 22:22:05
The change was to move this out of the "else build
|
| + Precompiler::PopulateWithICData(parsed_function->function(), |
| + callee_graph); |
| + if (inliner_->precompiler_ != NULL) { |
| + inliner_->precompiler_->TryApplyFeedback( |
| + parsed_function->function(), callee_graph); |
| + } |
| + } |
| +#endif |
| // The parameter stubs are a copy of the actual arguments providing |
| // concrete information about the values, for example constant values, |
| @@ -857,7 +882,6 @@ class CallSiteInliner : public ValueObject { |
| AotOptimizer optimizer(inliner_->precompiler_, callee_graph, |
| inliner_->use_speculative_inlining_, |
| inliner_->inlining_black_list_); |
| - optimizer.PopulateWithICData(); |
| optimizer.ApplyClassIds(); |
| DEBUG_ASSERT(callee_graph->VerifyUseLists()); |
| @@ -1375,6 +1399,7 @@ class CallSiteInliner : public ValueObject { |
| bool inlined_recursive_call_; |
| intptr_t inlining_depth_; |
| intptr_t inlining_recursion_depth_; |
| + intptr_t inlining_depth_threshold_; |
| CallSites* collected_call_sites_; |
| CallSites* inlining_call_sites_; |
| GrowableArray<ParsedFunction*> function_cache_; |
| @@ -1929,6 +1954,11 @@ bool FlowGraphInliner::AlwaysInline(const Function& function) { |
| return true; |
| } |
| + if (function.is_const()) { |
| + // Inlined const fields are smaller than a call. |
| + return true; |
| + } |
| + |
| if (function.IsGetterFunction() || function.IsSetterFunction() || |
| IsInlineableOperator(function) || |
| (function.kind() == RawFunction::kConstructor)) { |
| @@ -1962,7 +1992,13 @@ void FlowGraphInliner::Inline() { |
| printer.PrintBlocks(); |
| } |
| - CallSiteInliner inliner(this); |
| + intptr_t inlining_depth_threshold = FLAG_inlining_depth_threshold; |
| + if ((precompiler_ != NULL) && precompiler_->HasFeedback() && |
| + (top.usage_counter() <= 0)) { |
| + inlining_depth_threshold = 1; |
| + } |
| + |
| + CallSiteInliner inliner(this, inlining_depth_threshold); |
| inliner.InlineCalls(); |
| if (FLAG_print_inlining_tree) { |
| inliner.PrintInlinedInfo(top); |