| 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 |