Commit 098bd2a3 authored by Mythri's avatar Mythri Committed by Commit Bot

[TurboFan]In polymorphic inlining make decisions on individual functions.

In the current implementation the decision to inline polymorphic function
calls applies to all functions. Either we inline all of them or none of
them. Also, we decide to inline if the size of one of function is less
than the FLAG_max_inlined_nodes.

This cl changes it to a decision on individual functions. In the case of
polymorphic calls, we might inline some of the functions and not inline
others.

Bug: 
Change-Id: I2f4049b5e55445b4858b260d289c96090c6aaa74
Reviewed-on: https://chromium-review.googlesource.com/508668
Commit-Queue: Mythri Alle <mythria@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#45428}
parent ee838901
...@@ -109,14 +109,15 @@ Reduction JSInliningHeuristic::Reduce(Node* node) { ...@@ -109,14 +109,15 @@ Reduction JSInliningHeuristic::Reduce(Node* node) {
if (!shared->force_inline()) { if (!shared->force_inline()) {
force_inline = false; force_inline = false;
} }
if (CanInlineFunction(shared)) { candidate.can_inline_function[i] = CanInlineFunction(shared);
if (candidate.can_inline_function[i]) {
can_inline = true; can_inline = true;
} }
if (!IsSmallInlineFunction(shared)) { if (!IsSmallInlineFunction(shared)) {
small_inline = false; small_inline = false;
} }
} }
if (force_inline) return InlineCandidate(candidate); if (force_inline) return InlineCandidate(candidate, true);
if (!can_inline) return NoChange(); if (!can_inline) return NoChange();
// Stop inlining once the maximum allowed level is reached. // Stop inlining once the maximum allowed level is reached.
...@@ -153,7 +154,7 @@ Reduction JSInliningHeuristic::Reduce(Node* node) { ...@@ -153,7 +154,7 @@ Reduction JSInliningHeuristic::Reduce(Node* node) {
case kRestrictedInlining: case kRestrictedInlining:
return NoChange(); return NoChange();
case kStressInlining: case kStressInlining:
return InlineCandidate(candidate); return InlineCandidate(candidate, false);
case kGeneralInlining: case kGeneralInlining:
break; break;
} }
...@@ -166,11 +167,12 @@ Reduction JSInliningHeuristic::Reduce(Node* node) { ...@@ -166,11 +167,12 @@ Reduction JSInliningHeuristic::Reduce(Node* node) {
return NoChange(); return NoChange();
} }
// Forcibly inline small functions here. // Forcibly inline small functions here. In the case of polymorphic inlining
// small_inline is set only when all functions are small.
if (small_inline && cumulative_count_ <= FLAG_max_inlined_nodes_absolute) { if (small_inline && cumulative_count_ <= FLAG_max_inlined_nodes_absolute) {
TRACE("Inlining small function(s) at call site #%d:%s\n", node->id(), TRACE("Inlining small function(s) at call site #%d:%s\n", node->id(),
node->op()->mnemonic()); node->op()->mnemonic());
return InlineCandidate(candidate); return InlineCandidate(candidate, true);
} }
// In the general case we remember the candidate for later. // In the general case we remember the candidate for later.
...@@ -193,13 +195,14 @@ void JSInliningHeuristic::Finalize() { ...@@ -193,13 +195,14 @@ void JSInliningHeuristic::Finalize() {
candidates_.erase(i); candidates_.erase(i);
// Make sure we don't try to inline dead candidate nodes. // Make sure we don't try to inline dead candidate nodes.
if (!candidate.node->IsDead()) { if (!candidate.node->IsDead()) {
Reduction const reduction = InlineCandidate(candidate); Reduction const reduction = InlineCandidate(candidate, false);
if (reduction.Changed()) return; if (reduction.Changed()) return;
} }
} }
} }
Reduction JSInliningHeuristic::InlineCandidate(Candidate const& candidate) { Reduction JSInliningHeuristic::InlineCandidate(Candidate const& candidate,
bool force_inline) {
int const num_calls = candidate.num_functions; int const num_calls = candidate.num_functions;
Node* const node = candidate.node; Node* const node = candidate.node;
if (num_calls == 1) { if (num_calls == 1) {
...@@ -291,12 +294,16 @@ Reduction JSInliningHeuristic::InlineCandidate(Candidate const& candidate) { ...@@ -291,12 +294,16 @@ Reduction JSInliningHeuristic::InlineCandidate(Candidate const& candidate) {
for (int i = 0; i < num_calls; ++i) { for (int i = 0; i < num_calls; ++i) {
Handle<JSFunction> function = candidate.functions[i]; Handle<JSFunction> function = candidate.functions[i];
Node* node = calls[i]; Node* node = calls[i];
Reduction const reduction = inliner_.ReduceJSCall(node); if (force_inline ||
if (reduction.Changed()) { (candidate.can_inline_function[i] &&
// Killing the call node is not strictly necessary, but it is safer to cumulative_count_ < FLAG_max_inlined_nodes_cumulative)) {
// make sure we do not resurrect the node. Reduction const reduction = inliner_.ReduceJSCall(node);
node->Kill(); if (reduction.Changed()) {
cumulative_count_ += function->shared()->ast_node_count(); // Killing the call node is not strictly necessary, but it is safer to
// make sure we do not resurrect the node.
node->Kill();
cumulative_count_ += function->shared()->ast_node_count();
}
} }
} }
......
...@@ -37,6 +37,9 @@ class JSInliningHeuristic final : public AdvancedReducer { ...@@ -37,6 +37,9 @@ class JSInliningHeuristic final : public AdvancedReducer {
struct Candidate { struct Candidate {
Handle<JSFunction> functions[kMaxCallPolymorphism]; Handle<JSFunction> functions[kMaxCallPolymorphism];
// In the case of polymorphic inlining, this tells if each of the
// functions could be inlined.
bool can_inline_function[kMaxCallPolymorphism];
// TODO(2206): For now polymorphic inlining is treated orthogonally to // TODO(2206): For now polymorphic inlining is treated orthogonally to
// inlining based on SharedFunctionInfo. This should be unified and the // inlining based on SharedFunctionInfo. This should be unified and the
// above array should be switched to SharedFunctionInfo instead. Currently // above array should be switched to SharedFunctionInfo instead. Currently
...@@ -57,7 +60,7 @@ class JSInliningHeuristic final : public AdvancedReducer { ...@@ -57,7 +60,7 @@ class JSInliningHeuristic final : public AdvancedReducer {
// Dumps candidates to console. // Dumps candidates to console.
void PrintCandidates(); void PrintCandidates();
Reduction InlineCandidate(Candidate const& candidate); Reduction InlineCandidate(Candidate const& candidate, bool force_inline);
CommonOperatorBuilder* common() const; CommonOperatorBuilder* common() const;
Graph* graph() const; Graph* graph() const;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment