| 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 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 107 case UnallocatedOperand::SAME_AS_FIRST_INPUT: | 107 case UnallocatedOperand::SAME_AS_FIRST_INPUT: |
| 108 return os << "(1)"; | 108 return os << "(1)"; |
| 109 case UnallocatedOperand::ANY: | 109 case UnallocatedOperand::ANY: |
| 110 return os << "(-)"; | 110 return os << "(-)"; |
| 111 } | 111 } |
| 112 } | 112 } |
| 113 case InstructionOperand::CONSTANT: | 113 case InstructionOperand::CONSTANT: |
| 114 return os << "[constant:" << ConstantOperand::cast(op).virtual_register() | 114 return os << "[constant:" << ConstantOperand::cast(op).virtual_register() |
| 115 << "]"; | 115 << "]"; |
| 116 case InstructionOperand::IMMEDIATE: { | 116 case InstructionOperand::IMMEDIATE: { |
| 117 auto imm = ImmediateOperand::cast(op); | 117 ImmediateOperand imm = ImmediateOperand::cast(op); |
| 118 switch (imm.type()) { | 118 switch (imm.type()) { |
| 119 case ImmediateOperand::INLINE: | 119 case ImmediateOperand::INLINE: |
| 120 return os << "#" << imm.inline_value(); | 120 return os << "#" << imm.inline_value(); |
| 121 case ImmediateOperand::INDEXED: | 121 case ImmediateOperand::INDEXED: |
| 122 return os << "[immediate:" << imm.indexed_value() << "]"; | 122 return os << "[immediate:" << imm.indexed_value() << "]"; |
| 123 } | 123 } |
| 124 } | 124 } |
| 125 case InstructionOperand::EXPLICIT: | 125 case InstructionOperand::EXPLICIT: |
| 126 case InstructionOperand::ALLOCATED: { | 126 case InstructionOperand::ALLOCATED: { |
| 127 auto allocated = LocationOperand::cast(op); | 127 LocationOperand allocated = LocationOperand::cast(op); |
| 128 if (op.IsStackSlot()) { | 128 if (op.IsStackSlot()) { |
| 129 os << "[stack:" << LocationOperand::cast(op).index(); | 129 os << "[stack:" << LocationOperand::cast(op).index(); |
| 130 } else if (op.IsDoubleStackSlot()) { | 130 } else if (op.IsDoubleStackSlot()) { |
| 131 os << "[double_stack:" << LocationOperand::cast(op).index(); | 131 os << "[double_stack:" << LocationOperand::cast(op).index(); |
| 132 } else if (op.IsRegister()) { | 132 } else if (op.IsRegister()) { |
| 133 os << "[" << LocationOperand::cast(op).GetRegister().ToString() << "|R"; | 133 os << "[" << LocationOperand::cast(op).GetRegister().ToString() << "|R"; |
| 134 } else { | 134 } else { |
| 135 DCHECK(op.IsDoubleRegister()); | 135 DCHECK(op.IsDoubleRegister()); |
| 136 os << "[" << LocationOperand::cast(op).GetDoubleRegister().ToString() | 136 os << "[" << LocationOperand::cast(op).GetDoubleRegister().ToString() |
| 137 << "|R"; | 137 << "|R"; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 207 os << printable_op; | 207 os << printable_op; |
| 208 if (!mo.source().Equals(mo.destination())) { | 208 if (!mo.source().Equals(mo.destination())) { |
| 209 printable_op.op_ = mo.source(); | 209 printable_op.op_ = mo.source(); |
| 210 os << " = " << printable_op; | 210 os << " = " << printable_op; |
| 211 } | 211 } |
| 212 return os << ";"; | 212 return os << ";"; |
| 213 } | 213 } |
| 214 | 214 |
| 215 | 215 |
| 216 bool ParallelMove::IsRedundant() const { | 216 bool ParallelMove::IsRedundant() const { |
| 217 for (auto move : *this) { | 217 for (MoveOperands* move : *this) { |
| 218 if (!move->IsRedundant()) return false; | 218 if (!move->IsRedundant()) return false; |
| 219 } | 219 } |
| 220 return true; | 220 return true; |
| 221 } | 221 } |
| 222 | 222 |
| 223 | 223 |
| 224 MoveOperands* ParallelMove::PrepareInsertAfter(MoveOperands* move) const { | 224 MoveOperands* ParallelMove::PrepareInsertAfter(MoveOperands* move) const { |
| 225 MoveOperands* replacement = nullptr; | 225 MoveOperands* replacement = nullptr; |
| 226 MoveOperands* to_eliminate = nullptr; | 226 MoveOperands* to_eliminate = nullptr; |
| 227 for (auto curr : *this) { | 227 for (MoveOperands* curr : *this) { |
| 228 if (curr->IsEliminated()) continue; | 228 if (curr->IsEliminated()) continue; |
| 229 if (curr->destination().EqualsCanonicalized(move->source())) { | 229 if (curr->destination().EqualsCanonicalized(move->source())) { |
| 230 DCHECK(!replacement); | 230 DCHECK(!replacement); |
| 231 replacement = curr; | 231 replacement = curr; |
| 232 if (to_eliminate != nullptr) break; | 232 if (to_eliminate != nullptr) break; |
| 233 } else if (curr->destination().EqualsCanonicalized(move->destination())) { | 233 } else if (curr->destination().EqualsCanonicalized(move->destination())) { |
| 234 DCHECK(!to_eliminate); | 234 DCHECK(!to_eliminate); |
| 235 to_eliminate = curr; | 235 to_eliminate = curr; |
| 236 if (replacement != nullptr) break; | 236 if (replacement != nullptr) break; |
| 237 } | 237 } |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 314 const RegisterConfiguration* config = | 314 const RegisterConfiguration* config = |
| 315 RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN); | 315 RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN); |
| 316 Print(config); | 316 Print(config); |
| 317 } | 317 } |
| 318 | 318 |
| 319 | 319 |
| 320 std::ostream& operator<<(std::ostream& os, | 320 std::ostream& operator<<(std::ostream& os, |
| 321 const PrintableParallelMove& printable) { | 321 const PrintableParallelMove& printable) { |
| 322 const ParallelMove& pm = *printable.parallel_move_; | 322 const ParallelMove& pm = *printable.parallel_move_; |
| 323 bool first = true; | 323 bool first = true; |
| 324 for (auto move : pm) { | 324 for (MoveOperands* move : pm) { |
| 325 if (move->IsEliminated()) continue; | 325 if (move->IsEliminated()) continue; |
| 326 if (!first) os << " "; | 326 if (!first) os << " "; |
| 327 first = false; | 327 first = false; |
| 328 PrintableMoveOperands pmo = {printable.register_configuration_, move}; | 328 PrintableMoveOperands pmo = {printable.register_configuration_, move}; |
| 329 os << pmo; | 329 os << pmo; |
| 330 } | 330 } |
| 331 return os; | 331 return os; |
| 332 } | 332 } |
| 333 | 333 |
| 334 | 334 |
| 335 void ReferenceMap::RecordReference(const AllocatedOperand& op) { | 335 void ReferenceMap::RecordReference(const AllocatedOperand& op) { |
| 336 // Do not record arguments as pointers. | 336 // Do not record arguments as pointers. |
| 337 if (op.IsStackSlot() && LocationOperand::cast(op).index() < 0) return; | 337 if (op.IsStackSlot() && LocationOperand::cast(op).index() < 0) return; |
| 338 DCHECK(!op.IsDoubleRegister() && !op.IsDoubleStackSlot()); | 338 DCHECK(!op.IsDoubleRegister() && !op.IsDoubleStackSlot()); |
| 339 reference_operands_.push_back(op); | 339 reference_operands_.push_back(op); |
| 340 } | 340 } |
| 341 | 341 |
| 342 | 342 |
| 343 std::ostream& operator<<(std::ostream& os, const ReferenceMap& pm) { | 343 std::ostream& operator<<(std::ostream& os, const ReferenceMap& pm) { |
| 344 os << "{"; | 344 os << "{"; |
| 345 bool first = true; | 345 bool first = true; |
| 346 PrintableInstructionOperand poi = { | 346 PrintableInstructionOperand poi = { |
| 347 RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN), | 347 RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN), |
| 348 InstructionOperand()}; | 348 InstructionOperand()}; |
| 349 for (auto& op : pm.reference_operands_) { | 349 for (const InstructionOperand& op : pm.reference_operands_) { |
| 350 if (!first) { | 350 if (!first) { |
| 351 os << ";"; | 351 os << ";"; |
| 352 } else { | 352 } else { |
| 353 first = false; | 353 first = false; |
| 354 } | 354 } |
| 355 poi.op_ = op; | 355 poi.op_ = op; |
| 356 os << poi; | 356 os << poi; |
| 357 } | 357 } |
| 358 return os << "}"; | 358 return os << "}"; |
| 359 } | 359 } |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 630 // Expect precisely one predecessor: "block". | 630 // Expect precisely one predecessor: "block". |
| 631 CHECK(successor->PredecessorCount() == 1 && | 631 CHECK(successor->PredecessorCount() == 1 && |
| 632 successor->predecessors()[0] == block->rpo_number()); | 632 successor->predecessors()[0] == block->rpo_number()); |
| 633 } | 633 } |
| 634 } | 634 } |
| 635 } | 635 } |
| 636 } | 636 } |
| 637 | 637 |
| 638 void InstructionSequence::ComputeAssemblyOrder(InstructionBlocks* blocks) { | 638 void InstructionSequence::ComputeAssemblyOrder(InstructionBlocks* blocks) { |
| 639 int ao = 0; | 639 int ao = 0; |
| 640 for (auto const block : *blocks) { | 640 for (InstructionBlock* const block : *blocks) { |
| 641 if (!block->IsDeferred()) { | 641 if (!block->IsDeferred()) { |
| 642 block->set_ao_number(RpoNumber::FromInt(ao++)); | 642 block->set_ao_number(RpoNumber::FromInt(ao++)); |
| 643 } | 643 } |
| 644 } | 644 } |
| 645 for (auto const block : *blocks) { | 645 for (InstructionBlock* const block : *blocks) { |
| 646 if (block->IsDeferred()) { | 646 if (block->IsDeferred()) { |
| 647 block->set_ao_number(RpoNumber::FromInt(ao++)); | 647 block->set_ao_number(RpoNumber::FromInt(ao++)); |
| 648 } | 648 } |
| 649 } | 649 } |
| 650 } | 650 } |
| 651 | 651 |
| 652 | 652 |
| 653 InstructionSequence::InstructionSequence(Isolate* isolate, | 653 InstructionSequence::InstructionSequence(Isolate* isolate, |
| 654 Zone* instruction_zone, | 654 Zone* instruction_zone, |
| 655 InstructionBlocks* instruction_blocks) | 655 InstructionBlocks* instruction_blocks) |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 725 InstructionBlock* InstructionSequence::GetInstructionBlock( | 725 InstructionBlock* InstructionSequence::GetInstructionBlock( |
| 726 int instruction_index) const { | 726 int instruction_index) const { |
| 727 DCHECK(instruction_blocks_->size() == block_starts_.size()); | 727 DCHECK(instruction_blocks_->size() == block_starts_.size()); |
| 728 auto begin = block_starts_.begin(); | 728 auto begin = block_starts_.begin(); |
| 729 auto end = std::lower_bound(begin, block_starts_.end(), instruction_index); | 729 auto end = std::lower_bound(begin, block_starts_.end(), instruction_index); |
| 730 // Post condition of std::lower_bound: | 730 // Post condition of std::lower_bound: |
| 731 DCHECK(end == block_starts_.end() || *end >= instruction_index); | 731 DCHECK(end == block_starts_.end() || *end >= instruction_index); |
| 732 if (end == block_starts_.end() || *end > instruction_index) --end; | 732 if (end == block_starts_.end() || *end > instruction_index) --end; |
| 733 DCHECK(*end <= instruction_index); | 733 DCHECK(*end <= instruction_index); |
| 734 size_t index = std::distance(begin, end); | 734 size_t index = std::distance(begin, end); |
| 735 auto block = instruction_blocks_->at(index); | 735 InstructionBlock* block = instruction_blocks_->at(index); |
| 736 DCHECK(block->code_start() <= instruction_index && | 736 DCHECK(block->code_start() <= instruction_index && |
| 737 instruction_index < block->code_end()); | 737 instruction_index < block->code_end()); |
| 738 return block; | 738 return block; |
| 739 } | 739 } |
| 740 | 740 |
| 741 | 741 |
| 742 static MachineRepresentation FilterRepresentation(MachineRepresentation rep) { | 742 static MachineRepresentation FilterRepresentation(MachineRepresentation rep) { |
| 743 switch (rep) { | 743 switch (rep) { |
| 744 case MachineRepresentation::kBit: | 744 case MachineRepresentation::kBit: |
| 745 case MachineRepresentation::kWord8: | 745 case MachineRepresentation::kWord8: |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 856 if (!block->needs_frame()) os << " (no frame)"; | 856 if (!block->needs_frame()) os << " (no frame)"; |
| 857 if (block->must_construct_frame()) os << " (construct frame)"; | 857 if (block->must_construct_frame()) os << " (construct frame)"; |
| 858 if (block->must_deconstruct_frame()) os << " (deconstruct frame)"; | 858 if (block->must_deconstruct_frame()) os << " (deconstruct frame)"; |
| 859 if (block->IsLoopHeader()) { | 859 if (block->IsLoopHeader()) { |
| 860 os << " loop blocks: [" << block->rpo_number() << ", " << block->loop_end() | 860 os << " loop blocks: [" << block->rpo_number() << ", " << block->loop_end() |
| 861 << ")"; | 861 << ")"; |
| 862 } | 862 } |
| 863 os << " instructions: [" << block->code_start() << ", " << block->code_end() | 863 os << " instructions: [" << block->code_start() << ", " << block->code_end() |
| 864 << ")\n predecessors:"; | 864 << ")\n predecessors:"; |
| 865 | 865 |
| 866 for (auto pred : block->predecessors()) { | 866 for (RpoNumber pred : block->predecessors()) { |
| 867 os << " B" << pred.ToInt(); | 867 os << " B" << pred.ToInt(); |
| 868 } | 868 } |
| 869 os << "\n"; | 869 os << "\n"; |
| 870 | 870 |
| 871 for (auto phi : block->phis()) { | 871 for (const PhiInstruction* phi : block->phis()) { |
| 872 PrintableInstructionOperand printable_op = {config, phi->output()}; | 872 PrintableInstructionOperand printable_op = {config, phi->output()}; |
| 873 os << " phi: " << printable_op << " ="; | 873 os << " phi: " << printable_op << " ="; |
| 874 for (auto input : phi->operands()) { | 874 for (int input : phi->operands()) { |
| 875 os << " v" << input; | 875 os << " v" << input; |
| 876 } | 876 } |
| 877 os << "\n"; | 877 os << "\n"; |
| 878 } | 878 } |
| 879 | 879 |
| 880 ScopedVector<char> buf(32); | 880 ScopedVector<char> buf(32); |
| 881 PrintableInstruction printable_instr; | 881 PrintableInstruction printable_instr; |
| 882 printable_instr.register_configuration_ = config; | 882 printable_instr.register_configuration_ = config; |
| 883 for (int j = block->first_instruction_index(); | 883 for (int j = block->first_instruction_index(); |
| 884 j <= block->last_instruction_index(); j++) { | 884 j <= block->last_instruction_index(); j++) { |
| 885 // TODO(svenpanne) Add some basic formatting to our streams. | 885 // TODO(svenpanne) Add some basic formatting to our streams. |
| 886 SNPrintF(buf, "%5d", j); | 886 SNPrintF(buf, "%5d", j); |
| 887 printable_instr.instr_ = InstructionAt(j); | 887 printable_instr.instr_ = InstructionAt(j); |
| 888 os << " " << buf.start() << ": " << printable_instr << "\n"; | 888 os << " " << buf.start() << ": " << printable_instr << "\n"; |
| 889 } | 889 } |
| 890 | 890 |
| 891 for (auto succ : block->successors()) { | 891 for (RpoNumber succ : block->successors()) { |
| 892 os << " B" << succ.ToInt(); | 892 os << " B" << succ.ToInt(); |
| 893 } | 893 } |
| 894 os << "\n"; | 894 os << "\n"; |
| 895 } | 895 } |
| 896 | 896 |
| 897 void InstructionSequence::PrintBlock(int block_id) const { | 897 void InstructionSequence::PrintBlock(int block_id) const { |
| 898 const RegisterConfiguration* config = | 898 const RegisterConfiguration* config = |
| 899 RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN); | 899 RegisterConfiguration::ArchDefault(RegisterConfiguration::TURBOFAN); |
| 900 PrintBlock(config, block_id); | 900 PrintBlock(config, block_id); |
| 901 } | 901 } |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 982 } | 982 } |
| 983 for (int i = 0; i < code.InstructionBlockCount(); i++) { | 983 for (int i = 0; i < code.InstructionBlockCount(); i++) { |
| 984 printable.sequence_->PrintBlock(printable.register_configuration_, i); | 984 printable.sequence_->PrintBlock(printable.register_configuration_, i); |
| 985 } | 985 } |
| 986 return os; | 986 return os; |
| 987 } | 987 } |
| 988 | 988 |
| 989 } // namespace compiler | 989 } // namespace compiler |
| 990 } // namespace internal | 990 } // namespace internal |
| 991 } // namespace v8 | 991 } // namespace v8 |
| OLD | NEW |