Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(103)

Side by Side Diff: src/compiler/machine-graph-verifier.cc

Issue 2574353002: [turbofan] Added --csa-trap-on-node option that helps debugging graph verification issues. (Closed)
Patch Set: Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/machine-graph-verifier.h ('k') | src/compiler/pipeline.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 268
269 Schedule const* const schedule_; 269 Schedule const* const schedule_;
270 Linkage const* const linkage_; 270 Linkage const* const linkage_;
271 ZoneVector<MachineRepresentation> representation_vector_; 271 ZoneVector<MachineRepresentation> representation_vector_;
272 }; 272 };
273 273
274 class MachineRepresentationChecker { 274 class MachineRepresentationChecker {
275 public: 275 public:
276 MachineRepresentationChecker( 276 MachineRepresentationChecker(
277 Schedule const* const schedule, 277 Schedule const* const schedule,
278 MachineRepresentationInferrer const* const inferrer, bool is_stub) 278 MachineRepresentationInferrer const* const inferrer, bool is_stub,
279 : schedule_(schedule), inferrer_(inferrer), is_stub_(is_stub) {} 279 const char* name)
280 : schedule_(schedule),
281 inferrer_(inferrer),
282 is_stub_(is_stub),
283 name_(name) {}
280 284
281 void Run() { 285 void Run() {
282 BasicBlockVector const* blocks = schedule_->all_blocks(); 286 BasicBlockVector const* blocks = schedule_->all_blocks();
283 for (BasicBlock* block : *blocks) { 287 for (BasicBlock* block : *blocks) {
284 for (size_t i = 0; i <= block->NodeCount(); ++i) { 288 for (size_t i = 0; i <= block->NodeCount(); ++i) {
285 Node const* node = 289 Node const* node =
286 i < block->NodeCount() ? block->NodeAt(i) : block->control_input(); 290 i < block->NodeCount() ? block->NodeAt(i) : block->control_input();
287 if (node == nullptr) { 291 if (node == nullptr) {
288 DCHECK_EQ(block->NodeCount(), i); 292 DCHECK_EQ(block->NodeCount(), i);
289 break; 293 break;
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after
513 break; 517 break;
514 } 518 }
515 case IrOpcode::kTypedStateValues: 519 case IrOpcode::kTypedStateValues:
516 case IrOpcode::kFrameState: 520 case IrOpcode::kFrameState:
517 break; 521 break;
518 default: 522 default:
519 if (node->op()->ValueInputCount() != 0) { 523 if (node->op()->ValueInputCount() != 0) {
520 std::stringstream str; 524 std::stringstream str;
521 str << "Node #" << node->id() << ":" << *node->op() 525 str << "Node #" << node->id() << ":" << *node->op()
522 << " in the machine graph is not being checked."; 526 << " in the machine graph is not being checked.";
527 PrintDebugHelp(str, node);
523 FATAL(str.str().c_str()); 528 FATAL(str.str().c_str());
524 } 529 }
525 break; 530 break;
526 } 531 }
527 } 532 }
528 } 533 }
529 } 534 }
530 535
531 private: 536 private:
532 static bool Is32() { 537 static bool Is32() {
533 return MachineType::PointerRepresentation() == 538 return MachineType::PointerRepresentation() ==
534 MachineRepresentation::kWord32; 539 MachineRepresentation::kWord32;
535 } 540 }
536 static bool Is64() { 541 static bool Is64() {
537 return MachineType::PointerRepresentation() == 542 return MachineType::PointerRepresentation() ==
538 MachineRepresentation::kWord64; 543 MachineRepresentation::kWord64;
539 } 544 }
540 545
541 void CheckValueInputRepresentationIs(Node const* node, int index, 546 void CheckValueInputRepresentationIs(Node const* node, int index,
542 MachineRepresentation representation) { 547 MachineRepresentation representation) {
543 Node const* input = node->InputAt(index); 548 Node const* input = node->InputAt(index);
544 MachineRepresentation input_representation = 549 MachineRepresentation input_representation =
545 inferrer_->GetRepresentation(input); 550 inferrer_->GetRepresentation(input);
546 if (input_representation != representation) { 551 if (input_representation != representation) {
547 std::stringstream str; 552 std::stringstream str;
548 str << "TypeError: node #" << node->id() << ":" << *node->op() 553 str << "TypeError: node #" << node->id() << ":" << *node->op()
549 << " uses node #" << input->id() << ":" << *input->op() << ":" 554 << " uses node #" << input->id() << ":" << *input->op() << ":"
550 << input_representation << " which doesn't have a " << representation 555 << input_representation << " which doesn't have a " << representation
551 << " representation."; 556 << " representation.";
557 PrintDebugHelp(str, node);
552 FATAL(str.str().c_str()); 558 FATAL(str.str().c_str());
553 } 559 }
554 } 560 }
555 561
556 void CheckValueInputIsTagged(Node const* node, int index) { 562 void CheckValueInputIsTagged(Node const* node, int index) {
557 Node const* input = node->InputAt(index); 563 Node const* input = node->InputAt(index);
558 switch (inferrer_->GetRepresentation(input)) { 564 switch (inferrer_->GetRepresentation(input)) {
559 case MachineRepresentation::kTagged: 565 case MachineRepresentation::kTagged:
560 case MachineRepresentation::kTaggedPointer: 566 case MachineRepresentation::kTaggedPointer:
561 case MachineRepresentation::kTaggedSigned: 567 case MachineRepresentation::kTaggedSigned:
562 return; 568 return;
563 default: 569 default:
564 break; 570 break;
565 } 571 }
566 std::ostringstream str; 572 std::ostringstream str;
567 str << "TypeError: node #" << node->id() << ":" << *node->op() 573 str << "TypeError: node #" << node->id() << ":" << *node->op()
568 << " uses node #" << input->id() << ":" << *input->op() 574 << " uses node #" << input->id() << ":" << *input->op()
569 << " which doesn't have a tagged representation."; 575 << " which doesn't have a tagged representation.";
576 PrintDebugHelp(str, node);
570 FATAL(str.str().c_str()); 577 FATAL(str.str().c_str());
571 } 578 }
572 579
573 void CheckValueInputIsTaggedOrPointer(Node const* node, int index) { 580 void CheckValueInputIsTaggedOrPointer(Node const* node, int index) {
574 Node const* input = node->InputAt(index); 581 Node const* input = node->InputAt(index);
575 switch (inferrer_->GetRepresentation(input)) { 582 switch (inferrer_->GetRepresentation(input)) {
576 case MachineRepresentation::kTagged: 583 case MachineRepresentation::kTagged:
577 case MachineRepresentation::kTaggedPointer: 584 case MachineRepresentation::kTaggedPointer:
578 case MachineRepresentation::kTaggedSigned: 585 case MachineRepresentation::kTaggedSigned:
579 return; 586 return;
(...skipping 12 matching lines...) Expand all
592 break; 599 break;
593 default: 600 default:
594 break; 601 break;
595 } 602 }
596 if (inferrer_->GetRepresentation(input) != 603 if (inferrer_->GetRepresentation(input) !=
597 MachineType::PointerRepresentation()) { 604 MachineType::PointerRepresentation()) {
598 std::ostringstream str; 605 std::ostringstream str;
599 str << "TypeError: node #" << node->id() << ":" << *node->op() 606 str << "TypeError: node #" << node->id() << ":" << *node->op()
600 << " uses node #" << input->id() << ":" << *input->op() 607 << " uses node #" << input->id() << ":" << *input->op()
601 << " which doesn't have a tagged or pointer representation."; 608 << " which doesn't have a tagged or pointer representation.";
609 PrintDebugHelp(str, node);
602 FATAL(str.str().c_str()); 610 FATAL(str.str().c_str());
603 } 611 }
604 } 612 }
605 613
606 void CheckValueInputForInt32Op(Node const* node, int index) { 614 void CheckValueInputForInt32Op(Node const* node, int index) {
607 Node const* input = node->InputAt(index); 615 Node const* input = node->InputAt(index);
608 switch (inferrer_->GetRepresentation(input)) { 616 switch (inferrer_->GetRepresentation(input)) {
609 case MachineRepresentation::kBit: 617 case MachineRepresentation::kBit:
610 case MachineRepresentation::kWord8: 618 case MachineRepresentation::kWord8:
611 case MachineRepresentation::kWord16: 619 case MachineRepresentation::kWord16:
612 case MachineRepresentation::kWord32: 620 case MachineRepresentation::kWord32:
613 return; 621 return;
614 case MachineRepresentation::kNone: { 622 case MachineRepresentation::kNone: {
615 std::ostringstream str; 623 std::ostringstream str;
616 str << "TypeError: node #" << input->id() << ":" << *input->op() 624 str << "TypeError: node #" << input->id() << ":" << *input->op()
617 << " is untyped."; 625 << " is untyped.";
626 PrintDebugHelp(str, node);
618 FATAL(str.str().c_str()); 627 FATAL(str.str().c_str());
619 break; 628 break;
620 } 629 }
621 default: 630 default:
622 break; 631 break;
623 } 632 }
624 std::ostringstream str; 633 std::ostringstream str;
625 str << "TypeError: node #" << node->id() << ":" << *node->op() 634 str << "TypeError: node #" << node->id() << ":" << *node->op()
626 << " uses node #" << input->id() << ":" << *input->op() 635 << " uses node #" << input->id() << ":" << *input->op()
627 << " which doesn't have an int32-compatible representation."; 636 << " which doesn't have an int32-compatible representation.";
637 PrintDebugHelp(str, node);
628 FATAL(str.str().c_str()); 638 FATAL(str.str().c_str());
629 } 639 }
630 640
631 void CheckValueInputForInt64Op(Node const* node, int index) { 641 void CheckValueInputForInt64Op(Node const* node, int index) {
632 Node const* input = node->InputAt(index); 642 Node const* input = node->InputAt(index);
633 MachineRepresentation input_representation = 643 MachineRepresentation input_representation =
634 inferrer_->GetRepresentation(input); 644 inferrer_->GetRepresentation(input);
635 switch (input_representation) { 645 switch (input_representation) {
636 case MachineRepresentation::kWord64: 646 case MachineRepresentation::kWord64:
637 return; 647 return;
638 case MachineRepresentation::kNone: { 648 case MachineRepresentation::kNone: {
639 std::ostringstream str; 649 std::ostringstream str;
640 str << "TypeError: node #" << input->id() << ":" << *input->op() 650 str << "TypeError: node #" << input->id() << ":" << *input->op()
641 << " is untyped."; 651 << " is untyped.";
652 PrintDebugHelp(str, node);
642 FATAL(str.str().c_str()); 653 FATAL(str.str().c_str());
643 break; 654 break;
644 } 655 }
645 656
646 default: 657 default:
647 break; 658 break;
648 } 659 }
649 std::ostringstream str; 660 std::ostringstream str;
650 str << "TypeError: node #" << node->id() << ":" << *node->op() 661 str << "TypeError: node #" << node->id() << ":" << *node->op()
651 << " uses node #" << input->id() << ":" << *input->op() << ":" 662 << " uses node #" << input->id() << ":" << *input->op() << ":"
652 << input_representation 663 << input_representation
653 << " which doesn't have a kWord64 representation."; 664 << " which doesn't have a kWord64 representation.";
665 PrintDebugHelp(str, node);
654 FATAL(str.str().c_str()); 666 FATAL(str.str().c_str());
655 } 667 }
656 668
657 void CheckValueInputForFloat32Op(Node const* node, int index) { 669 void CheckValueInputForFloat32Op(Node const* node, int index) {
658 Node const* input = node->InputAt(index); 670 Node const* input = node->InputAt(index);
659 if (MachineRepresentation::kFloat32 == 671 if (MachineRepresentation::kFloat32 ==
660 inferrer_->GetRepresentation(input)) { 672 inferrer_->GetRepresentation(input)) {
661 return; 673 return;
662 } 674 }
663 std::ostringstream str; 675 std::ostringstream str;
664 str << "TypeError: node #" << node->id() << ":" << *node->op() 676 str << "TypeError: node #" << node->id() << ":" << *node->op()
665 << " uses node #" << input->id() << ":" << *input->op() 677 << " uses node #" << input->id() << ":" << *input->op()
666 << " which doesn't have a kFloat32 representation."; 678 << " which doesn't have a kFloat32 representation.";
679 PrintDebugHelp(str, node);
667 FATAL(str.str().c_str()); 680 FATAL(str.str().c_str());
668 } 681 }
669 682
670 void CheckValueInputForFloat64Op(Node const* node, int index) { 683 void CheckValueInputForFloat64Op(Node const* node, int index) {
671 Node const* input = node->InputAt(index); 684 Node const* input = node->InputAt(index);
672 if (MachineRepresentation::kFloat64 == 685 if (MachineRepresentation::kFloat64 ==
673 inferrer_->GetRepresentation(input)) { 686 inferrer_->GetRepresentation(input)) {
674 return; 687 return;
675 } 688 }
676 std::ostringstream str; 689 std::ostringstream str;
677 str << "TypeError: node #" << node->id() << ":" << *node->op() 690 str << "TypeError: node #" << node->id() << ":" << *node->op()
678 << " uses node #" << input->id() << ":" << *input->op() 691 << " uses node #" << input->id() << ":" << *input->op()
679 << " which doesn't have a kFloat64 representation."; 692 << " which doesn't have a kFloat64 representation.";
693 PrintDebugHelp(str, node);
680 FATAL(str.str().c_str()); 694 FATAL(str.str().c_str());
681 } 695 }
682 696
683 void CheckCallInputs(Node const* node) { 697 void CheckCallInputs(Node const* node) {
684 CallDescriptor const* desc = CallDescriptorOf(node->op()); 698 CallDescriptor const* desc = CallDescriptorOf(node->op());
685 std::ostringstream str; 699 std::ostringstream str;
686 bool should_log_error = false; 700 bool should_log_error = false;
687 for (size_t i = 0; i < desc->InputCount(); ++i) { 701 for (size_t i = 0; i < desc->InputCount(); ++i) {
688 Node const* input = node->InputAt(static_cast<int>(i)); 702 Node const* input = node->InputAt(static_cast<int>(i));
689 MachineRepresentation const input_type = 703 MachineRepresentation const input_type =
690 inferrer_->GetRepresentation(input); 704 inferrer_->GetRepresentation(input);
691 MachineRepresentation const expected_input_type = 705 MachineRepresentation const expected_input_type =
692 desc->GetInputType(i).representation(); 706 desc->GetInputType(i).representation();
693 if (!IsCompatible(expected_input_type, input_type)) { 707 if (!IsCompatible(expected_input_type, input_type)) {
694 if (!should_log_error) { 708 if (!should_log_error) {
695 should_log_error = true; 709 should_log_error = true;
696 str << "TypeError: node #" << node->id() << ":" << *node->op() 710 str << "TypeError: node #" << node->id() << ":" << *node->op()
697 << " has wrong type for:" << std::endl; 711 << " has wrong type for:" << std::endl;
698 } else { 712 } else {
699 str << std::endl; 713 str << std::endl;
700 } 714 }
701 str << " * input " << i << " (" << input->id() << ":" << *input->op() 715 str << " * input " << i << " (" << input->id() << ":" << *input->op()
702 << ") doesn't have a " << expected_input_type << " representation."; 716 << ") doesn't have a " << expected_input_type << " representation.";
703 } 717 }
704 } 718 }
705 if (should_log_error) { 719 if (should_log_error) {
720 PrintDebugHelp(str, node);
706 FATAL(str.str().c_str()); 721 FATAL(str.str().c_str());
707 } 722 }
708 } 723 }
709 724
710 bool Intersect(MachineRepresentation lhs, MachineRepresentation rhs) { 725 bool Intersect(MachineRepresentation lhs, MachineRepresentation rhs) {
711 return (GetRepresentationProperties(lhs) & 726 return (GetRepresentationProperties(lhs) &
712 GetRepresentationProperties(rhs)) != 0; 727 GetRepresentationProperties(rhs)) != 0;
713 } 728 }
714 729
715 enum RepresentationProperties { kIsPointer = 1, kIsTagged = 2 }; 730 enum RepresentationProperties { kIsPointer = 1, kIsTagged = 2 };
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
758 return (actual == MachineRepresentation::kBit || 773 return (actual == MachineRepresentation::kBit ||
759 actual == MachineRepresentation::kWord8 || 774 actual == MachineRepresentation::kWord8 ||
760 actual == MachineRepresentation::kWord16 || 775 actual == MachineRepresentation::kWord16 ||
761 actual == MachineRepresentation::kWord32); 776 actual == MachineRepresentation::kWord32);
762 case MachineRepresentation::kNone: 777 case MachineRepresentation::kNone:
763 UNREACHABLE(); 778 UNREACHABLE();
764 } 779 }
765 return false; 780 return false;
766 } 781 }
767 782
783 void PrintDebugHelp(std::ostream& out, Node const* node) {
784 if (DEBUG_BOOL) {
785 out << "\n#\n# Specify option --csa-trap-on-node=" << name_ << ","
786 << node->id() << " for debugging.";
787 }
788 }
789
768 Schedule const* const schedule_; 790 Schedule const* const schedule_;
769 MachineRepresentationInferrer const* const inferrer_; 791 MachineRepresentationInferrer const* const inferrer_;
770 bool is_stub_; 792 bool is_stub_;
793 const char* name_;
771 }; 794 };
772 795
773 } // namespace 796 } // namespace
774 797
775 void MachineGraphVerifier::Run(Graph* graph, Schedule const* const schedule, 798 void MachineGraphVerifier::Run(Graph* graph, Schedule const* const schedule,
776 Linkage* linkage, bool is_stub, 799 Linkage* linkage, bool is_stub, const char* name,
777 Zone* temp_zone) { 800 Zone* temp_zone) {
778 MachineRepresentationInferrer representation_inferrer(schedule, graph, 801 MachineRepresentationInferrer representation_inferrer(schedule, graph,
779 linkage, temp_zone); 802 linkage, temp_zone);
780 MachineRepresentationChecker checker(schedule, &representation_inferrer, 803 MachineRepresentationChecker checker(schedule, &representation_inferrer,
781 is_stub); 804 is_stub, name);
782 checker.Run(); 805 checker.Run();
783 } 806 }
784 807
785 } // namespace compiler 808 } // namespace compiler
786 } // namespace internal 809 } // namespace internal
787 } // namespace v8 810 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/machine-graph-verifier.h ('k') | src/compiler/pipeline.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698