blob: d317c3877c82866356317581af2ceb1914ffed2c [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001// 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
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00007#include "src/compiler/graph.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008#include "src/compiler/node.h"
9#include "src/compiler/operator.h"
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000010#include "test/cctest/cctest.h"
Ben Murdochb8a8cc12014-11-26 15:28:44 +000011
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000012namespace v8 {
13namespace internal {
14namespace compiler {
Ben Murdochb8a8cc12014-11-26 15:28:44 +000015
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000016#define NONE reinterpret_cast<Node*>(1)
Ben Murdochb8a8cc12014-11-26 15:28:44 +000017
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000018static Operator dummy_operator0(IrOpcode::kParameter, Operator::kNoWrite,
19 "dummy", 0, 0, 0, 1, 0, 0);
20static Operator dummy_operator1(IrOpcode::kParameter, Operator::kNoWrite,
21 "dummy", 1, 0, 0, 1, 0, 0);
22static Operator dummy_operator2(IrOpcode::kParameter, Operator::kNoWrite,
23 "dummy", 2, 0, 0, 1, 0, 0);
24static Operator dummy_operator3(IrOpcode::kParameter, Operator::kNoWrite,
25 "dummy", 3, 0, 0, 1, 0, 0);
26
27#define CHECK_USES(node, ...) \
28 do { \
29 Node* __array[] = {__VA_ARGS__}; \
30 int __size = \
31 __array[0] != NONE ? static_cast<int>(arraysize(__array)) : 0; \
32 CheckUseChain(node, __array, __size); \
33 } while (false)
Ben Murdochb8a8cc12014-11-26 15:28:44 +000034
35
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000036namespace {
37
38typedef std::multiset<Node*, std::less<Node*>> NodeMSet;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000039
40
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000041void CheckUseChain(Node* node, Node** uses, int use_count) {
42 // Check ownership.
43 if (use_count == 1) CHECK(node->OwnedBy(uses[0]));
44 if (use_count > 1) {
45 for (int i = 0; i < use_count; i++) {
46 CHECK(!node->OwnedBy(uses[i]));
47 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000048 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000049
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000050 // Check the self-reported use count.
51 CHECK_EQ(use_count, node->UseCount());
Ben Murdochb8a8cc12014-11-26 15:28:44 +000052
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000053 // Build the expectation set.
54 NodeMSet expect_set;
55 for (int i = 0; i < use_count; i++) {
56 expect_set.insert(uses[i]);
Ben Murdochb8a8cc12014-11-26 15:28:44 +000057 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000058
59 {
60 // Check that iterating over the uses gives the right counts.
61 NodeMSet use_set;
62 for (auto use : node->uses()) {
63 use_set.insert(use);
64 }
65 CHECK(expect_set == use_set);
66 }
67
68 {
69 // Check that iterating over the use edges gives the right counts,
70 // input indices, from(), and to() pointers.
71 NodeMSet use_set;
72 for (auto edge : node->use_edges()) {
73 CHECK_EQ(node, edge.to());
74 CHECK_EQ(node, edge.from()->InputAt(edge.index()));
75 use_set.insert(edge.from());
76 }
77 CHECK(expect_set == use_set);
78 }
79
80 {
81 // Check the use nodes actually have the node as inputs.
82 for (Node* use : node->uses()) {
83 size_t count = 0;
84 for (Node* input : use->inputs()) {
85 if (input == node) count++;
86 }
87 CHECK_EQ(count, expect_set.count(use));
88 }
89 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +000090}
91
92
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000093void 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 }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000129}
130
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000131} // namespace
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000132
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000133
134#define CHECK_INPUTS(node, ...) \
135 do { \
136 Node* __array[] = {__VA_ARGS__}; \
137 int __size = \
138 __array[0] != NONE ? static_cast<int>(arraysize(__array)) : 0; \
139 CheckInputs(node, __array, __size); \
140 } while (false)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000141
142
143TEST(NodeUseIteratorReplaceUses) {
Ben Murdochda12d292016-06-02 14:46:10 +0100144 base::AccountingAllocator allocator;
145 Zone zone(&allocator);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000146 Graph graph(&zone);
147 Node* n0 = graph.NewNode(&dummy_operator0);
148 Node* n1 = graph.NewNode(&dummy_operator1, n0);
149 Node* n2 = graph.NewNode(&dummy_operator1, n0);
150 Node* n3 = graph.NewNode(&dummy_operator0);
151
152 CHECK_USES(n0, n1, n2);
153
154 CHECK_INPUTS(n1, n0);
155 CHECK_INPUTS(n2, n0);
156
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000157 n0->ReplaceUses(n3);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000158
159 CHECK_USES(n0, NONE);
160 CHECK_USES(n1, NONE);
161 CHECK_USES(n2, NONE);
162 CHECK_USES(n3, n1, n2);
163
164 CHECK_INPUTS(n1, n3);
165 CHECK_INPUTS(n2, n3);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000166}
167
168
169TEST(NodeUseIteratorReplaceUsesSelf) {
Ben Murdochda12d292016-06-02 14:46:10 +0100170 base::AccountingAllocator allocator;
171 Zone zone(&allocator);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000172 Graph graph(&zone);
173 Node* n0 = graph.NewNode(&dummy_operator0);
174 Node* n1 = graph.NewNode(&dummy_operator1, n0);
175
176 CHECK_USES(n0, n1);
177 CHECK_USES(n1, NONE);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000178
179 n1->ReplaceInput(0, n1); // Create self-reference.
180
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000181 CHECK_USES(n0, NONE);
182 CHECK_USES(n1, n1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000183
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000184 Node* n2 = graph.NewNode(&dummy_operator0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000185
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000186 n1->ReplaceUses(n2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000187
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000188 CHECK_USES(n0, NONE);
189 CHECK_USES(n1, NONE);
190 CHECK_USES(n2, n1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000191}
192
193
194TEST(ReplaceInput) {
Ben Murdochda12d292016-06-02 14:46:10 +0100195 base::AccountingAllocator allocator;
196 Zone zone(&allocator);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000197 Graph graph(&zone);
198 Node* n0 = graph.NewNode(&dummy_operator0);
199 Node* n1 = graph.NewNode(&dummy_operator0);
200 Node* n2 = graph.NewNode(&dummy_operator0);
201 Node* n3 = graph.NewNode(&dummy_operator3, n0, n1, n2);
202 Node* n4 = graph.NewNode(&dummy_operator0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000203
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000204 CHECK_USES(n0, n3);
205 CHECK_USES(n1, n3);
206 CHECK_USES(n2, n3);
207 CHECK_USES(n3, NONE);
208 CHECK_USES(n4, NONE);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000209
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000210 CHECK_INPUTS(n3, n0, n1, n2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000211
212 n3->ReplaceInput(1, n4);
213
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000214 CHECK_USES(n1, NONE);
215 CHECK_USES(n4, n3);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000216
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000217 CHECK_INPUTS(n3, n0, n4, n2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000218}
219
220
221TEST(OwnedBy) {
Ben Murdochda12d292016-06-02 14:46:10 +0100222 base::AccountingAllocator allocator;
223 Zone zone(&allocator);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000224 Graph graph(&zone);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000225
226 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000227 Node* n0 = graph.NewNode(&dummy_operator0);
228 Node* n1 = graph.NewNode(&dummy_operator0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000229
230 CHECK(!n0->OwnedBy(n1));
231 CHECK(!n1->OwnedBy(n0));
232
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000233 Node* n2 = graph.NewNode(&dummy_operator1, n0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000234 CHECK(n0->OwnedBy(n2));
235 CHECK(!n2->OwnedBy(n0));
236
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000237 Node* n3 = graph.NewNode(&dummy_operator1, n0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000238 CHECK(!n0->OwnedBy(n2));
239 CHECK(!n0->OwnedBy(n3));
240 CHECK(!n2->OwnedBy(n0));
241 CHECK(!n3->OwnedBy(n0));
242 }
243
244 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000245 Node* n0 = graph.NewNode(&dummy_operator0);
246 Node* n1 = graph.NewNode(&dummy_operator1, n0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000247 CHECK(n0->OwnedBy(n1));
248 CHECK(!n1->OwnedBy(n0));
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000249 Node* n2 = graph.NewNode(&dummy_operator1, n0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000250 CHECK(!n0->OwnedBy(n1));
251 CHECK(!n0->OwnedBy(n2));
252 CHECK(!n1->OwnedBy(n0));
253 CHECK(!n1->OwnedBy(n2));
254 CHECK(!n2->OwnedBy(n0));
255 CHECK(!n2->OwnedBy(n1));
256
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000257 Node* n3 = graph.NewNode(&dummy_operator0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000258 n2->ReplaceInput(0, n3);
259
260 CHECK(n0->OwnedBy(n1));
261 CHECK(!n1->OwnedBy(n0));
262 CHECK(!n1->OwnedBy(n0));
263 CHECK(!n1->OwnedBy(n2));
264 CHECK(!n2->OwnedBy(n0));
265 CHECK(!n2->OwnedBy(n1));
266 CHECK(n3->OwnedBy(n2));
267 CHECK(!n2->OwnedBy(n3));
268 }
269}
270
271
272TEST(Uses) {
Ben Murdochda12d292016-06-02 14:46:10 +0100273 base::AccountingAllocator allocator;
274 Zone zone(&allocator);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000275 Graph graph(&zone);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000276
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000277 Node* n0 = graph.NewNode(&dummy_operator0);
278 Node* n1 = graph.NewNode(&dummy_operator1, n0);
279
280 CHECK_USES(n0, n1);
281 CHECK_USES(n1, NONE);
282
283 Node* n2 = graph.NewNode(&dummy_operator1, n0);
284
285 CHECK_USES(n0, n1, n2);
286 CHECK_USES(n2, NONE);
287
288 Node* n3 = graph.NewNode(&dummy_operator1, n0);
289
290 CHECK_USES(n0, n1, n2, n3);
291 CHECK_USES(n3, NONE);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000292}
293
294
295TEST(Inputs) {
Ben Murdochda12d292016-06-02 14:46:10 +0100296 base::AccountingAllocator allocator;
297 Zone zone(&allocator);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000298 Graph graph(&zone);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000299
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000300 Node* n0 = graph.NewNode(&dummy_operator0);
301 Node* n1 = graph.NewNode(&dummy_operator1, n0);
302 Node* n2 = graph.NewNode(&dummy_operator1, n0);
303 Node* n3 = graph.NewNode(&dummy_operator3, n0, n1, n2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000304
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000305 CHECK_INPUTS(n3, n0, n1, n2);
306
307 Node* n4 = graph.NewNode(&dummy_operator3, n0, n1, n2);
308 n3->AppendInput(graph.zone(), n4);
309
310 CHECK_INPUTS(n3, n0, n1, n2, n4);
311 CHECK_USES(n4, n3);
312
313 n3->AppendInput(graph.zone(), n4);
314
315 CHECK_INPUTS(n3, n0, n1, n2, n4, n4);
316 CHECK_USES(n4, n3, n3);
317
318 Node* n5 = graph.NewNode(&dummy_operator1, n4);
319
320 CHECK_USES(n4, n3, n3, n5);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000321}
322
323
324TEST(RemoveInput) {
Ben Murdochda12d292016-06-02 14:46:10 +0100325 base::AccountingAllocator allocator;
326 Zone zone(&allocator);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000327 Graph graph(&zone);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000328
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000329 Node* n0 = graph.NewNode(&dummy_operator0);
330 Node* n1 = graph.NewNode(&dummy_operator1, n0);
331 Node* n2 = graph.NewNode(&dummy_operator2, n0, n1);
332
333 CHECK_INPUTS(n0, NONE);
334 CHECK_INPUTS(n1, n0);
335 CHECK_INPUTS(n2, n0, n1);
336 CHECK_USES(n0, n1, n2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000337
338 n1->RemoveInput(0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000339 CHECK_INPUTS(n1, NONE);
340 CHECK_USES(n0, n2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000341
342 n2->RemoveInput(0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000343 CHECK_INPUTS(n2, n1);
344 CHECK_USES(n0, NONE);
345 CHECK_USES(n1, n2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000346
347 n2->RemoveInput(0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000348 CHECK_INPUTS(n2, NONE);
349 CHECK_USES(n0, NONE);
350 CHECK_USES(n1, NONE);
351 CHECK_USES(n2, NONE);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000352}
353
354
355TEST(AppendInputsAndIterator) {
Ben Murdochda12d292016-06-02 14:46:10 +0100356 base::AccountingAllocator allocator;
357 Zone zone(&allocator);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000358 Graph graph(&zone);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000359
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000360 Node* n0 = graph.NewNode(&dummy_operator0);
361 Node* n1 = graph.NewNode(&dummy_operator1, n0);
362 Node* n2 = graph.NewNode(&dummy_operator2, n0, n1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000363
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000364 CHECK_INPUTS(n0, NONE);
365 CHECK_INPUTS(n1, n0);
366 CHECK_INPUTS(n2, n0, n1);
367 CHECK_USES(n0, n1, n2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000368
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000369 Node* n3 = graph.NewNode(&dummy_operator0);
370
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000371 n2->AppendInput(graph.zone(), n3);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000372
373 CHECK_INPUTS(n2, n0, n1, n3);
374 CHECK_USES(n3, n2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000375}
376
377
378TEST(NullInputsSimple) {
Ben Murdochda12d292016-06-02 14:46:10 +0100379 base::AccountingAllocator allocator;
380 Zone zone(&allocator);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000381 Graph graph(&zone);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000382
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000383 Node* n0 = graph.NewNode(&dummy_operator0);
384 Node* n1 = graph.NewNode(&dummy_operator1, n0);
385 Node* n2 = graph.NewNode(&dummy_operator2, n0, n1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000386
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000387 CHECK_INPUTS(n0, NONE);
388 CHECK_INPUTS(n1, n0);
389 CHECK_INPUTS(n2, n0, n1);
390 CHECK_USES(n0, n1, n2);
391
392 n2->ReplaceInput(0, nullptr);
393
394 CHECK_INPUTS(n2, NULL, n1);
395
396 CHECK_USES(n0, n1);
397
398 n2->ReplaceInput(1, nullptr);
399
400 CHECK_INPUTS(n2, NULL, NULL);
401
402 CHECK_USES(n1, NONE);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000403}
404
405
406TEST(NullInputsAppended) {
Ben Murdochda12d292016-06-02 14:46:10 +0100407 base::AccountingAllocator allocator;
408 Zone zone(&allocator);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000409 Graph graph(&zone);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000410
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000411 Node* n0 = graph.NewNode(&dummy_operator0);
412 Node* n1 = graph.NewNode(&dummy_operator1, n0);
413 Node* n2 = graph.NewNode(&dummy_operator1, n0);
414 Node* n3 = graph.NewNode(&dummy_operator1, n0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000415 n3->AppendInput(graph.zone(), n1);
416 n3->AppendInput(graph.zone(), n2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000417
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000418 CHECK_INPUTS(n3, n0, n1, n2);
419 CHECK_USES(n0, n1, n2, n3);
420 CHECK_USES(n1, n3);
421 CHECK_USES(n2, n3);
422
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000423 n3->ReplaceInput(1, NULL);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000424 CHECK_USES(n1, NONE);
425
426 CHECK_INPUTS(n3, n0, NULL, n2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000427}
428
429
430TEST(ReplaceUsesFromAppendedInputs) {
Ben Murdochda12d292016-06-02 14:46:10 +0100431 base::AccountingAllocator allocator;
432 Zone zone(&allocator);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000433 Graph graph(&zone);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000434
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000435 Node* n0 = graph.NewNode(&dummy_operator0);
436 Node* n1 = graph.NewNode(&dummy_operator1, n0);
437 Node* n2 = graph.NewNode(&dummy_operator1, n0);
438 Node* n3 = graph.NewNode(&dummy_operator0);
439
440 CHECK_INPUTS(n2, n0);
441
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000442 n2->AppendInput(graph.zone(), n1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000443 CHECK_INPUTS(n2, n0, n1);
444 CHECK_USES(n1, n2);
445
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000446 n2->AppendInput(graph.zone(), n0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000447 CHECK_INPUTS(n2, n0, n1, n0);
448 CHECK_USES(n1, n2);
449 CHECK_USES(n0, n2, n1, n2);
450
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000451 n0->ReplaceUses(n3);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000452
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000453 CHECK_USES(n0, NONE);
454 CHECK_INPUTS(n2, n3, n1, n3);
455 CHECK_USES(n3, n2, n1, n2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000456}
457
458
459TEST(ReplaceInputMultipleUses) {
Ben Murdochda12d292016-06-02 14:46:10 +0100460 base::AccountingAllocator allocator;
461 Zone zone(&allocator);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000462 Graph graph(&zone);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000463
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000464 Node* n0 = graph.NewNode(&dummy_operator0);
465 Node* n1 = graph.NewNode(&dummy_operator0);
466 Node* n2 = graph.NewNode(&dummy_operator1, n0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000467 n2->ReplaceInput(0, n1);
468 CHECK_EQ(0, n0->UseCount());
469 CHECK_EQ(1, n1->UseCount());
470
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000471 Node* n3 = graph.NewNode(&dummy_operator1, n0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000472 n3->ReplaceInput(0, n1);
473 CHECK_EQ(0, n0->UseCount());
474 CHECK_EQ(2, n1->UseCount());
475}
476
477
478TEST(TrimInputCountInline) {
Ben Murdochda12d292016-06-02 14:46:10 +0100479 base::AccountingAllocator allocator;
480 Zone zone(&allocator);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000481 Graph graph(&zone);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000482
483 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000484 Node* n0 = graph.NewNode(&dummy_operator0);
485 Node* n1 = graph.NewNode(&dummy_operator1, n0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000486 n1->TrimInputCount(1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000487 CHECK_INPUTS(n1, n0);
488 CHECK_USES(n0, n1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000489 }
490
491 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000492 Node* n0 = graph.NewNode(&dummy_operator0);
493 Node* n1 = graph.NewNode(&dummy_operator1, n0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000494 n1->TrimInputCount(0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000495 CHECK_INPUTS(n1, NONE);
496 CHECK_USES(n0, NONE);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000497 }
498
499 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000500 Node* n0 = graph.NewNode(&dummy_operator0);
501 Node* n1 = graph.NewNode(&dummy_operator0);
502 Node* n2 = graph.NewNode(&dummy_operator2, n0, n1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000503 n2->TrimInputCount(2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000504 CHECK_INPUTS(n2, n0, n1);
505 CHECK_USES(n0, n2);
506 CHECK_USES(n1, n2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000507 }
508
509 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000510 Node* n0 = graph.NewNode(&dummy_operator0);
511 Node* n1 = graph.NewNode(&dummy_operator0);
512 Node* n2 = graph.NewNode(&dummy_operator2, n0, n1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000513 n2->TrimInputCount(1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000514 CHECK_INPUTS(n2, n0);
515 CHECK_USES(n0, n2);
516 CHECK_USES(n1, NONE);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000517 }
518
519 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000520 Node* n0 = graph.NewNode(&dummy_operator0);
521 Node* n1 = graph.NewNode(&dummy_operator0);
522 Node* n2 = graph.NewNode(&dummy_operator2, n0, n1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000523 n2->TrimInputCount(0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000524 CHECK_INPUTS(n2, NONE);
525 CHECK_USES(n0, NONE);
526 CHECK_USES(n1, NONE);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000527 }
528
529 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000530 Node* n0 = graph.NewNode(&dummy_operator0);
531 Node* n2 = graph.NewNode(&dummy_operator2, n0, n0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000532 n2->TrimInputCount(1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000533 CHECK_INPUTS(n2, n0);
534 CHECK_USES(n0, n2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000535 }
536
537 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000538 Node* n0 = graph.NewNode(&dummy_operator0);
539 Node* n2 = graph.NewNode(&dummy_operator2, n0, n0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000540 n2->TrimInputCount(0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000541 CHECK_INPUTS(n2, NONE);
542 CHECK_USES(n0, NONE);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000543 }
544}
545
546
547TEST(TrimInputCountOutOfLine1) {
Ben Murdochda12d292016-06-02 14:46:10 +0100548 base::AccountingAllocator allocator;
549 Zone zone(&allocator);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000550 Graph graph(&zone);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000551
552 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000553 Node* n0 = graph.NewNode(&dummy_operator0);
554 Node* n1 = graph.NewNode(&dummy_operator0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000555 n1->AppendInput(graph.zone(), n0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000556 CHECK_INPUTS(n1, n0);
557 CHECK_USES(n0, n1);
558
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000559 n1->TrimInputCount(1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000560 CHECK_INPUTS(n1, n0);
561 CHECK_USES(n0, n1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000562 }
563
564 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000565 Node* n0 = graph.NewNode(&dummy_operator0);
566 Node* n1 = graph.NewNode(&dummy_operator0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000567 n1->AppendInput(graph.zone(), n0);
568 CHECK_EQ(1, n1->InputCount());
569 n1->TrimInputCount(0);
570 CHECK_EQ(0, n1->InputCount());
571 CHECK_EQ(0, n0->UseCount());
572 }
573
574 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000575 Node* n0 = graph.NewNode(&dummy_operator0);
576 Node* n1 = graph.NewNode(&dummy_operator0);
577 Node* n2 = graph.NewNode(&dummy_operator0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000578 n2->AppendInput(graph.zone(), n0);
579 n2->AppendInput(graph.zone(), n1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000580 CHECK_INPUTS(n2, n0, n1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000581 n2->TrimInputCount(2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000582 CHECK_INPUTS(n2, n0, n1);
583 CHECK_USES(n0, n2);
584 CHECK_USES(n1, n2);
585 CHECK_USES(n2, NONE);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000586 }
587
588 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000589 Node* n0 = graph.NewNode(&dummy_operator0);
590 Node* n1 = graph.NewNode(&dummy_operator0);
591 Node* n2 = graph.NewNode(&dummy_operator0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000592 n2->AppendInput(graph.zone(), n0);
593 n2->AppendInput(graph.zone(), n1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000594 CHECK_INPUTS(n2, n0, n1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000595 n2->TrimInputCount(1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000596 CHECK_INPUTS(n2, n0);
597 CHECK_USES(n0, n2);
598 CHECK_USES(n1, NONE);
599 CHECK_USES(n2, NONE);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000600 }
601
602 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000603 Node* n0 = graph.NewNode(&dummy_operator0);
604 Node* n1 = graph.NewNode(&dummy_operator0);
605 Node* n2 = graph.NewNode(&dummy_operator0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000606 n2->AppendInput(graph.zone(), n0);
607 n2->AppendInput(graph.zone(), n1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000608 CHECK_INPUTS(n2, n0, n1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000609 n2->TrimInputCount(0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000610 CHECK_INPUTS(n2, NONE);
611 CHECK_USES(n0, NONE);
612 CHECK_USES(n1, NONE);
613 CHECK_USES(n2, NONE);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000614 }
615
616 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000617 Node* n0 = graph.NewNode(&dummy_operator0);
618 Node* n2 = graph.NewNode(&dummy_operator0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000619 n2->AppendInput(graph.zone(), n0);
620 n2->AppendInput(graph.zone(), n0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000621 CHECK_INPUTS(n2, n0, n0);
622 CHECK_USES(n0, n2, n2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000623 n2->TrimInputCount(1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000624 CHECK_INPUTS(n2, n0);
625 CHECK_USES(n0, n2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000626 }
627
628 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000629 Node* n0 = graph.NewNode(&dummy_operator0);
630 Node* n2 = graph.NewNode(&dummy_operator0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000631 n2->AppendInput(graph.zone(), n0);
632 n2->AppendInput(graph.zone(), n0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000633 CHECK_INPUTS(n2, n0, n0);
634 CHECK_USES(n0, n2, n2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000635 n2->TrimInputCount(0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000636 CHECK_INPUTS(n2, NONE);
637 CHECK_USES(n0, NONE);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000638 }
639}
640
641
642TEST(TrimInputCountOutOfLine2) {
Ben Murdochda12d292016-06-02 14:46:10 +0100643 base::AccountingAllocator allocator;
644 Zone zone(&allocator);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000645 Graph graph(&zone);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000646
647 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000648 Node* n0 = graph.NewNode(&dummy_operator0);
649 Node* n1 = graph.NewNode(&dummy_operator0);
650 Node* n2 = graph.NewNode(&dummy_operator1, n0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000651 n2->AppendInput(graph.zone(), n1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000652 CHECK_INPUTS(n2, n0, n1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000653 n2->TrimInputCount(2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000654 CHECK_INPUTS(n2, n0, n1);
655 CHECK_USES(n0, n2);
656 CHECK_USES(n1, n2);
657 CHECK_USES(n2, NONE);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000658 }
659
660 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000661 Node* n0 = graph.NewNode(&dummy_operator0);
662 Node* n1 = graph.NewNode(&dummy_operator0);
663 Node* n2 = graph.NewNode(&dummy_operator1, n0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000664 n2->AppendInput(graph.zone(), n1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000665 CHECK_INPUTS(n2, n0, n1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000666 n2->TrimInputCount(1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000667 CHECK_INPUTS(n2, n0);
668 CHECK_USES(n0, n2);
669 CHECK_USES(n1, NONE);
670 CHECK_USES(n2, NONE);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000671 }
672
673 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000674 Node* n0 = graph.NewNode(&dummy_operator0);
675 Node* n1 = graph.NewNode(&dummy_operator0);
676 Node* n2 = graph.NewNode(&dummy_operator1, n0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000677 n2->AppendInput(graph.zone(), n1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000678 CHECK_INPUTS(n2, n0, n1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000679 n2->TrimInputCount(0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000680 CHECK_INPUTS(n2, NONE);
681 CHECK_USES(n0, NONE);
682 CHECK_USES(n1, NONE);
683 CHECK_USES(n2, NONE);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000684 }
685
686 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000687 Node* n0 = graph.NewNode(&dummy_operator0);
688 Node* n2 = graph.NewNode(&dummy_operator1, n0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000689 n2->AppendInput(graph.zone(), n0);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000690 CHECK_INPUTS(n2, n0, n0);
691 CHECK_USES(n0, n2, n2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000692 n2->TrimInputCount(1);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000693 CHECK_INPUTS(n2, n0);
694 CHECK_USES(n0, n2);
695 CHECK_USES(n2, NONE);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000696 }
697
698 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000699 Node* n0 = graph.NewNode(&dummy_operator0);
700 Node* n2 = graph.NewNode(&dummy_operator1, n0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000701 n2->AppendInput(graph.zone(), n0);
702 CHECK_EQ(2, n2->InputCount());
703 CHECK_EQ(2, n0->UseCount());
704 n2->TrimInputCount(0);
705 CHECK_EQ(0, n2->InputCount());
706 CHECK_EQ(0, n0->UseCount());
707 CHECK_EQ(0, n2->UseCount());
708 }
709}
710
711
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000712TEST(NullAllInputs) {
Ben Murdochda12d292016-06-02 14:46:10 +0100713 base::AccountingAllocator allocator;
714 Zone zone(&allocator);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000715 Graph graph(&zone);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000716
717 for (int i = 0; i < 2; i++) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000718 Node* n0 = graph.NewNode(&dummy_operator0);
719 Node* n1 = graph.NewNode(&dummy_operator1, n0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000720 Node* n2;
721 if (i == 0) {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000722 n2 = graph.NewNode(&dummy_operator2, n0, n1);
723 CHECK_INPUTS(n2, n0, n1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000724 } else {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000725 n2 = graph.NewNode(&dummy_operator1, n0);
726 CHECK_INPUTS(n2, n0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000727 n2->AppendInput(graph.zone(), n1); // with out-of-line input.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000728 CHECK_INPUTS(n2, n0, n1);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000729 }
730
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000731 n0->NullAllInputs();
732 CHECK_INPUTS(n0, NONE);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000733
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000734 CHECK_USES(n0, n1, n2);
735 n1->NullAllInputs();
736 CHECK_INPUTS(n1, NULL);
737 CHECK_INPUTS(n2, n0, n1);
738 CHECK_USES(n0, n2);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000739
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000740 n2->NullAllInputs();
741 CHECK_INPUTS(n1, NULL);
742 CHECK_INPUTS(n2, NULL, NULL);
743 CHECK_USES(n0, NONE);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000744 }
745
746 {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000747 Node* n0 = graph.NewNode(&dummy_operator0);
748 Node* n1 = graph.NewNode(&dummy_operator1, n0);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000749 n1->ReplaceInput(0, n1); // self-reference.
750
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000751 CHECK_INPUTS(n0, NONE);
752 CHECK_INPUTS(n1, n1);
753 CHECK_USES(n0, NONE);
754 CHECK_USES(n1, n1);
755 n1->NullAllInputs();
756
757 CHECK_INPUTS(n0, NONE);
758 CHECK_INPUTS(n1, NULL);
759 CHECK_USES(n0, NONE);
760 CHECK_USES(n1, NONE);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000761 }
762}
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000763
764
765TEST(AppendAndTrim) {
Ben Murdochda12d292016-06-02 14:46:10 +0100766 base::AccountingAllocator allocator;
767 Zone zone(&allocator);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000768 Graph graph(&zone);
769
770 Node* nodes[] = {
771 graph.NewNode(&dummy_operator0), graph.NewNode(&dummy_operator0),
772 graph.NewNode(&dummy_operator0), graph.NewNode(&dummy_operator0),
773 graph.NewNode(&dummy_operator0)};
774
775 int max = static_cast<int>(arraysize(nodes));
776
777 Node* last = graph.NewNode(&dummy_operator0);
778
779 for (int i = 0; i < max; i++) {
780 last->AppendInput(graph.zone(), nodes[i]);
781 CheckInputs(last, nodes, i + 1);
782
783 for (int j = 0; j < max; j++) {
784 if (j <= i) CHECK_USES(nodes[j], last);
785 if (j > i) CHECK_USES(nodes[j], NONE);
786 }
787
788 CHECK_USES(last, NONE);
789 }
790
791 for (int i = max; i >= 0; i--) {
792 last->TrimInputCount(i);
793 CheckInputs(last, nodes, i);
794
795 for (int j = 0; j < i; j++) {
796 if (j < i) CHECK_USES(nodes[j], last);
797 if (j >= i) CHECK_USES(nodes[j], NONE);
798 }
799
800 CHECK_USES(last, NONE);
801 }
802}
803
804} // namespace compiler
805} // namespace internal
806} // namespace v8