| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/il_printer.h" | 5 #include "vm/il_printer.h" |
| 6 | 6 |
| 7 #include "vm/intermediate_language.h" | 7 #include "vm/intermediate_language.h" |
| 8 #include "vm/os.h" | 8 #include "vm/os.h" |
| 9 #include "vm/parser.h" | 9 #include "vm/parser.h" |
| 10 | 10 |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 162 | 162 |
| 163 | 163 |
| 164 void Instruction::PrintOperandsTo(BufferFormatter* f) const { | 164 void Instruction::PrintOperandsTo(BufferFormatter* f) const { |
| 165 for (int i = 0; i < InputCount(); ++i) { | 165 for (int i = 0; i < InputCount(); ++i) { |
| 166 if (i > 0) f->Print(", "); | 166 if (i > 0) f->Print(", "); |
| 167 if (InputAt(i) != NULL) InputAt(i)->PrintTo(f); | 167 if (InputAt(i) != NULL) InputAt(i)->PrintTo(f); |
| 168 } | 168 } |
| 169 } | 169 } |
| 170 | 170 |
| 171 | 171 |
| 172 void Instruction::PrintToVisualizer(BufferFormatter* f) const { | |
| 173 PrintTo(f); | |
| 174 } | |
| 175 | |
| 176 | |
| 177 void Definition::PrintTo(BufferFormatter* f) const { | 172 void Definition::PrintTo(BufferFormatter* f) const { |
| 178 PrintUse(f, *this); | 173 PrintUse(f, *this); |
| 179 if (is_used()) { | 174 if (is_used()) { |
| 180 if (HasSSATemp() || (temp_index() != -1)) f->Print(" <- "); | 175 if (HasSSATemp() || (temp_index() != -1)) f->Print(" <- "); |
| 181 } | 176 } |
| 182 f->Print("%s:%"Pd"(", DebugName(), GetDeoptId()); | 177 f->Print("%s:%"Pd"(", DebugName(), GetDeoptId()); |
| 183 PrintOperandsTo(f); | 178 PrintOperandsTo(f); |
| 184 f->Print(")"); | 179 f->Print(")"); |
| 185 PrintPropagatedType(f, *this); | 180 PrintPropagatedType(f, *this); |
| 186 if (range_ != NULL) { | 181 if (range_ != NULL) { |
| 187 f->Print(" "); | 182 f->Print(" "); |
| 188 range_->PrintTo(f); | 183 range_->PrintTo(f); |
| 189 } | 184 } |
| 190 } | 185 } |
| 191 | 186 |
| 192 | 187 |
| 193 void Definition::PrintOperandsTo(BufferFormatter* f) const { | 188 void Definition::PrintOperandsTo(BufferFormatter* f) const { |
| 194 for (int i = 0; i < InputCount(); ++i) { | 189 for (int i = 0; i < InputCount(); ++i) { |
| 195 if (i > 0) f->Print(", "); | 190 if (i > 0) f->Print(", "); |
| 196 if (InputAt(i) != NULL) InputAt(i)->PrintTo(f); | 191 if (InputAt(i) != NULL) InputAt(i)->PrintTo(f); |
| 197 } | 192 } |
| 198 } | 193 } |
| 199 | 194 |
| 200 | 195 |
| 201 void Definition::PrintToVisualizer(BufferFormatter* f) const { | |
| 202 PrintTo(f); | |
| 203 } | |
| 204 | |
| 205 | |
| 206 void Value::PrintTo(BufferFormatter* f) const { | 196 void Value::PrintTo(BufferFormatter* f) const { |
| 207 PrintUse(f, *definition()); | 197 PrintUse(f, *definition()); |
| 208 } | 198 } |
| 209 | 199 |
| 210 | 200 |
| 211 void ConstantInstr::PrintOperandsTo(BufferFormatter* f) const { | 201 void ConstantInstr::PrintOperandsTo(BufferFormatter* f) const { |
| 212 f->Print("#%s", value().ToCString()); | 202 f->Print("#%s", value().ToCString()); |
| 213 } | 203 } |
| 214 | 204 |
| 215 | 205 |
| (...skipping 426 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 642 f->Print("%s ", DebugName()); | 632 f->Print("%s ", DebugName()); |
| 643 for (intptr_t i = 0; i < moves_.length(); i++) { | 633 for (intptr_t i = 0; i < moves_.length(); i++) { |
| 644 if (i != 0) f->Print(", "); | 634 if (i != 0) f->Print(", "); |
| 645 moves_[i]->dest().PrintTo(f); | 635 moves_[i]->dest().PrintTo(f); |
| 646 f->Print(" <- "); | 636 f->Print(" <- "); |
| 647 moves_[i]->src().PrintTo(f); | 637 moves_[i]->src().PrintTo(f); |
| 648 } | 638 } |
| 649 } | 639 } |
| 650 | 640 |
| 651 | 641 |
| 652 void FlowGraphVisualizer::Print(const char* format, ...) { | |
| 653 char str[1000]; | |
| 654 BufferFormatter f(str, sizeof(str)); | |
| 655 f.Print("%*s", static_cast<int>(2 * indent_), ""); | |
| 656 va_list args; | |
| 657 va_start(args, format); | |
| 658 f.VPrint(format, args); | |
| 659 va_end(args); | |
| 660 (*Dart::flow_graph_writer())(str, strlen(str)); | |
| 661 } | |
| 662 | |
| 663 | |
| 664 void FlowGraphVisualizer::PrintInstruction(Instruction* instr) { | |
| 665 char str[1000]; | |
| 666 BufferFormatter f(str, sizeof(str)); | |
| 667 instr->PrintToVisualizer(&f); | |
| 668 if (FLAG_print_environments && (instr->env() != NULL)) { | |
| 669 instr->env()->PrintTo(&f); | |
| 670 } | |
| 671 f.Print(" <|@\n"); | |
| 672 (*Dart::flow_graph_writer())(str, strlen(str)); | |
| 673 } | |
| 674 | |
| 675 | |
| 676 void FlowGraphVisualizer::PrintFunction() { | |
| 677 #define BEGIN(name) \ | |
| 678 Print("begin_%s\n", name); \ | |
| 679 indent_++; | |
| 680 #define END(name) \ | |
| 681 Print("end_%s\n", name); \ | |
| 682 indent_--; | |
| 683 | |
| 684 { | |
| 685 BEGIN("compilation"); | |
| 686 const char* name = function_.ToFullyQualifiedCString(); | |
| 687 Print("%s \"%s\"\n", "name", name); | |
| 688 Print("%s \"%s\"\n", "method", name); | |
| 689 Print("%s %d\n", "date", 0); // Required field. Unused. | |
| 690 END("compilation"); | |
| 691 } | |
| 692 | |
| 693 { | |
| 694 BEGIN("cfg"); | |
| 695 Print("%s \"%s\"\n", "name", "Flow graph builder"); | |
| 696 | |
| 697 for (intptr_t i = 0; i < block_order_.length(); ++i) { | |
| 698 BEGIN("block"); | |
| 699 BlockEntryInstr* entry = block_order_[i]; | |
| 700 Print("%s \"B%"Pd"\"\n", "name", entry->block_id()); | |
| 701 Print("%s %d\n", "from_bci", -1); // Required field. Unused. | |
| 702 Print("%s %d\n", "to_bci", -1); // Required field. Unused. | |
| 703 | |
| 704 Print("predecessors"); | |
| 705 for (intptr_t j = 0; j < entry->PredecessorCount(); ++j) { | |
| 706 BlockEntryInstr* pred = entry->PredecessorAt(j); | |
| 707 Print(" \"B%"Pd"\"", pred->block_id()); | |
| 708 } | |
| 709 Print("\n"); | |
| 710 | |
| 711 Print("successors"); | |
| 712 Instruction* last = entry->last_instruction(); | |
| 713 for (intptr_t j = 0; j < last->SuccessorCount(); ++j) { | |
| 714 intptr_t next_id = last->SuccessorAt(j)->block_id(); | |
| 715 Print(" \"B%"Pd"\"", next_id); | |
| 716 } | |
| 717 Print("\n"); | |
| 718 | |
| 719 // TODO(fschneider): Use this for exception handlers. | |
| 720 Print("xhandlers\n"); | |
| 721 | |
| 722 // Can be freely used to mark blocks | |
| 723 Print("flags\n"); | |
| 724 | |
| 725 if (entry->dominator() != NULL) { | |
| 726 Print("%s \"B%"Pd"\"\n", "dominator", entry->dominator()->block_id()); | |
| 727 } | |
| 728 | |
| 729 // TODO(fschneider): Mark blocks with loop nesting level. | |
| 730 Print("%s %d\n", "loop_depth", 0); | |
| 731 | |
| 732 { | |
| 733 BEGIN("states"); // Required section. | |
| 734 { | |
| 735 BEGIN("locals"); // Required section. | |
| 736 JoinEntryInstr* join = entry->AsJoinEntry(); | |
| 737 intptr_t num_phis = (join != NULL && join->phi_count()) | |
| 738 ? join->phis()->length() | |
| 739 : 0; | |
| 740 Print("%s %"Pd"\n", "size", num_phis); | |
| 741 for (intptr_t j = 0; j < num_phis; ++j) { | |
| 742 PhiInstr* phi = (*join->phis())[j]; | |
| 743 if (phi != NULL) { | |
| 744 Print("%"Pd" ", j); // Print variable index. | |
| 745 char buffer[120]; | |
| 746 BufferFormatter formatter(buffer, sizeof(buffer)); | |
| 747 phi->PrintToVisualizer(&formatter); | |
| 748 Print("%s\n", buffer); | |
| 749 } | |
| 750 } | |
| 751 END("locals"); | |
| 752 } | |
| 753 END("states"); | |
| 754 } | |
| 755 | |
| 756 { | |
| 757 BEGIN("HIR"); | |
| 758 // Print the block entry. | |
| 759 Print("0 0 "); // Required fields "bci" and "use". Unused. | |
| 760 PrintInstruction(block_order_[i]); | |
| 761 // And all the successors until an exit, branch, or a block entry. | |
| 762 BlockEntryInstr* entry = block_order_[i]; | |
| 763 Instruction* current = entry; | |
| 764 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { | |
| 765 current = it.Current(); | |
| 766 Print("0 0 "); | |
| 767 PrintInstruction(current); | |
| 768 } | |
| 769 if (current->next() != NULL) { | |
| 770 ASSERT(current->next()->IsBlockEntry()); | |
| 771 Print("0 0 _ Goto B%"Pd" <|@\n", | |
| 772 current->next()->AsBlockEntry()->block_id()); | |
| 773 } | |
| 774 END("HIR"); | |
| 775 } | |
| 776 END("block"); | |
| 777 } | |
| 778 END("cfg"); | |
| 779 } | |
| 780 #undef BEGIN | |
| 781 #undef END | |
| 782 } | |
| 783 | |
| 784 | |
| 785 // === Printing instructions in a visualizer-understandable format: | |
| 786 // "result instruction(op1, op2)" where result is a temporary name | |
| 787 // or _ for instruction without result. | |
| 788 void GraphEntryInstr::PrintToVisualizer(BufferFormatter* f) const { | |
| 789 const GrowableArray<Definition*>& defns = initial_definitions_; | |
| 790 f->Print("_ [graph]"); | |
| 791 if (defns.length() > 0) { | |
| 792 f->Print(" init={ "); | |
| 793 for (intptr_t i = 0; i < defns.length(); ++i) { | |
| 794 if (i > 0) f->Print(", "); | |
| 795 defns[i]->PrintTo(f); | |
| 796 } | |
| 797 f->Print(" }"); | |
| 798 } | |
| 799 } | |
| 800 | |
| 801 | |
| 802 void JoinEntryInstr::PrintToVisualizer(BufferFormatter* f) const { | |
| 803 f->Print("_ [join]"); | |
| 804 } | |
| 805 | |
| 806 | |
| 807 void PhiInstr::PrintToVisualizer(BufferFormatter* f) const { | |
| 808 f->Print("v%"Pd" [", ssa_temp_index()); | |
| 809 for (intptr_t i = 0; i < InputCount(); ++i) { | |
| 810 if (i > 0) f->Print(" "); | |
| 811 InputAt(i)->PrintTo(f); | |
| 812 } | |
| 813 f->Print("]"); | |
| 814 } | |
| 815 | |
| 816 | |
| 817 void ParameterInstr::PrintToVisualizer(BufferFormatter* f) const { | |
| 818 ASSERT(HasSSATemp()); | |
| 819 ASSERT(temp_index() == -1); | |
| 820 f->Print("v%"Pd" Parameter(%"Pd")", ssa_temp_index(), index()); | |
| 821 } | |
| 822 | |
| 823 | |
| 824 void TargetEntryInstr::PrintToVisualizer(BufferFormatter* f) const { | |
| 825 f->Print("_ [target"); | |
| 826 if (IsCatchEntry()) { | |
| 827 f->Print(" catch %"Pd"]", catch_try_index()); | |
| 828 } else { | |
| 829 f->Print("]"); | |
| 830 } | |
| 831 } | |
| 832 | |
| 833 | |
| 834 void PushArgumentInstr::PrintToVisualizer(BufferFormatter* f) const { | |
| 835 f->Print("_ %s ", DebugName()); | |
| 836 value()->PrintTo(f); | |
| 837 } | |
| 838 | |
| 839 | |
| 840 void GotoInstr::PrintToVisualizer(BufferFormatter* f) const { | |
| 841 f->Print("_ goto B%"Pd"", successor()->block_id()); | |
| 842 } | |
| 843 | |
| 844 | |
| 845 void BranchInstr::PrintToVisualizer(BufferFormatter* f) const { | |
| 846 f->Print("_ %s ", DebugName()); | |
| 847 f->Print("if "); | |
| 848 comparison()->PrintTo(f); | |
| 849 f->Print(" goto (B%"Pd", B%"Pd")", | |
| 850 true_successor()->block_id(), | |
| 851 false_successor()->block_id()); | |
| 852 } | |
| 853 | |
| 854 | |
| 855 void ParallelMoveInstr::PrintToVisualizer(BufferFormatter* f) const { | |
| 856 UNIMPLEMENTED(); | |
| 857 } | |
| 858 | |
| 859 | |
| 860 void Environment::PrintTo(BufferFormatter* f) const { | 642 void Environment::PrintTo(BufferFormatter* f) const { |
| 861 f->Print(" env={ "); | 643 f->Print(" env={ "); |
| 862 int arg_count = 0; | 644 int arg_count = 0; |
| 863 for (intptr_t i = 0; i < values_.length(); ++i) { | 645 for (intptr_t i = 0; i < values_.length(); ++i) { |
| 864 if (i > 0) f->Print(", "); | 646 if (i > 0) f->Print(", "); |
| 865 if (values_[i]->definition()->IsPushArgument()) { | 647 if (values_[i]->definition()->IsPushArgument()) { |
| 866 f->Print("a%d", arg_count++); | 648 f->Print("a%d", arg_count++); |
| 867 } else { | 649 } else { |
| 868 values_[i]->PrintTo(f); | 650 values_[i]->PrintTo(f); |
| 869 } | 651 } |
| 870 if ((locations_ != NULL) && !locations_[i].IsInvalid()) { | 652 if ((locations_ != NULL) && !locations_[i].IsInvalid()) { |
| 871 f->Print(" ["); | 653 f->Print(" ["); |
| 872 locations_[i].PrintTo(f); | 654 locations_[i].PrintTo(f); |
| 873 f->Print("]"); | 655 f->Print("]"); |
| 874 } | 656 } |
| 875 } | 657 } |
| 876 f->Print(" }"); | 658 f->Print(" }"); |
| 877 if (outer_ != NULL) outer_->PrintTo(f); | 659 if (outer_ != NULL) outer_->PrintTo(f); |
| 878 } | 660 } |
| 879 | 661 |
| 880 } // namespace dart | 662 } // namespace dart |
| OLD | NEW |