Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(83)

Unified Diff: src/compiler/js-inlining.cc

Issue 481413002: Revert "Add initial support for inlining." (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/compiler/js-inlining.h ('k') | src/compiler/js-typed-lowering.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/compiler/js-inlining.cc
diff --git a/src/compiler/js-inlining.cc b/src/compiler/js-inlining.cc
deleted file mode 100644
index 5dcc0e1e4278163cf4d9d63746ae4c7adf58bd7a..0000000000000000000000000000000000000000
--- a/src/compiler/js-inlining.cc
+++ /dev/null
@@ -1,327 +0,0 @@
-// Copyright 2014 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/compiler/ast-graph-builder.h"
-#include "src/compiler/common-operator.h"
-#include "src/compiler/generic-node-inl.h"
-#include "src/compiler/graph-inl.h"
-#include "src/compiler/graph-visualizer.h"
-#include "src/compiler/js-inlining.h"
-#include "src/compiler/js-operator.h"
-#include "src/compiler/node-aux-data-inl.h"
-#include "src/compiler/node-matchers.h"
-#include "src/compiler/node-properties-inl.h"
-#include "src/compiler/simplified-operator.h"
-#include "src/compiler/typer.h"
-#include "src/parser.h"
-#include "src/rewriter.h"
-#include "src/scopes.h"
-
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-class InlinerVisitor : public NullNodeVisitor {
- public:
- explicit InlinerVisitor(JSInliner* inliner) : inliner_(inliner) {}
-
- GenericGraphVisit::Control Post(Node* node) {
- switch (node->opcode()) {
- case IrOpcode::kJSCallFunction:
- inliner_->TryInlineCall(node);
- break;
- default:
- break;
- }
- return GenericGraphVisit::CONTINUE;
- }
-
- private:
- JSInliner* inliner_;
-};
-
-
-void JSInliner::Inline() {
- InlinerVisitor visitor(this);
- jsgraph_->graph()->VisitNodeInputsFromEnd(&visitor);
-}
-
-
-static void MoveWithDependencies(Graph* graph, Node* node, Node* old_block,
- Node* new_block) {
- if (OperatorProperties::HasControlInput(node->op())) {
- // Check if we have left the old_block.
- if (NodeProperties::GetControlInput(node) != old_block) return;
- // If not, move this node to the new_block.
- NodeProperties::ReplaceControlInput(node, new_block);
- }
- // Independent of whether a node has a control input or not,
- // it might have a dependency that is pinned to old_block.
- for (InputIter iter = node->inputs().begin(); iter != node->inputs().end();
- ++iter) {
- if (NodeProperties::IsControlEdge(iter.edge())) continue;
- MoveWithDependencies(graph, *iter, old_block, new_block);
- }
-}
-
-
-static void MoveAllControlNodes(Node* from, Node* to) {
- for (UseIter iter = from->uses().begin(); iter != from->uses().end();) {
- if (NodeProperties::IsControlEdge(iter.edge())) {
- iter.UpdateToAndIncrement(to);
- } else {
- ++iter;
- }
- }
-}
-
-
-// TODO(sigurds) Find a home for this function and reuse it everywhere (esp. in
-// test cases, where similar code is currently duplicated).
-static void Parse(Handle<JSFunction> function, CompilationInfoWithZone* info) {
- CHECK(Parser::Parse(info));
- StrictMode strict_mode = info->function()->strict_mode();
- info->SetStrictMode(strict_mode);
- info->SetOptimizing(BailoutId::None(), Handle<Code>(function->code()));
- CHECK(Rewriter::Rewrite(info));
- CHECK(Scope::Analyze(info));
- CHECK_NE(NULL, info->scope());
- Handle<ScopeInfo> scope_info = ScopeInfo::Create(info->scope(), info->zone());
- info->shared_info()->set_scope_info(*scope_info);
-}
-
-
-// A facade on a JSFunction's graph to facilitate inlining. It assumes the
-// that the function graph has only one return statement, and provides
-// {UnifyReturn} to convert a function graph to that end.
-// InlineAtCall will create some new nodes using {graph}'s builders (and hence
-// those nodes will live in {graph}'s zone.
-class Inlinee {
- public:
- explicit Inlinee(JSGraph* graph) : jsgraph_(graph) {}
-
- Graph* graph() { return jsgraph_->graph(); }
- JSGraph* jsgraph() { return jsgraph_; }
-
- // Returns the last regular control node, that is
- // the last control node before the end node.
- Node* end_block() { return NodeProperties::GetControlInput(unique_return()); }
-
- // Return the effect output of the graph,
- // that is the effect input of the return statement of the inlinee.
- Node* effect_output() {
- return NodeProperties::GetEffectInput(unique_return());
- }
- // Return the value output of the graph,
- // that is the value input of the return statement of the inlinee.
- Node* value_output() {
- return NodeProperties::GetValueInput(unique_return(), 0);
- }
- // Return the unique return statement of the graph.
- Node* unique_return() {
- Node* unique_return =
- NodeProperties::GetControlInput(jsgraph_->graph()->end());
- DCHECK_EQ(IrOpcode::kReturn, unique_return->opcode());
- return unique_return;
- }
- // Inline this graph at {call}, use {jsgraph} and its zone to create
- // any new nodes.
- void InlineAtCall(JSGraph* jsgraph, Node* call);
- // Ensure that only a single return reaches the end node.
- void UnifyReturn();
-
- private:
- JSGraph* jsgraph_;
-};
-
-
-void Inlinee::UnifyReturn() {
- Graph* graph = jsgraph_->graph();
-
- Node* final_merge = NodeProperties::GetControlInput(graph->end(), 0);
- if (final_merge->opcode() == IrOpcode::kReturn) {
- // nothing to do
- return;
- }
- DCHECK_EQ(IrOpcode::kMerge, final_merge->opcode());
-
- int predecessors =
- OperatorProperties::GetControlInputCount(final_merge->op());
- Operator* op_phi = jsgraph_->common()->Phi(predecessors);
- Operator* op_ephi = jsgraph_->common()->EffectPhi(predecessors);
-
- std::vector<Node*> values;
- std::vector<Node*> effects;
- // Iterate over all control flow predecessors,
- // which must be return statements.
- InputIter iter = final_merge->inputs().begin();
- while (iter != final_merge->inputs().end()) {
- Node* input = *iter;
- switch (input->opcode()) {
- case IrOpcode::kReturn:
- values.push_back(NodeProperties::GetValueInput(input, 0));
- effects.push_back(NodeProperties::GetEffectInput(input));
- iter.UpdateToAndIncrement(NodeProperties::GetControlInput(input));
- input->RemoveAllInputs();
- break;
- default:
- UNREACHABLE();
- ++iter;
- break;
- }
- }
- values.push_back(final_merge);
- effects.push_back(final_merge);
- Node* phi = graph->NewNode(op_phi, values.size(), values.data());
- Node* ephi = graph->NewNode(op_ephi, effects.size(), effects.data());
- Node* new_return =
- graph->NewNode(jsgraph_->common()->Return(), phi, ephi, final_merge);
- graph->end()->ReplaceInput(0, new_return);
-}
-
-
-void Inlinee::InlineAtCall(JSGraph* jsgraph, Node* call) {
- MachineOperatorBuilder machine(jsgraph->zone());
-
- Node* control = NodeProperties::GetControlInput(call);
- // Move all the nodes to the end block.
- MoveAllControlNodes(control, end_block());
- // Now move the ones the call depends on back up.
- // We have to do this back-and-forth to treat the case where the call is
- // pinned to the start block.
- MoveWithDependencies(graph(), call, end_block(), control);
-
- // The inlinee uses the context from the JSFunction object. This will
- // also be the effect dependency for the inlinee as it produces an effect.
- // TODO(sigurds) Use simplified load once it is ready.
- Node* context = jsgraph->graph()->NewNode(
- machine.Load(kMachAnyTagged), NodeProperties::GetValueInput(call, 0),
- jsgraph->Int32Constant(JSFunction::kContextOffset - kHeapObjectTag),
- NodeProperties::GetEffectInput(call));
-
- // {inlinee_inputs} counts JSFunction, Receiver, arguments, context,
- // but not effect, control.
- int inlinee_inputs = graph()->start()->op()->OutputCount();
- // Context is last argument.
- int inlinee_context_index = inlinee_inputs - 1;
- // {inliner_inputs} counts JSFunction, Receiver, arguments, but not
- // context, effect, control.
- int inliner_inputs = OperatorProperties::GetValueInputCount(call->op());
- // Iterate over all uses of the start node.
- UseIter iter = graph()->start()->uses().begin();
- while (iter != graph()->start()->uses().end()) {
- Node* use = *iter;
- switch (use->opcode()) {
- case IrOpcode::kParameter: {
- int index = 1 + static_cast<Operator1<int>*>(use->op())->parameter();
- if (index < inliner_inputs && index < inlinee_context_index) {
- // There is an input from the call, and the index is a value
- // projection but not the context, so rewire the input.
- NodeProperties::ReplaceWithValue(*iter, call->InputAt(index));
- } else if (index == inlinee_context_index) {
- // This is the context projection, rewire it to the context from the
- // JSFunction object.
- NodeProperties::ReplaceWithValue(*iter, context);
- } else if (index < inlinee_context_index) {
- // Call has fewer arguments than required, fill with undefined.
- NodeProperties::ReplaceWithValue(*iter, jsgraph->UndefinedConstant());
- } else {
- // We got too many arguments, discard for now.
- // TODO(sigurds): Fix to treat arguments array correctly.
- }
- ++iter;
- break;
- }
- default:
- if (NodeProperties::IsEffectEdge(iter.edge())) {
- iter.UpdateToAndIncrement(context);
- } else if (NodeProperties::IsControlEdge(iter.edge())) {
- iter.UpdateToAndIncrement(control);
- } else {
- UNREACHABLE();
- }
- break;
- }
- }
-
- // Iterate over all uses of the call node.
- iter = call->uses().begin();
- while (iter != call->uses().end()) {
- if (NodeProperties::IsEffectEdge(iter.edge())) {
- iter.UpdateToAndIncrement(effect_output());
- } else if (NodeProperties::IsControlEdge(iter.edge())) {
- UNREACHABLE();
- } else {
- DCHECK(NodeProperties::IsValueEdge(iter.edge()));
- iter.UpdateToAndIncrement(value_output());
- }
- }
- call->RemoveAllInputs();
- DCHECK_EQ(0, call->UseCount());
- // TODO(sigurds) Remove this once we copy.
- unique_return()->RemoveAllInputs();
-}
-
-
-void JSInliner::TryInlineCall(Node* node) {
- DCHECK_EQ(IrOpcode::kJSCallFunction, node->opcode());
-
- ValueMatcher<Handle<JSFunction> > match(node->InputAt(0));
- if (!match.HasValue()) {
- return;
- }
-
- Handle<JSFunction> function = match.Value();
-
- if (function->shared()->native()) {
- if (FLAG_trace_turbo_inlining) {
- SmartArrayPointer<char> name =
- function->shared()->DebugName()->ToCString();
- PrintF("Not Inlining %s into %s because inlinee is native\n", name.get(),
- info_->shared_info()->DebugName()->ToCString().get());
- }
- return;
- }
-
- CompilationInfoWithZone info(function);
- Parse(function, &info);
-
- if (info.scope()->arguments() != NULL) {
- // For now do not inline functions that use their arguments array.
- SmartArrayPointer<char> name = function->shared()->DebugName()->ToCString();
- if (FLAG_trace_turbo_inlining) {
- PrintF(
- "Not Inlining %s into %s because inlinee uses arguments "
- "array\n",
- name.get(), info_->shared_info()->DebugName()->ToCString().get());
- }
- return;
- }
-
- if (FLAG_trace_turbo_inlining) {
- SmartArrayPointer<char> name = function->shared()->DebugName()->ToCString();
- PrintF("Inlining %s into %s\n", name.get(),
- info_->shared_info()->DebugName()->ToCString().get());
- }
-
- Graph graph(info_->zone());
- graph.SetNextNodeId(jsgraph_->graph()->NextNodeID());
-
- Typer typer(info_->zone());
- CommonOperatorBuilder common(info_->zone());
- JSGraph jsgraph(&graph, &common, &typer);
-
- AstGraphBuilder graph_builder(&info, &jsgraph);
- graph_builder.CreateGraph();
-
- Inlinee inlinee(&jsgraph);
- inlinee.UnifyReturn();
- inlinee.InlineAtCall(jsgraph_, node);
-
- jsgraph_->graph()->SetNextNodeId(inlinee.graph()->NextNodeID());
-}
-}
-}
-} // namespace v8::internal::compiler
« no previous file with comments | « src/compiler/js-inlining.h ('k') | src/compiler/js-typed-lowering.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698