1e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org// Copyright 2014 the V8 project authors. All rights reserved.
2e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org// Use of this source code is governed by a BSD-style license that can be
3e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org// found in the LICENSE file.
4e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
52c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org#include "src/compiler/access-builder.h"
6e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org#include "src/compiler/ast-graph-builder.h"
7e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org#include "src/compiler/common-operator.h"
8e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org#include "src/compiler/generic-node-inl.h"
9e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org#include "src/compiler/graph-inl.h"
10e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org#include "src/compiler/graph-visualizer.h"
11e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org#include "src/compiler/js-inlining.h"
12e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org#include "src/compiler/js-operator.h"
13e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org#include "src/compiler/node-aux-data-inl.h"
14e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org#include "src/compiler/node-matchers.h"
15e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org#include "src/compiler/node-properties-inl.h"
16e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org#include "src/compiler/simplified-operator.h"
17e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org#include "src/compiler/typer.h"
18a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org#include "src/full-codegen.h"
19e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org#include "src/parser.h"
20e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org#include "src/rewriter.h"
21e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org#include "src/scopes.h"
22e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
23e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
24e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.orgnamespace v8 {
25e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.orgnamespace internal {
26e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.orgnamespace compiler {
27e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
28e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.orgclass InlinerVisitor : public NullNodeVisitor {
29e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org public:
30e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  explicit InlinerVisitor(JSInliner* inliner) : inliner_(inliner) {}
31e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
32e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  GenericGraphVisit::Control Post(Node* node) {
33e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    switch (node->opcode()) {
34e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      case IrOpcode::kJSCallFunction:
35e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org        inliner_->TryInlineCall(node);
36e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org        break;
37e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      default:
38e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org        break;
39e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    }
40e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    return GenericGraphVisit::CONTINUE;
41e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  }
42e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
43e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org private:
44e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  JSInliner* inliner_;
45e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org};
46e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
47e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
48e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.orgvoid JSInliner::Inline() {
49e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  InlinerVisitor visitor(this);
50e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  jsgraph_->graph()->VisitNodeInputsFromEnd(&visitor);
51e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org}
52e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
53e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
54e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org// TODO(sigurds) Find a home for this function and reuse it everywhere (esp. in
55e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org// test cases, where similar code is currently duplicated).
56e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.orgstatic void Parse(Handle<JSFunction> function, CompilationInfoWithZone* info) {
57e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  CHECK(Parser::Parse(info));
58e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  CHECK(Rewriter::Rewrite(info));
59e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  CHECK(Scope::Analyze(info));
60a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  CHECK(Compiler::EnsureDeoptimizationSupport(info));
61e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org}
62e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
63e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
64e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org// A facade on a JSFunction's graph to facilitate inlining. It assumes the
65e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org// that the function graph has only one return statement, and provides
66e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org// {UnifyReturn} to convert a function graph to that end.
67e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.orgclass Inlinee {
68e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org public:
69b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  Inlinee(Node* start, Node* end) : start_(start), end_(end) {}
70e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
71e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  // Returns the last regular control node, that is
72e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  // the last control node before the end node.
73e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Node* end_block() { return NodeProperties::GetControlInput(unique_return()); }
74e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
75e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  // Return the effect output of the graph,
76e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  // that is the effect input of the return statement of the inlinee.
77e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Node* effect_output() {
78e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    return NodeProperties::GetEffectInput(unique_return());
79e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  }
80e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  // Return the value output of the graph,
81e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  // that is the value input of the return statement of the inlinee.
82e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Node* value_output() {
83e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    return NodeProperties::GetValueInput(unique_return(), 0);
84e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  }
85e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  // Return the unique return statement of the graph.
86e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Node* unique_return() {
87b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    Node* unique_return = NodeProperties::GetControlInput(end_);
88e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    DCHECK_EQ(IrOpcode::kReturn, unique_return->opcode());
89e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    return unique_return;
90e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  }
91a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
92a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  // Counts JSFunction, Receiver, arguments, context but not effect, control.
93a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  size_t total_parameters() { return start_->op()->OutputCount(); }
94a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
95a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  // Counts only formal parameters.
96a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  size_t formal_parameters() {
97a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org    DCHECK_GE(total_parameters(), 3);
98a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org    return total_parameters() - 3;
99a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  }
100a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
101e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  // Inline this graph at {call}, use {jsgraph} and its zone to create
102e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  // any new nodes.
103e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  void InlineAtCall(JSGraph* jsgraph, Node* call);
104b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
105e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  // Ensure that only a single return reaches the end node.
106b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  static void UnifyReturn(JSGraph* jsgraph);
107e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
108e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org private:
109b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  Node* start_;
110b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  Node* end_;
111e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org};
112e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
113e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
114b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.orgvoid Inlinee::UnifyReturn(JSGraph* jsgraph) {
115b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  Graph* graph = jsgraph->graph();
116e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
117e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Node* final_merge = NodeProperties::GetControlInput(graph->end(), 0);
118e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  if (final_merge->opcode() == IrOpcode::kReturn) {
119e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    // nothing to do
120e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    return;
121e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  }
122e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  DCHECK_EQ(IrOpcode::kMerge, final_merge->opcode());
123e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
124e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  int predecessors =
125e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      OperatorProperties::GetControlInputCount(final_merge->op());
126e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
127b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  const Operator* op_phi = jsgraph->common()->Phi(kMachAnyTagged, predecessors);
128b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  const Operator* op_ephi = jsgraph->common()->EffectPhi(predecessors);
129b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
130b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  NodeVector values(jsgraph->zone());
131b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  NodeVector effects(jsgraph->zone());
132e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  // Iterate over all control flow predecessors,
133e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  // which must be return statements.
134e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  InputIter iter = final_merge->inputs().begin();
135e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  while (iter != final_merge->inputs().end()) {
136e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    Node* input = *iter;
137e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    switch (input->opcode()) {
138e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      case IrOpcode::kReturn:
139e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org        values.push_back(NodeProperties::GetValueInput(input, 0));
140e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org        effects.push_back(NodeProperties::GetEffectInput(input));
141e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org        iter.UpdateToAndIncrement(NodeProperties::GetControlInput(input));
142e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org        input->RemoveAllInputs();
143e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org        break;
144e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      default:
145e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org        UNREACHABLE();
146e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org        ++iter;
147e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org        break;
148e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    }
149e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  }
150e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  values.push_back(final_merge);
151e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  effects.push_back(final_merge);
152e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Node* phi =
153e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      graph->NewNode(op_phi, static_cast<int>(values.size()), &values.front());
154e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Node* ephi = graph->NewNode(op_ephi, static_cast<int>(effects.size()),
155e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org                              &effects.front());
156e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Node* new_return =
157b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      graph->NewNode(jsgraph->common()->Return(), phi, ephi, final_merge);
158e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  graph->end()->ReplaceInput(0, new_return);
159e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org}
160e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
161e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
162b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.orgclass CopyVisitor : public NullNodeVisitor {
163b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org public:
164b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  CopyVisitor(Graph* source_graph, Graph* target_graph, Zone* temp_zone)
165b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      : copies_(source_graph->NodeCount(), NULL, temp_zone),
166b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org        sentinels_(source_graph->NodeCount(), NULL, temp_zone),
167b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org        source_graph_(source_graph),
168b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org        target_graph_(target_graph),
169b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org        temp_zone_(temp_zone),
170b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org        sentinel_op_(IrOpcode::kDead, Operator::kNoProperties, 0, 0,
171b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org                     "sentinel") {}
172b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
173b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  GenericGraphVisit::Control Post(Node* original) {
174b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    NodeVector inputs(temp_zone_);
175b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    for (InputIter it = original->inputs().begin();
176b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org         it != original->inputs().end(); ++it) {
177b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      inputs.push_back(GetCopy(*it));
178b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    }
179b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
180b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    // Reuse the operator in the copy. This assumes that op lives in a zone
181b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    // that lives longer than graph()'s zone.
182b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    Node* copy =
183b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org        target_graph_->NewNode(original->op(), static_cast<int>(inputs.size()),
184b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org                               (inputs.empty() ? NULL : &inputs.front()));
185b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    copies_[original->id()] = copy;
186b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    return GenericGraphVisit::CONTINUE;
187b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  }
188b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
189b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  Node* GetCopy(Node* original) {
190b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    Node* copy = copies_[original->id()];
191b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    if (copy == NULL) {
192b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      copy = GetSentinel(original);
193b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    }
194b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    DCHECK_NE(NULL, copy);
195b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    return copy;
196b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  }
197b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
198b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  void CopyGraph() {
199b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    source_graph_->VisitNodeInputsFromEnd(this);
200b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    ReplaceSentinels();
201b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  }
202b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
203b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  const NodeVector& copies() { return copies_; }
204b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
205b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org private:
206b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  void ReplaceSentinels() {
207a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org    for (NodeId id = 0; id < source_graph_->NodeCount(); ++id) {
208b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      Node* sentinel = sentinels_[id];
209b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      if (sentinel == NULL) continue;
210b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      Node* copy = copies_[id];
211b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      DCHECK_NE(NULL, copy);
212b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      sentinel->ReplaceUses(copy);
213b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    }
214b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  }
215b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
216b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  Node* GetSentinel(Node* original) {
217b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    Node* sentinel = sentinels_[original->id()];
218b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    if (sentinel == NULL) {
219b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org      sentinel = target_graph_->NewNode(&sentinel_op_);
220b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    }
221b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org    return sentinel;
222b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  }
223b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
224b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  NodeVector copies_;
225b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  NodeVector sentinels_;
226b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  Graph* source_graph_;
227b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  Graph* target_graph_;
228b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  Zone* temp_zone_;
229b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  SimpleOperator sentinel_op_;
230b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org};
231b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
232b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org
233e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.orgvoid Inlinee::InlineAtCall(JSGraph* jsgraph, Node* call) {
234d71b62088ad094b1187c06c92d1f27fab56aaddbmachenbach@chromium.org  // The scheduler is smart enough to place our code; we just ensure {control}
235d71b62088ad094b1187c06c92d1f27fab56aaddbmachenbach@chromium.org  // becomes the control input of the start of the inlinee.
236e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Node* control = NodeProperties::GetControlInput(call);
237e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
238e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  // The inlinee uses the context from the JSFunction object. This will
239e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  // also be the effect dependency for the inlinee as it produces an effect.
2402c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org  SimplifiedOperatorBuilder simplified(jsgraph->zone());
241e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Node* context = jsgraph->graph()->NewNode(
2422c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      simplified.LoadField(AccessBuilder::ForJSFunctionContext()),
2432c81ceb7f1e1ccf5f304be0646f4c1375941a7f2machenbach@chromium.org      NodeProperties::GetValueInput(call, 0),
244e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      NodeProperties::GetEffectInput(call));
245e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
246e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  // Context is last argument.
247a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  int inlinee_context_index = static_cast<int>(total_parameters()) - 1;
248e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  // {inliner_inputs} counts JSFunction, Receiver, arguments, but not
249e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  // context, effect, control.
250e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  int inliner_inputs = OperatorProperties::GetValueInputCount(call->op());
251e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  // Iterate over all uses of the start node.
252b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  UseIter iter = start_->uses().begin();
253b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  while (iter != start_->uses().end()) {
254e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    Node* use = *iter;
255e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    switch (use->opcode()) {
256e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      case IrOpcode::kParameter: {
2571af4d9551ad496a28c342004b1a4e2a3840228f7machenbach@chromium.org        int index = 1 + OpParameter<int>(use->op());
258e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org        if (index < inliner_inputs && index < inlinee_context_index) {
259e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org          // There is an input from the call, and the index is a value
260e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org          // projection but not the context, so rewire the input.
261e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org          NodeProperties::ReplaceWithValue(*iter, call->InputAt(index));
262e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org        } else if (index == inlinee_context_index) {
263e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org          // This is the context projection, rewire it to the context from the
264e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org          // JSFunction object.
265e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org          NodeProperties::ReplaceWithValue(*iter, context);
266e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org        } else if (index < inlinee_context_index) {
267e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org          // Call has fewer arguments than required, fill with undefined.
268e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org          NodeProperties::ReplaceWithValue(*iter, jsgraph->UndefinedConstant());
269e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org        } else {
270e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org          // We got too many arguments, discard for now.
271e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org          // TODO(sigurds): Fix to treat arguments array correctly.
272e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org        }
273e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org        ++iter;
274e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org        break;
275e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      }
276e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      default:
277e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org        if (NodeProperties::IsEffectEdge(iter.edge())) {
278e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org          iter.UpdateToAndIncrement(context);
279e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org        } else if (NodeProperties::IsControlEdge(iter.edge())) {
280e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org          iter.UpdateToAndIncrement(control);
281e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org        } else {
282e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org          UNREACHABLE();
283e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org        }
284e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org        break;
285e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    }
286e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  }
287e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
288e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  // Iterate over all uses of the call node.
289e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  iter = call->uses().begin();
290e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  while (iter != call->uses().end()) {
291e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    if (NodeProperties::IsEffectEdge(iter.edge())) {
292e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      iter.UpdateToAndIncrement(effect_output());
293e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    } else if (NodeProperties::IsControlEdge(iter.edge())) {
294e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      UNREACHABLE();
295e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    } else {
296e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      DCHECK(NodeProperties::IsValueEdge(iter.edge()));
297e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      iter.UpdateToAndIncrement(value_output());
298e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    }
299e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  }
300e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  call->RemoveAllInputs();
301e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  DCHECK_EQ(0, call->UseCount());
302e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  // TODO(sigurds) Remove this once we copy.
303e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  unique_return()->RemoveAllInputs();
304e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org}
305e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
306e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
307a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org// TODO(turbofan) Provide such accessors for every node, possibly even
308a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org// generate them.
309a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.orgclass JSCallFunctionAccessor {
310a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org public:
311a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  explicit JSCallFunctionAccessor(Node* call) : call_(call) {
312a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org    DCHECK_EQ(IrOpcode::kJSCallFunction, call->opcode());
313a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  }
314a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
315a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  Node* jsfunction() { return call_->InputAt(0); }
316a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
317a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  Node* receiver() { return call_->InputAt(1); }
318a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
319a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  Node* formal_argument(size_t index) {
320a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org    DCHECK(index < formal_arguments());
321a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org    return call_->InputAt(static_cast<int>(2 + index));
322a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  }
323a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
324a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  size_t formal_arguments() {
325a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org    // {value_inputs} includes jsfunction and receiver.
326a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org    size_t value_inputs = OperatorProperties::GetValueInputCount(call_->op());
327a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org    DCHECK_GE(call_->InputCount(), 2);
328a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org    return value_inputs - 2;
329a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  }
330a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
331a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  Node* frame_state() { return NodeProperties::GetFrameStateInput(call_); }
332a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
333a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org private:
334a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  Node* call_;
335a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org};
336e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
337a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
338a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.orgvoid JSInliner::AddClosureToFrameState(Node* frame_state,
339a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org                                       Handle<JSFunction> jsfunction) {
340a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  FrameStateCallInfo call_info = OpParameter<FrameStateCallInfo>(frame_state);
341a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  const Operator* op = jsgraph_->common()->FrameState(
342a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      FrameStateType::JS_FRAME, call_info.bailout_id(),
343a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      call_info.state_combine(), jsfunction);
344a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  frame_state->set_op(op);
345a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org}
346a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
347a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
348a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.orgNode* JSInliner::CreateArgumentsAdaptorFrameState(JSCallFunctionAccessor* call,
349a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org                                                  Handle<JSFunction> jsfunction,
350a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org                                                  Zone* temp_zone) {
351a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  const Operator* op =
352a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      jsgraph_->common()->FrameState(FrameStateType::ARGUMENTS_ADAPTOR,
353a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org                                     BailoutId(-1), kIgnoreOutput, jsfunction);
354a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  const Operator* op0 = jsgraph_->common()->StateValues(0);
355a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  Node* node0 = jsgraph_->graph()->NewNode(op0);
356a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  NodeVector params(temp_zone);
357a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  params.push_back(call->receiver());
358a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  for (size_t argument = 0; argument != call->formal_arguments(); ++argument) {
359a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org    params.push_back(call->formal_argument(argument));
360a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  }
361a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  const Operator* op_param =
362a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      jsgraph_->common()->StateValues(static_cast<int>(params.size()));
363a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  Node* params_node = jsgraph_->graph()->NewNode(
364a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      op_param, static_cast<int>(params.size()), &params.front());
365a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  return jsgraph_->graph()->NewNode(op, params_node, node0, node0,
366a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org                                    jsgraph_->UndefinedConstant(),
367a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org                                    call->frame_state());
368a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org}
369a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
370a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
371a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.orgvoid JSInliner::TryInlineCall(Node* call_node) {
372a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  JSCallFunctionAccessor call(call_node);
373a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
374a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  HeapObjectMatcher<JSFunction> match(call.jsfunction());
375e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  if (!match.HasValue()) {
376e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    return;
377e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  }
378e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
379e20e19efeef112c26d0e63b1e5118e695b42d855machenbach@chromium.org  Handle<JSFunction> function = match.Value().handle();
380e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
381e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  if (function->shared()->native()) {
382e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    if (FLAG_trace_turbo_inlining) {
383e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      SmartArrayPointer<char> name =
384e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org          function->shared()->DebugName()->ToCString();
385e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      PrintF("Not Inlining %s into %s because inlinee is native\n", name.get(),
386e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org             info_->shared_info()->DebugName()->ToCString().get());
387e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    }
388e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    return;
389e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  }
390e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
391e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  CompilationInfoWithZone info(function);
392e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  Parse(function, &info);
393e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
394e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  if (info.scope()->arguments() != NULL) {
395e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    // For now do not inline functions that use their arguments array.
396e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    SmartArrayPointer<char> name = function->shared()->DebugName()->ToCString();
397e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    if (FLAG_trace_turbo_inlining) {
398e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org      PrintF(
399e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org          "Not Inlining %s into %s because inlinee uses arguments "
400e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org          "array\n",
401e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org          name.get(), info_->shared_info()->DebugName()->ToCString().get());
402e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    }
403e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    return;
404e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  }
405e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
406e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  if (FLAG_trace_turbo_inlining) {
407e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    SmartArrayPointer<char> name = function->shared()->DebugName()->ToCString();
408e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org    PrintF("Inlining %s into %s\n", name.get(),
409e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org           info_->shared_info()->DebugName()->ToCString().get());
410e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  }
411e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
412b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  Graph graph(info.zone());
413b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  Typer typer(info.zone());
414b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  JSGraph jsgraph(&graph, jsgraph_->common(), jsgraph_->javascript(), &typer,
415b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org                  jsgraph_->machine());
416e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
417e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  AstGraphBuilder graph_builder(&info, &jsgraph);
418e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org  graph_builder.CreateGraph();
419b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  Inlinee::UnifyReturn(&jsgraph);
420e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
421b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  CopyVisitor visitor(&graph, jsgraph_->graph(), info.zone());
422b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  visitor.CopyGraph();
423e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org
424b376fed08cb9d90a3f67f655adf63c4b35feb106machenbach@chromium.org  Inlinee inlinee(visitor.GetCopy(graph.start()), visitor.GetCopy(graph.end()));
425a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
426a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  Node* outer_frame_state = call.frame_state();
427a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  // Insert argument adaptor frame if required.
428a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  if (call.formal_arguments() != inlinee.formal_parameters()) {
429a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org    outer_frame_state =
430a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org        CreateArgumentsAdaptorFrameState(&call, function, info.zone());
431a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  }
432a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
433a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  for (NodeVectorConstIter it = visitor.copies().begin();
434a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org       it != visitor.copies().end(); ++it) {
435a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org    Node* node = *it;
436a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org    if (node != NULL && node->opcode() == IrOpcode::kFrameState) {
437a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      AddClosureToFrameState(node, function);
438a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org      NodeProperties::ReplaceFrameStateInput(node, outer_frame_state);
439a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org    }
440a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  }
441a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org
442a2c0c1516848536a514b3178d2c040b7df0ceb5bmachenbach@chromium.org  inlinee.InlineAtCall(jsgraph_, call_node);
443e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org}
444e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org}
445e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org}
446e2a8937454723a720c81acc3f9e4162b18999b43machenbach@chromium.org}  // namespace v8::internal::compiler
447