Index: src/compiler/js-inlining-heuristic.cc |
diff --git a/src/compiler/js-inlining-heuristic.cc b/src/compiler/js-inlining-heuristic.cc |
index 2abf611c89371388b98efe831992772c185b99ed..515618da759c7147f43e5be36ea2a7693f425015 100644 |
--- a/src/compiler/js-inlining-heuristic.cc |
+++ b/src/compiler/js-inlining-heuristic.cc |
@@ -4,6 +4,7 @@ |
#include "src/compiler/js-inlining-heuristic.h" |
+#include "src/compiler/dead-code-elimination.h" // TODO(mstarzinger): Remove! |
#include "src/compiler/node-matchers.h" |
#include "src/objects-inl.h" |
@@ -24,9 +25,88 @@ Reduction JSInliningHeuristic::Reduce(Node* node) { |
return inliner_.ReduceJSCallFunction(node, function); |
} |
- // All other functions are only handled with general inlining. |
- if (mode_ == kRestrictedInlining) return NoChange(); |
- return inliner_.ReduceJSCallFunction(node, function); |
+ // Handling of special inlining modes right away: |
+ // - For restricted inlining: stop all handling at this point. |
+ // - For stressing inlining: immediately handle all functions. |
+ switch (mode_) { |
+ case kRestrictedInlining: |
+ return NoChange(); |
+ case kStressInlining: |
+ return inliner_.ReduceJSCallFunction(node, function); |
+ case kGeneralInlining: |
+ break; |
+ } |
+ |
+ // --------------------------------------------------------------------------- |
+ // Everything below this line is part of the inlining heuristic. |
+ // --------------------------------------------------------------------------- |
+ |
+ // Built-in functions are handled by the JSBuiltinReducer. |
+ if (function->shared()->HasBuiltinFunctionId()) return NoChange(); |
+ |
+ // Quick check on source code length to avoid parsing large candidate. |
+ if (function->shared()->SourceSize() > FLAG_max_inlined_source_size) { |
+ return NoChange(); |
+ } |
+ |
+ // Quick check on the size of the AST to avoid parsing large candidate. |
+ if (function->shared()->ast_node_count() > FLAG_max_inlined_nodes) { |
+ return NoChange(); |
+ } |
+ |
+ // Gather feedback on how often this call site has been hit before. |
+ CallFunctionParameters p = CallFunctionParametersOf(node->op()); |
+ CallICNexus nexus(p.feedback().vector(), p.feedback().slot()); |
+ int calls = nexus.ExtractCallCount(); |
+ |
+ // --------------------------------------------------------------------------- |
+ // Everything above this line is part of the inlining heuristic. |
+ // --------------------------------------------------------------------------- |
+ |
+ // In the general case we remember the candidate for later. |
+ candidates_.push_back({function, node, calls}); |
+ return NoChange(); |
+} |
+ |
+ |
+void JSInliningHeuristic::ProcessCandidates() { |
+ if (candidates_.empty()) return; // Nothing to do without candidates. |
+ std::sort(candidates_.begin(), candidates_.end(), Compare); |
+ if (FLAG_trace_turbo_inlining) PrintCandidates(); |
+ |
+ int cumulative_count = 0; |
+ for (const Candidate& candidate : candidates_) { |
+ if (cumulative_count > FLAG_max_inlined_nodes_cumulative) break; |
+ inliner_.ReduceJSCallFunction(candidate.node, candidate.function); |
+ cumulative_count += candidate.function->shared()->ast_node_count(); |
+ } |
+ |
+ // TODO(mstarzinger): Temporary workaround to eliminate dead control from the |
+ // graph being introduced by the inliner. Make this part of the pipeline. |
+ GraphReducer graph_reducer(local_zone_, jsgraph_->graph(), jsgraph_->Dead()); |
+ DeadCodeElimination dead_code_elimination(&graph_reducer, jsgraph_->graph(), |
+ jsgraph_->common()); |
+ graph_reducer.AddReducer(&dead_code_elimination); |
+ graph_reducer.ReduceGraph(); |
+} |
+ |
+ |
+// static |
+bool JSInliningHeuristic::Compare(const Candidate& left, |
+ const Candidate& right) { |
+ return left.calls > right.calls; |
+} |
+ |
+ |
+void JSInliningHeuristic::PrintCandidates() { |
+ PrintF("Candidates for inlining (size=%zu):\n", candidates_.size()); |
+ for (const Candidate& candidate : candidates_) { |
+ PrintF(" id:%d, calls:%d, size[source]:%d, size[ast]:%d / %s\n", |
+ candidate.node->id(), candidate.calls, |
+ candidate.function->shared()->SourceSize(), |
+ candidate.function->shared()->ast_node_count(), |
+ candidate.function->shared()->DebugName()->ToCString().get()); |
+ } |
} |
} // namespace compiler |