Home | History | Annotate | Download | only in compiler
      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
      3 // found in the LICENSE file.
      4 
      5 #include "src/compiler/state-values-utils.h"
      6 #include "test/unittests/compiler/graph-unittest.h"
      7 #include "test/unittests/compiler/node-test-utils.h"
      8 #include "test/unittests/test-utils.h"
      9 #include "testing/gmock/include/gmock/gmock.h"
     10 
     11 namespace v8 {
     12 namespace internal {
     13 namespace compiler {
     14 
     15 class StateValuesIteratorTest : public GraphTest {
     16  public:
     17   StateValuesIteratorTest() : GraphTest(3) {}
     18 
     19   Node* StateValuesFromVector(NodeVector* nodes) {
     20     int count = static_cast<int>(nodes->size());
     21     return graph()->NewNode(common()->StateValues(count), count,
     22                             count == 0 ? nullptr : &(nodes->front()));
     23   }
     24 };
     25 
     26 
     27 TEST_F(StateValuesIteratorTest, SimpleIteration) {
     28   NodeVector inputs(zone());
     29   const int count = 10;
     30   for (int i = 0; i < count; i++) {
     31     inputs.push_back(Int32Constant(i));
     32   }
     33   Node* state_values = StateValuesFromVector(&inputs);
     34   int i = 0;
     35   for (StateValuesAccess::TypedNode node : StateValuesAccess(state_values)) {
     36     EXPECT_THAT(node.node, IsInt32Constant(i));
     37     i++;
     38   }
     39   EXPECT_EQ(count, i);
     40 }
     41 
     42 
     43 TEST_F(StateValuesIteratorTest, EmptyIteration) {
     44   NodeVector inputs(zone());
     45   Node* state_values = StateValuesFromVector(&inputs);
     46   for (auto node : StateValuesAccess(state_values)) {
     47     USE(node);
     48     FAIL();
     49   }
     50 }
     51 
     52 
     53 TEST_F(StateValuesIteratorTest, NestedIteration) {
     54   NodeVector inputs(zone());
     55   int count = 0;
     56   for (int i = 0; i < 8; i++) {
     57     if (i == 2) {
     58       // Single nested in index 2.
     59       NodeVector nested_inputs(zone());
     60       for (int j = 0; j < 8; j++) {
     61         nested_inputs.push_back(Int32Constant(count++));
     62       }
     63       inputs.push_back(StateValuesFromVector(&nested_inputs));
     64     } else if (i == 5) {
     65       // Double nested at index 5.
     66       NodeVector nested_inputs(zone());
     67       for (int j = 0; j < 8; j++) {
     68         if (j == 7) {
     69           NodeVector doubly_nested_inputs(zone());
     70           for (int k = 0; k < 2; k++) {
     71             doubly_nested_inputs.push_back(Int32Constant(count++));
     72           }
     73           nested_inputs.push_back(StateValuesFromVector(&doubly_nested_inputs));
     74         } else {
     75           nested_inputs.push_back(Int32Constant(count++));
     76         }
     77       }
     78       inputs.push_back(StateValuesFromVector(&nested_inputs));
     79     } else {
     80       inputs.push_back(Int32Constant(count++));
     81     }
     82   }
     83   Node* state_values = StateValuesFromVector(&inputs);
     84   int i = 0;
     85   for (StateValuesAccess::TypedNode node : StateValuesAccess(state_values)) {
     86     EXPECT_THAT(node.node, IsInt32Constant(i));
     87     i++;
     88   }
     89   EXPECT_EQ(count, i);
     90 }
     91 
     92 
     93 TEST_F(StateValuesIteratorTest, TreeFromVector) {
     94   int sizes[] = {0, 1, 2, 100, 5000, 30000};
     95   TRACED_FOREACH(int, count, sizes) {
     96     JSOperatorBuilder javascript(zone());
     97     MachineOperatorBuilder machine(zone());
     98     JSGraph jsgraph(isolate(), graph(), common(), &javascript, nullptr,
     99                     &machine);
    100 
    101     // Generate the input vector.
    102     NodeVector inputs(zone());
    103     for (int i = 0; i < count; i++) {
    104       inputs.push_back(Int32Constant(i));
    105     }
    106 
    107     // Build the tree.
    108     StateValuesCache builder(&jsgraph);
    109     Node* values_node = builder.GetNodeForValues(
    110         inputs.size() == 0 ? nullptr : &(inputs.front()), inputs.size());
    111 
    112     // Check the tree contents with vector.
    113     int i = 0;
    114     for (StateValuesAccess::TypedNode node : StateValuesAccess(values_node)) {
    115       EXPECT_THAT(node.node, IsInt32Constant(i));
    116       i++;
    117     }
    118     EXPECT_EQ(inputs.size(), static_cast<size_t>(i));
    119   }
    120 }
    121 
    122 
    123 TEST_F(StateValuesIteratorTest, BuildTreeIdentical) {
    124   int sizes[] = {0, 1, 2, 100, 5000, 30000};
    125   TRACED_FOREACH(int, count, sizes) {
    126     JSOperatorBuilder javascript(zone());
    127     MachineOperatorBuilder machine(zone());
    128     JSGraph jsgraph(isolate(), graph(), common(), &javascript, nullptr,
    129                     &machine);
    130 
    131     // Generate the input vector.
    132     NodeVector inputs(zone());
    133     for (int i = 0; i < count; i++) {
    134       inputs.push_back(Int32Constant(i));
    135     }
    136 
    137     // Build two trees from the same data.
    138     StateValuesCache builder(&jsgraph);
    139     Node* node1 = builder.GetNodeForValues(
    140         inputs.size() == 0 ? nullptr : &(inputs.front()), inputs.size());
    141     Node* node2 = builder.GetNodeForValues(
    142         inputs.size() == 0 ? nullptr : &(inputs.front()), inputs.size());
    143 
    144     // The trees should be equal since the data was the same.
    145     EXPECT_EQ(node1, node2);
    146   }
    147 }
    148 
    149 }  // namespace compiler
    150 }  // namespace internal
    151 }  // namespace v8
    152