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> |
11 #include <set> | 11 #include <set> |
12 | 12 |
13 #include "src/compiler/common-operator.h" | 13 #include "src/compiler/common-operator.h" |
14 #include "src/compiler/frame.h" | 14 #include "src/compiler/frame.h" |
15 #include "src/compiler/graph.h" | |
16 #include "src/compiler/instruction-codes.h" | 15 #include "src/compiler/instruction-codes.h" |
17 #include "src/compiler/opcodes.h" | 16 #include "src/compiler/opcodes.h" |
18 #include "src/compiler/schedule.h" | 17 #include "src/compiler/schedule.h" |
18 #include "src/compiler/source-position.h" | |
19 // TODO(titzer): don't include the macro-assembler? | 19 // TODO(titzer): don't include the macro-assembler? |
20 #include "src/macro-assembler.h" | 20 #include "src/macro-assembler.h" |
21 #include "src/zone-allocator.h" | 21 #include "src/zone-allocator.h" |
22 | 22 |
23 namespace v8 { | 23 namespace v8 { |
24 namespace internal { | 24 namespace internal { |
25 namespace compiler { | 25 namespace compiler { |
26 | 26 |
27 // Forward declarations. | 27 // Forward declarations. |
28 class Linkage; | 28 class Linkage; |
(...skipping 560 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
589 friend std::ostream& operator<<(std::ostream& os, const Instruction& instr); | 589 friend std::ostream& operator<<(std::ostream& os, const Instruction& instr); |
590 ParallelMove* parallel_moves_[LAST_INNER_POSITION + 1]; | 590 ParallelMove* parallel_moves_[LAST_INNER_POSITION + 1]; |
591 }; | 591 }; |
592 | 592 |
593 | 593 |
594 // This special kind of gap move instruction represents the beginning of a | 594 // This special kind of gap move instruction represents the beginning of a |
595 // block of code. | 595 // block of code. |
596 // TODO(titzer): move code_start and code_end from BasicBlock to here. | 596 // TODO(titzer): move code_start and code_end from BasicBlock to here. |
597 class BlockStartInstruction FINAL : public GapInstruction { | 597 class BlockStartInstruction FINAL : public GapInstruction { |
598 public: | 598 public: |
599 BasicBlock* block() const { return block_; } | |
600 Label* label() { return &label_; } | 599 Label* label() { return &label_; } |
600 BasicBlock::RpoNumber rpo_number() const { return rpo_number_; } | |
601 | 601 |
602 static BlockStartInstruction* New(Zone* zone, BasicBlock* block) { | 602 static BlockStartInstruction* New(Zone* zone, BasicBlock* block) { |
603 void* buffer = zone->New(sizeof(BlockStartInstruction)); | 603 void* buffer = zone->New(sizeof(BlockStartInstruction)); |
604 return new (buffer) BlockStartInstruction(block); | 604 return new (buffer) BlockStartInstruction(block); |
605 } | 605 } |
606 | 606 |
607 static BlockStartInstruction* cast(Instruction* instr) { | 607 static BlockStartInstruction* cast(Instruction* instr) { |
608 DCHECK(instr->IsBlockStart()); | 608 DCHECK(instr->IsBlockStart()); |
609 return static_cast<BlockStartInstruction*>(instr); | 609 return static_cast<BlockStartInstruction*>(instr); |
610 } | 610 } |
611 | 611 |
612 private: | 612 private: |
613 explicit BlockStartInstruction(BasicBlock* block) | 613 explicit BlockStartInstruction(BasicBlock* block) |
614 : GapInstruction(kBlockStartInstruction), block_(block) {} | 614 : GapInstruction(kBlockStartInstruction), |
615 rpo_number_(block->GetRpoNumber()) {} | |
615 | 616 |
616 BasicBlock* block_; | 617 BasicBlock::RpoNumber rpo_number_; |
617 Label label_; | 618 Label label_; |
618 }; | 619 }; |
619 | 620 |
620 | 621 |
621 class SourcePositionInstruction FINAL : public Instruction { | 622 class SourcePositionInstruction FINAL : public Instruction { |
622 public: | 623 public: |
623 static SourcePositionInstruction* New(Zone* zone, SourcePosition position) { | 624 static SourcePositionInstruction* New(Zone* zone, SourcePosition position) { |
624 void* buffer = zone->New(sizeof(SourcePositionInstruction)); | 625 void* buffer = zone->New(sizeof(SourcePositionInstruction)); |
625 return new (buffer) SourcePositionInstruction(position); | 626 return new (buffer) SourcePositionInstruction(position); |
626 } | 627 } |
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
774 } | 775 } |
775 | 776 |
776 BasicBlock* BlockAt(int rpo_number) const { | 777 BasicBlock* BlockAt(int rpo_number) const { |
777 return (*schedule_->rpo_order())[rpo_number]; | 778 return (*schedule_->rpo_order())[rpo_number]; |
778 } | 779 } |
779 | 780 |
780 BasicBlock* GetContainingLoop(BasicBlock* block) { | 781 BasicBlock* GetContainingLoop(BasicBlock* block) { |
781 return block->loop_header(); | 782 return block->loop_header(); |
782 } | 783 } |
783 | 784 |
784 int GetLoopEnd(BasicBlock* block) const { return block->loop_end(); } | |
785 | |
786 BasicBlock* GetBasicBlock(int instruction_index); | 785 BasicBlock* GetBasicBlock(int instruction_index); |
787 | 786 |
788 int GetVirtualRegister(const Node* node); | 787 int GetVirtualRegister(const Node* node); |
789 // TODO(dcarney): find a way to remove this. | 788 // TODO(dcarney): find a way to remove this. |
790 const int* GetNodeMapForTesting() const { return node_map_; } | 789 const int* GetNodeMapForTesting() const { return node_map_; } |
791 | 790 |
792 bool IsReference(int virtual_register) const; | 791 bool IsReference(int virtual_register) const; |
793 bool IsDouble(int virtual_register) const; | 792 bool IsDouble(int virtual_register) const; |
794 | 793 |
795 void MarkAsReference(int virtual_register); | 794 void MarkAsReference(int virtual_register); |
796 void MarkAsDouble(int virtual_register); | 795 void MarkAsDouble(int virtual_register); |
797 | 796 |
798 void AddGapMove(int index, InstructionOperand* from, InstructionOperand* to); | 797 void AddGapMove(int index, InstructionOperand* from, InstructionOperand* to); |
799 | 798 |
800 Label* GetLabel(BasicBlock* block); | 799 Label* GetLabel(BasicBlock::RpoNumber rpo); |
801 BlockStartInstruction* GetBlockStart(BasicBlock* block); | 800 BlockStartInstruction* GetBlockStart(BasicBlock::RpoNumber rpo); |
802 | 801 |
803 typedef InstructionDeque::const_iterator const_iterator; | 802 typedef InstructionDeque::const_iterator const_iterator; |
804 const_iterator begin() const { return instructions_.begin(); } | 803 const_iterator begin() const { return instructions_.begin(); } |
805 const_iterator end() const { return instructions_.end(); } | 804 const_iterator end() const { return instructions_.end(); } |
806 | 805 |
807 GapInstruction* GapAt(int index) const { | 806 GapInstruction* GapAt(int index) const { |
808 return GapInstruction::cast(InstructionAt(index)); | 807 return GapInstruction::cast(InstructionAt(index)); |
809 } | 808 } |
810 bool IsGapAt(int index) const { return InstructionAt(index)->IsGapMoves(); } | 809 bool IsGapAt(int index) const { return InstructionAt(index)->IsGapMoves(); } |
811 Instruction* InstructionAt(int index) const { | 810 Instruction* InstructionAt(int index) const { |
812 DCHECK(index >= 0); | 811 DCHECK(index >= 0); |
813 DCHECK(index < static_cast<int>(instructions_.size())); | 812 DCHECK(index < static_cast<int>(instructions_.size())); |
814 return instructions_[index]; | 813 return instructions_[index]; |
815 } | 814 } |
816 | 815 |
817 Frame* frame() { return &frame_; } | 816 Frame* frame() { return &frame_; } |
818 Isolate* isolate() const { return zone()->isolate(); } | 817 Isolate* isolate() const { return zone()->isolate(); } |
819 Linkage* linkage() const { return linkage_; } | 818 Linkage* linkage() const { return linkage_; } |
820 Schedule* schedule() const { return schedule_; } | 819 Schedule* schedule() const { return schedule_; } |
821 const PointerMapDeque* pointer_maps() const { return &pointer_maps_; } | 820 const PointerMapDeque* pointer_maps() const { return &pointer_maps_; } |
822 Zone* zone() const { return zone_; } | 821 Zone* zone() const { return zone_; } |
823 | 822 |
824 // Used by the code generator while adding instructions. | 823 // Used by the instruction selector while adding instructions. |
825 int AddInstruction(Instruction* instr, BasicBlock* block); | 824 int AddInstruction(Instruction* instr); |
826 void StartBlock(BasicBlock* block); | 825 void StartBlock(BasicBlock* block); |
827 void EndBlock(BasicBlock* block); | 826 void EndBlock(BasicBlock* block); |
827 void set_code_start(BasicBlock* block, int start) { | |
828 return GetBlockData(block).set_code_start(start); | |
829 } | |
830 void set_code_end(BasicBlock* block, int end) { | |
831 return GetBlockData(block).set_code_end(end); | |
832 } | |
833 // TODO(dcarney): use RpoNumber for all of the below. | |
834 int code_start(BasicBlock::RpoNumber rpo_number) const { | |
835 return GetBlockData(rpo_number).code_start(); | |
836 } | |
837 int code_start(BasicBlock* block) const { | |
838 return GetBlockData(block).code_start(); | |
839 } | |
840 int code_end(BasicBlock* block) const { | |
841 return GetBlockData(block).code_end(); | |
842 } | |
843 int first_instruction_index(BasicBlock* block) const { | |
844 return GetBlockData(block).first_instruction_index(); | |
845 } | |
846 int last_instruction_index(BasicBlock* block) const { | |
847 return GetBlockData(block).last_instruction_index(); | |
848 } | |
828 | 849 |
829 int AddConstant(Node* node, Constant constant) { | 850 int AddConstant(Node* node, Constant constant) { |
830 int virtual_register = GetVirtualRegister(node); | 851 int virtual_register = GetVirtualRegister(node); |
831 DCHECK(constants_.find(virtual_register) == constants_.end()); | 852 DCHECK(constants_.find(virtual_register) == constants_.end()); |
832 constants_.insert(std::make_pair(virtual_register, constant)); | 853 constants_.insert(std::make_pair(virtual_register, constant)); |
833 return virtual_register; | 854 return virtual_register; |
834 } | 855 } |
835 Constant GetConstant(int virtual_register) const { | 856 Constant GetConstant(int virtual_register) const { |
836 ConstantMap::const_iterator it = constants_.find(virtual_register); | 857 ConstantMap::const_iterator it = constants_.find(virtual_register); |
837 DCHECK(it != constants_.end()); | 858 DCHECK(it != constants_.end()); |
(...skipping 23 matching lines...) Expand all Loading... | |
861 private: | 882 private: |
862 explicit StateId(int id) : id_(id) {} | 883 explicit StateId(int id) : id_(id) {} |
863 int id_; | 884 int id_; |
864 }; | 885 }; |
865 | 886 |
866 StateId AddFrameStateDescriptor(FrameStateDescriptor* descriptor); | 887 StateId AddFrameStateDescriptor(FrameStateDescriptor* descriptor); |
867 FrameStateDescriptor* GetFrameStateDescriptor(StateId deoptimization_id); | 888 FrameStateDescriptor* GetFrameStateDescriptor(StateId deoptimization_id); |
868 int GetFrameStateDescriptorCount(); | 889 int GetFrameStateDescriptorCount(); |
869 | 890 |
870 private: | 891 private: |
892 class BlockData { | |
893 public: | |
894 BlockData() : code_start_(-1), code_end_(-1) {} | |
895 // Instruction indexes (used by the register allocator). | |
896 int first_instruction_index() const { | |
897 DCHECK(code_start_ >= 0); | |
898 DCHECK(code_end_ > 0); | |
899 DCHECK(code_end_ >= code_start_); | |
900 return code_start_; | |
901 } | |
902 int last_instruction_index() const { | |
903 DCHECK(code_start_ >= 0); | |
904 DCHECK(code_end_ > 0); | |
905 DCHECK(code_end_ >= code_start_); | |
906 return code_end_ - 1; | |
907 } | |
908 | |
909 int32_t code_start() const { return code_start_; } | |
910 void set_code_start(int32_t start) { code_start_ = start; } | |
911 | |
912 int32_t code_end() const { return code_end_; } | |
913 void set_code_end(int32_t end) { code_end_ = end; } | |
914 | |
915 private: | |
916 int32_t code_start_; // start index of arch-specific code. | |
917 int32_t code_end_; // end index of arch-specific code. | |
918 }; | |
919 | |
920 const BlockData& GetBlockData(BasicBlock::RpoNumber rpo_number) const { | |
921 return block_data_[rpo_number.ToSize()]; | |
922 } | |
923 const BlockData& GetBlockData(BasicBlock* block) const { | |
Benedikt Meurer
2014/10/14 03:44:13
Can we avoid adding this wrapper function?
Benedikt Meurer
2014/10/14 03:44:13
Can we avoid adding this wrapper function?
dcarney
2014/10/14 08:14:37
Done.
| |
924 return GetBlockData(block->GetRpoNumber()); | |
925 } | |
926 BlockData& GetBlockData(BasicBlock::RpoNumber rpo_number) { | |
927 return block_data_[rpo_number.ToSize()]; | |
928 } | |
929 BlockData& GetBlockData(BasicBlock* block) { | |
Benedikt Meurer
2014/10/14 03:44:13
Can we avoid adding this wrapper function?
dcarney
2014/10/14 08:14:37
Done.
| |
930 return GetBlockData(block->GetRpoNumber()); | |
931 } | |
932 | |
871 friend std::ostream& operator<<(std::ostream& os, | 933 friend std::ostream& operator<<(std::ostream& os, |
872 const InstructionSequence& code); | 934 const InstructionSequence& code); |
873 | 935 |
874 typedef std::set<int, std::less<int>, ZoneIntAllocator> VirtualRegisterSet; | 936 typedef std::set<int, std::less<int>, ZoneIntAllocator> VirtualRegisterSet; |
937 typedef ZoneVector<BlockData> BlockDataVector; | |
875 | 938 |
876 Zone* zone_; | 939 Zone* zone_; |
877 int node_count_; | 940 int node_count_; |
878 int* node_map_; | 941 int* node_map_; |
942 BlockDataVector block_data_; | |
879 Linkage* linkage_; | 943 Linkage* linkage_; |
880 Schedule* schedule_; | 944 Schedule* schedule_; |
881 ConstantMap constants_; | 945 ConstantMap constants_; |
882 ConstantDeque immediates_; | 946 ConstantDeque immediates_; |
883 InstructionDeque instructions_; | 947 InstructionDeque instructions_; |
884 int next_virtual_register_; | 948 int next_virtual_register_; |
885 PointerMapDeque pointer_maps_; | 949 PointerMapDeque pointer_maps_; |
886 VirtualRegisterSet doubles_; | 950 VirtualRegisterSet doubles_; |
887 VirtualRegisterSet references_; | 951 VirtualRegisterSet references_; |
888 Frame frame_; | 952 Frame frame_; |
889 DeoptimizationVector deoptimization_entries_; | 953 DeoptimizationVector deoptimization_entries_; |
890 }; | 954 }; |
891 | 955 |
892 std::ostream& operator<<(std::ostream& os, const InstructionSequence& code); | 956 std::ostream& operator<<(std::ostream& os, const InstructionSequence& code); |
893 | 957 |
894 } // namespace compiler | 958 } // namespace compiler |
895 } // namespace internal | 959 } // namespace internal |
896 } // namespace v8 | 960 } // namespace v8 |
897 | 961 |
898 #endif // V8_COMPILER_INSTRUCTION_H_ | 962 #endif // V8_COMPILER_INSTRUCTION_H_ |
OLD | NEW |