LCOV - code coverage report
Current view: top level - src/compiler - tail-call-optimization.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 15 15 100.0 %
Date: 2017-04-26 Functions: 1 1 100.0 %

          Line data    Source code
       1             : // Copyright 2015 the V8 project authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file.
       4             : 
       5             : #include "src/compiler/tail-call-optimization.h"
       6             : 
       7             : #include "src/compiler/common-operator.h"
       8             : #include "src/compiler/graph.h"
       9             : #include "src/compiler/linkage.h"
      10             : #include "src/compiler/node-matchers.h"
      11             : #include "src/compiler/node-properties.h"
      12             : 
      13             : namespace v8 {
      14             : namespace internal {
      15             : namespace compiler {
      16             : 
      17    44498710 : Reduction TailCallOptimization::Reduce(Node* node) {
      18    44495489 :   if (node->opcode() != IrOpcode::kReturn) return NoChange();
      19             :   // The value which is returned must be the result of a potential tail call,
      20             :   // there must be no try/catch/finally around the Call, and there must be no
      21             :   // other effect or control between the Call and the Return nodes.
      22      566517 :   Node* const call = NodeProperties::GetValueInput(node, 1);
      23      819789 :   if (call->opcode() == IrOpcode::kCall &&
      24      256852 :       CallDescriptorOf(call->op())->SupportsTailCalls() &&
      25         714 :       NodeProperties::GetEffectInput(node) == call &&
      26         712 :       NodeProperties::GetControlInput(node) == call &&
      27      564004 :       !NodeProperties::IsExceptionalCall(call) && call->UseCount() == 3) {
      28             :     // Ensure that no additional arguments are being popped other than those in
      29             :     // the CallDescriptor, otherwise the tail call transformation is invalid.
      30             :     DCHECK_EQ(0, Int32Matcher(NodeProperties::GetValueInput(node, 0)).Value());
      31             :     // Furthermore, the Return node value, effect, and control depends
      32             :     // directly on the Call, no other uses of the Call node exist.
      33             :     //
      34             :     // The input graph looks as follows:
      35             : 
      36             :     // Value1 ... ValueN Effect Control
      37             :     //   ^          ^      ^       ^
      38             :     //   |          |      |       |
      39             :     //   |          +--+ +-+       |
      40             :     //   +----------+  | |  +------+
      41             :     //               \ | | /
      42             :     //             Call[Descriptor]
      43             :     //                ^ ^ ^
      44             :     //  Int32(0) <-+  | | |
      45             :     //              \ | | |
      46             :     //               Return
      47             :     //                  ^
      48             :     //                  |
      49             : 
      50             :     // The resulting graph looks like this:
      51             : 
      52             :     // Value1 ... ValueN Effect Control
      53             :     //   ^          ^      ^       ^
      54             :     //   |          |      |       |
      55             :     //   |          +--+ +-+       |
      56             :     //   +----------+  | |  +------+
      57             :     //               \ | | /
      58             :     //           TailCall[Descriptor]
      59             :     //                 ^
      60             :     //                 |
      61             : 
      62             :     DCHECK_EQ(4, node->InputCount());
      63         355 :     node->ReplaceInput(0, NodeProperties::GetEffectInput(call));
      64         355 :     node->ReplaceInput(1, NodeProperties::GetControlInput(call));
      65         355 :     node->RemoveInput(3);
      66         355 :     node->RemoveInput(2);
      67        9663 :     for (int index = 0; index < call->op()->ValueInputCount(); ++index) {
      68             :       node->InsertInput(graph()->zone(), index,
      69        5732 :                         NodeProperties::GetValueInput(call, index));
      70             :     }
      71             :     NodeProperties::ChangeOp(node,
      72         710 :                              common()->TailCall(CallDescriptorOf(call->op())));
      73             :     return Changed(node);
      74             :   }
      75             :   return NoChange();
      76             : }
      77             : 
      78             : }  // namespace compiler
      79             : }  // namespace internal
      80             : }  // namespace v8

Generated by: LCOV version 1.10