OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/common-operator.h" | 5 #include "src/compiler/common-operator.h" |
6 #include "src/compiler/graph.h" | 6 #include "src/compiler/graph.h" |
7 #include "src/compiler/instruction.h" | 7 #include "src/compiler/instruction.h" |
8 #include "src/compiler/schedule.h" | 8 #include "src/compiler/schedule.h" |
9 #include "src/compiler/state-values-utils.h" | 9 #include "src/compiler/state-values-utils.h" |
10 | 10 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
61 return condition; | 61 return condition; |
62 } | 62 } |
63 UNREACHABLE(); | 63 UNREACHABLE(); |
64 return condition; | 64 return condition; |
65 } | 65 } |
66 | 66 |
67 bool InstructionOperand::InterferesWith(const InstructionOperand& that) const { | 67 bool InstructionOperand::InterferesWith(const InstructionOperand& that) const { |
68 return EqualsCanonicalized(that); | 68 return EqualsCanonicalized(that); |
69 } | 69 } |
70 | 70 |
71 void InstructionOperand::Print(std::ostream& os, | 71 void InstructionOperand::Print(const RegisterConfiguration* config) const { |
72 const RegisterConfiguration* config) const { | 72 OFStream os(stdout); |
73 PrintableInstructionOperand wrapper; | 73 PrintableInstructionOperand wrapper; |
74 wrapper.register_configuration_ = config; | 74 wrapper.register_configuration_ = config; |
75 wrapper.op_ = *this; | 75 wrapper.op_ = *this; |
76 os << wrapper << std::endl; | 76 os << wrapper << std::endl; |
77 } | 77 } |
78 | 78 |
79 void InstructionOperand::Print(std::ostream& os) const { | 79 void InstructionOperand::Print() const { Print(GetRegConfig()); } |
80 Print(os, GetRegConfig()); | |
81 } | |
82 | 80 |
83 std::ostream& operator<<(std::ostream& os, | 81 std::ostream& operator<<(std::ostream& os, |
84 const PrintableInstructionOperand& printable) { | 82 const PrintableInstructionOperand& printable) { |
85 const InstructionOperand& op = printable.op_; | 83 const InstructionOperand& op = printable.op_; |
86 const RegisterConfiguration* conf = printable.register_configuration_; | 84 const RegisterConfiguration* conf = printable.register_configuration_; |
87 switch (op.kind()) { | 85 switch (op.kind()) { |
88 case InstructionOperand::UNALLOCATED: { | 86 case InstructionOperand::UNALLOCATED: { |
89 const UnallocatedOperand* unalloc = UnallocatedOperand::cast(&op); | 87 const UnallocatedOperand* unalloc = UnallocatedOperand::cast(&op); |
90 os << "v" << unalloc->virtual_register(); | 88 os << "v" << unalloc->virtual_register(); |
91 if (unalloc->basic_policy() == UnallocatedOperand::FIXED_SLOT) { | 89 if (unalloc->basic_policy() == UnallocatedOperand::FIXED_SLOT) { |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 } | 192 } |
195 return os << "]"; | 193 return os << "]"; |
196 } | 194 } |
197 case InstructionOperand::INVALID: | 195 case InstructionOperand::INVALID: |
198 return os << "(x)"; | 196 return os << "(x)"; |
199 } | 197 } |
200 UNREACHABLE(); | 198 UNREACHABLE(); |
201 return os; | 199 return os; |
202 } | 200 } |
203 | 201 |
204 void MoveOperands::Print(std::ostream& os, | 202 void MoveOperands::Print(const RegisterConfiguration* config) const { |
205 const RegisterConfiguration* config) const { | 203 OFStream os(stdout); |
206 PrintableInstructionOperand wrapper; | 204 PrintableInstructionOperand wrapper; |
207 wrapper.register_configuration_ = config; | 205 wrapper.register_configuration_ = config; |
208 wrapper.op_ = destination(); | 206 wrapper.op_ = destination(); |
209 os << wrapper << " = "; | 207 os << wrapper << " = "; |
210 wrapper.op_ = source(); | 208 wrapper.op_ = source(); |
211 os << wrapper << std::endl; | 209 os << wrapper << std::endl; |
212 } | 210 } |
213 | 211 |
214 void MoveOperands::Print(std::ostream& os) const { Print(os, GetRegConfig()); } | 212 void MoveOperands::Print() const { Print(GetRegConfig()); } |
215 | 213 |
216 std::ostream& operator<<(std::ostream& os, | 214 std::ostream& operator<<(std::ostream& os, |
217 const PrintableMoveOperands& printable) { | 215 const PrintableMoveOperands& printable) { |
218 const MoveOperands& mo = *printable.move_operands_; | 216 const MoveOperands& mo = *printable.move_operands_; |
219 PrintableInstructionOperand printable_op = {printable.register_configuration_, | 217 PrintableInstructionOperand printable_op = {printable.register_configuration_, |
220 mo.destination()}; | 218 mo.destination()}; |
221 os << printable_op; | 219 os << printable_op; |
222 if (!mo.source().Equals(mo.destination())) { | 220 if (!mo.source().Equals(mo.destination())) { |
223 printable_op.op_ = mo.source(); | 221 printable_op.op_ = mo.source(); |
224 os << " = " << printable_op; | 222 os << " = " << printable_op; |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
309 bool Instruction::AreMovesRedundant() const { | 307 bool Instruction::AreMovesRedundant() const { |
310 for (int i = Instruction::FIRST_GAP_POSITION; | 308 for (int i = Instruction::FIRST_GAP_POSITION; |
311 i <= Instruction::LAST_GAP_POSITION; i++) { | 309 i <= Instruction::LAST_GAP_POSITION; i++) { |
312 if (parallel_moves_[i] != nullptr && !parallel_moves_[i]->IsRedundant()) { | 310 if (parallel_moves_[i] != nullptr && !parallel_moves_[i]->IsRedundant()) { |
313 return false; | 311 return false; |
314 } | 312 } |
315 } | 313 } |
316 return true; | 314 return true; |
317 } | 315 } |
318 | 316 |
319 void Instruction::Print(std::ostream& os, | 317 void Instruction::Print(const RegisterConfiguration* config) const { |
320 const RegisterConfiguration* config) const { | 318 OFStream os(stdout); |
321 PrintableInstruction wrapper; | 319 PrintableInstruction wrapper; |
322 wrapper.instr_ = this; | 320 wrapper.instr_ = this; |
323 wrapper.register_configuration_ = config; | 321 wrapper.register_configuration_ = config; |
324 os << wrapper << std::endl; | 322 os << wrapper << std::endl; |
325 } | 323 } |
326 | 324 |
327 void Instruction::Print(std::ostream& os) const { Print(os, GetRegConfig()); } | 325 void Instruction::Print() const { Print(GetRegConfig()); } |
328 | 326 |
329 std::ostream& operator<<(std::ostream& os, | 327 std::ostream& operator<<(std::ostream& os, |
330 const PrintableParallelMove& printable) { | 328 const PrintableParallelMove& printable) { |
331 const ParallelMove& pm = *printable.parallel_move_; | 329 const ParallelMove& pm = *printable.parallel_move_; |
332 bool first = true; | 330 bool first = true; |
333 for (MoveOperands* move : pm) { | 331 for (MoveOperands* move : pm) { |
334 if (move->IsEliminated()) continue; | 332 if (move->IsEliminated()) continue; |
335 if (!first) os << " "; | 333 if (!first) os << " "; |
336 first = false; | 334 first = false; |
337 PrintableMoveOperands pmo = {printable.register_configuration_, move}; | 335 PrintableMoveOperands pmo = {printable.register_configuration_, move}; |
(...skipping 287 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
625 for (BasicBlock* successor : block->successors()) { | 623 for (BasicBlock* successor : block->successors()) { |
626 instr_block->successors().push_back(GetRpo(successor)); | 624 instr_block->successors().push_back(GetRpo(successor)); |
627 } | 625 } |
628 instr_block->predecessors().reserve(block->PredecessorCount()); | 626 instr_block->predecessors().reserve(block->PredecessorCount()); |
629 for (BasicBlock* predecessor : block->predecessors()) { | 627 for (BasicBlock* predecessor : block->predecessors()) { |
630 instr_block->predecessors().push_back(GetRpo(predecessor)); | 628 instr_block->predecessors().push_back(GetRpo(predecessor)); |
631 } | 629 } |
632 return instr_block; | 630 return instr_block; |
633 } | 631 } |
634 | 632 |
| 633 std::ostream& operator<<(std::ostream& os, |
| 634 PrintableInstructionBlock& printable_block) { |
| 635 const InstructionBlock* block = printable_block.block_; |
| 636 const RegisterConfiguration* config = printable_block.register_configuration_; |
| 637 const InstructionSequence* code = printable_block.code_; |
| 638 |
| 639 os << "B" << block->rpo_number(); |
| 640 os << ": AO#" << block->ao_number(); |
| 641 if (block->IsDeferred()) os << " (deferred)"; |
| 642 if (!block->needs_frame()) os << " (no frame)"; |
| 643 if (block->must_construct_frame()) os << " (construct frame)"; |
| 644 if (block->must_deconstruct_frame()) os << " (deconstruct frame)"; |
| 645 if (block->IsLoopHeader()) { |
| 646 os << " loop blocks: [" << block->rpo_number() << ", " << block->loop_end() |
| 647 << ")"; |
| 648 } |
| 649 os << " instructions: [" << block->code_start() << ", " << block->code_end() |
| 650 << ")" << std::endl |
| 651 << " predecessors:"; |
| 652 |
| 653 for (RpoNumber pred : block->predecessors()) { |
| 654 os << " B" << pred.ToInt(); |
| 655 } |
| 656 os << std::endl; |
| 657 |
| 658 for (const PhiInstruction* phi : block->phis()) { |
| 659 PrintableInstructionOperand printable_op = {config, phi->output()}; |
| 660 os << " phi: " << printable_op << " ="; |
| 661 for (int input : phi->operands()) { |
| 662 os << " v" << input; |
| 663 } |
| 664 os << std::endl; |
| 665 } |
| 666 |
| 667 ScopedVector<char> buf(32); |
| 668 PrintableInstruction printable_instr; |
| 669 printable_instr.register_configuration_ = config; |
| 670 for (int j = block->first_instruction_index(); |
| 671 j <= block->last_instruction_index(); j++) { |
| 672 // TODO(svenpanne) Add some basic formatting to our streams. |
| 673 SNPrintF(buf, "%5d", j); |
| 674 printable_instr.instr_ = code->InstructionAt(j); |
| 675 os << " " << buf.start() << ": " << printable_instr << std::endl; |
| 676 } |
| 677 |
| 678 for (RpoNumber succ : block->successors()) { |
| 679 os << " B" << succ.ToInt(); |
| 680 } |
| 681 os << std::endl; |
| 682 return os; |
| 683 } |
| 684 |
635 InstructionBlocks* InstructionSequence::InstructionBlocksFor( | 685 InstructionBlocks* InstructionSequence::InstructionBlocksFor( |
636 Zone* zone, const Schedule* schedule) { | 686 Zone* zone, const Schedule* schedule) { |
637 InstructionBlocks* blocks = zone->NewArray<InstructionBlocks>(1); | 687 InstructionBlocks* blocks = zone->NewArray<InstructionBlocks>(1); |
638 new (blocks) InstructionBlocks( | 688 new (blocks) InstructionBlocks( |
639 static_cast<int>(schedule->rpo_order()->size()), nullptr, zone); | 689 static_cast<int>(schedule->rpo_order()->size()), nullptr, zone); |
640 size_t rpo_number = 0; | 690 size_t rpo_number = 0; |
641 for (BasicBlockVector::const_iterator it = schedule->rpo_order()->begin(); | 691 for (BasicBlockVector::const_iterator it = schedule->rpo_order()->begin(); |
642 it != schedule->rpo_order()->end(); ++it, ++rpo_number) { | 692 it != schedule->rpo_order()->end(); ++it, ++rpo_number) { |
643 DCHECK(!(*blocks)[rpo_number]); | 693 DCHECK(!(*blocks)[rpo_number]); |
644 DCHECK(GetRpo(*it).ToSize() == rpo_number); | 694 DCHECK(GetRpo(*it).ToSize() == rpo_number); |
(...skipping 223 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
868 *result = it->second; | 918 *result = it->second; |
869 return true; | 919 return true; |
870 } | 920 } |
871 | 921 |
872 | 922 |
873 void InstructionSequence::SetSourcePosition(const Instruction* instr, | 923 void InstructionSequence::SetSourcePosition(const Instruction* instr, |
874 SourcePosition value) { | 924 SourcePosition value) { |
875 source_positions_.insert(std::make_pair(instr, value)); | 925 source_positions_.insert(std::make_pair(instr, value)); |
876 } | 926 } |
877 | 927 |
878 void InstructionSequence::Print(std::ostream& os, | 928 void InstructionSequence::Print(const RegisterConfiguration* config) const { |
879 const RegisterConfiguration* config) const { | 929 OFStream os(stdout); |
880 PrintableInstructionSequence wrapper; | 930 PrintableInstructionSequence wrapper; |
881 wrapper.register_configuration_ = config; | 931 wrapper.register_configuration_ = config; |
882 wrapper.sequence_ = this; | 932 wrapper.sequence_ = this; |
883 os << wrapper << std::endl; | 933 os << wrapper << std::endl; |
884 } | 934 } |
885 | 935 |
886 void InstructionSequence::Print(std::ostream& os) const { | 936 void InstructionSequence::Print() const { Print(GetRegConfig()); } |
887 Print(os, GetRegConfig()); | |
888 } | |
889 | 937 |
890 void InstructionSequence::PrintBlock(std::ostream& os, | 938 void InstructionSequence::PrintBlock(const RegisterConfiguration* config, |
891 const RegisterConfiguration* config, | |
892 int block_id) const { | 939 int block_id) const { |
| 940 OFStream os(stdout); |
893 RpoNumber rpo = RpoNumber::FromInt(block_id); | 941 RpoNumber rpo = RpoNumber::FromInt(block_id); |
894 const InstructionBlock* block = InstructionBlockAt(rpo); | 942 const InstructionBlock* block = InstructionBlockAt(rpo); |
895 CHECK(block->rpo_number() == rpo); | 943 CHECK(block->rpo_number() == rpo); |
896 | 944 PrintableInstructionBlock printable_block = {config, block, this}; |
897 os << "B" << block->rpo_number(); | 945 os << printable_block << std::endl; |
898 os << ": AO#" << block->ao_number(); | |
899 if (block->IsDeferred()) os << " (deferred)"; | |
900 if (!block->needs_frame()) os << " (no frame)"; | |
901 if (block->must_construct_frame()) os << " (construct frame)"; | |
902 if (block->must_deconstruct_frame()) os << " (deconstruct frame)"; | |
903 if (block->IsLoopHeader()) { | |
904 os << " loop blocks: [" << block->rpo_number() << ", " << block->loop_end() | |
905 << ")"; | |
906 } | |
907 os << " instructions: [" << block->code_start() << ", " << block->code_end() | |
908 << ")\n predecessors:"; | |
909 | |
910 for (RpoNumber pred : block->predecessors()) { | |
911 os << " B" << pred.ToInt(); | |
912 } | |
913 os << "\n"; | |
914 | |
915 for (const PhiInstruction* phi : block->phis()) { | |
916 PrintableInstructionOperand printable_op = {config, phi->output()}; | |
917 os << " phi: " << printable_op << " ="; | |
918 for (int input : phi->operands()) { | |
919 os << " v" << input; | |
920 } | |
921 os << "\n"; | |
922 } | |
923 | |
924 ScopedVector<char> buf(32); | |
925 PrintableInstruction printable_instr; | |
926 printable_instr.register_configuration_ = config; | |
927 for (int j = block->first_instruction_index(); | |
928 j <= block->last_instruction_index(); j++) { | |
929 // TODO(svenpanne) Add some basic formatting to our streams. | |
930 SNPrintF(buf, "%5d", j); | |
931 printable_instr.instr_ = InstructionAt(j); | |
932 os << " " << buf.start() << ": " << printable_instr << "\n"; | |
933 } | |
934 | |
935 for (RpoNumber succ : block->successors()) { | |
936 os << " B" << succ.ToInt(); | |
937 } | |
938 os << "\n"; | |
939 } | 946 } |
940 | 947 |
941 void InstructionSequence::PrintBlock(std::ostream& os, int block_id) const { | 948 void InstructionSequence::PrintBlock(int block_id) const { |
942 PrintBlock(os, GetRegConfig(), block_id); | 949 PrintBlock(GetRegConfig(), block_id); |
943 } | 950 } |
944 | 951 |
945 FrameStateDescriptor::FrameStateDescriptor( | 952 FrameStateDescriptor::FrameStateDescriptor( |
946 Zone* zone, FrameStateType type, BailoutId bailout_id, | 953 Zone* zone, FrameStateType type, BailoutId bailout_id, |
947 OutputFrameStateCombine state_combine, size_t parameters_count, | 954 OutputFrameStateCombine state_combine, size_t parameters_count, |
948 size_t locals_count, size_t stack_count, | 955 size_t locals_count, size_t stack_count, |
949 MaybeHandle<SharedFunctionInfo> shared_info, | 956 MaybeHandle<SharedFunctionInfo> shared_info, |
950 FrameStateDescriptor* outer_state) | 957 FrameStateDescriptor* outer_state) |
951 : type_(type), | 958 : type_(type), |
952 bailout_id_(bailout_id), | 959 bailout_id_(bailout_id), |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1015 const InstructionSequence& code = *printable.sequence_; | 1022 const InstructionSequence& code = *printable.sequence_; |
1016 for (size_t i = 0; i < code.immediates_.size(); ++i) { | 1023 for (size_t i = 0; i < code.immediates_.size(); ++i) { |
1017 Constant constant = code.immediates_[i]; | 1024 Constant constant = code.immediates_[i]; |
1018 os << "IMM#" << i << ": " << constant << "\n"; | 1025 os << "IMM#" << i << ": " << constant << "\n"; |
1019 } | 1026 } |
1020 int i = 0; | 1027 int i = 0; |
1021 for (ConstantMap::const_iterator it = code.constants_.begin(); | 1028 for (ConstantMap::const_iterator it = code.constants_.begin(); |
1022 it != code.constants_.end(); ++i, ++it) { | 1029 it != code.constants_.end(); ++i, ++it) { |
1023 os << "CST#" << i << ": v" << it->first << " = " << it->second << "\n"; | 1030 os << "CST#" << i << ": v" << it->first << " = " << it->second << "\n"; |
1024 } | 1031 } |
| 1032 PrintableInstructionBlock printable_block = { |
| 1033 printable.register_configuration_, nullptr, printable.sequence_}; |
1025 for (int i = 0; i < code.InstructionBlockCount(); i++) { | 1034 for (int i = 0; i < code.InstructionBlockCount(); i++) { |
1026 printable.sequence_->PrintBlock(os, printable.register_configuration_, i); | 1035 printable_block.block_ = code.InstructionBlockAt(RpoNumber::FromInt(i)); |
| 1036 os << printable_block; |
1027 } | 1037 } |
1028 return os; | 1038 return os; |
1029 } | 1039 } |
1030 | 1040 |
1031 } // namespace compiler | 1041 } // namespace compiler |
1032 } // namespace internal | 1042 } // namespace internal |
1033 } // namespace v8 | 1043 } // namespace v8 |
OLD | NEW |