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