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 |