| 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 #ifndef V8_COMPILER_INSTRUCTION_H_ | 5 #ifndef V8_COMPILER_INSTRUCTION_H_ |
| 6 #define V8_COMPILER_INSTRUCTION_H_ | 6 #define V8_COMPILER_INSTRUCTION_H_ |
| 7 | 7 |
| 8 #include <deque> | 8 #include <deque> |
| 9 #include <iosfwd> | 9 #include <iosfwd> |
| 10 #include <map> | 10 #include <map> |
| (...skipping 423 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 434 } | 434 } |
| 435 | 435 |
| 436 bool HasOutput() const { return OutputCount() == 1; } | 436 bool HasOutput() const { return OutputCount() == 1; } |
| 437 InstructionOperand* Output() const { return OutputAt(0); } | 437 InstructionOperand* Output() const { return OutputAt(0); } |
| 438 | 438 |
| 439 size_t InputCount() const { return InputCountField::decode(bit_field_); } | 439 size_t InputCount() const { return InputCountField::decode(bit_field_); } |
| 440 InstructionOperand* InputAt(size_t i) const { | 440 InstructionOperand* InputAt(size_t i) const { |
| 441 DCHECK(i < InputCount()); | 441 DCHECK(i < InputCount()); |
| 442 return operands_[OutputCount() + i]; | 442 return operands_[OutputCount() + i]; |
| 443 } | 443 } |
| 444 void SetInputAt(size_t i, InstructionOperand* operand) { |
| 445 DCHECK(i < InputCount()); |
| 446 operands_[OutputCount() + i] = operand; |
| 447 } |
| 444 | 448 |
| 445 size_t TempCount() const { return TempCountField::decode(bit_field_); } | 449 size_t TempCount() const { return TempCountField::decode(bit_field_); } |
| 446 InstructionOperand* TempAt(size_t i) const { | 450 InstructionOperand* TempAt(size_t i) const { |
| 447 DCHECK(i < TempCount()); | 451 DCHECK(i < TempCount()); |
| 448 return operands_[OutputCount() + InputCount() + i]; | 452 return operands_[OutputCount() + InputCount() + i]; |
| 449 } | 453 } |
| 450 | 454 |
| 451 InstructionCode opcode() const { return opcode_; } | 455 InstructionCode opcode() const { return opcode_; } |
| 452 ArchOpcode arch_opcode() const { return ArchOpcodeField::decode(opcode()); } | 456 ArchOpcode arch_opcode() const { return ArchOpcodeField::decode(opcode()); } |
| 453 AddressingMode addressing_mode() const { | 457 AddressingMode addressing_mode() const { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 513 DCHECK_EQ(NULL, pointer_map_); | 517 DCHECK_EQ(NULL, pointer_map_); |
| 514 pointer_map_ = map; | 518 pointer_map_ = map; |
| 515 } | 519 } |
| 516 | 520 |
| 517 // Placement new operator so that we can smash instructions into | 521 // Placement new operator so that we can smash instructions into |
| 518 // zone-allocated memory. | 522 // zone-allocated memory. |
| 519 void* operator new(size_t, void* location) { return location; } | 523 void* operator new(size_t, void* location) { return location; } |
| 520 | 524 |
| 521 void operator delete(void* pointer, void* location) { UNREACHABLE(); } | 525 void operator delete(void* pointer, void* location) { UNREACHABLE(); } |
| 522 | 526 |
| 527 void OverwriteWithNop() { |
| 528 opcode_ = ArchOpcodeField::encode(kArchNop); |
| 529 bit_field_ = 0; |
| 530 pointer_map_ = NULL; |
| 531 } |
| 532 |
| 533 bool IsNop() const { |
| 534 return arch_opcode() == kArchNop && InputCount() == 0 && |
| 535 OutputCount() == 0 && TempCount() == 0; |
| 536 } |
| 537 |
| 523 protected: | 538 protected: |
| 524 explicit Instruction(InstructionCode opcode) | 539 explicit Instruction(InstructionCode opcode) |
| 525 : opcode_(opcode), | 540 : opcode_(opcode), |
| 526 bit_field_(OutputCountField::encode(0) | InputCountField::encode(0) | | 541 bit_field_(OutputCountField::encode(0) | InputCountField::encode(0) | |
| 527 TempCountField::encode(0) | IsCallField::encode(false) | | 542 TempCountField::encode(0) | IsCallField::encode(false) | |
| 528 IsControlField::encode(false)), | 543 IsControlField::encode(false)), |
| 529 pointer_map_(NULL) {} | 544 pointer_map_(NULL) {} |
| 530 | 545 |
| 531 Instruction(InstructionCode opcode, size_t output_count, | 546 Instruction(InstructionCode opcode, size_t output_count, |
| 532 InstructionOperand** outputs, size_t input_count, | 547 InstructionOperand** outputs, size_t input_count, |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 592 } | 607 } |
| 593 | 608 |
| 594 ParallelMove* GetParallelMove(InnerPosition pos) { | 609 ParallelMove* GetParallelMove(InnerPosition pos) { |
| 595 return parallel_moves_[pos]; | 610 return parallel_moves_[pos]; |
| 596 } | 611 } |
| 597 | 612 |
| 598 const ParallelMove* GetParallelMove(InnerPosition pos) const { | 613 const ParallelMove* GetParallelMove(InnerPosition pos) const { |
| 599 return parallel_moves_[pos]; | 614 return parallel_moves_[pos]; |
| 600 } | 615 } |
| 601 | 616 |
| 617 bool IsRedundant() const; |
| 618 |
| 602 static GapInstruction* New(Zone* zone) { | 619 static GapInstruction* New(Zone* zone) { |
| 603 void* buffer = zone->New(sizeof(GapInstruction)); | 620 void* buffer = zone->New(sizeof(GapInstruction)); |
| 604 return new (buffer) GapInstruction(kGapInstruction); | 621 return new (buffer) GapInstruction(kGapInstruction); |
| 605 } | 622 } |
| 606 | 623 |
| 607 static GapInstruction* cast(Instruction* instr) { | 624 static GapInstruction* cast(Instruction* instr) { |
| 608 DCHECK(instr->IsGapMoves()); | 625 DCHECK(instr->IsGapMoves()); |
| 609 return static_cast<GapInstruction*>(instr); | 626 return static_cast<GapInstruction*>(instr); |
| 610 } | 627 } |
| 611 | 628 |
| (...skipping 274 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 886 | 903 |
| 887 typedef ZoneVector<BasicBlock::RpoNumber> Successors; | 904 typedef ZoneVector<BasicBlock::RpoNumber> Successors; |
| 888 Successors& successors() { return successors_; } | 905 Successors& successors() { return successors_; } |
| 889 const Successors& successors() const { return successors_; } | 906 const Successors& successors() const { return successors_; } |
| 890 size_t SuccessorCount() const { return successors_.size(); } | 907 size_t SuccessorCount() const { return successors_.size(); } |
| 891 | 908 |
| 892 typedef ZoneVector<PhiInstruction*> PhiInstructions; | 909 typedef ZoneVector<PhiInstruction*> PhiInstructions; |
| 893 const PhiInstructions& phis() const { return phis_; } | 910 const PhiInstructions& phis() const { return phis_; } |
| 894 void AddPhi(PhiInstruction* phi) { phis_.push_back(phi); } | 911 void AddPhi(PhiInstruction* phi) { phis_.push_back(phi); } |
| 895 | 912 |
| 913 void set_ao_number(BasicBlock::RpoNumber ao_number) { |
| 914 ao_number_ = ao_number; |
| 915 } |
| 916 |
| 896 private: | 917 private: |
| 897 Successors successors_; | 918 Successors successors_; |
| 898 Predecessors predecessors_; | 919 Predecessors predecessors_; |
| 899 PhiInstructions phis_; | 920 PhiInstructions phis_; |
| 900 const BasicBlock::Id id_; | 921 const BasicBlock::Id id_; |
| 901 const BasicBlock::RpoNumber ao_number_; // Assembly order number. | 922 BasicBlock::RpoNumber ao_number_; // Assembly order number. |
| 902 const BasicBlock::RpoNumber rpo_number_; | 923 const BasicBlock::RpoNumber rpo_number_; |
| 903 const BasicBlock::RpoNumber loop_header_; | 924 const BasicBlock::RpoNumber loop_header_; |
| 904 const BasicBlock::RpoNumber loop_end_; | 925 const BasicBlock::RpoNumber loop_end_; |
| 905 int32_t code_start_; // start index of arch-specific code. | 926 int32_t code_start_; // start index of arch-specific code. |
| 906 int32_t code_end_; // end index of arch-specific code. | 927 int32_t code_end_; // end index of arch-specific code. |
| 907 const bool deferred_; // Block contains deferred code. | 928 const bool deferred_; // Block contains deferred code. |
| 908 }; | 929 }; |
| 909 | 930 |
| 910 typedef ZoneDeque<Constant> ConstantDeque; | 931 typedef ZoneDeque<Constant> ConstantDeque; |
| 911 typedef std::map<int, Constant, std::less<int>, | 932 typedef std::map<int, Constant, std::less<int>, |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 984 Isolate* isolate() const { return zone()->isolate(); } | 1005 Isolate* isolate() const { return zone()->isolate(); } |
| 985 const PointerMapDeque* pointer_maps() const { return &pointer_maps_; } | 1006 const PointerMapDeque* pointer_maps() const { return &pointer_maps_; } |
| 986 Zone* zone() const { return zone_; } | 1007 Zone* zone() const { return zone_; } |
| 987 | 1008 |
| 988 // Used by the instruction selector while adding instructions. | 1009 // Used by the instruction selector while adding instructions. |
| 989 int AddInstruction(Instruction* instr); | 1010 int AddInstruction(Instruction* instr); |
| 990 void StartBlock(BasicBlock::RpoNumber rpo); | 1011 void StartBlock(BasicBlock::RpoNumber rpo); |
| 991 void EndBlock(BasicBlock::RpoNumber rpo); | 1012 void EndBlock(BasicBlock::RpoNumber rpo); |
| 992 | 1013 |
| 993 int AddConstant(int virtual_register, Constant constant) { | 1014 int AddConstant(int virtual_register, Constant constant) { |
| 1015 // TODO(titzer): allow RPO numbers as constants? |
| 1016 DCHECK(constant.type() != Constant::kRpoNumber); |
| 994 DCHECK(virtual_register >= 0 && virtual_register < next_virtual_register_); | 1017 DCHECK(virtual_register >= 0 && virtual_register < next_virtual_register_); |
| 995 DCHECK(constants_.find(virtual_register) == constants_.end()); | 1018 DCHECK(constants_.find(virtual_register) == constants_.end()); |
| 996 constants_.insert(std::make_pair(virtual_register, constant)); | 1019 constants_.insert(std::make_pair(virtual_register, constant)); |
| 997 return virtual_register; | 1020 return virtual_register; |
| 998 } | 1021 } |
| 999 Constant GetConstant(int virtual_register) const { | 1022 Constant GetConstant(int virtual_register) const { |
| 1000 ConstantMap::const_iterator it = constants_.find(virtual_register); | 1023 ConstantMap::const_iterator it = constants_.find(virtual_register); |
| 1001 DCHECK(it != constants_.end()); | 1024 DCHECK(it != constants_.end()); |
| 1002 DCHECK_EQ(virtual_register, it->first); | 1025 DCHECK_EQ(virtual_register, it->first); |
| 1003 return it->second; | 1026 return it->second; |
| 1004 } | 1027 } |
| 1005 | 1028 |
| 1006 typedef ConstantDeque Immediates; | 1029 typedef ZoneVector<Constant> Immediates; |
| 1007 const Immediates& immediates() const { return immediates_; } | 1030 Immediates& immediates() { return immediates_; } |
| 1008 | 1031 |
| 1009 int AddImmediate(Constant constant) { | 1032 int AddImmediate(Constant constant) { |
| 1010 int index = static_cast<int>(immediates_.size()); | 1033 int index = static_cast<int>(immediates_.size()); |
| 1011 immediates_.push_back(constant); | 1034 immediates_.push_back(constant); |
| 1012 return index; | 1035 return index; |
| 1013 } | 1036 } |
| 1014 Constant GetImmediate(int index) const { | 1037 Constant GetImmediate(int index) const { |
| 1015 DCHECK(index >= 0); | 1038 DCHECK(index >= 0); |
| 1016 DCHECK(index < static_cast<int>(immediates_.size())); | 1039 DCHECK(index < static_cast<int>(immediates_.size())); |
| 1017 return immediates_[index]; | 1040 return immediates_[index]; |
| 1018 } | 1041 } |
| 1019 | 1042 |
| 1020 class StateId { | 1043 class StateId { |
| 1021 public: | 1044 public: |
| 1022 static StateId FromInt(int id) { return StateId(id); } | 1045 static StateId FromInt(int id) { return StateId(id); } |
| 1023 int ToInt() const { return id_; } | 1046 int ToInt() const { return id_; } |
| 1024 | 1047 |
| 1025 private: | 1048 private: |
| 1026 explicit StateId(int id) : id_(id) {} | 1049 explicit StateId(int id) : id_(id) {} |
| 1027 int id_; | 1050 int id_; |
| 1028 }; | 1051 }; |
| 1029 | 1052 |
| 1030 StateId AddFrameStateDescriptor(FrameStateDescriptor* descriptor); | 1053 StateId AddFrameStateDescriptor(FrameStateDescriptor* descriptor); |
| 1031 FrameStateDescriptor* GetFrameStateDescriptor(StateId deoptimization_id); | 1054 FrameStateDescriptor* GetFrameStateDescriptor(StateId deoptimization_id); |
| 1032 int GetFrameStateDescriptorCount(); | 1055 int GetFrameStateDescriptorCount(); |
| 1033 | 1056 |
| 1057 BasicBlock::RpoNumber InputRpo(Instruction* instr, size_t index) { |
| 1058 InstructionOperand* operand = instr->InputAt(index); |
| 1059 Constant constant = operand->IsImmediate() ? GetImmediate(operand->index()) |
| 1060 : GetConstant(operand->index()); |
| 1061 return constant.ToRpoNumber(); |
| 1062 } |
| 1063 |
| 1034 private: | 1064 private: |
| 1035 friend std::ostream& operator<<(std::ostream& os, | 1065 friend std::ostream& operator<<(std::ostream& os, |
| 1036 const PrintableInstructionSequence& code); | 1066 const PrintableInstructionSequence& code); |
| 1037 | 1067 |
| 1038 typedef std::set<int, std::less<int>, ZoneIntAllocator> VirtualRegisterSet; | 1068 typedef std::set<int, std::less<int>, ZoneIntAllocator> VirtualRegisterSet; |
| 1039 | 1069 |
| 1040 Zone* const zone_; | 1070 Zone* const zone_; |
| 1041 InstructionBlocks* const instruction_blocks_; | 1071 InstructionBlocks* const instruction_blocks_; |
| 1042 IntVector block_starts_; | 1072 IntVector block_starts_; |
| 1043 ConstantMap constants_; | 1073 ConstantMap constants_; |
| 1044 ConstantDeque immediates_; | 1074 Immediates immediates_; |
| 1045 InstructionDeque instructions_; | 1075 InstructionDeque instructions_; |
| 1046 int next_virtual_register_; | 1076 int next_virtual_register_; |
| 1047 PointerMapDeque pointer_maps_; | 1077 PointerMapDeque pointer_maps_; |
| 1048 VirtualRegisterSet doubles_; | 1078 VirtualRegisterSet doubles_; |
| 1049 VirtualRegisterSet references_; | 1079 VirtualRegisterSet references_; |
| 1050 DeoptimizationVector deoptimization_entries_; | 1080 DeoptimizationVector deoptimization_entries_; |
| 1051 | 1081 |
| 1052 DISALLOW_COPY_AND_ASSIGN(InstructionSequence); | 1082 DISALLOW_COPY_AND_ASSIGN(InstructionSequence); |
| 1053 }; | 1083 }; |
| 1054 | 1084 |
| 1055 | 1085 |
| 1056 struct PrintableInstructionSequence { | 1086 struct PrintableInstructionSequence { |
| 1057 const RegisterConfiguration* register_configuration_; | 1087 const RegisterConfiguration* register_configuration_; |
| 1058 const InstructionSequence* sequence_; | 1088 const InstructionSequence* sequence_; |
| 1059 }; | 1089 }; |
| 1060 | 1090 |
| 1061 | 1091 |
| 1062 std::ostream& operator<<(std::ostream& os, | 1092 std::ostream& operator<<(std::ostream& os, |
| 1063 const PrintableInstructionSequence& code); | 1093 const PrintableInstructionSequence& code); |
| 1064 | 1094 |
| 1065 } // namespace compiler | 1095 } // namespace compiler |
| 1066 } // namespace internal | 1096 } // namespace internal |
| 1067 } // namespace v8 | 1097 } // namespace v8 |
| 1068 | 1098 |
| 1069 #endif // V8_COMPILER_INSTRUCTION_H_ | 1099 #endif // V8_COMPILER_INSTRUCTION_H_ |
| OLD | NEW |