// Copyright 2014 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 "src/compiler/state-values-utils.h"
#include "src/bit-vector.h"
#include "test/unittests/compiler/graph-unittest.h"
#include "test/unittests/compiler/node-test-utils.h"
#include "test/unittests/test-utils.h"
#include "testing/gmock/include/gmock/gmock.h"

namespace v8 {
namespace internal {
namespace compiler {

class StateValuesIteratorTest : public GraphTest {
 public:
  StateValuesIteratorTest() : GraphTest(3) {}

  Node* StateValuesFromVector(NodeVector* nodes) {
    int count = static_cast<int>(nodes->size());
    return graph()->NewNode(
        common()->StateValues(count, SparseInputMask::Dense()), count,
        count == 0 ? nullptr : &(nodes->front()));
  }
};


TEST_F(StateValuesIteratorTest, SimpleIteration) {
  NodeVector inputs(zone());
  const int count = 10;
  for (int i = 0; i < count; i++) {
    inputs.push_back(Int32Constant(i));
  }
  Node* state_values = StateValuesFromVector(&inputs);
  int i = 0;
  for (StateValuesAccess::TypedNode node : StateValuesAccess(state_values)) {
    EXPECT_THAT(node.node, IsInt32Constant(i));
    i++;
  }
  EXPECT_EQ(count, i);
}


TEST_F(StateValuesIteratorTest, EmptyIteration) {
  NodeVector inputs(zone());
  Node* state_values = StateValuesFromVector(&inputs);
  for (auto node : StateValuesAccess(state_values)) {
    USE(node);
    FAIL();
  }
}


TEST_F(StateValuesIteratorTest, NestedIteration) {
  NodeVector inputs(zone());
  int count = 0;
  for (int i = 0; i < 8; i++) {
    if (i == 2) {
      // Single nested in index 2.
      NodeVector nested_inputs(zone());
      for (int j = 0; j < 8; j++) {
        nested_inputs.push_back(Int32Constant(count++));
      }
      inputs.push_back(StateValuesFromVector(&nested_inputs));
    } else if (i == 5) {
      // Double nested at index 5.
      NodeVector nested_inputs(zone());
      for (int j = 0; j < 8; j++) {
        if (j == 7) {
          NodeVector doubly_nested_inputs(zone());
          for (int k = 0; k < 2; k++) {
            doubly_nested_inputs.push_back(Int32Constant(count++));
          }
          nested_inputs.push_back(StateValuesFromVector(&doubly_nested_inputs));
        } else {
          nested_inputs.push_back(Int32Constant(count++));
        }
      }
      inputs.push_back(StateValuesFromVector(&nested_inputs));
    } else {
      inputs.push_back(Int32Constant(count++));
    }
  }
  Node* state_values = StateValuesFromVector(&inputs);
  int i = 0;
  for (StateValuesAccess::TypedNode node : StateValuesAccess(state_values)) {
    EXPECT_THAT(node.node, IsInt32Constant(i));
    i++;
  }
  EXPECT_EQ(count, i);
}


TEST_F(StateValuesIteratorTest, TreeFromVector) {
  int sizes[] = {0, 1, 2, 100, 5000, 30000};
  TRACED_FOREACH(int, count, sizes) {
    JSOperatorBuilder javascript(zone());
    MachineOperatorBuilder machine(zone());
    JSGraph jsgraph(isolate(), graph(), common(), &javascript, nullptr,
                    &machine);

    // Generate the input vector.
    NodeVector inputs(zone());
    for (int i = 0; i < count; i++) {
      inputs.push_back(Int32Constant(i));
    }

    // Build the tree.
    StateValuesCache builder(&jsgraph);
    Node* values_node = builder.GetNodeForValues(
        inputs.size() == 0 ? nullptr : &(inputs.front()), inputs.size(),
        nullptr);

    // Check the tree contents with vector.
    int i = 0;
    for (StateValuesAccess::TypedNode node : StateValuesAccess(values_node)) {
      EXPECT_THAT(node.node, IsInt32Constant(i));
      i++;
    }
    EXPECT_EQ(inputs.size(), static_cast<size_t>(i));
  }
}

TEST_F(StateValuesIteratorTest, TreeFromVectorWithLiveness) {
  int sizes[] = {0, 1, 2, 100, 5000, 30000};
  TRACED_FOREACH(int, count, sizes) {
    JSOperatorBuilder javascript(zone());
    MachineOperatorBuilder machine(zone());
    JSGraph jsgraph(isolate(), graph(), common(), &javascript, nullptr,
                    &machine);

    // Generate the input vector.
    NodeVector inputs(zone());
    for (int i = 0; i < count; i++) {
      inputs.push_back(Int32Constant(i));
    }
    // Generate the input liveness.
    BitVector liveness(count, zone());
    for (int i = 0; i < count; i++) {
      if (i % 3 == 0) {
        liveness.Add(i);
      }
    }

    // Build the tree.
    StateValuesCache builder(&jsgraph);
    Node* values_node = builder.GetNodeForValues(
        inputs.size() == 0 ? nullptr : &(inputs.front()), inputs.size(),
        &liveness);

    // Check the tree contents with vector.
    int i = 0;
    for (StateValuesAccess::TypedNode node : StateValuesAccess(values_node)) {
      if (liveness.Contains(i)) {
        EXPECT_THAT(node.node, IsInt32Constant(i));
      } else {
        EXPECT_EQ(node.node, nullptr);
      }
      i++;
    }
    EXPECT_EQ(inputs.size(), static_cast<size_t>(i));
  }
}

TEST_F(StateValuesIteratorTest, BuildTreeIdentical) {
  int sizes[] = {0, 1, 2, 100, 5000, 30000};
  TRACED_FOREACH(int, count, sizes) {
    JSOperatorBuilder javascript(zone());
    MachineOperatorBuilder machine(zone());
    JSGraph jsgraph(isolate(), graph(), common(), &javascript, nullptr,
                    &machine);

    // Generate the input vector.
    NodeVector inputs(zone());
    for (int i = 0; i < count; i++) {
      inputs.push_back(Int32Constant(i));
    }

    // Build two trees from the same data.
    StateValuesCache builder(&jsgraph);
    Node* node1 = builder.GetNodeForValues(
        inputs.size() == 0 ? nullptr : &(inputs.front()), inputs.size(),
        nullptr);
    Node* node2 = builder.GetNodeForValues(
        inputs.size() == 0 ? nullptr : &(inputs.front()), inputs.size(),
        nullptr);

    // The trees should be equal since the data was the same.
    EXPECT_EQ(node1, node2);
  }
}

TEST_F(StateValuesIteratorTest, BuildTreeWithLivenessIdentical) {
  int sizes[] = {0, 1, 2, 100, 5000, 30000};
  TRACED_FOREACH(int, count, sizes) {
    JSOperatorBuilder javascript(zone());
    MachineOperatorBuilder machine(zone());
    JSGraph jsgraph(isolate(), graph(), common(), &javascript, nullptr,
                    &machine);

    // Generate the input vector.
    NodeVector inputs(zone());
    for (int i = 0; i < count; i++) {
      inputs.push_back(Int32Constant(i));
    }
    // Generate the input liveness.
    BitVector liveness(count, zone());
    for (int i = 0; i < count; i++) {
      if (i % 3 == 0) {
        liveness.Add(i);
      }
    }

    // Build two trees from the same data.
    StateValuesCache builder(&jsgraph);
    Node* node1 = builder.GetNodeForValues(
        inputs.size() == 0 ? nullptr : &(inputs.front()), inputs.size(),
        &liveness);
    Node* node2 = builder.GetNodeForValues(
        inputs.size() == 0 ? nullptr : &(inputs.front()), inputs.size(),
        &liveness);

    // The trees should be equal since the data was the same.
    EXPECT_EQ(node1, node2);
  }
}

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