OLD | NEW |
1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/machine-graph-verifier.h" | 5 #include "src/compiler/machine-graph-verifier.h" |
6 | 6 |
7 #include "src/compiler/common-operator.h" | 7 #include "src/compiler/common-operator.h" |
8 #include "src/compiler/graph.h" | 8 #include "src/compiler/graph.h" |
9 #include "src/compiler/linkage.h" | 9 #include "src/compiler/linkage.h" |
10 #include "src/compiler/machine-operator.h" | 10 #include "src/compiler/machine-operator.h" |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
299 } | 299 } |
300 } else { | 300 } else { |
301 CheckValueInputForInt64Op(node, 0); | 301 CheckValueInputForInt64Op(node, 0); |
302 CheckValueInputForInt64Op(node, 1); | 302 CheckValueInputForInt64Op(node, 1); |
303 } | 303 } |
304 break; | 304 break; |
305 case IrOpcode::kInt64LessThan: | 305 case IrOpcode::kInt64LessThan: |
306 case IrOpcode::kInt64LessThanOrEqual: | 306 case IrOpcode::kInt64LessThanOrEqual: |
307 case IrOpcode::kUint64LessThan: | 307 case IrOpcode::kUint64LessThan: |
308 case IrOpcode::kUint64LessThanOrEqual: | 308 case IrOpcode::kUint64LessThanOrEqual: |
309 CheckValueInputForInt64Op(node, 0); | 309 // Allows Smi operands in stubs. |
310 CheckValueInputForInt64Op(node, 1); | 310 CheckValueInputForInt64Op(node, 0, is_stub_); |
| 311 CheckValueInputForInt64Op(node, 1, is_stub_); |
| 312 if (is_stub_) { |
| 313 CheckCompatibleValueInputRepresentations(node, 0, 1); |
| 314 } |
311 break; | 315 break; |
312 case IrOpcode::kInt32x4ExtractLane: | 316 case IrOpcode::kInt32x4ExtractLane: |
313 CheckValueInputRepresentationIs(node, 0, | 317 CheckValueInputRepresentationIs(node, 0, |
314 MachineRepresentation::kSimd128); | 318 MachineRepresentation::kSimd128); |
315 break; | 319 break; |
316 #define LABEL(opcode) case IrOpcode::k##opcode: | 320 #define LABEL(opcode) case IrOpcode::k##opcode: |
317 case IrOpcode::kChangeInt32ToTagged: | 321 case IrOpcode::kChangeInt32ToTagged: |
318 case IrOpcode::kChangeUint32ToTagged: | 322 case IrOpcode::kChangeUint32ToTagged: |
319 case IrOpcode::kChangeInt32ToFloat64: | 323 case IrOpcode::kChangeInt32ToFloat64: |
320 case IrOpcode::kChangeUint32ToFloat64: | 324 case IrOpcode::kChangeUint32ToFloat64: |
(...skipping 14 matching lines...) Expand all Loading... |
335 } else { | 339 } else { |
336 CheckValueInputForInt32Op(node, 0); | 340 CheckValueInputForInt32Op(node, 0); |
337 CheckValueInputForInt32Op(node, 1); | 341 CheckValueInputForInt32Op(node, 1); |
338 } | 342 } |
339 break; | 343 break; |
340 | 344 |
341 case IrOpcode::kInt32LessThan: | 345 case IrOpcode::kInt32LessThan: |
342 case IrOpcode::kInt32LessThanOrEqual: | 346 case IrOpcode::kInt32LessThanOrEqual: |
343 case IrOpcode::kUint32LessThan: | 347 case IrOpcode::kUint32LessThan: |
344 case IrOpcode::kUint32LessThanOrEqual: | 348 case IrOpcode::kUint32LessThanOrEqual: |
345 MACHINE_BINOP_32_LIST(LABEL) { | 349 case IrOpcode::kInt32Add: |
346 CheckValueInputForInt32Op(node, 0); | 350 case IrOpcode::kInt32Sub: |
347 CheckValueInputForInt32Op(node, 1); | 351 // Allows Smi operands in stubs. |
| 352 CheckValueInputForInt32Op(node, 0, is_stub_); |
| 353 CheckValueInputForInt32Op(node, 1, is_stub_); |
| 354 if (is_stub_) { |
| 355 CheckCompatibleValueInputRepresentations(node, 0, 1); |
348 } | 356 } |
349 break; | 357 break; |
| 358 case IrOpcode::kWord32And: |
| 359 case IrOpcode::kWord32Or: |
| 360 case IrOpcode::kWord32Xor: |
| 361 case IrOpcode::kWord32Shl: |
| 362 case IrOpcode::kWord32Shr: |
| 363 case IrOpcode::kWord32Sar: |
| 364 case IrOpcode::kWord32Ror: |
| 365 case IrOpcode::kInt32Mul: |
| 366 case IrOpcode::kInt32AddWithOverflow: |
| 367 case IrOpcode::kInt32SubWithOverflow: |
| 368 case IrOpcode::kInt32MulWithOverflow: |
| 369 case IrOpcode::kInt32MulHigh: |
| 370 case IrOpcode::kInt32Div: |
| 371 case IrOpcode::kInt32Mod: |
| 372 case IrOpcode::kUint32Div: |
| 373 case IrOpcode::kUint32Mod: |
| 374 case IrOpcode::kUint32MulHigh: |
| 375 CheckValueInputForInt32Op(node, 0); |
| 376 CheckValueInputForInt32Op(node, 1); |
| 377 break; |
350 MACHINE_BINOP_64_LIST(LABEL) { | 378 MACHINE_BINOP_64_LIST(LABEL) { |
351 CheckValueInputForInt64Op(node, 0); | 379 CheckValueInputForInt64Op(node, 0); |
352 CheckValueInputForInt64Op(node, 1); | 380 CheckValueInputForInt64Op(node, 1); |
353 } | 381 } |
354 break; | 382 break; |
355 case IrOpcode::kFloat32Equal: | 383 case IrOpcode::kFloat32Equal: |
356 case IrOpcode::kFloat32LessThan: | 384 case IrOpcode::kFloat32LessThan: |
357 case IrOpcode::kFloat32LessThanOrEqual: | 385 case IrOpcode::kFloat32LessThanOrEqual: |
358 MACHINE_FLOAT32_BINOP_LIST(LABEL) { | 386 MACHINE_FLOAT32_BINOP_LIST(LABEL) { |
359 CheckValueInputForFloat32Op(node, 0); | 387 CheckValueInputForFloat32Op(node, 0); |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
481 if (input_representation != representation) { | 509 if (input_representation != representation) { |
482 std::stringstream str; | 510 std::stringstream str; |
483 str << "TypeError: node #" << node->id() << ":" << *node->op() | 511 str << "TypeError: node #" << node->id() << ":" << *node->op() |
484 << " uses node #" << input->id() << ":" << *input->op() << ":" | 512 << " uses node #" << input->id() << ":" << *input->op() << ":" |
485 << input_representation << " which doesn't have a " << representation | 513 << input_representation << " which doesn't have a " << representation |
486 << " representation."; | 514 << " representation."; |
487 FATAL(str.str().c_str()); | 515 FATAL(str.str().c_str()); |
488 } | 516 } |
489 } | 517 } |
490 | 518 |
| 519 MachineRepresentation Promote(MachineRepresentation rep) { |
| 520 switch (rep) { |
| 521 case MachineRepresentation::kBit: |
| 522 case MachineRepresentation::kWord8: |
| 523 case MachineRepresentation::kWord16: |
| 524 case MachineRepresentation::kWord32: |
| 525 return MachineRepresentation::kWord32; |
| 526 case MachineRepresentation::kTagged: |
| 527 case MachineRepresentation::kTaggedSigned: |
| 528 case MachineRepresentation::kTaggedPointer: |
| 529 return MachineRepresentation::kTagged; |
| 530 default: |
| 531 break; |
| 532 } |
| 533 return rep; |
| 534 } |
| 535 |
| 536 void CheckCompatibleValueInputRepresentations(Node const* node, int index1, |
| 537 int index2) { |
| 538 Node const* input1 = node->InputAt(index1); |
| 539 MachineRepresentation input_representation1 = |
| 540 inferrer_->GetRepresentation(input1); |
| 541 Node const* input2 = node->InputAt(index2); |
| 542 MachineRepresentation input_representation2 = |
| 543 inferrer_->GetRepresentation(input2); |
| 544 if (Promote(input_representation1) != Promote(input_representation2)) { |
| 545 std::stringstream str; |
| 546 str << "TypeError: node #" << node->id() << ":" << *node->op() |
| 547 << " uses operands with incompatible representations: node #" |
| 548 << input1->id() << ":" << *input1->op() << ":" |
| 549 << input_representation1 << " and #" << input2->id() << ":" |
| 550 << *input2->op() << ":" << input_representation2 << "."; |
| 551 FATAL(str.str().c_str()); |
| 552 } |
| 553 } |
| 554 |
491 void CheckValueInputIsTagged(Node const* node, int index) { | 555 void CheckValueInputIsTagged(Node const* node, int index) { |
492 Node const* input = node->InputAt(index); | 556 Node const* input = node->InputAt(index); |
493 switch (inferrer_->GetRepresentation(input)) { | 557 switch (inferrer_->GetRepresentation(input)) { |
494 case MachineRepresentation::kTagged: | 558 case MachineRepresentation::kTagged: |
495 case MachineRepresentation::kTaggedPointer: | 559 case MachineRepresentation::kTaggedPointer: |
496 case MachineRepresentation::kTaggedSigned: | 560 case MachineRepresentation::kTaggedSigned: |
497 return; | 561 return; |
498 default: | 562 default: |
499 break; | 563 break; |
500 } | 564 } |
(...skipping 30 matching lines...) Expand all Loading... |
531 if (inferrer_->GetRepresentation(input) != | 595 if (inferrer_->GetRepresentation(input) != |
532 MachineType::PointerRepresentation()) { | 596 MachineType::PointerRepresentation()) { |
533 std::ostringstream str; | 597 std::ostringstream str; |
534 str << "TypeError: node #" << node->id() << ":" << *node->op() | 598 str << "TypeError: node #" << node->id() << ":" << *node->op() |
535 << " uses node #" << input->id() << ":" << *input->op() | 599 << " uses node #" << input->id() << ":" << *input->op() |
536 << " which doesn't have a tagged or pointer representation."; | 600 << " which doesn't have a tagged or pointer representation."; |
537 FATAL(str.str().c_str()); | 601 FATAL(str.str().c_str()); |
538 } | 602 } |
539 } | 603 } |
540 | 604 |
541 void CheckValueInputForInt32Op(Node const* node, int index) { | 605 void CheckValueInputForInt32Op(Node const* node, int index, |
| 606 bool allow_tagged = false) { |
542 Node const* input = node->InputAt(index); | 607 Node const* input = node->InputAt(index); |
543 switch (inferrer_->GetRepresentation(input)) { | 608 switch (inferrer_->GetRepresentation(input)) { |
544 case MachineRepresentation::kBit: | 609 case MachineRepresentation::kBit: |
545 case MachineRepresentation::kWord8: | 610 case MachineRepresentation::kWord8: |
546 case MachineRepresentation::kWord16: | 611 case MachineRepresentation::kWord16: |
547 case MachineRepresentation::kWord32: | 612 case MachineRepresentation::kWord32: |
548 return; | 613 return; |
| 614 case MachineRepresentation::kTagged: |
| 615 case MachineRepresentation::kTaggedSigned: |
| 616 case MachineRepresentation::kTaggedPointer: |
| 617 if (Is32() && allow_tagged) { |
| 618 return; |
| 619 } |
| 620 break; |
549 case MachineRepresentation::kNone: { | 621 case MachineRepresentation::kNone: { |
550 std::ostringstream str; | 622 std::ostringstream str; |
551 str << "TypeError: node #" << input->id() << ":" << *input->op() | 623 str << "TypeError: node #" << input->id() << ":" << *input->op() |
552 << " is untyped."; | 624 << " is untyped."; |
553 FATAL(str.str().c_str()); | 625 FATAL(str.str().c_str()); |
554 break; | 626 break; |
555 } | 627 } |
556 default: | 628 default: |
557 break; | 629 break; |
558 } | 630 } |
559 std::ostringstream str; | 631 std::ostringstream str; |
560 str << "TypeError: node #" << node->id() << ":" << *node->op() | 632 str << "TypeError: node #" << node->id() << ":" << *node->op() |
561 << " uses node #" << input->id() << ":" << *input->op() | 633 << " uses node #" << input->id() << ":" << *input->op() |
562 << " which doesn't have an int32-compatible representation."; | 634 << " which doesn't have an int32-compatible representation."; |
563 FATAL(str.str().c_str()); | 635 FATAL(str.str().c_str()); |
564 } | 636 } |
565 | 637 |
566 void CheckValueInputForInt64Op(Node const* node, int index) { | 638 void CheckValueInputForInt64Op(Node const* node, int index, |
| 639 bool allow_tagged = false) { |
567 Node const* input = node->InputAt(index); | 640 Node const* input = node->InputAt(index); |
568 MachineRepresentation input_representation = | 641 MachineRepresentation input_representation = |
569 inferrer_->GetRepresentation(input); | 642 inferrer_->GetRepresentation(input); |
570 switch (input_representation) { | 643 switch (input_representation) { |
571 case MachineRepresentation::kWord64: | 644 case MachineRepresentation::kWord64: |
572 return; | 645 return; |
| 646 case MachineRepresentation::kTagged: |
| 647 case MachineRepresentation::kTaggedSigned: |
| 648 case MachineRepresentation::kTaggedPointer: |
| 649 if (Is64() && allow_tagged) { |
| 650 return; |
| 651 } |
| 652 break; |
573 case MachineRepresentation::kNone: { | 653 case MachineRepresentation::kNone: { |
574 std::ostringstream str; | 654 std::ostringstream str; |
575 str << "TypeError: node #" << input->id() << ":" << *input->op() | 655 str << "TypeError: node #" << input->id() << ":" << *input->op() |
576 << " is untyped."; | 656 << " is untyped."; |
577 FATAL(str.str().c_str()); | 657 FATAL(str.str().c_str()); |
578 break; | 658 break; |
579 } | 659 } |
580 | 660 |
581 default: | 661 default: |
582 break; | 662 break; |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
713 MachineRepresentationInferrer representation_inferrer(schedule, graph, | 793 MachineRepresentationInferrer representation_inferrer(schedule, graph, |
714 linkage, temp_zone); | 794 linkage, temp_zone); |
715 MachineRepresentationChecker checker(schedule, &representation_inferrer, | 795 MachineRepresentationChecker checker(schedule, &representation_inferrer, |
716 is_stub); | 796 is_stub); |
717 checker.Run(); | 797 checker.Run(); |
718 } | 798 } |
719 | 799 |
720 } // namespace compiler | 800 } // namespace compiler |
721 } // namespace internal | 801 } // namespace internal |
722 } // namespace v8 | 802 } // namespace v8 |
OLD | NEW |