LCOV - code coverage report
Current view: top level - test/cctest/compiler - test-node.cc (source / functions) Hit Total Coverage
Test: app.info Lines: 452 452 100.0 %
Date: 2019-04-17 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       53278 : static Operator dummy_operator0(IrOpcode::kParameter, Operator::kNoWrite,
      20       26639 :                                 "dummy", 0, 0, 0, 1, 0, 0);
      21       53278 : static Operator dummy_operator1(IrOpcode::kParameter, Operator::kNoWrite,
      22       26639 :                                 "dummy", 1, 0, 0, 1, 0, 0);
      23       53278 : static Operator dummy_operator2(IrOpcode::kParameter, Operator::kNoWrite,
      24       26639 :                                 "dummy", 2, 0, 0, 1, 0, 0);
      25       53278 : static Operator dummy_operator3(IrOpcode::kParameter, Operator::kNoWrite,
      26       26639 :                                 "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         735 : void CheckUseChain(Node* node, Node** uses, int use_count) {
      43             :   // Check ownership.
      44        1060 :   if (use_count == 1) CHECK(node->OwnedBy(uses[0]));
      45         735 :   if (use_count > 1) {
      46         475 :     for (int i = 0; i < use_count; i++) {
      47         390 :       CHECK(!node->OwnedBy(uses[i]));
      48             :     }
      49             :   }
      50             : 
      51             :   // Check the self-reported use count.
      52         735 :   CHECK_EQ(use_count, node->UseCount());
      53             : 
      54             :   // Build the expectation set.
      55             :   NodeMSet expect_set;
      56        1775 :   for (int i = 0; i < use_count; i++) {
      57         520 :     expect_set.insert(uses[i]);
      58             :   }
      59             : 
      60             :   {
      61             :     // Check that iterating over the uses gives the right counts.
      62             :     NodeMSet use_set;
      63        1775 :     for (auto use : node->uses()) {
      64             :       use_set.insert(use);
      65             :     }
      66         735 :     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        1255 :     for (auto edge : node->use_edges()) {
      74         520 :       CHECK_EQ(node, edge.to());
      75         520 :       CHECK_EQ(node, edge.from()->InputAt(edge.index()));
      76        1040 :       use_set.insert(edge.from());
      77             :     }
      78         735 :     CHECK(expect_set == use_set);
      79             :   }
      80             : 
      81             :   {
      82             :     // Check the use nodes actually have the node as inputs.
      83        1775 :     for (Node* use : node->uses()) {
      84             :       size_t count = 0;
      85        1770 :       for (Node* input : use->inputs()) {
      86        1250 :         if (input == node) count++;
      87             :       }
      88         520 :       CHECK_EQ(count, expect_set.count(use));
      89             :     }
      90             :   }
      91         735 : }
      92             : 
      93             : 
      94         470 : void CheckInputs(Node* node, Node** inputs, int input_count) {
      95         470 :   CHECK_EQ(input_count, node->InputCount());
      96             :   // Check InputAt().
      97        2250 :   for (int i = 0; i < static_cast<int>(input_count); i++) {
      98         890 :     CHECK_EQ(inputs[i], node->InputAt(i));
      99             :   }
     100             : 
     101             :   // Check input iterator.
     102             :   int index = 0;
     103        1360 :   for (Node* input : node->inputs()) {
     104         890 :     CHECK_EQ(inputs[index], input);
     105         890 :     index++;
     106             :   }
     107             : 
     108             :   // Check use lists of inputs.
     109        2250 :   for (int i = 0; i < static_cast<int>(input_count); i++) {
     110         890 :     Node* input = inputs[i];
     111         890 :     if (!input) continue;  // skip null inputs
     112             :     bool found = false;
     113             :     // Check regular use list.
     114         850 :     for (Node* use : input->uses()) {
     115         850 :       if (use == node) {
     116             :         found = true;
     117             :         break;
     118             :       }
     119             :     }
     120         825 :     CHECK(found);
     121             :     int count = 0;
     122             :     // Check use edge list.
     123        2620 :     for (auto edge : input->use_edges()) {
     124        2860 :       if (edge.from() == node && edge.to() == input && edge.index() == i) {
     125         825 :         count++;
     126             :       }
     127             :     }
     128         825 :     CHECK_EQ(1, count);
     129             :   }
     130         470 : }
     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       26644 : TEST(NodeUseIteratorReplaceUses) {
     145          10 :   v8::internal::AccountingAllocator allocator;
     146          10 :   Zone zone(&allocator, ZONE_NAME);
     147           5 :   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           5 :   CHECK_USES(n0, n1, n2);
     154             : 
     155           5 :   CHECK_INPUTS(n1, n0);
     156           5 :   CHECK_INPUTS(n2, n0);
     157             : 
     158           5 :   n0->ReplaceUses(n3);
     159             : 
     160           5 :   CHECK_USES(n0, NONE);
     161           5 :   CHECK_USES(n1, NONE);
     162           5 :   CHECK_USES(n2, NONE);
     163           5 :   CHECK_USES(n3, n1, n2);
     164             : 
     165           5 :   CHECK_INPUTS(n1, n3);
     166           5 :   CHECK_INPUTS(n2, n3);
     167           5 : }
     168             : 
     169             : 
     170       26644 : TEST(NodeUseIteratorReplaceUsesSelf) {
     171          10 :   v8::internal::AccountingAllocator allocator;
     172          10 :   Zone zone(&allocator, ZONE_NAME);
     173           5 :   Graph graph(&zone);
     174             :   Node* n0 = graph.NewNode(&dummy_operator0);
     175             :   Node* n1 = graph.NewNode(&dummy_operator1, n0);
     176             : 
     177           5 :   CHECK_USES(n0, n1);
     178           5 :   CHECK_USES(n1, NONE);
     179             : 
     180           5 :   n1->ReplaceInput(0, n1);  // Create self-reference.
     181             : 
     182           5 :   CHECK_USES(n0, NONE);
     183           5 :   CHECK_USES(n1, n1);
     184             : 
     185             :   Node* n2 = graph.NewNode(&dummy_operator0);
     186             : 
     187           5 :   n1->ReplaceUses(n2);
     188             : 
     189           5 :   CHECK_USES(n0, NONE);
     190           5 :   CHECK_USES(n1, NONE);
     191           5 :   CHECK_USES(n2, n1);
     192           5 : }
     193             : 
     194             : 
     195       26644 : TEST(ReplaceInput) {
     196          10 :   v8::internal::AccountingAllocator allocator;
     197          10 :   Zone zone(&allocator, ZONE_NAME);
     198           5 :   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           5 :   CHECK_USES(n0, n3);
     206           5 :   CHECK_USES(n1, n3);
     207           5 :   CHECK_USES(n2, n3);
     208           5 :   CHECK_USES(n3, NONE);
     209           5 :   CHECK_USES(n4, NONE);
     210             : 
     211           5 :   CHECK_INPUTS(n3, n0, n1, n2);
     212             : 
     213           5 :   n3->ReplaceInput(1, n4);
     214             : 
     215           5 :   CHECK_USES(n1, NONE);
     216           5 :   CHECK_USES(n4, n3);
     217             : 
     218           5 :   CHECK_INPUTS(n3, n0, n4, n2);
     219           5 : }
     220             : 
     221             : 
     222       26644 : TEST(OwnedBy) {
     223          10 :   v8::internal::AccountingAllocator allocator;
     224          10 :   Zone zone(&allocator, ZONE_NAME);
     225           5 :   Graph graph(&zone);
     226             : 
     227             :   {
     228             :     Node* n0 = graph.NewNode(&dummy_operator0);
     229             :     Node* n1 = graph.NewNode(&dummy_operator0);
     230             : 
     231           5 :     CHECK(!n0->OwnedBy(n1));
     232           5 :     CHECK(!n1->OwnedBy(n0));
     233             : 
     234             :     Node* n2 = graph.NewNode(&dummy_operator1, n0);
     235           5 :     CHECK(n0->OwnedBy(n2));
     236           5 :     CHECK(!n2->OwnedBy(n0));
     237             : 
     238             :     Node* n3 = graph.NewNode(&dummy_operator1, n0);
     239           5 :     CHECK(!n0->OwnedBy(n2));
     240           5 :     CHECK(!n0->OwnedBy(n3));
     241           5 :     CHECK(!n2->OwnedBy(n0));
     242           5 :     CHECK(!n3->OwnedBy(n0));
     243             :   }
     244             : 
     245             :   {
     246             :     Node* n0 = graph.NewNode(&dummy_operator0);
     247             :     Node* n1 = graph.NewNode(&dummy_operator1, n0);
     248           5 :     CHECK(n0->OwnedBy(n1));
     249           5 :     CHECK(!n1->OwnedBy(n0));
     250             :     Node* n2 = graph.NewNode(&dummy_operator1, n0);
     251           5 :     CHECK(!n0->OwnedBy(n1));
     252           5 :     CHECK(!n0->OwnedBy(n2));
     253           5 :     CHECK(!n1->OwnedBy(n0));
     254           5 :     CHECK(!n1->OwnedBy(n2));
     255           5 :     CHECK(!n2->OwnedBy(n0));
     256           5 :     CHECK(!n2->OwnedBy(n1));
     257             : 
     258             :     Node* n3 = graph.NewNode(&dummy_operator0);
     259           5 :     n2->ReplaceInput(0, n3);
     260             : 
     261           5 :     CHECK(n0->OwnedBy(n1));
     262           5 :     CHECK(!n1->OwnedBy(n0));
     263           5 :     CHECK(!n1->OwnedBy(n0));
     264           5 :     CHECK(!n1->OwnedBy(n2));
     265           5 :     CHECK(!n2->OwnedBy(n0));
     266           5 :     CHECK(!n2->OwnedBy(n1));
     267           5 :     CHECK(n3->OwnedBy(n2));
     268           5 :     CHECK(!n2->OwnedBy(n3));
     269             :   }
     270           5 : }
     271             : 
     272             : 
     273       26644 : TEST(Uses) {
     274          10 :   v8::internal::AccountingAllocator allocator;
     275          10 :   Zone zone(&allocator, ZONE_NAME);
     276           5 :   Graph graph(&zone);
     277             : 
     278             :   Node* n0 = graph.NewNode(&dummy_operator0);
     279             :   Node* n1 = graph.NewNode(&dummy_operator1, n0);
     280             : 
     281           5 :   CHECK_USES(n0, n1);
     282           5 :   CHECK_USES(n1, NONE);
     283             : 
     284             :   Node* n2 = graph.NewNode(&dummy_operator1, n0);
     285             : 
     286           5 :   CHECK_USES(n0, n1, n2);
     287           5 :   CHECK_USES(n2, NONE);
     288             : 
     289             :   Node* n3 = graph.NewNode(&dummy_operator1, n0);
     290             : 
     291           5 :   CHECK_USES(n0, n1, n2, n3);
     292           5 :   CHECK_USES(n3, NONE);
     293           5 : }
     294             : 
     295             : 
     296       26644 : TEST(Inputs) {
     297          10 :   v8::internal::AccountingAllocator allocator;
     298          10 :   Zone zone(&allocator, ZONE_NAME);
     299           5 :   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           5 :   CHECK_INPUTS(n3, n0, n1, n2);
     307             : 
     308             :   Node* n4 = graph.NewNode(&dummy_operator3, n0, n1, n2);
     309           5 :   n3->AppendInput(graph.zone(), n4);
     310             : 
     311           5 :   CHECK_INPUTS(n3, n0, n1, n2, n4);
     312           5 :   CHECK_USES(n4, n3);
     313             : 
     314           5 :   n3->AppendInput(graph.zone(), n4);
     315             : 
     316           5 :   CHECK_INPUTS(n3, n0, n1, n2, n4, n4);
     317           5 :   CHECK_USES(n4, n3, n3);
     318             : 
     319             :   Node* n5 = graph.NewNode(&dummy_operator1, n4);
     320             : 
     321           5 :   CHECK_USES(n4, n3, n3, n5);
     322           5 : }
     323             : 
     324       26644 : TEST(InsertInputs) {
     325          10 :   v8::internal::AccountingAllocator allocator;
     326          10 :   Zone zone(&allocator, ZONE_NAME);
     327           5 :   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           5 :     node->InsertInputs(graph.zone(), 0, 1);
     336           5 :     node->ReplaceInput(0, n1);
     337           5 :     CHECK_INPUTS(node, n1, n0);
     338             :   }
     339             :   {
     340             :     Node* node = graph.NewNode(&dummy_operator1, n0);
     341           5 :     node->InsertInputs(graph.zone(), 0, 2);
     342           5 :     node->ReplaceInput(0, node);
     343           5 :     node->ReplaceInput(1, n2);
     344           5 :     CHECK_INPUTS(node, node, n2, n0);
     345             :   }
     346             :   {
     347             :     Node* node = graph.NewNode(&dummy_operator3, n0, n1, n2);
     348           5 :     node->InsertInputs(graph.zone(), 0, 1);
     349           5 :     node->ReplaceInput(0, node);
     350           5 :     CHECK_INPUTS(node, node, n0, n1, n2);
     351             :   }
     352             :   {
     353             :     Node* node = graph.NewNode(&dummy_operator3, n0, n1, n2);
     354           5 :     node->InsertInputs(graph.zone(), 1, 1);
     355           5 :     node->ReplaceInput(1, node);
     356           5 :     CHECK_INPUTS(node, n0, node, n1, n2);
     357             :   }
     358             :   {
     359             :     Node* node = graph.NewNode(&dummy_operator3, n0, n1, n2);
     360           5 :     node->InsertInputs(graph.zone(), 2, 1);
     361           5 :     node->ReplaceInput(2, node);
     362           5 :     CHECK_INPUTS(node, n0, n1, node, n2);
     363             :   }
     364             :   {
     365             :     Node* node = graph.NewNode(&dummy_operator3, n0, n1, n2);
     366           5 :     node->InsertInputs(graph.zone(), 2, 1);
     367           5 :     node->ReplaceInput(2, node);
     368           5 :     CHECK_INPUTS(node, n0, n1, node, n2);
     369             :   }
     370             :   {
     371             :     Node* node = graph.NewNode(&dummy_operator3, n0, n1, n2);
     372           5 :     node->InsertInputs(graph.zone(), 0, 4);
     373           5 :     node->ReplaceInput(0, node);
     374           5 :     node->ReplaceInput(1, node);
     375           5 :     node->ReplaceInput(2, node);
     376           5 :     node->ReplaceInput(3, node);
     377           5 :     CHECK_INPUTS(node, node, node, node, node, n0, n1, n2);
     378             :   }
     379             :   {
     380             :     Node* node = graph.NewNode(&dummy_operator3, n0, n1, n2);
     381           5 :     node->InsertInputs(graph.zone(), 1, 4);
     382           5 :     node->ReplaceInput(1, node);
     383           5 :     node->ReplaceInput(2, node);
     384           5 :     node->ReplaceInput(3, node);
     385           5 :     node->ReplaceInput(4, node);
     386           5 :     CHECK_INPUTS(node, n0, node, node, node, node, n1, n2);
     387             :   }
     388             :   {
     389             :     Node* node = graph.NewNode(&dummy_operator3, n0, n1, n2);
     390           5 :     node->InsertInputs(graph.zone(), 2, 4);
     391           5 :     node->ReplaceInput(2, node);
     392           5 :     node->ReplaceInput(3, node);
     393           5 :     node->ReplaceInput(4, node);
     394           5 :     node->ReplaceInput(5, node);
     395           5 :     CHECK_INPUTS(node, n0, n1, node, node, node, node, n2);
     396             :   }
     397           5 : }
     398             : 
     399       26644 : TEST(RemoveInput) {
     400          10 :   v8::internal::AccountingAllocator allocator;
     401          10 :   Zone zone(&allocator, ZONE_NAME);
     402           5 :   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           5 :   CHECK_INPUTS(n0, NONE);
     409           5 :   CHECK_INPUTS(n1, n0);
     410           5 :   CHECK_INPUTS(n2, n0, n1);
     411           5 :   CHECK_USES(n0, n1, n2);
     412             : 
     413           5 :   n1->RemoveInput(0);
     414           5 :   CHECK_INPUTS(n1, NONE);
     415           5 :   CHECK_USES(n0, n2);
     416             : 
     417           5 :   n2->RemoveInput(0);
     418           5 :   CHECK_INPUTS(n2, n1);
     419           5 :   CHECK_USES(n0, NONE);
     420           5 :   CHECK_USES(n1, n2);
     421             : 
     422           5 :   n2->RemoveInput(0);
     423           5 :   CHECK_INPUTS(n2, NONE);
     424           5 :   CHECK_USES(n0, NONE);
     425           5 :   CHECK_USES(n1, NONE);
     426           5 :   CHECK_USES(n2, NONE);
     427           5 : }
     428             : 
     429             : 
     430       26644 : TEST(AppendInputsAndIterator) {
     431          10 :   v8::internal::AccountingAllocator allocator;
     432          10 :   Zone zone(&allocator, ZONE_NAME);
     433           5 :   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           5 :   CHECK_INPUTS(n0, NONE);
     440           5 :   CHECK_INPUTS(n1, n0);
     441           5 :   CHECK_INPUTS(n2, n0, n1);
     442           5 :   CHECK_USES(n0, n1, n2);
     443             : 
     444             :   Node* n3 = graph.NewNode(&dummy_operator0);
     445             : 
     446           5 :   n2->AppendInput(graph.zone(), n3);
     447             : 
     448           5 :   CHECK_INPUTS(n2, n0, n1, n3);
     449           5 :   CHECK_USES(n3, n2);
     450           5 : }
     451             : 
     452             : 
     453       26644 : TEST(NullInputsSimple) {
     454          10 :   v8::internal::AccountingAllocator allocator;
     455          10 :   Zone zone(&allocator, ZONE_NAME);
     456           5 :   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           5 :   CHECK_INPUTS(n0, NONE);
     463           5 :   CHECK_INPUTS(n1, n0);
     464           5 :   CHECK_INPUTS(n2, n0, n1);
     465           5 :   CHECK_USES(n0, n1, n2);
     466             : 
     467           5 :   n2->ReplaceInput(0, nullptr);
     468             : 
     469           5 :   CHECK_INPUTS(n2, nullptr, n1);
     470             : 
     471           5 :   CHECK_USES(n0, n1);
     472             : 
     473           5 :   n2->ReplaceInput(1, nullptr);
     474             : 
     475           5 :   CHECK_INPUTS(n2, nullptr, nullptr);
     476             : 
     477           5 :   CHECK_USES(n1, NONE);
     478           5 : }
     479             : 
     480             : 
     481       26644 : TEST(NullInputsAppended) {
     482          10 :   v8::internal::AccountingAllocator allocator;
     483          10 :   Zone zone(&allocator, ZONE_NAME);
     484           5 :   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           5 :   n3->AppendInput(graph.zone(), n1);
     491           5 :   n3->AppendInput(graph.zone(), n2);
     492             : 
     493           5 :   CHECK_INPUTS(n3, n0, n1, n2);
     494           5 :   CHECK_USES(n0, n1, n2, n3);
     495           5 :   CHECK_USES(n1, n3);
     496           5 :   CHECK_USES(n2, n3);
     497             : 
     498           5 :   n3->ReplaceInput(1, nullptr);
     499           5 :   CHECK_USES(n1, NONE);
     500             : 
     501           5 :   CHECK_INPUTS(n3, n0, nullptr, n2);
     502           5 : }
     503             : 
     504             : 
     505       26644 : TEST(ReplaceUsesFromAppendedInputs) {
     506          10 :   v8::internal::AccountingAllocator allocator;
     507          10 :   Zone zone(&allocator, ZONE_NAME);
     508           5 :   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           5 :   CHECK_INPUTS(n2, n0);
     516             : 
     517           5 :   n2->AppendInput(graph.zone(), n1);
     518           5 :   CHECK_INPUTS(n2, n0, n1);
     519           5 :   CHECK_USES(n1, n2);
     520             : 
     521           5 :   n2->AppendInput(graph.zone(), n0);
     522           5 :   CHECK_INPUTS(n2, n0, n1, n0);
     523           5 :   CHECK_USES(n1, n2);
     524           5 :   CHECK_USES(n0, n2, n1, n2);
     525             : 
     526           5 :   n0->ReplaceUses(n3);
     527             : 
     528           5 :   CHECK_USES(n0, NONE);
     529           5 :   CHECK_INPUTS(n2, n3, n1, n3);
     530           5 :   CHECK_USES(n3, n2, n1, n2);
     531           5 : }
     532             : 
     533             : 
     534       26644 : TEST(ReplaceInputMultipleUses) {
     535          10 :   v8::internal::AccountingAllocator allocator;
     536          10 :   Zone zone(&allocator, ZONE_NAME);
     537           5 :   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           5 :   n2->ReplaceInput(0, n1);
     543           5 :   CHECK_EQ(0, n0->UseCount());
     544           5 :   CHECK_EQ(1, n1->UseCount());
     545             : 
     546             :   Node* n3 = graph.NewNode(&dummy_operator1, n0);
     547           5 :   n3->ReplaceInput(0, n1);
     548           5 :   CHECK_EQ(0, n0->UseCount());
     549           5 :   CHECK_EQ(2, n1->UseCount());
     550           5 : }
     551             : 
     552             : 
     553       26644 : TEST(TrimInputCountInline) {
     554          10 :   v8::internal::AccountingAllocator allocator;
     555          10 :   Zone zone(&allocator, ZONE_NAME);
     556           5 :   Graph graph(&zone);
     557             : 
     558             :   {
     559             :     Node* n0 = graph.NewNode(&dummy_operator0);
     560             :     Node* n1 = graph.NewNode(&dummy_operator1, n0);
     561           5 :     n1->TrimInputCount(1);
     562           5 :     CHECK_INPUTS(n1, n0);
     563           5 :     CHECK_USES(n0, n1);
     564             :   }
     565             : 
     566             :   {
     567             :     Node* n0 = graph.NewNode(&dummy_operator0);
     568             :     Node* n1 = graph.NewNode(&dummy_operator1, n0);
     569           5 :     n1->TrimInputCount(0);
     570           5 :     CHECK_INPUTS(n1, NONE);
     571           5 :     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           5 :     n2->TrimInputCount(2);
     579           5 :     CHECK_INPUTS(n2, n0, n1);
     580           5 :     CHECK_USES(n0, n2);
     581           5 :     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           5 :     n2->TrimInputCount(1);
     589           5 :     CHECK_INPUTS(n2, n0);
     590           5 :     CHECK_USES(n0, n2);
     591           5 :     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           5 :     n2->TrimInputCount(0);
     599           5 :     CHECK_INPUTS(n2, NONE);
     600           5 :     CHECK_USES(n0, NONE);
     601           5 :     CHECK_USES(n1, NONE);
     602             :   }
     603             : 
     604             :   {
     605             :     Node* n0 = graph.NewNode(&dummy_operator0);
     606             :     Node* n2 = graph.NewNode(&dummy_operator2, n0, n0);
     607           5 :     n2->TrimInputCount(1);
     608           5 :     CHECK_INPUTS(n2, n0);
     609           5 :     CHECK_USES(n0, n2);
     610             :   }
     611             : 
     612             :   {
     613             :     Node* n0 = graph.NewNode(&dummy_operator0);
     614             :     Node* n2 = graph.NewNode(&dummy_operator2, n0, n0);
     615           5 :     n2->TrimInputCount(0);
     616           5 :     CHECK_INPUTS(n2, NONE);
     617           5 :     CHECK_USES(n0, NONE);
     618             :   }
     619           5 : }
     620             : 
     621             : 
     622       26644 : TEST(TrimInputCountOutOfLine1) {
     623          10 :   v8::internal::AccountingAllocator allocator;
     624          10 :   Zone zone(&allocator, ZONE_NAME);
     625           5 :   Graph graph(&zone);
     626             : 
     627             :   {
     628             :     Node* n0 = graph.NewNode(&dummy_operator0);
     629             :     Node* n1 = graph.NewNode(&dummy_operator0);
     630           5 :     n1->AppendInput(graph.zone(), n0);
     631           5 :     CHECK_INPUTS(n1, n0);
     632           5 :     CHECK_USES(n0, n1);
     633             : 
     634           5 :     n1->TrimInputCount(1);
     635           5 :     CHECK_INPUTS(n1, n0);
     636           5 :     CHECK_USES(n0, n1);
     637             :   }
     638             : 
     639             :   {
     640             :     Node* n0 = graph.NewNode(&dummy_operator0);
     641             :     Node* n1 = graph.NewNode(&dummy_operator0);
     642           5 :     n1->AppendInput(graph.zone(), n0);
     643           5 :     CHECK_EQ(1, n1->InputCount());
     644           5 :     n1->TrimInputCount(0);
     645           5 :     CHECK_EQ(0, n1->InputCount());
     646           5 :     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           5 :     n2->AppendInput(graph.zone(), n0);
     654           5 :     n2->AppendInput(graph.zone(), n1);
     655           5 :     CHECK_INPUTS(n2, n0, n1);
     656           5 :     n2->TrimInputCount(2);
     657           5 :     CHECK_INPUTS(n2, n0, n1);
     658           5 :     CHECK_USES(n0, n2);
     659           5 :     CHECK_USES(n1, n2);
     660           5 :     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           5 :     n2->AppendInput(graph.zone(), n0);
     668           5 :     n2->AppendInput(graph.zone(), n1);
     669           5 :     CHECK_INPUTS(n2, n0, n1);
     670           5 :     n2->TrimInputCount(1);
     671           5 :     CHECK_INPUTS(n2, n0);
     672           5 :     CHECK_USES(n0, n2);
     673           5 :     CHECK_USES(n1, NONE);
     674           5 :     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           5 :     n2->AppendInput(graph.zone(), n0);
     682           5 :     n2->AppendInput(graph.zone(), n1);
     683           5 :     CHECK_INPUTS(n2, n0, n1);
     684           5 :     n2->TrimInputCount(0);
     685           5 :     CHECK_INPUTS(n2, NONE);
     686           5 :     CHECK_USES(n0, NONE);
     687           5 :     CHECK_USES(n1, NONE);
     688           5 :     CHECK_USES(n2, NONE);
     689             :   }
     690             : 
     691             :   {
     692             :     Node* n0 = graph.NewNode(&dummy_operator0);
     693             :     Node* n2 = graph.NewNode(&dummy_operator0);
     694           5 :     n2->AppendInput(graph.zone(), n0);
     695           5 :     n2->AppendInput(graph.zone(), n0);
     696           5 :     CHECK_INPUTS(n2, n0, n0);
     697           5 :     CHECK_USES(n0, n2, n2);
     698           5 :     n2->TrimInputCount(1);
     699           5 :     CHECK_INPUTS(n2, n0);
     700           5 :     CHECK_USES(n0, n2);
     701             :   }
     702             : 
     703             :   {
     704             :     Node* n0 = graph.NewNode(&dummy_operator0);
     705             :     Node* n2 = graph.NewNode(&dummy_operator0);
     706           5 :     n2->AppendInput(graph.zone(), n0);
     707           5 :     n2->AppendInput(graph.zone(), n0);
     708           5 :     CHECK_INPUTS(n2, n0, n0);
     709           5 :     CHECK_USES(n0, n2, n2);
     710           5 :     n2->TrimInputCount(0);
     711           5 :     CHECK_INPUTS(n2, NONE);
     712           5 :     CHECK_USES(n0, NONE);
     713             :   }
     714           5 : }
     715             : 
     716             : 
     717       26644 : TEST(TrimInputCountOutOfLine2) {
     718          10 :   v8::internal::AccountingAllocator allocator;
     719          10 :   Zone zone(&allocator, ZONE_NAME);
     720           5 :   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           5 :     n2->AppendInput(graph.zone(), n1);
     727           5 :     CHECK_INPUTS(n2, n0, n1);
     728           5 :     n2->TrimInputCount(2);
     729           5 :     CHECK_INPUTS(n2, n0, n1);
     730           5 :     CHECK_USES(n0, n2);
     731           5 :     CHECK_USES(n1, n2);
     732           5 :     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           5 :     n2->AppendInput(graph.zone(), n1);
     740           5 :     CHECK_INPUTS(n2, n0, n1);
     741           5 :     n2->TrimInputCount(1);
     742           5 :     CHECK_INPUTS(n2, n0);
     743           5 :     CHECK_USES(n0, n2);
     744           5 :     CHECK_USES(n1, NONE);
     745           5 :     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           5 :     n2->AppendInput(graph.zone(), n1);
     753           5 :     CHECK_INPUTS(n2, n0, n1);
     754           5 :     n2->TrimInputCount(0);
     755           5 :     CHECK_INPUTS(n2, NONE);
     756           5 :     CHECK_USES(n0, NONE);
     757           5 :     CHECK_USES(n1, NONE);
     758           5 :     CHECK_USES(n2, NONE);
     759             :   }
     760             : 
     761             :   {
     762             :     Node* n0 = graph.NewNode(&dummy_operator0);
     763             :     Node* n2 = graph.NewNode(&dummy_operator1, n0);
     764           5 :     n2->AppendInput(graph.zone(), n0);
     765           5 :     CHECK_INPUTS(n2, n0, n0);
     766           5 :     CHECK_USES(n0, n2, n2);
     767           5 :     n2->TrimInputCount(1);
     768           5 :     CHECK_INPUTS(n2, n0);
     769           5 :     CHECK_USES(n0, n2);
     770           5 :     CHECK_USES(n2, NONE);
     771             :   }
     772             : 
     773             :   {
     774             :     Node* n0 = graph.NewNode(&dummy_operator0);
     775             :     Node* n2 = graph.NewNode(&dummy_operator1, n0);
     776           5 :     n2->AppendInput(graph.zone(), n0);
     777           5 :     CHECK_EQ(2, n2->InputCount());
     778           5 :     CHECK_EQ(2, n0->UseCount());
     779           5 :     n2->TrimInputCount(0);
     780           5 :     CHECK_EQ(0, n2->InputCount());
     781           5 :     CHECK_EQ(0, n0->UseCount());
     782           5 :     CHECK_EQ(0, n2->UseCount());
     783             :   }
     784           5 : }
     785             : 
     786             : 
     787       26644 : TEST(NullAllInputs) {
     788          10 :   v8::internal::AccountingAllocator allocator;
     789          10 :   Zone zone(&allocator, ZONE_NAME);
     790           5 :   Graph graph(&zone);
     791             : 
     792          25 :   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          10 :     if (i == 0) {
     797             :       n2 = graph.NewNode(&dummy_operator2, n0, n1);
     798           5 :       CHECK_INPUTS(n2, n0, n1);
     799             :     } else {
     800             :       n2 = graph.NewNode(&dummy_operator1, n0);
     801           5 :       CHECK_INPUTS(n2, n0);
     802           5 :       n2->AppendInput(graph.zone(), n1);  // with out-of-line input.
     803           5 :       CHECK_INPUTS(n2, n0, n1);
     804             :     }
     805             : 
     806          10 :     n0->NullAllInputs();
     807          10 :     CHECK_INPUTS(n0, NONE);
     808             : 
     809          10 :     CHECK_USES(n0, n1, n2);
     810          10 :     n1->NullAllInputs();
     811          10 :     CHECK_INPUTS(n1, nullptr);
     812          10 :     CHECK_INPUTS(n2, n0, n1);
     813          10 :     CHECK_USES(n0, n2);
     814             : 
     815          10 :     n2->NullAllInputs();
     816          10 :     CHECK_INPUTS(n1, nullptr);
     817          10 :     CHECK_INPUTS(n2, nullptr, nullptr);
     818          10 :     CHECK_USES(n0, NONE);
     819             :   }
     820             : 
     821             :   {
     822             :     Node* n0 = graph.NewNode(&dummy_operator0);
     823             :     Node* n1 = graph.NewNode(&dummy_operator1, n0);
     824           5 :     n1->ReplaceInput(0, n1);  // self-reference.
     825             : 
     826           5 :     CHECK_INPUTS(n0, NONE);
     827           5 :     CHECK_INPUTS(n1, n1);
     828           5 :     CHECK_USES(n0, NONE);
     829           5 :     CHECK_USES(n1, n1);
     830           5 :     n1->NullAllInputs();
     831             : 
     832           5 :     CHECK_INPUTS(n0, NONE);
     833           5 :     CHECK_INPUTS(n1, nullptr);
     834           5 :     CHECK_USES(n0, NONE);
     835           5 :     CHECK_USES(n1, NONE);
     836             :   }
     837           5 : }
     838             : 
     839             : 
     840       26644 : TEST(AppendAndTrim) {
     841          10 :   v8::internal::AccountingAllocator allocator;
     842          10 :   Zone zone(&allocator, ZONE_NAME);
     843           5 :   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          25 :       graph.NewNode(&dummy_operator0)};
     849             : 
     850             :   int max = static_cast<int>(arraysize(nodes));
     851             : 
     852             :   Node* last = graph.NewNode(&dummy_operator0);
     853             : 
     854          55 :   for (int i = 0; i < max; i++) {
     855          25 :     last->AppendInput(graph.zone(), nodes[i]);
     856          25 :     CheckInputs(last, nodes, i + 1);
     857             : 
     858         275 :     for (int j = 0; j < max; j++) {
     859         125 :       if (j <= i) CHECK_USES(nodes[j], last);
     860         125 :       if (j > i) CHECK_USES(nodes[j], NONE);
     861             :     }
     862             : 
     863          25 :     CHECK_USES(last, NONE);
     864             :   }
     865             : 
     866          65 :   for (int i = max; i >= 0; i--) {
     867          30 :     last->TrimInputCount(i);
     868          30 :     CheckInputs(last, nodes, i);
     869             : 
     870         180 :     for (int j = 0; j < i; j++) {
     871          75 :       if (j < i) CHECK_USES(nodes[j], last);
     872          75 :       if (j >= i) CHECK_USES(nodes[j], NONE);
     873             :     }
     874             : 
     875          30 :     CHECK_USES(last, NONE);
     876             :   }
     877           5 : }
     878             : 
     879             : #undef NONE
     880             : #undef CHECK_USES
     881             : #undef CHECK_INPUTS
     882             : 
     883             : }  // namespace node
     884             : }  // namespace compiler
     885             : }  // namespace internal
     886       79917 : }  // namespace v8

Generated by: LCOV version 1.10