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