LCOV - code coverage report
Current view: top level - test/cctest/compiler - test-node.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 467 467 100.0 %
Date: 2017-10-20 Functions: 22 22 100.0 %

          Line data    Source code
       1             : // Copyright 2013 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 <functional>
       6             : 
       7             : #include "src/compiler/graph.h"
       8             : #include "src/compiler/node.h"
       9             : #include "src/compiler/operator.h"
      10             : #include "test/cctest/cctest.h"
      11             : 
      12             : namespace v8 {
      13             : namespace internal {
      14             : namespace compiler {
      15             : namespace node {
      16             : 
      17             : #define NONE reinterpret_cast<Node*>(1)
      18             : 
      19       47436 : static Operator dummy_operator0(IrOpcode::kParameter, Operator::kNoWrite,
      20       23718 :                                 "dummy", 0, 0, 0, 1, 0, 0);
      21       47436 : static Operator dummy_operator1(IrOpcode::kParameter, Operator::kNoWrite,
      22       23718 :                                 "dummy", 1, 0, 0, 1, 0, 0);
      23       47436 : static Operator dummy_operator2(IrOpcode::kParameter, Operator::kNoWrite,
      24       23718 :                                 "dummy", 2, 0, 0, 1, 0, 0);
      25       47436 : static Operator dummy_operator3(IrOpcode::kParameter, Operator::kNoWrite,
      26       23718 :                                 "dummy", 3, 0, 0, 1, 0, 0);
      27             : 
      28             : #define CHECK_USES(node, ...)                                          \
      29             :   do {                                                                 \
      30             :     Node* __array[] = {__VA_ARGS__};                                   \
      31             :     int __size =                                                       \
      32             :         __array[0] != NONE ? static_cast<int>(arraysize(__array)) : 0; \
      33             :     CheckUseChain(node, __array, __size);                              \
      34             :   } while (false)
      35             : 
      36             : 
      37             : namespace {
      38             : 
      39             : typedef std::multiset<Node*, std::less<Node*>> NodeMSet;
      40             : 
      41             : 
      42        1506 : void CheckUseChain(Node* node, Node** uses, int use_count) {
      43             :   // Check ownership.
      44        1272 :   if (use_count == 1) CHECK(node->OwnedBy(uses[0]));
      45         882 :   if (use_count > 1) {
      46         234 :     for (int i = 0; i < use_count; i++) {
      47         468 :       CHECK(!node->OwnedBy(uses[i]));
      48             :     }
      49             :   }
      50             : 
      51             :   // Check the self-reported use count.
      52         882 :   CHECK_EQ(use_count, node->UseCount());
      53             : 
      54             :   // Build the expectation set.
      55             :   NodeMSet expect_set;
      56        1506 :   for (int i = 0; i < use_count; i++) {
      57         624 :     expect_set.insert(uses[i]);
      58             :   }
      59             : 
      60             :   {
      61             :     // Check that iterating over the uses gives the right counts.
      62             :     NodeMSet use_set;
      63        2130 :     for (auto use : node->uses()) {
      64             :       use_set.insert(use);
      65             :     }
      66         882 :     CHECK(expect_set == use_set);
      67             :   }
      68             : 
      69             :   {
      70             :     // Check that iterating over the use edges gives the right counts,
      71             :     // input indices, from(), and to() pointers.
      72             :     NodeMSet use_set;
      73        1506 :     for (auto edge : node->use_edges()) {
      74         624 :       CHECK_EQ(node, edge.to());
      75         624 :       CHECK_EQ(node, edge.from()->InputAt(edge.index()));
      76        1248 :       use_set.insert(edge.from());
      77             :     }
      78         882 :     CHECK(expect_set == use_set);
      79             :   }
      80             : 
      81             :   {
      82             :     // Check the use nodes actually have the node as inputs.
      83        2130 :     for (Node* use : node->uses()) {
      84             :       size_t count = 0;
      85        2124 :       for (Node* input : use->inputs()) {
      86        1500 :         if (input == node) count++;
      87             :       }
      88         624 :       CHECK_EQ(count, expect_set.count(use));
      89             :     }
      90             :   }
      91         882 : }
      92             : 
      93             : 
      94         564 : void CheckInputs(Node* node, Node** inputs, int input_count) {
      95         564 :   CHECK_EQ(input_count, node->InputCount());
      96             :   // Check InputAt().
      97        1068 :   for (int i = 0; i < static_cast<int>(input_count); i++) {
      98        1068 :     CHECK_EQ(inputs[i], node->InputAt(i));
      99             :   }
     100             : 
     101             :   // Check input iterator.
     102             :   int index = 0;
     103        1632 :   for (Node* input : node->inputs()) {
     104        1068 :     CHECK_EQ(inputs[index], input);
     105        1068 :     index++;
     106             :   }
     107             : 
     108             :   // Check use lists of inputs.
     109        1068 :   for (int i = 0; i < static_cast<int>(input_count); i++) {
     110        1068 :     Node* input = inputs[i];
     111        1068 :     if (!input) continue;  // skip null inputs
     112             :     bool found = false;
     113             :     // Check regular use list.
     114        1020 :     for (Node* use : input->uses()) {
     115        1020 :       if (use == node) {
     116             :         found = true;
     117             :         break;
     118             :       }
     119             :     }
     120         990 :     CHECK(found);
     121             :     int count = 0;
     122             :     // Check use edge list.
     123        3144 :     for (auto edge : input->use_edges()) {
     124        3432 :       if (edge.from() == node && edge.to() == input && edge.index() == i) {
     125         990 :         count++;
     126             :       }
     127             :     }
     128         990 :     CHECK_EQ(1, count);
     129             :   }
     130         564 : }
     131             : 
     132             : }  // namespace
     133             : 
     134             : 
     135             : #define CHECK_INPUTS(node, ...)                                        \
     136             :   do {                                                                 \
     137             :     Node* __array[] = {__VA_ARGS__};                                   \
     138             :     int __size =                                                       \
     139             :         __array[0] != NONE ? static_cast<int>(arraysize(__array)) : 0; \
     140             :     CheckInputs(node, __array, __size);                                \
     141             :   } while (false)
     142             : 
     143             : 
     144       23724 : TEST(NodeUseIteratorReplaceUses) {
     145           6 :   v8::internal::AccountingAllocator allocator;
     146          12 :   Zone zone(&allocator, ZONE_NAME);
     147           6 :   Graph graph(&zone);
     148             :   Node* n0 = graph.NewNode(&dummy_operator0);
     149             :   Node* n1 = graph.NewNode(&dummy_operator1, n0);
     150             :   Node* n2 = graph.NewNode(&dummy_operator1, n0);
     151             :   Node* n3 = graph.NewNode(&dummy_operator0);
     152             : 
     153           6 :   CHECK_USES(n0, n1, n2);
     154             : 
     155           6 :   CHECK_INPUTS(n1, n0);
     156           6 :   CHECK_INPUTS(n2, n0);
     157             : 
     158           6 :   n0->ReplaceUses(n3);
     159             : 
     160           6 :   CHECK_USES(n0, NONE);
     161           6 :   CHECK_USES(n1, NONE);
     162           6 :   CHECK_USES(n2, NONE);
     163           6 :   CHECK_USES(n3, n1, n2);
     164             : 
     165           6 :   CHECK_INPUTS(n1, n3);
     166          12 :   CHECK_INPUTS(n2, n3);
     167           6 : }
     168             : 
     169             : 
     170       23724 : TEST(NodeUseIteratorReplaceUsesSelf) {
     171           6 :   v8::internal::AccountingAllocator allocator;
     172          12 :   Zone zone(&allocator, ZONE_NAME);
     173           6 :   Graph graph(&zone);
     174             :   Node* n0 = graph.NewNode(&dummy_operator0);
     175             :   Node* n1 = graph.NewNode(&dummy_operator1, n0);
     176             : 
     177           6 :   CHECK_USES(n0, n1);
     178           6 :   CHECK_USES(n1, NONE);
     179             : 
     180           6 :   n1->ReplaceInput(0, n1);  // Create self-reference.
     181             : 
     182           6 :   CHECK_USES(n0, NONE);
     183           6 :   CHECK_USES(n1, n1);
     184             : 
     185             :   Node* n2 = graph.NewNode(&dummy_operator0);
     186             : 
     187           6 :   n1->ReplaceUses(n2);
     188             : 
     189           6 :   CHECK_USES(n0, NONE);
     190           6 :   CHECK_USES(n1, NONE);
     191          12 :   CHECK_USES(n2, n1);
     192           6 : }
     193             : 
     194             : 
     195       23724 : TEST(ReplaceInput) {
     196           6 :   v8::internal::AccountingAllocator allocator;
     197          12 :   Zone zone(&allocator, ZONE_NAME);
     198           6 :   Graph graph(&zone);
     199             :   Node* n0 = graph.NewNode(&dummy_operator0);
     200             :   Node* n1 = graph.NewNode(&dummy_operator0);
     201             :   Node* n2 = graph.NewNode(&dummy_operator0);
     202             :   Node* n3 = graph.NewNode(&dummy_operator3, n0, n1, n2);
     203             :   Node* n4 = graph.NewNode(&dummy_operator0);
     204             : 
     205           6 :   CHECK_USES(n0, n3);
     206           6 :   CHECK_USES(n1, n3);
     207           6 :   CHECK_USES(n2, n3);
     208           6 :   CHECK_USES(n3, NONE);
     209           6 :   CHECK_USES(n4, NONE);
     210             : 
     211           6 :   CHECK_INPUTS(n3, n0, n1, n2);
     212             : 
     213           6 :   n3->ReplaceInput(1, n4);
     214             : 
     215           6 :   CHECK_USES(n1, NONE);
     216           6 :   CHECK_USES(n4, n3);
     217             : 
     218          12 :   CHECK_INPUTS(n3, n0, n4, n2);
     219           6 : }
     220             : 
     221             : 
     222       23724 : TEST(OwnedBy) {
     223           6 :   v8::internal::AccountingAllocator allocator;
     224          12 :   Zone zone(&allocator, ZONE_NAME);
     225           6 :   Graph graph(&zone);
     226             : 
     227             :   {
     228          18 :     Node* n0 = graph.NewNode(&dummy_operator0);
     229           6 :     Node* n1 = graph.NewNode(&dummy_operator0);
     230             : 
     231           6 :     CHECK(!n0->OwnedBy(n1));
     232           6 :     CHECK(!n1->OwnedBy(n0));
     233             : 
     234          12 :     Node* n2 = graph.NewNode(&dummy_operator1, n0);
     235           6 :     CHECK(n0->OwnedBy(n2));
     236           6 :     CHECK(!n2->OwnedBy(n0));
     237             : 
     238           6 :     Node* n3 = graph.NewNode(&dummy_operator1, n0);
     239           6 :     CHECK(!n0->OwnedBy(n2));
     240           6 :     CHECK(!n0->OwnedBy(n3));
     241           6 :     CHECK(!n2->OwnedBy(n0));
     242           6 :     CHECK(!n3->OwnedBy(n0));
     243             :   }
     244             : 
     245             :   {
     246          18 :     Node* n0 = graph.NewNode(&dummy_operator0);
     247          18 :     Node* n1 = graph.NewNode(&dummy_operator1, n0);
     248           6 :     CHECK(n0->OwnedBy(n1));
     249           6 :     CHECK(!n1->OwnedBy(n0));
     250          12 :     Node* n2 = graph.NewNode(&dummy_operator1, n0);
     251           6 :     CHECK(!n0->OwnedBy(n1));
     252           6 :     CHECK(!n0->OwnedBy(n2));
     253           6 :     CHECK(!n1->OwnedBy(n0));
     254           6 :     CHECK(!n1->OwnedBy(n2));
     255           6 :     CHECK(!n2->OwnedBy(n0));
     256           6 :     CHECK(!n2->OwnedBy(n1));
     257             : 
     258           6 :     Node* n3 = graph.NewNode(&dummy_operator0);
     259           6 :     n2->ReplaceInput(0, n3);
     260             : 
     261           6 :     CHECK(n0->OwnedBy(n1));
     262           6 :     CHECK(!n1->OwnedBy(n0));
     263           6 :     CHECK(!n1->OwnedBy(n0));
     264           6 :     CHECK(!n1->OwnedBy(n2));
     265           6 :     CHECK(!n2->OwnedBy(n0));
     266           6 :     CHECK(!n2->OwnedBy(n1));
     267           6 :     CHECK(n3->OwnedBy(n2));
     268           6 :     CHECK(!n2->OwnedBy(n3));
     269           6 :   }
     270           6 : }
     271             : 
     272             : 
     273       23724 : TEST(Uses) {
     274           6 :   v8::internal::AccountingAllocator allocator;
     275          12 :   Zone zone(&allocator, ZONE_NAME);
     276           6 :   Graph graph(&zone);
     277             : 
     278             :   Node* n0 = graph.NewNode(&dummy_operator0);
     279             :   Node* n1 = graph.NewNode(&dummy_operator1, n0);
     280             : 
     281           6 :   CHECK_USES(n0, n1);
     282           6 :   CHECK_USES(n1, NONE);
     283             : 
     284             :   Node* n2 = graph.NewNode(&dummy_operator1, n0);
     285             : 
     286           6 :   CHECK_USES(n0, n1, n2);
     287           6 :   CHECK_USES(n2, NONE);
     288             : 
     289             :   Node* n3 = graph.NewNode(&dummy_operator1, n0);
     290             : 
     291           6 :   CHECK_USES(n0, n1, n2, n3);
     292          12 :   CHECK_USES(n3, NONE);
     293           6 : }
     294             : 
     295             : 
     296       23724 : TEST(Inputs) {
     297           6 :   v8::internal::AccountingAllocator allocator;
     298          12 :   Zone zone(&allocator, ZONE_NAME);
     299           6 :   Graph graph(&zone);
     300             : 
     301             :   Node* n0 = graph.NewNode(&dummy_operator0);
     302             :   Node* n1 = graph.NewNode(&dummy_operator1, n0);
     303             :   Node* n2 = graph.NewNode(&dummy_operator1, n0);
     304             :   Node* n3 = graph.NewNode(&dummy_operator3, n0, n1, n2);
     305             : 
     306           6 :   CHECK_INPUTS(n3, n0, n1, n2);
     307             : 
     308             :   Node* n4 = graph.NewNode(&dummy_operator3, n0, n1, n2);
     309           6 :   n3->AppendInput(graph.zone(), n4);
     310             : 
     311           6 :   CHECK_INPUTS(n3, n0, n1, n2, n4);
     312           6 :   CHECK_USES(n4, n3);
     313             : 
     314           6 :   n3->AppendInput(graph.zone(), n4);
     315             : 
     316           6 :   CHECK_INPUTS(n3, n0, n1, n2, n4, n4);
     317           6 :   CHECK_USES(n4, n3, n3);
     318             : 
     319             :   Node* n5 = graph.NewNode(&dummy_operator1, n4);
     320             : 
     321          12 :   CHECK_USES(n4, n3, n3, n5);
     322           6 : }
     323             : 
     324       23724 : TEST(InsertInputs) {
     325           6 :   v8::internal::AccountingAllocator allocator;
     326          12 :   Zone zone(&allocator, ZONE_NAME);
     327           6 :   Graph graph(&zone);
     328             : 
     329             :   Node* n0 = graph.NewNode(&dummy_operator0);
     330             :   Node* n1 = graph.NewNode(&dummy_operator1, n0);
     331             :   Node* n2 = graph.NewNode(&dummy_operator1, n0);
     332             : 
     333             :   {
     334             :     Node* node = graph.NewNode(&dummy_operator1, n0);
     335           6 :     node->InsertInputs(graph.zone(), 0, 1);
     336           6 :     node->ReplaceInput(0, n1);
     337           6 :     CHECK_INPUTS(node, n1, n0);
     338             :   }
     339             :   {
     340             :     Node* node = graph.NewNode(&dummy_operator1, n0);
     341           6 :     node->InsertInputs(graph.zone(), 0, 2);
     342           6 :     node->ReplaceInput(0, node);
     343           6 :     node->ReplaceInput(1, n2);
     344           6 :     CHECK_INPUTS(node, node, n2, n0);
     345             :   }
     346             :   {
     347             :     Node* node = graph.NewNode(&dummy_operator3, n0, n1, n2);
     348           6 :     node->InsertInputs(graph.zone(), 0, 1);
     349           6 :     node->ReplaceInput(0, node);
     350           6 :     CHECK_INPUTS(node, node, n0, n1, n2);
     351             :   }
     352             :   {
     353             :     Node* node = graph.NewNode(&dummy_operator3, n0, n1, n2);
     354           6 :     node->InsertInputs(graph.zone(), 1, 1);
     355           6 :     node->ReplaceInput(1, node);
     356           6 :     CHECK_INPUTS(node, n0, node, n1, n2);
     357             :   }
     358             :   {
     359             :     Node* node = graph.NewNode(&dummy_operator3, n0, n1, n2);
     360           6 :     node->InsertInputs(graph.zone(), 2, 1);
     361           6 :     node->ReplaceInput(2, node);
     362           6 :     CHECK_INPUTS(node, n0, n1, node, n2);
     363             :   }
     364             :   {
     365             :     Node* node = graph.NewNode(&dummy_operator3, n0, n1, n2);
     366           6 :     node->InsertInputs(graph.zone(), 2, 1);
     367           6 :     node->ReplaceInput(2, node);
     368           6 :     CHECK_INPUTS(node, n0, n1, node, n2);
     369             :   }
     370             :   {
     371             :     Node* node = graph.NewNode(&dummy_operator3, n0, n1, n2);
     372           6 :     node->InsertInputs(graph.zone(), 0, 4);
     373           6 :     node->ReplaceInput(0, node);
     374           6 :     node->ReplaceInput(1, node);
     375           6 :     node->ReplaceInput(2, node);
     376           6 :     node->ReplaceInput(3, node);
     377           6 :     CHECK_INPUTS(node, node, node, node, node, n0, n1, n2);
     378             :   }
     379             :   {
     380             :     Node* node = graph.NewNode(&dummy_operator3, n0, n1, n2);
     381           6 :     node->InsertInputs(graph.zone(), 1, 4);
     382           6 :     node->ReplaceInput(1, node);
     383           6 :     node->ReplaceInput(2, node);
     384           6 :     node->ReplaceInput(3, node);
     385           6 :     node->ReplaceInput(4, node);
     386           6 :     CHECK_INPUTS(node, n0, node, node, node, node, n1, n2);
     387             :   }
     388             :   {
     389             :     Node* node = graph.NewNode(&dummy_operator3, n0, n1, n2);
     390           6 :     node->InsertInputs(graph.zone(), 2, 4);
     391           6 :     node->ReplaceInput(2, node);
     392           6 :     node->ReplaceInput(3, node);
     393           6 :     node->ReplaceInput(4, node);
     394           6 :     node->ReplaceInput(5, node);
     395           6 :     CHECK_INPUTS(node, n0, n1, node, node, node, node, n2);
     396           6 :   }
     397           6 : }
     398             : 
     399       23724 : TEST(RemoveInput) {
     400           6 :   v8::internal::AccountingAllocator allocator;
     401          12 :   Zone zone(&allocator, ZONE_NAME);
     402           6 :   Graph graph(&zone);
     403             : 
     404             :   Node* n0 = graph.NewNode(&dummy_operator0);
     405             :   Node* n1 = graph.NewNode(&dummy_operator1, n0);
     406             :   Node* n2 = graph.NewNode(&dummy_operator2, n0, n1);
     407             : 
     408           6 :   CHECK_INPUTS(n0, NONE);
     409           6 :   CHECK_INPUTS(n1, n0);
     410           6 :   CHECK_INPUTS(n2, n0, n1);
     411           6 :   CHECK_USES(n0, n1, n2);
     412             : 
     413           6 :   n1->RemoveInput(0);
     414           6 :   CHECK_INPUTS(n1, NONE);
     415           6 :   CHECK_USES(n0, n2);
     416             : 
     417           6 :   n2->RemoveInput(0);
     418           6 :   CHECK_INPUTS(n2, n1);
     419           6 :   CHECK_USES(n0, NONE);
     420           6 :   CHECK_USES(n1, n2);
     421             : 
     422           6 :   n2->RemoveInput(0);
     423           6 :   CHECK_INPUTS(n2, NONE);
     424           6 :   CHECK_USES(n0, NONE);
     425           6 :   CHECK_USES(n1, NONE);
     426          12 :   CHECK_USES(n2, NONE);
     427           6 : }
     428             : 
     429             : 
     430       23724 : TEST(AppendInputsAndIterator) {
     431           6 :   v8::internal::AccountingAllocator allocator;
     432          12 :   Zone zone(&allocator, ZONE_NAME);
     433           6 :   Graph graph(&zone);
     434             : 
     435             :   Node* n0 = graph.NewNode(&dummy_operator0);
     436             :   Node* n1 = graph.NewNode(&dummy_operator1, n0);
     437             :   Node* n2 = graph.NewNode(&dummy_operator2, n0, n1);
     438             : 
     439           6 :   CHECK_INPUTS(n0, NONE);
     440           6 :   CHECK_INPUTS(n1, n0);
     441           6 :   CHECK_INPUTS(n2, n0, n1);
     442           6 :   CHECK_USES(n0, n1, n2);
     443             : 
     444             :   Node* n3 = graph.NewNode(&dummy_operator0);
     445             : 
     446           6 :   n2->AppendInput(graph.zone(), n3);
     447             : 
     448           6 :   CHECK_INPUTS(n2, n0, n1, n3);
     449          12 :   CHECK_USES(n3, n2);
     450           6 : }
     451             : 
     452             : 
     453       23724 : TEST(NullInputsSimple) {
     454           6 :   v8::internal::AccountingAllocator allocator;
     455          12 :   Zone zone(&allocator, ZONE_NAME);
     456           6 :   Graph graph(&zone);
     457             : 
     458             :   Node* n0 = graph.NewNode(&dummy_operator0);
     459             :   Node* n1 = graph.NewNode(&dummy_operator1, n0);
     460             :   Node* n2 = graph.NewNode(&dummy_operator2, n0, n1);
     461             : 
     462           6 :   CHECK_INPUTS(n0, NONE);
     463           6 :   CHECK_INPUTS(n1, n0);
     464           6 :   CHECK_INPUTS(n2, n0, n1);
     465           6 :   CHECK_USES(n0, n1, n2);
     466             : 
     467           6 :   n2->ReplaceInput(0, nullptr);
     468             : 
     469           6 :   CHECK_INPUTS(n2, nullptr, n1);
     470             : 
     471           6 :   CHECK_USES(n0, n1);
     472             : 
     473           6 :   n2->ReplaceInput(1, nullptr);
     474             : 
     475           6 :   CHECK_INPUTS(n2, nullptr, nullptr);
     476             : 
     477          12 :   CHECK_USES(n1, NONE);
     478           6 : }
     479             : 
     480             : 
     481       23724 : TEST(NullInputsAppended) {
     482           6 :   v8::internal::AccountingAllocator allocator;
     483          12 :   Zone zone(&allocator, ZONE_NAME);
     484           6 :   Graph graph(&zone);
     485             : 
     486             :   Node* n0 = graph.NewNode(&dummy_operator0);
     487             :   Node* n1 = graph.NewNode(&dummy_operator1, n0);
     488             :   Node* n2 = graph.NewNode(&dummy_operator1, n0);
     489             :   Node* n3 = graph.NewNode(&dummy_operator1, n0);
     490           6 :   n3->AppendInput(graph.zone(), n1);
     491           6 :   n3->AppendInput(graph.zone(), n2);
     492             : 
     493           6 :   CHECK_INPUTS(n3, n0, n1, n2);
     494           6 :   CHECK_USES(n0, n1, n2, n3);
     495           6 :   CHECK_USES(n1, n3);
     496           6 :   CHECK_USES(n2, n3);
     497             : 
     498           6 :   n3->ReplaceInput(1, nullptr);
     499           6 :   CHECK_USES(n1, NONE);
     500             : 
     501          12 :   CHECK_INPUTS(n3, n0, nullptr, n2);
     502           6 : }
     503             : 
     504             : 
     505       23724 : TEST(ReplaceUsesFromAppendedInputs) {
     506           6 :   v8::internal::AccountingAllocator allocator;
     507          12 :   Zone zone(&allocator, ZONE_NAME);
     508           6 :   Graph graph(&zone);
     509             : 
     510             :   Node* n0 = graph.NewNode(&dummy_operator0);
     511             :   Node* n1 = graph.NewNode(&dummy_operator1, n0);
     512             :   Node* n2 = graph.NewNode(&dummy_operator1, n0);
     513             :   Node* n3 = graph.NewNode(&dummy_operator0);
     514             : 
     515           6 :   CHECK_INPUTS(n2, n0);
     516             : 
     517           6 :   n2->AppendInput(graph.zone(), n1);
     518           6 :   CHECK_INPUTS(n2, n0, n1);
     519           6 :   CHECK_USES(n1, n2);
     520             : 
     521           6 :   n2->AppendInput(graph.zone(), n0);
     522           6 :   CHECK_INPUTS(n2, n0, n1, n0);
     523           6 :   CHECK_USES(n1, n2);
     524           6 :   CHECK_USES(n0, n2, n1, n2);
     525             : 
     526           6 :   n0->ReplaceUses(n3);
     527             : 
     528           6 :   CHECK_USES(n0, NONE);
     529           6 :   CHECK_INPUTS(n2, n3, n1, n3);
     530          12 :   CHECK_USES(n3, n2, n1, n2);
     531           6 : }
     532             : 
     533             : 
     534       23724 : TEST(ReplaceInputMultipleUses) {
     535           6 :   v8::internal::AccountingAllocator allocator;
     536          12 :   Zone zone(&allocator, ZONE_NAME);
     537           6 :   Graph graph(&zone);
     538             : 
     539             :   Node* n0 = graph.NewNode(&dummy_operator0);
     540             :   Node* n1 = graph.NewNode(&dummy_operator0);
     541             :   Node* n2 = graph.NewNode(&dummy_operator1, n0);
     542           6 :   n2->ReplaceInput(0, n1);
     543           6 :   CHECK_EQ(0, n0->UseCount());
     544           6 :   CHECK_EQ(1, n1->UseCount());
     545             : 
     546             :   Node* n3 = graph.NewNode(&dummy_operator1, n0);
     547           6 :   n3->ReplaceInput(0, n1);
     548           6 :   CHECK_EQ(0, n0->UseCount());
     549          12 :   CHECK_EQ(2, n1->UseCount());
     550           6 : }
     551             : 
     552             : 
     553       23724 : TEST(TrimInputCountInline) {
     554           6 :   v8::internal::AccountingAllocator allocator;
     555          12 :   Zone zone(&allocator, ZONE_NAME);
     556           6 :   Graph graph(&zone);
     557             : 
     558             :   {
     559             :     Node* n0 = graph.NewNode(&dummy_operator0);
     560             :     Node* n1 = graph.NewNode(&dummy_operator1, n0);
     561           6 :     n1->TrimInputCount(1);
     562           6 :     CHECK_INPUTS(n1, n0);
     563           6 :     CHECK_USES(n0, n1);
     564             :   }
     565             : 
     566             :   {
     567             :     Node* n0 = graph.NewNode(&dummy_operator0);
     568             :     Node* n1 = graph.NewNode(&dummy_operator1, n0);
     569           6 :     n1->TrimInputCount(0);
     570           6 :     CHECK_INPUTS(n1, NONE);
     571           6 :     CHECK_USES(n0, NONE);
     572             :   }
     573             : 
     574             :   {
     575             :     Node* n0 = graph.NewNode(&dummy_operator0);
     576             :     Node* n1 = graph.NewNode(&dummy_operator0);
     577             :     Node* n2 = graph.NewNode(&dummy_operator2, n0, n1);
     578           6 :     n2->TrimInputCount(2);
     579           6 :     CHECK_INPUTS(n2, n0, n1);
     580           6 :     CHECK_USES(n0, n2);
     581           6 :     CHECK_USES(n1, n2);
     582             :   }
     583             : 
     584             :   {
     585             :     Node* n0 = graph.NewNode(&dummy_operator0);
     586             :     Node* n1 = graph.NewNode(&dummy_operator0);
     587             :     Node* n2 = graph.NewNode(&dummy_operator2, n0, n1);
     588           6 :     n2->TrimInputCount(1);
     589           6 :     CHECK_INPUTS(n2, n0);
     590           6 :     CHECK_USES(n0, n2);
     591           6 :     CHECK_USES(n1, NONE);
     592             :   }
     593             : 
     594             :   {
     595             :     Node* n0 = graph.NewNode(&dummy_operator0);
     596             :     Node* n1 = graph.NewNode(&dummy_operator0);
     597             :     Node* n2 = graph.NewNode(&dummy_operator2, n0, n1);
     598           6 :     n2->TrimInputCount(0);
     599           6 :     CHECK_INPUTS(n2, NONE);
     600           6 :     CHECK_USES(n0, NONE);
     601           6 :     CHECK_USES(n1, NONE);
     602             :   }
     603             : 
     604             :   {
     605             :     Node* n0 = graph.NewNode(&dummy_operator0);
     606             :     Node* n2 = graph.NewNode(&dummy_operator2, n0, n0);
     607           6 :     n2->TrimInputCount(1);
     608           6 :     CHECK_INPUTS(n2, n0);
     609           6 :     CHECK_USES(n0, n2);
     610             :   }
     611             : 
     612             :   {
     613             :     Node* n0 = graph.NewNode(&dummy_operator0);
     614             :     Node* n2 = graph.NewNode(&dummy_operator2, n0, n0);
     615           6 :     n2->TrimInputCount(0);
     616           6 :     CHECK_INPUTS(n2, NONE);
     617           6 :     CHECK_USES(n0, NONE);
     618           6 :   }
     619           6 : }
     620             : 
     621             : 
     622       23724 : TEST(TrimInputCountOutOfLine1) {
     623           6 :   v8::internal::AccountingAllocator allocator;
     624          12 :   Zone zone(&allocator, ZONE_NAME);
     625           6 :   Graph graph(&zone);
     626             : 
     627             :   {
     628             :     Node* n0 = graph.NewNode(&dummy_operator0);
     629             :     Node* n1 = graph.NewNode(&dummy_operator0);
     630           6 :     n1->AppendInput(graph.zone(), n0);
     631           6 :     CHECK_INPUTS(n1, n0);
     632           6 :     CHECK_USES(n0, n1);
     633             : 
     634           6 :     n1->TrimInputCount(1);
     635           6 :     CHECK_INPUTS(n1, n0);
     636           6 :     CHECK_USES(n0, n1);
     637             :   }
     638             : 
     639             :   {
     640             :     Node* n0 = graph.NewNode(&dummy_operator0);
     641             :     Node* n1 = graph.NewNode(&dummy_operator0);
     642           6 :     n1->AppendInput(graph.zone(), n0);
     643           6 :     CHECK_EQ(1, n1->InputCount());
     644           6 :     n1->TrimInputCount(0);
     645           6 :     CHECK_EQ(0, n1->InputCount());
     646           6 :     CHECK_EQ(0, n0->UseCount());
     647             :   }
     648             : 
     649             :   {
     650             :     Node* n0 = graph.NewNode(&dummy_operator0);
     651             :     Node* n1 = graph.NewNode(&dummy_operator0);
     652             :     Node* n2 = graph.NewNode(&dummy_operator0);
     653           6 :     n2->AppendInput(graph.zone(), n0);
     654           6 :     n2->AppendInput(graph.zone(), n1);
     655           6 :     CHECK_INPUTS(n2, n0, n1);
     656           6 :     n2->TrimInputCount(2);
     657           6 :     CHECK_INPUTS(n2, n0, n1);
     658           6 :     CHECK_USES(n0, n2);
     659           6 :     CHECK_USES(n1, n2);
     660           6 :     CHECK_USES(n2, NONE);
     661             :   }
     662             : 
     663             :   {
     664             :     Node* n0 = graph.NewNode(&dummy_operator0);
     665             :     Node* n1 = graph.NewNode(&dummy_operator0);
     666             :     Node* n2 = graph.NewNode(&dummy_operator0);
     667           6 :     n2->AppendInput(graph.zone(), n0);
     668           6 :     n2->AppendInput(graph.zone(), n1);
     669           6 :     CHECK_INPUTS(n2, n0, n1);
     670           6 :     n2->TrimInputCount(1);
     671           6 :     CHECK_INPUTS(n2, n0);
     672           6 :     CHECK_USES(n0, n2);
     673           6 :     CHECK_USES(n1, NONE);
     674           6 :     CHECK_USES(n2, NONE);
     675             :   }
     676             : 
     677             :   {
     678             :     Node* n0 = graph.NewNode(&dummy_operator0);
     679             :     Node* n1 = graph.NewNode(&dummy_operator0);
     680             :     Node* n2 = graph.NewNode(&dummy_operator0);
     681           6 :     n2->AppendInput(graph.zone(), n0);
     682           6 :     n2->AppendInput(graph.zone(), n1);
     683           6 :     CHECK_INPUTS(n2, n0, n1);
     684           6 :     n2->TrimInputCount(0);
     685           6 :     CHECK_INPUTS(n2, NONE);
     686           6 :     CHECK_USES(n0, NONE);
     687           6 :     CHECK_USES(n1, NONE);
     688           6 :     CHECK_USES(n2, NONE);
     689             :   }
     690             : 
     691             :   {
     692             :     Node* n0 = graph.NewNode(&dummy_operator0);
     693             :     Node* n2 = graph.NewNode(&dummy_operator0);
     694           6 :     n2->AppendInput(graph.zone(), n0);
     695           6 :     n2->AppendInput(graph.zone(), n0);
     696           6 :     CHECK_INPUTS(n2, n0, n0);
     697           6 :     CHECK_USES(n0, n2, n2);
     698           6 :     n2->TrimInputCount(1);
     699           6 :     CHECK_INPUTS(n2, n0);
     700           6 :     CHECK_USES(n0, n2);
     701             :   }
     702             : 
     703             :   {
     704             :     Node* n0 = graph.NewNode(&dummy_operator0);
     705             :     Node* n2 = graph.NewNode(&dummy_operator0);
     706           6 :     n2->AppendInput(graph.zone(), n0);
     707           6 :     n2->AppendInput(graph.zone(), n0);
     708           6 :     CHECK_INPUTS(n2, n0, n0);
     709           6 :     CHECK_USES(n0, n2, n2);
     710           6 :     n2->TrimInputCount(0);
     711           6 :     CHECK_INPUTS(n2, NONE);
     712           6 :     CHECK_USES(n0, NONE);
     713           6 :   }
     714           6 : }
     715             : 
     716             : 
     717       23724 : TEST(TrimInputCountOutOfLine2) {
     718           6 :   v8::internal::AccountingAllocator allocator;
     719          12 :   Zone zone(&allocator, ZONE_NAME);
     720           6 :   Graph graph(&zone);
     721             : 
     722             :   {
     723             :     Node* n0 = graph.NewNode(&dummy_operator0);
     724             :     Node* n1 = graph.NewNode(&dummy_operator0);
     725             :     Node* n2 = graph.NewNode(&dummy_operator1, n0);
     726           6 :     n2->AppendInput(graph.zone(), n1);
     727           6 :     CHECK_INPUTS(n2, n0, n1);
     728           6 :     n2->TrimInputCount(2);
     729           6 :     CHECK_INPUTS(n2, n0, n1);
     730           6 :     CHECK_USES(n0, n2);
     731           6 :     CHECK_USES(n1, n2);
     732           6 :     CHECK_USES(n2, NONE);
     733             :   }
     734             : 
     735             :   {
     736             :     Node* n0 = graph.NewNode(&dummy_operator0);
     737             :     Node* n1 = graph.NewNode(&dummy_operator0);
     738             :     Node* n2 = graph.NewNode(&dummy_operator1, n0);
     739           6 :     n2->AppendInput(graph.zone(), n1);
     740           6 :     CHECK_INPUTS(n2, n0, n1);
     741           6 :     n2->TrimInputCount(1);
     742           6 :     CHECK_INPUTS(n2, n0);
     743           6 :     CHECK_USES(n0, n2);
     744           6 :     CHECK_USES(n1, NONE);
     745           6 :     CHECK_USES(n2, NONE);
     746             :   }
     747             : 
     748             :   {
     749             :     Node* n0 = graph.NewNode(&dummy_operator0);
     750             :     Node* n1 = graph.NewNode(&dummy_operator0);
     751             :     Node* n2 = graph.NewNode(&dummy_operator1, n0);
     752           6 :     n2->AppendInput(graph.zone(), n1);
     753           6 :     CHECK_INPUTS(n2, n0, n1);
     754           6 :     n2->TrimInputCount(0);
     755           6 :     CHECK_INPUTS(n2, NONE);
     756           6 :     CHECK_USES(n0, NONE);
     757           6 :     CHECK_USES(n1, NONE);
     758           6 :     CHECK_USES(n2, NONE);
     759             :   }
     760             : 
     761             :   {
     762             :     Node* n0 = graph.NewNode(&dummy_operator0);
     763             :     Node* n2 = graph.NewNode(&dummy_operator1, n0);
     764           6 :     n2->AppendInput(graph.zone(), n0);
     765           6 :     CHECK_INPUTS(n2, n0, n0);
     766           6 :     CHECK_USES(n0, n2, n2);
     767           6 :     n2->TrimInputCount(1);
     768           6 :     CHECK_INPUTS(n2, n0);
     769           6 :     CHECK_USES(n0, n2);
     770           6 :     CHECK_USES(n2, NONE);
     771             :   }
     772             : 
     773             :   {
     774             :     Node* n0 = graph.NewNode(&dummy_operator0);
     775             :     Node* n2 = graph.NewNode(&dummy_operator1, n0);
     776           6 :     n2->AppendInput(graph.zone(), n0);
     777           6 :     CHECK_EQ(2, n2->InputCount());
     778           6 :     CHECK_EQ(2, n0->UseCount());
     779           6 :     n2->TrimInputCount(0);
     780           6 :     CHECK_EQ(0, n2->InputCount());
     781           6 :     CHECK_EQ(0, n0->UseCount());
     782           6 :     CHECK_EQ(0, n2->UseCount());
     783           6 :   }
     784           6 : }
     785             : 
     786             : 
     787       23724 : TEST(NullAllInputs) {
     788           6 :   v8::internal::AccountingAllocator allocator;
     789          12 :   Zone zone(&allocator, ZONE_NAME);
     790           6 :   Graph graph(&zone);
     791             : 
     792          18 :   for (int i = 0; i < 2; i++) {
     793             :     Node* n0 = graph.NewNode(&dummy_operator0);
     794             :     Node* n1 = graph.NewNode(&dummy_operator1, n0);
     795             :     Node* n2;
     796          12 :     if (i == 0) {
     797             :       n2 = graph.NewNode(&dummy_operator2, n0, n1);
     798           6 :       CHECK_INPUTS(n2, n0, n1);
     799             :     } else {
     800             :       n2 = graph.NewNode(&dummy_operator1, n0);
     801           6 :       CHECK_INPUTS(n2, n0);
     802           6 :       n2->AppendInput(graph.zone(), n1);  // with out-of-line input.
     803           6 :       CHECK_INPUTS(n2, n0, n1);
     804             :     }
     805             : 
     806          12 :     n0->NullAllInputs();
     807          12 :     CHECK_INPUTS(n0, NONE);
     808             : 
     809          12 :     CHECK_USES(n0, n1, n2);
     810          12 :     n1->NullAllInputs();
     811          12 :     CHECK_INPUTS(n1, nullptr);
     812          12 :     CHECK_INPUTS(n2, n0, n1);
     813          12 :     CHECK_USES(n0, n2);
     814             : 
     815          12 :     n2->NullAllInputs();
     816          12 :     CHECK_INPUTS(n1, nullptr);
     817          12 :     CHECK_INPUTS(n2, nullptr, nullptr);
     818          12 :     CHECK_USES(n0, NONE);
     819             :   }
     820             : 
     821             :   {
     822             :     Node* n0 = graph.NewNode(&dummy_operator0);
     823             :     Node* n1 = graph.NewNode(&dummy_operator1, n0);
     824           6 :     n1->ReplaceInput(0, n1);  // self-reference.
     825             : 
     826           6 :     CHECK_INPUTS(n0, NONE);
     827           6 :     CHECK_INPUTS(n1, n1);
     828           6 :     CHECK_USES(n0, NONE);
     829           6 :     CHECK_USES(n1, n1);
     830           6 :     n1->NullAllInputs();
     831             : 
     832           6 :     CHECK_INPUTS(n0, NONE);
     833           6 :     CHECK_INPUTS(n1, nullptr);
     834           6 :     CHECK_USES(n0, NONE);
     835           6 :     CHECK_USES(n1, NONE);
     836           6 :   }
     837           6 : }
     838             : 
     839             : 
     840       23724 : TEST(AppendAndTrim) {
     841           6 :   v8::internal::AccountingAllocator allocator;
     842          12 :   Zone zone(&allocator, ZONE_NAME);
     843           6 :   Graph graph(&zone);
     844             : 
     845             :   Node* nodes[] = {
     846             :       graph.NewNode(&dummy_operator0), graph.NewNode(&dummy_operator0),
     847             :       graph.NewNode(&dummy_operator0), graph.NewNode(&dummy_operator0),
     848          30 :       graph.NewNode(&dummy_operator0)};
     849             : 
     850             :   int max = static_cast<int>(arraysize(nodes));
     851             : 
     852             :   Node* last = graph.NewNode(&dummy_operator0);
     853             : 
     854          42 :   for (int i = 0; i < max; i++) {
     855          30 :     last->AppendInput(graph.zone(), nodes[i]);
     856          30 :     CheckInputs(last, nodes, i + 1);
     857             : 
     858         180 :     for (int j = 0; j < max; j++) {
     859         150 :       if (j <= i) CHECK_USES(nodes[j], last);
     860         150 :       if (j > i) CHECK_USES(nodes[j], NONE);
     861             :     }
     862             : 
     863          30 :     CHECK_USES(last, NONE);
     864             :   }
     865             : 
     866          36 :   for (int i = max; i >= 0; i--) {
     867          36 :     last->TrimInputCount(i);
     868          36 :     CheckInputs(last, nodes, i);
     869             : 
     870         126 :     for (int j = 0; j < i; j++) {
     871          90 :       if (j < i) CHECK_USES(nodes[j], last);
     872          90 :       if (j >= i) CHECK_USES(nodes[j], NONE);
     873             :     }
     874             : 
     875          36 :     CHECK_USES(last, NONE);
     876           6 :   }
     877           6 : }
     878             : 
     879             : #undef NONE
     880             : #undef CHECK_USES
     881             : #undef CHECK_INPUTS
     882             : 
     883             : }  // namespace node
     884             : }  // namespace compiler
     885             : }  // namespace internal
     886       71154 : }  // namespace v8

Generated by: LCOV version 1.10