Commit a556a104 authored by bmeurer's avatar bmeurer Committed by Commit bot

[turbofan] Context specialize during inlining.

Context specialization enables inlining (at least currently it is the
only enabler for inlining), but inlining enables more possibilities for
context specialization. So we really need to run them together.

This is especially important with the "module based builtins" that we're
working towards.

BUG=v8:3952
LOG=n

Review URL: https://codereview.chromium.org/988423004

Cr-Commit-Position: refs/heads/master@{#27085}
parent 60c1ad02
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "src/compiler/all-nodes.h" #include "src/compiler/all-nodes.h"
#include "src/compiler/ast-graph-builder.h" #include "src/compiler/ast-graph-builder.h"
#include "src/compiler/common-operator.h" #include "src/compiler/common-operator.h"
#include "src/compiler/js-context-specialization.h"
#include "src/compiler/js-operator.h" #include "src/compiler/js-operator.h"
#include "src/compiler/node-matchers.h" #include "src/compiler/node-matchers.h"
#include "src/compiler/node-properties.h" #include "src/compiler/node-properties.h"
...@@ -99,7 +100,7 @@ class Inlinee { ...@@ -99,7 +100,7 @@ class Inlinee {
// Inline this graph at {call}, use {jsgraph} and its zone to create // Inline this graph at {call}, use {jsgraph} and its zone to create
// any new nodes. // any new nodes.
Reduction InlineAtCall(JSGraph* jsgraph, Node* call, Node* context); Reduction InlineAtCall(JSGraph* jsgraph, Node* call);
// Ensure that only a single return reaches the end node. // Ensure that only a single return reaches the end node.
static void UnifyReturn(JSGraph* jsgraph); static void UnifyReturn(JSGraph* jsgraph);
...@@ -212,7 +213,7 @@ class CopyVisitor { ...@@ -212,7 +213,7 @@ class CopyVisitor {
}; };
Reduction Inlinee::InlineAtCall(JSGraph* jsgraph, Node* call, Node* context) { Reduction Inlinee::InlineAtCall(JSGraph* jsgraph, Node* call) {
// The scheduler is smart enough to place our code; we just ensure {control} // The scheduler is smart enough to place our code; we just ensure {control}
// becomes the control input of the start of the inlinee, and {effect} becomes // becomes the control input of the start of the inlinee, and {effect} becomes
// the effect input of the start of the inlinee. // the effect input of the start of the inlinee.
...@@ -235,9 +236,9 @@ Reduction Inlinee::InlineAtCall(JSGraph* jsgraph, Node* call, Node* context) { ...@@ -235,9 +236,9 @@ Reduction Inlinee::InlineAtCall(JSGraph* jsgraph, Node* call, Node* context) {
// projection but not the context, so rewire the input. // projection but not the context, so rewire the input.
NodeProperties::ReplaceWithValue(use, call->InputAt(index)); NodeProperties::ReplaceWithValue(use, call->InputAt(index));
} else if (index == inlinee_context_index) { } else if (index == inlinee_context_index) {
// This is the context projection, rewire it to the context from the // TODO(turbofan): We always context specialize inlinees currently, so
// JSFunction object. // we should never get here.
NodeProperties::ReplaceWithValue(use, context); UNREACHABLE();
} else if (index < inlinee_context_index) { } else if (index < inlinee_context_index) {
// Call has fewer arguments than required, fill with undefined. // Call has fewer arguments than required, fill with undefined.
NodeProperties::ReplaceWithValue(use, jsgraph->UndefinedConstant()); NodeProperties::ReplaceWithValue(use, jsgraph->UndefinedConstant());
...@@ -341,8 +342,16 @@ Reduction JSInliner::Reduce(Node* node) { ...@@ -341,8 +342,16 @@ Reduction JSInliner::Reduce(Node* node) {
JSGraph jsgraph(info.isolate(), &graph, jsgraph_->common(), JSGraph jsgraph(info.isolate(), &graph, jsgraph_->common(),
jsgraph_->javascript(), jsgraph_->machine()); jsgraph_->javascript(), jsgraph_->machine());
// The inlinee specializes to the context from the JSFunction object.
// TODO(turbofan): We might want to load the context from the JSFunction at
// runtime in case we only know the SharedFunctionInfo once we have dynamic
// type feedback in the compiler.
AstGraphBuilder graph_builder(local_zone_, &info, &jsgraph); AstGraphBuilder graph_builder(local_zone_, &info, &jsgraph);
graph_builder.CreateGraph(false, false); graph_builder.CreateGraph(true, false);
JSContextSpecializer context_specializer(&jsgraph);
GraphReducer graph_reducer(&graph, local_zone_);
graph_reducer.AddReducer(&context_specializer);
graph_reducer.ReduceGraph();
Inlinee::UnifyReturn(&jsgraph); Inlinee::UnifyReturn(&jsgraph);
CopyVisitor visitor(&graph, jsgraph_->graph(), info.zone()); CopyVisitor visitor(&graph, jsgraph_->graph(), info.zone());
...@@ -367,13 +376,7 @@ Reduction JSInliner::Reduce(Node* node) { ...@@ -367,13 +376,7 @@ Reduction JSInliner::Reduce(Node* node) {
} }
} }
// The inlinee uses the context from the JSFunction object. return inlinee.InlineAtCall(jsgraph_, node);
// TODO(turbofan): We might want to load the context from the JSFunction at
// runtime in case we only know the SharedFunctionInfo once we have dynamic
// type feedback in the compiler.
Node* context = jsgraph_->HeapConstant(handle(function->context()));
return inlinee.InlineAtCall(jsgraph_, node, context);
} }
} // namespace compiler } // namespace compiler
......
...@@ -508,4 +508,22 @@ TEST(InlineBuiltin) { ...@@ -508,4 +508,22 @@ TEST(InlineBuiltin) {
T.CheckCall(T.true_value()); T.CheckCall(T.true_value());
} }
TEST(InlineNestedBuiltin) {
FLAG_turbo_deoptimization = true;
FunctionTester T(
"(function () {"
" function foo(s,t,u) { AssertInlineCount(3); return true; }"
" function baz(s,t,u) { return foo(s,t,u); }"
" function bar() { return baz(); };"
" %SetInlineBuiltinFlag(foo);"
" %SetInlineBuiltinFlag(baz);"
" return bar;"
"})();",
kBuiltinInlineFlags);
InstallAssertInlineCountHelper(CcTest::isolate());
T.CheckCall(T.true_value());
}
#endif // V8_TURBOFAN_TARGET #endif // V8_TURBOFAN_TARGET
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