// Copyright 2013 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 <functional>

#include "src/compiler/graph.h"
#include "src/compiler/node.h"
#include "src/compiler/operator.h"
#include "test/cctest/cctest.h"

namespace v8 {
namespace internal {
namespace compiler {
namespace node {

#define NONE reinterpret_cast<Node*>(1)

static Operator dummy_operator0(IrOpcode::kParameter, Operator::kNoWrite,
                                "dummy", 0, 0, 0, 1, 0, 0);
static Operator dummy_operator1(IrOpcode::kParameter, Operator::kNoWrite,
                                "dummy", 1, 0, 0, 1, 0, 0);
static Operator dummy_operator2(IrOpcode::kParameter, Operator::kNoWrite,
                                "dummy", 2, 0, 0, 1, 0, 0);
static Operator dummy_operator3(IrOpcode::kParameter, Operator::kNoWrite,
                                "dummy", 3, 0, 0, 1, 0, 0);

#define CHECK_USES(node, ...)                                          \
  do {                                                                 \
    Node* __array[] = {__VA_ARGS__};                                   \
    int __size =                                                       \
        __array[0] != NONE ? static_cast<int>(arraysize(__array)) : 0; \
    CheckUseChain(node, __array, __size);                              \
  } while (false)


namespace {

using NodeMSet = std::multiset<Node*, std::less<Node*>>;

void CheckUseChain(Node* node, Node** uses, int use_count) {
  // Check ownership.
  if (use_count == 1) CHECK(node->OwnedBy(uses[0]));
  if (use_count > 1) {
    for (int i = 0; i < use_count; i++) {
      CHECK(!node->OwnedBy(uses[i]));
    }
  }

  // Check the self-reported use count.
  CHECK_EQ(use_count, node->UseCount());

  // Build the expectation set.
  NodeMSet expect_set;
  for (int i = 0; i < use_count; i++) {
    expect_set.insert(uses[i]);
  }

  {
    // Check that iterating over the uses gives the right counts.
    NodeMSet use_set;
    for (auto use : node->uses()) {
      use_set.insert(use);
    }
    CHECK(expect_set == use_set);
  }

  {
    // Check that iterating over the use edges gives the right counts,
    // input indices, from(), and to() pointers.
    NodeMSet use_set;
    for (auto edge : node->use_edges()) {
      CHECK_EQ(node, edge.to());
      CHECK_EQ(node, edge.from()->InputAt(edge.index()));
      use_set.insert(edge.from());
    }
    CHECK(expect_set == use_set);
  }

  {
    // Check the use nodes actually have the node as inputs.
    for (Node* use : node->uses()) {
      size_t count = 0;
      for (Node* input : use->inputs()) {
        if (input == node) count++;
      }
      CHECK_EQ(count, expect_set.count(use));
    }
  }
}


void CheckInputs(Node* node, Node** inputs, int input_count) {
  CHECK_EQ(input_count, node->InputCount());
  // Check InputAt().
  for (int i = 0; i < static_cast<int>(input_count); i++) {
    CHECK_EQ(inputs[i], node->InputAt(i));
  }

  // Check input iterator.
  int index = 0;
  for (Node* input : node->inputs()) {
    CHECK_EQ(inputs[index], input);
    index++;
  }

  // Check use lists of inputs.
  for (int i = 0; i < static_cast<int>(input_count); i++) {
    Node* input = inputs[i];
    if (!input) continue;  // skip null inputs
    bool found = false;
    // Check regular use list.
    for (Node* use : input->uses()) {
      if (use == node) {
        found = true;
        break;
      }
    }
    CHECK(found);
    int count = 0;
    // Check use edge list.
    for (auto edge : input->use_edges()) {
      if (edge.from() == node && edge.to() == input && edge.index() == i) {
        count++;
      }
    }
    CHECK_EQ(1, count);
  }
}

}  // namespace


#define CHECK_INPUTS(node, ...)                                        \
  do {                                                                 \
    Node* __array[] = {__VA_ARGS__};                                   \
    int __size =                                                       \
        __array[0] != NONE ? static_cast<int>(arraysize(__array)) : 0; \
    CheckInputs(node, __array, __size);                                \
  } while (false)


TEST(NodeUseIteratorReplaceUses) {
  v8::internal::AccountingAllocator allocator;
  Zone zone(&allocator, ZONE_NAME);
  Graph graph(&zone);
  Node* n0 = graph.NewNode(&dummy_operator0);
  Node* n1 = graph.NewNode(&dummy_operator1, n0);
  Node* n2 = graph.NewNode(&dummy_operator1, n0);
  Node* n3 = graph.NewNode(&dummy_operator0);

  CHECK_USES(n0, n1, n2);

  CHECK_INPUTS(n1, n0);
  CHECK_INPUTS(n2, n0);

  n0->ReplaceUses(n3);

  CHECK_USES(n0, NONE);
  CHECK_USES(n1, NONE);
  CHECK_USES(n2, NONE);
  CHECK_USES(n3, n1, n2);

  CHECK_INPUTS(n1, n3);
  CHECK_INPUTS(n2, n3);
}


TEST(NodeUseIteratorReplaceUsesSelf) {
  v8::internal::AccountingAllocator allocator;
  Zone zone(&allocator, ZONE_NAME);
  Graph graph(&zone);
  Node* n0 = graph.NewNode(&dummy_operator0);
  Node* n1 = graph.NewNode(&dummy_operator1, n0);

  CHECK_USES(n0, n1);
  CHECK_USES(n1, NONE);

  n1->ReplaceInput(0, n1);  // Create self-reference.

  CHECK_USES(n0, NONE);
  CHECK_USES(n1, n1);

  Node* n2 = graph.NewNode(&dummy_operator0);

  n1->ReplaceUses(n2);

  CHECK_USES(n0, NONE);
  CHECK_USES(n1, NONE);
  CHECK_USES(n2, n1);
}


TEST(ReplaceInput) {
  v8::internal::AccountingAllocator allocator;
  Zone zone(&allocator, ZONE_NAME);
  Graph graph(&zone);
  Node* n0 = graph.NewNode(&dummy_operator0);
  Node* n1 = graph.NewNode(&dummy_operator0);
  Node* n2 = graph.NewNode(&dummy_operator0);
  Node* n3 = graph.NewNode(&dummy_operator3, n0, n1, n2);
  Node* n4 = graph.NewNode(&dummy_operator0);

  CHECK_USES(n0, n3);
  CHECK_USES(n1, n3);
  CHECK_USES(n2, n3);
  CHECK_USES(n3, NONE);
  CHECK_USES(n4, NONE);

  CHECK_INPUTS(n3, n0, n1, n2);

  n3->ReplaceInput(1, n4);

  CHECK_USES(n1, NONE);
  CHECK_USES(n4, n3);

  CHECK_INPUTS(n3, n0, n4, n2);
}


TEST(OwnedBy) {
  v8::internal::AccountingAllocator allocator;
  Zone zone(&allocator, ZONE_NAME);
  Graph graph(&zone);

  {
    Node* n0 = graph.NewNode(&dummy_operator0);
    Node* n1 = graph.NewNode(&dummy_operator0);

    CHECK(!n0->OwnedBy(n1));
    CHECK(!n1->OwnedBy(n0));

    Node* n2 = graph.NewNode(&dummy_operator1, n0);
    CHECK(n0->OwnedBy(n2));
    CHECK(!n2->OwnedBy(n0));

    Node* n3 = graph.NewNode(&dummy_operator1, n0);
    CHECK(!n0->OwnedBy(n2));
    CHECK(!n0->OwnedBy(n3));
    CHECK(!n2->OwnedBy(n0));
    CHECK(!n3->OwnedBy(n0));
  }

  {
    Node* n0 = graph.NewNode(&dummy_operator0);
    Node* n1 = graph.NewNode(&dummy_operator1, n0);
    CHECK(n0->OwnedBy(n1));
    CHECK(!n1->OwnedBy(n0));
    Node* n2 = graph.NewNode(&dummy_operator1, n0);
    CHECK(!n0->OwnedBy(n1));
    CHECK(!n0->OwnedBy(n2));
    CHECK(!n1->OwnedBy(n0));
    CHECK(!n1->OwnedBy(n2));
    CHECK(!n2->OwnedBy(n0));
    CHECK(!n2->OwnedBy(n1));

    Node* n3 = graph.NewNode(&dummy_operator0);
    n2->ReplaceInput(0, n3);

    CHECK(n0->OwnedBy(n1));
    CHECK(!n1->OwnedBy(n0));
    CHECK(!n1->OwnedBy(n0));
    CHECK(!n1->OwnedBy(n2));
    CHECK(!n2->OwnedBy(n0));
    CHECK(!n2->OwnedBy(n1));
    CHECK(n3->OwnedBy(n2));
    CHECK(!n2->OwnedBy(n3));
  }
}


TEST(Uses) {
  v8::internal::AccountingAllocator allocator;
  Zone zone(&allocator, ZONE_NAME);
  Graph graph(&zone);

  Node* n0 = graph.NewNode(&dummy_operator0);
  Node* n1 = graph.NewNode(&dummy_operator1, n0);

  CHECK_USES(n0, n1);
  CHECK_USES(n1, NONE);

  Node* n2 = graph.NewNode(&dummy_operator1, n0);

  CHECK_USES(n0, n1, n2);
  CHECK_USES(n2, NONE);

  Node* n3 = graph.NewNode(&dummy_operator1, n0);

  CHECK_USES(n0, n1, n2, n3);
  CHECK_USES(n3, NONE);
}


TEST(Inputs) {
  v8::internal::AccountingAllocator allocator;
  Zone zone(&allocator, ZONE_NAME);
  Graph graph(&zone);

  Node* n0 = graph.NewNode(&dummy_operator0);
  Node* n1 = graph.NewNode(&dummy_operator1, n0);
  Node* n2 = graph.NewNode(&dummy_operator1, n0);
  Node* n3 = graph.NewNode(&dummy_operator3, n0, n1, n2);

  CHECK_INPUTS(n3, n0, n1, n2);

  Node* n4 = graph.NewNode(&dummy_operator3, n0, n1, n2);
  n3->AppendInput(graph.zone(), n4);

  CHECK_INPUTS(n3, n0, n1, n2, n4);
  CHECK_USES(n4, n3);

  n3->AppendInput(graph.zone(), n4);

  CHECK_INPUTS(n3, n0, n1, n2, n4, n4);
  CHECK_USES(n4, n3, n3);

  Node* n5 = graph.NewNode(&dummy_operator1, n4);

  CHECK_USES(n4, n3, n3, n5);
}

TEST(InsertInputs) {
  v8::internal::AccountingAllocator allocator;
  Zone zone(&allocator, ZONE_NAME);
  Graph graph(&zone);

  Node* n0 = graph.NewNode(&dummy_operator0);
  Node* n1 = graph.NewNode(&dummy_operator1, n0);
  Node* n2 = graph.NewNode(&dummy_operator1, n0);

  {
    Node* node = graph.NewNode(&dummy_operator1, n0);
    node->InsertInputs(graph.zone(), 0, 1);
    node->ReplaceInput(0, n1);
    CHECK_INPUTS(node, n1, n0);
  }
  {
    Node* node = graph.NewNode(&dummy_operator1, n0);
    node->InsertInputs(graph.zone(), 0, 2);
    node->ReplaceInput(0, node);
    node->ReplaceInput(1, n2);
    CHECK_INPUTS(node, node, n2, n0);
  }
  {
    Node* node = graph.NewNode(&dummy_operator3, n0, n1, n2);
    node->InsertInputs(graph.zone(), 0, 1);
    node->ReplaceInput(0, node);
    CHECK_INPUTS(node, node, n0, n1, n2);
  }
  {
    Node* node = graph.NewNode(&dummy_operator3, n0, n1, n2);
    node->InsertInputs(graph.zone(), 1, 1);
    node->ReplaceInput(1, node);
    CHECK_INPUTS(node, n0, node, n1, n2);
  }
  {
    Node* node = graph.NewNode(&dummy_operator3, n0, n1, n2);
    node->InsertInputs(graph.zone(), 2, 1);
    node->ReplaceInput(2, node);
    CHECK_INPUTS(node, n0, n1, node, n2);
  }
  {
    Node* node = graph.NewNode(&dummy_operator3, n0, n1, n2);
    node->InsertInputs(graph.zone(), 2, 1);
    node->ReplaceInput(2, node);
    CHECK_INPUTS(node, n0, n1, node, n2);
  }
  {
    Node* node = graph.NewNode(&dummy_operator3, n0, n1, n2);
    node->InsertInputs(graph.zone(), 0, 4);
    node->ReplaceInput(0, node);
    node->ReplaceInput(1, node);
    node->ReplaceInput(2, node);
    node->ReplaceInput(3, node);
    CHECK_INPUTS(node, node, node, node, node, n0, n1, n2);
  }
  {
    Node* node = graph.NewNode(&dummy_operator3, n0, n1, n2);
    node->InsertInputs(graph.zone(), 1, 4);
    node->ReplaceInput(1, node);
    node->ReplaceInput(2, node);
    node->ReplaceInput(3, node);
    node->ReplaceInput(4, node);
    CHECK_INPUTS(node, n0, node, node, node, node, n1, n2);
  }
  {
    Node* node = graph.NewNode(&dummy_operator3, n0, n1, n2);
    node->InsertInputs(graph.zone(), 2, 4);
    node->ReplaceInput(2, node);
    node->ReplaceInput(3, node);
    node->ReplaceInput(4, node);
    node->ReplaceInput(5, node);
    CHECK_INPUTS(node, n0, n1, node, node, node, node, n2);
  }
}

TEST(RemoveInput) {
  v8::internal::AccountingAllocator allocator;
  Zone zone(&allocator, ZONE_NAME);
  Graph graph(&zone);

  Node* n0 = graph.NewNode(&dummy_operator0);
  Node* n1 = graph.NewNode(&dummy_operator1, n0);
  Node* n2 = graph.NewNode(&dummy_operator2, n0, n1);

  CHECK_INPUTS(n0, NONE);
  CHECK_INPUTS(n1, n0);
  CHECK_INPUTS(n2, n0, n1);
  CHECK_USES(n0, n1, n2);

  n1->RemoveInput(0);
  CHECK_INPUTS(n1, NONE);
  CHECK_USES(n0, n2);

  n2->RemoveInput(0);
  CHECK_INPUTS(n2, n1);
  CHECK_USES(n0, NONE);
  CHECK_USES(n1, n2);

  n2->RemoveInput(0);
  CHECK_INPUTS(n2, NONE);
  CHECK_USES(n0, NONE);
  CHECK_USES(n1, NONE);
  CHECK_USES(n2, NONE);
}


TEST(AppendInputsAndIterator) {
  v8::internal::AccountingAllocator allocator;
  Zone zone(&allocator, ZONE_NAME);
  Graph graph(&zone);

  Node* n0 = graph.NewNode(&dummy_operator0);
  Node* n1 = graph.NewNode(&dummy_operator1, n0);
  Node* n2 = graph.NewNode(&dummy_operator2, n0, n1);

  CHECK_INPUTS(n0, NONE);
  CHECK_INPUTS(n1, n0);
  CHECK_INPUTS(n2, n0, n1);
  CHECK_USES(n0, n1, n2);

  Node* n3 = graph.NewNode(&dummy_operator0);

  n2->AppendInput(graph.zone(), n3);

  CHECK_INPUTS(n2, n0, n1, n3);
  CHECK_USES(n3, n2);
}


TEST(NullInputsSimple) {
  v8::internal::AccountingAllocator allocator;
  Zone zone(&allocator, ZONE_NAME);
  Graph graph(&zone);

  Node* n0 = graph.NewNode(&dummy_operator0);
  Node* n1 = graph.NewNode(&dummy_operator1, n0);
  Node* n2 = graph.NewNode(&dummy_operator2, n0, n1);

  CHECK_INPUTS(n0, NONE);
  CHECK_INPUTS(n1, n0);
  CHECK_INPUTS(n2, n0, n1);
  CHECK_USES(n0, n1, n2);

  n2->ReplaceInput(0, nullptr);

  CHECK_INPUTS(n2, nullptr, n1);

  CHECK_USES(n0, n1);

  n2->ReplaceInput(1, nullptr);

  CHECK_INPUTS(n2, nullptr, nullptr);

  CHECK_USES(n1, NONE);
}


TEST(NullInputsAppended) {
  v8::internal::AccountingAllocator allocator;
  Zone zone(&allocator, ZONE_NAME);
  Graph graph(&zone);

  Node* n0 = graph.NewNode(&dummy_operator0);
  Node* n1 = graph.NewNode(&dummy_operator1, n0);
  Node* n2 = graph.NewNode(&dummy_operator1, n0);
  Node* n3 = graph.NewNode(&dummy_operator1, n0);
  n3->AppendInput(graph.zone(), n1);
  n3->AppendInput(graph.zone(), n2);

  CHECK_INPUTS(n3, n0, n1, n2);
  CHECK_USES(n0, n1, n2, n3);
  CHECK_USES(n1, n3);
  CHECK_USES(n2, n3);

  n3->ReplaceInput(1, nullptr);
  CHECK_USES(n1, NONE);

  CHECK_INPUTS(n3, n0, nullptr, n2);
}


TEST(ReplaceUsesFromAppendedInputs) {
  v8::internal::AccountingAllocator allocator;
  Zone zone(&allocator, ZONE_NAME);
  Graph graph(&zone);

  Node* n0 = graph.NewNode(&dummy_operator0);
  Node* n1 = graph.NewNode(&dummy_operator1, n0);
  Node* n2 = graph.NewNode(&dummy_operator1, n0);
  Node* n3 = graph.NewNode(&dummy_operator0);

  CHECK_INPUTS(n2, n0);

  n2->AppendInput(graph.zone(), n1);
  CHECK_INPUTS(n2, n0, n1);
  CHECK_USES(n1, n2);

  n2->AppendInput(graph.zone(), n0);
  CHECK_INPUTS(n2, n0, n1, n0);
  CHECK_USES(n1, n2);
  CHECK_USES(n0, n2, n1, n2);

  n0->ReplaceUses(n3);

  CHECK_USES(n0, NONE);
  CHECK_INPUTS(n2, n3, n1, n3);
  CHECK_USES(n3, n2, n1, n2);
}


TEST(ReplaceInputMultipleUses) {
  v8::internal::AccountingAllocator allocator;
  Zone zone(&allocator, ZONE_NAME);
  Graph graph(&zone);

  Node* n0 = graph.NewNode(&dummy_operator0);
  Node* n1 = graph.NewNode(&dummy_operator0);
  Node* n2 = graph.NewNode(&dummy_operator1, n0);
  n2->ReplaceInput(0, n1);
  CHECK_EQ(0, n0->UseCount());
  CHECK_EQ(1, n1->UseCount());

  Node* n3 = graph.NewNode(&dummy_operator1, n0);
  n3->ReplaceInput(0, n1);
  CHECK_EQ(0, n0->UseCount());
  CHECK_EQ(2, n1->UseCount());
}


TEST(TrimInputCountInline) {
  v8::internal::AccountingAllocator allocator;
  Zone zone(&allocator, ZONE_NAME);
  Graph graph(&zone);

  {
    Node* n0 = graph.NewNode(&dummy_operator0);
    Node* n1 = graph.NewNode(&dummy_operator1, n0);
    n1->TrimInputCount(1);
    CHECK_INPUTS(n1, n0);
    CHECK_USES(n0, n1);
  }

  {
    Node* n0 = graph.NewNode(&dummy_operator0);
    Node* n1 = graph.NewNode(&dummy_operator1, n0);
    n1->TrimInputCount(0);
    CHECK_INPUTS(n1, NONE);
    CHECK_USES(n0, NONE);
  }

  {
    Node* n0 = graph.NewNode(&dummy_operator0);
    Node* n1 = graph.NewNode(&dummy_operator0);
    Node* n2 = graph.NewNode(&dummy_operator2, n0, n1);
    n2->TrimInputCount(2);
    CHECK_INPUTS(n2, n0, n1);
    CHECK_USES(n0, n2);
    CHECK_USES(n1, n2);
  }

  {
    Node* n0 = graph.NewNode(&dummy_operator0);
    Node* n1 = graph.NewNode(&dummy_operator0);
    Node* n2 = graph.NewNode(&dummy_operator2, n0, n1);
    n2->TrimInputCount(1);
    CHECK_INPUTS(n2, n0);
    CHECK_USES(n0, n2);
    CHECK_USES(n1, NONE);
  }

  {
    Node* n0 = graph.NewNode(&dummy_operator0);
    Node* n1 = graph.NewNode(&dummy_operator0);
    Node* n2 = graph.NewNode(&dummy_operator2, n0, n1);
    n2->TrimInputCount(0);
    CHECK_INPUTS(n2, NONE);
    CHECK_USES(n0, NONE);
    CHECK_USES(n1, NONE);
  }

  {
    Node* n0 = graph.NewNode(&dummy_operator0);
    Node* n2 = graph.NewNode(&dummy_operator2, n0, n0);
    n2->TrimInputCount(1);
    CHECK_INPUTS(n2, n0);
    CHECK_USES(n0, n2);
  }

  {
    Node* n0 = graph.NewNode(&dummy_operator0);
    Node* n2 = graph.NewNode(&dummy_operator2, n0, n0);
    n2->TrimInputCount(0);
    CHECK_INPUTS(n2, NONE);
    CHECK_USES(n0, NONE);
  }
}


TEST(TrimInputCountOutOfLine1) {
  v8::internal::AccountingAllocator allocator;
  Zone zone(&allocator, ZONE_NAME);
  Graph graph(&zone);

  {
    Node* n0 = graph.NewNode(&dummy_operator0);
    Node* n1 = graph.NewNode(&dummy_operator0);
    n1->AppendInput(graph.zone(), n0);
    CHECK_INPUTS(n1, n0);
    CHECK_USES(n0, n1);

    n1->TrimInputCount(1);
    CHECK_INPUTS(n1, n0);
    CHECK_USES(n0, n1);
  }

  {
    Node* n0 = graph.NewNode(&dummy_operator0);
    Node* n1 = graph.NewNode(&dummy_operator0);
    n1->AppendInput(graph.zone(), n0);
    CHECK_EQ(1, n1->InputCount());
    n1->TrimInputCount(0);
    CHECK_EQ(0, n1->InputCount());
    CHECK_EQ(0, n0->UseCount());
  }

  {
    Node* n0 = graph.NewNode(&dummy_operator0);
    Node* n1 = graph.NewNode(&dummy_operator0);
    Node* n2 = graph.NewNode(&dummy_operator0);
    n2->AppendInput(graph.zone(), n0);
    n2->AppendInput(graph.zone(), n1);
    CHECK_INPUTS(n2, n0, n1);
    n2->TrimInputCount(2);
    CHECK_INPUTS(n2, n0, n1);
    CHECK_USES(n0, n2);
    CHECK_USES(n1, n2);
    CHECK_USES(n2, NONE);
  }

  {
    Node* n0 = graph.NewNode(&dummy_operator0);
    Node* n1 = graph.NewNode(&dummy_operator0);
    Node* n2 = graph.NewNode(&dummy_operator0);
    n2->AppendInput(graph.zone(), n0);
    n2->AppendInput(graph.zone(), n1);
    CHECK_INPUTS(n2, n0, n1);
    n2->TrimInputCount(1);
    CHECK_INPUTS(n2, n0);
    CHECK_USES(n0, n2);
    CHECK_USES(n1, NONE);
    CHECK_USES(n2, NONE);
  }

  {
    Node* n0 = graph.NewNode(&dummy_operator0);
    Node* n1 = graph.NewNode(&dummy_operator0);
    Node* n2 = graph.NewNode(&dummy_operator0);
    n2->AppendInput(graph.zone(), n0);
    n2->AppendInput(graph.zone(), n1);
    CHECK_INPUTS(n2, n0, n1);
    n2->TrimInputCount(0);
    CHECK_INPUTS(n2, NONE);
    CHECK_USES(n0, NONE);
    CHECK_USES(n1, NONE);
    CHECK_USES(n2, NONE);
  }

  {
    Node* n0 = graph.NewNode(&dummy_operator0);
    Node* n2 = graph.NewNode(&dummy_operator0);
    n2->AppendInput(graph.zone(), n0);
    n2->AppendInput(graph.zone(), n0);
    CHECK_INPUTS(n2, n0, n0);
    CHECK_USES(n0, n2, n2);
    n2->TrimInputCount(1);
    CHECK_INPUTS(n2, n0);
    CHECK_USES(n0, n2);
  }

  {
    Node* n0 = graph.NewNode(&dummy_operator0);
    Node* n2 = graph.NewNode(&dummy_operator0);
    n2->AppendInput(graph.zone(), n0);
    n2->AppendInput(graph.zone(), n0);
    CHECK_INPUTS(n2, n0, n0);
    CHECK_USES(n0, n2, n2);
    n2->TrimInputCount(0);
    CHECK_INPUTS(n2, NONE);
    CHECK_USES(n0, NONE);
  }
}


TEST(TrimInputCountOutOfLine2) {
  v8::internal::AccountingAllocator allocator;
  Zone zone(&allocator, ZONE_NAME);
  Graph graph(&zone);

  {
    Node* n0 = graph.NewNode(&dummy_operator0);
    Node* n1 = graph.NewNode(&dummy_operator0);
    Node* n2 = graph.NewNode(&dummy_operator1, n0);
    n2->AppendInput(graph.zone(), n1);
    CHECK_INPUTS(n2, n0, n1);
    n2->TrimInputCount(2);
    CHECK_INPUTS(n2, n0, n1);
    CHECK_USES(n0, n2);
    CHECK_USES(n1, n2);
    CHECK_USES(n2, NONE);
  }

  {
    Node* n0 = graph.NewNode(&dummy_operator0);
    Node* n1 = graph.NewNode(&dummy_operator0);
    Node* n2 = graph.NewNode(&dummy_operator1, n0);
    n2->AppendInput(graph.zone(), n1);
    CHECK_INPUTS(n2, n0, n1);
    n2->TrimInputCount(1);
    CHECK_INPUTS(n2, n0);
    CHECK_USES(n0, n2);
    CHECK_USES(n1, NONE);
    CHECK_USES(n2, NONE);
  }

  {
    Node* n0 = graph.NewNode(&dummy_operator0);
    Node* n1 = graph.NewNode(&dummy_operator0);
    Node* n2 = graph.NewNode(&dummy_operator1, n0);
    n2->AppendInput(graph.zone(), n1);
    CHECK_INPUTS(n2, n0, n1);
    n2->TrimInputCount(0);
    CHECK_INPUTS(n2, NONE);
    CHECK_USES(n0, NONE);
    CHECK_USES(n1, NONE);
    CHECK_USES(n2, NONE);
  }

  {
    Node* n0 = graph.NewNode(&dummy_operator0);
    Node* n2 = graph.NewNode(&dummy_operator1, n0);
    n2->AppendInput(graph.zone(), n0);
    CHECK_INPUTS(n2, n0, n0);
    CHECK_USES(n0, n2, n2);
    n2->TrimInputCount(1);
    CHECK_INPUTS(n2, n0);
    CHECK_USES(n0, n2);
    CHECK_USES(n2, NONE);
  }

  {
    Node* n0 = graph.NewNode(&dummy_operator0);
    Node* n2 = graph.NewNode(&dummy_operator1, n0);
    n2->AppendInput(graph.zone(), n0);
    CHECK_EQ(2, n2->InputCount());
    CHECK_EQ(2, n0->UseCount());
    n2->TrimInputCount(0);
    CHECK_EQ(0, n2->InputCount());
    CHECK_EQ(0, n0->UseCount());
    CHECK_EQ(0, n2->UseCount());
  }
}


TEST(NullAllInputs) {
  v8::internal::AccountingAllocator allocator;
  Zone zone(&allocator, ZONE_NAME);
  Graph graph(&zone);

  for (int i = 0; i < 2; i++) {
    Node* n0 = graph.NewNode(&dummy_operator0);
    Node* n1 = graph.NewNode(&dummy_operator1, n0);
    Node* n2;
    if (i == 0) {
      n2 = graph.NewNode(&dummy_operator2, n0, n1);
      CHECK_INPUTS(n2, n0, n1);
    } else {
      n2 = graph.NewNode(&dummy_operator1, n0);
      CHECK_INPUTS(n2, n0);
      n2->AppendInput(graph.zone(), n1);  // with out-of-line input.
      CHECK_INPUTS(n2, n0, n1);
    }

    n0->NullAllInputs();
    CHECK_INPUTS(n0, NONE);

    CHECK_USES(n0, n1, n2);
    n1->NullAllInputs();
    CHECK_INPUTS(n1, nullptr);
    CHECK_INPUTS(n2, n0, n1);
    CHECK_USES(n0, n2);

    n2->NullAllInputs();
    CHECK_INPUTS(n1, nullptr);
    CHECK_INPUTS(n2, nullptr, nullptr);
    CHECK_USES(n0, NONE);
  }

  {
    Node* n0 = graph.NewNode(&dummy_operator0);
    Node* n1 = graph.NewNode(&dummy_operator1, n0);
    n1->ReplaceInput(0, n1);  // self-reference.

    CHECK_INPUTS(n0, NONE);
    CHECK_INPUTS(n1, n1);
    CHECK_USES(n0, NONE);
    CHECK_USES(n1, n1);
    n1->NullAllInputs();

    CHECK_INPUTS(n0, NONE);
    CHECK_INPUTS(n1, nullptr);
    CHECK_USES(n0, NONE);
    CHECK_USES(n1, NONE);
  }
}


TEST(AppendAndTrim) {
  v8::internal::AccountingAllocator allocator;
  Zone zone(&allocator, ZONE_NAME);
  Graph graph(&zone);

  Node* nodes[] = {
      graph.NewNode(&dummy_operator0), graph.NewNode(&dummy_operator0),
      graph.NewNode(&dummy_operator0), graph.NewNode(&dummy_operator0),
      graph.NewNode(&dummy_operator0)};

  int max = static_cast<int>(arraysize(nodes));

  Node* last = graph.NewNode(&dummy_operator0);

  for (int i = 0; i < max; i++) {
    last->AppendInput(graph.zone(), nodes[i]);
    CheckInputs(last, nodes, i + 1);

    for (int j = 0; j < max; j++) {
      if (j <= i) CHECK_USES(nodes[j], last);
      if (j > i) CHECK_USES(nodes[j], NONE);
    }

    CHECK_USES(last, NONE);
  }

  for (int i = max; i >= 0; i--) {
    last->TrimInputCount(i);
    CheckInputs(last, nodes, i);

    for (int j = 0; j < i; j++) {
      if (j < i) CHECK_USES(nodes[j], last);
      if (j >= i) CHECK_USES(nodes[j], NONE);
    }

    CHECK_USES(last, NONE);
  }
}

#undef NONE
#undef CHECK_USES
#undef CHECK_INPUTS

}  // namespace node
}  // namespace compiler
}  // namespace internal
}  // namespace v8
