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