OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/ast-graph-builder.h" | 5 #include "src/compiler/ast-graph-builder.h" |
6 #include "src/compiler/common-operator.h" | 6 #include "src/compiler/common-operator.h" |
7 #include "src/compiler/generic-node-inl.h" | 7 #include "src/compiler/generic-node-inl.h" |
8 #include "src/compiler/graph-inl.h" | 8 #include "src/compiler/graph-inl.h" |
9 #include "src/compiler/graph-visualizer.h" | 9 #include "src/compiler/graph-visualizer.h" |
10 #include "src/compiler/js-inlining.h" | 10 #include "src/compiler/js-inlining.h" |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
42 JSInliner* inliner_; | 42 JSInliner* inliner_; |
43 }; | 43 }; |
44 | 44 |
45 | 45 |
46 void JSInliner::Inline() { | 46 void JSInliner::Inline() { |
47 InlinerVisitor visitor(this); | 47 InlinerVisitor visitor(this); |
48 jsgraph_->graph()->VisitNodeInputsFromEnd(&visitor); | 48 jsgraph_->graph()->VisitNodeInputsFromEnd(&visitor); |
49 } | 49 } |
50 | 50 |
51 | 51 |
52 static void MoveWithDependencies(Graph* graph, Node* node, Node* old_block, | |
53 Node* new_block) { | |
54 if (OperatorProperties::HasControlInput(node->op())) { | |
55 // Check if we have left the old_block. | |
56 if (NodeProperties::GetControlInput(node) != old_block) return; | |
57 // If not, move this node to the new_block. | |
58 NodeProperties::ReplaceControlInput(node, new_block); | |
59 } | |
60 // Independent of whether a node has a control input or not, | |
61 // it might have a dependency that is pinned to old_block. | |
62 for (InputIter iter = node->inputs().begin(); iter != node->inputs().end(); | |
63 ++iter) { | |
64 if (NodeProperties::IsControlEdge(iter.edge())) continue; | |
65 MoveWithDependencies(graph, *iter, old_block, new_block); | |
66 } | |
67 } | |
68 | |
69 | |
70 static void MoveAllControlNodes(Node* from, Node* to) { | |
71 for (UseIter iter = from->uses().begin(); iter != from->uses().end();) { | |
72 if (NodeProperties::IsControlEdge(iter.edge())) { | |
73 iter.UpdateToAndIncrement(to); | |
74 } else { | |
75 ++iter; | |
76 } | |
77 } | |
78 } | |
79 | |
80 | |
81 // TODO(sigurds) Find a home for this function and reuse it everywhere (esp. in | 52 // TODO(sigurds) Find a home for this function and reuse it everywhere (esp. in |
82 // test cases, where similar code is currently duplicated). | 53 // test cases, where similar code is currently duplicated). |
83 static void Parse(Handle<JSFunction> function, CompilationInfoWithZone* info) { | 54 static void Parse(Handle<JSFunction> function, CompilationInfoWithZone* info) { |
84 CHECK(Parser::Parse(info)); | 55 CHECK(Parser::Parse(info)); |
85 StrictMode strict_mode = info->function()->strict_mode(); | 56 StrictMode strict_mode = info->function()->strict_mode(); |
86 info->SetStrictMode(strict_mode); | 57 info->SetStrictMode(strict_mode); |
87 info->SetOptimizing(BailoutId::None(), Handle<Code>(function->code())); | 58 info->SetOptimizing(BailoutId::None(), Handle<Code>(function->code())); |
88 CHECK(Rewriter::Rewrite(info)); | 59 CHECK(Rewriter::Rewrite(info)); |
89 CHECK(Scope::Analyze(info)); | 60 CHECK(Scope::Analyze(info)); |
90 CHECK_NE(NULL, info->scope()); | 61 CHECK_NE(NULL, info->scope()); |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
180 &effects.front()); | 151 &effects.front()); |
181 Node* new_return = | 152 Node* new_return = |
182 graph->NewNode(jsgraph_->common()->Return(), phi, ephi, final_merge); | 153 graph->NewNode(jsgraph_->common()->Return(), phi, ephi, final_merge); |
183 graph->end()->ReplaceInput(0, new_return); | 154 graph->end()->ReplaceInput(0, new_return); |
184 } | 155 } |
185 | 156 |
186 | 157 |
187 void Inlinee::InlineAtCall(JSGraph* jsgraph, Node* call) { | 158 void Inlinee::InlineAtCall(JSGraph* jsgraph, Node* call) { |
188 MachineOperatorBuilder machine(jsgraph->zone()); | 159 MachineOperatorBuilder machine(jsgraph->zone()); |
189 | 160 |
| 161 // The scheduler is smart enough to place our code; we just ensure {control} |
| 162 // becomes the control input of the start of the inlinee. |
190 Node* control = NodeProperties::GetControlInput(call); | 163 Node* control = NodeProperties::GetControlInput(call); |
191 // Move all the nodes to the end block. | |
192 MoveAllControlNodes(control, end_block()); | |
193 // Now move the ones the call depends on back up. | |
194 // We have to do this back-and-forth to treat the case where the call is | |
195 // pinned to the start block. | |
196 MoveWithDependencies(graph(), call, end_block(), control); | |
197 | 164 |
198 // The inlinee uses the context from the JSFunction object. This will | 165 // The inlinee uses the context from the JSFunction object. This will |
199 // also be the effect dependency for the inlinee as it produces an effect. | 166 // also be the effect dependency for the inlinee as it produces an effect. |
200 // TODO(sigurds) Use simplified load once it is ready. | 167 // TODO(sigurds) Use simplified load once it is ready. |
201 Node* context = jsgraph->graph()->NewNode( | 168 Node* context = jsgraph->graph()->NewNode( |
202 machine.Load(kMachAnyTagged), NodeProperties::GetValueInput(call, 0), | 169 machine.Load(kMachAnyTagged), NodeProperties::GetValueInput(call, 0), |
203 jsgraph->Int32Constant(JSFunction::kContextOffset - kHeapObjectTag), | 170 jsgraph->Int32Constant(JSFunction::kContextOffset - kHeapObjectTag), |
204 NodeProperties::GetEffectInput(call)); | 171 NodeProperties::GetEffectInput(call)); |
205 | 172 |
206 // {inlinee_inputs} counts JSFunction, Receiver, arguments, context, | 173 // {inlinee_inputs} counts JSFunction, Receiver, arguments, context, |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
320 | 287 |
321 Inlinee inlinee(&jsgraph); | 288 Inlinee inlinee(&jsgraph); |
322 inlinee.UnifyReturn(); | 289 inlinee.UnifyReturn(); |
323 inlinee.InlineAtCall(jsgraph_, node); | 290 inlinee.InlineAtCall(jsgraph_, node); |
324 | 291 |
325 jsgraph_->graph()->SetNextNodeId(inlinee.graph()->NextNodeID()); | 292 jsgraph_->graph()->SetNextNodeId(inlinee.graph()->NextNodeID()); |
326 } | 293 } |
327 } | 294 } |
328 } | 295 } |
329 } // namespace v8::internal::compiler | 296 } // namespace v8::internal::compiler |
OLD | NEW |