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 735 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
746 size_t parameters_count_; | 746 size_t parameters_count_; |
747 size_t locals_count_; | 747 size_t locals_count_; |
748 size_t stack_count_; | 748 size_t stack_count_; |
749 ZoneVector<MachineType> types_; | 749 ZoneVector<MachineType> types_; |
750 FrameStateDescriptor* outer_state_; | 750 FrameStateDescriptor* outer_state_; |
751 MaybeHandle<JSFunction> jsfunction_; | 751 MaybeHandle<JSFunction> jsfunction_; |
752 }; | 752 }; |
753 | 753 |
754 std::ostream& operator<<(std::ostream& os, const Constant& constant); | 754 std::ostream& operator<<(std::ostream& os, const Constant& constant); |
755 | 755 |
| 756 |
| 757 // TODO(dcarney): this is a temporary hack. turn into an actual instruction. |
| 758 class PhiInstruction : public ZoneObject { |
| 759 public: |
| 760 PhiInstruction(Zone* zone, int virtual_register) |
| 761 : virtual_register_(virtual_register), operands_(zone) {} |
| 762 |
| 763 int virtual_register() const { return virtual_register_; } |
| 764 const IntVector& operands() const { return operands_; } |
| 765 IntVector& operands() { return operands_; } |
| 766 |
| 767 private: |
| 768 const int virtual_register_; |
| 769 IntVector operands_; |
| 770 }; |
| 771 |
| 772 |
| 773 // Analogue of BasicBlock for Instructions instead of Nodes. |
| 774 class InstructionBlock : public ZoneObject { |
| 775 public: |
| 776 explicit InstructionBlock(Zone* zone, const BasicBlock* block); |
| 777 |
| 778 // Instruction indexes (used by the register allocator). |
| 779 int first_instruction_index() const { |
| 780 DCHECK(code_start_ >= 0); |
| 781 DCHECK(code_end_ > 0); |
| 782 DCHECK(code_end_ >= code_start_); |
| 783 return code_start_; |
| 784 } |
| 785 int last_instruction_index() const { |
| 786 DCHECK(code_start_ >= 0); |
| 787 DCHECK(code_end_ > 0); |
| 788 DCHECK(code_end_ >= code_start_); |
| 789 return code_end_ - 1; |
| 790 } |
| 791 |
| 792 int32_t code_start() const { return code_start_; } |
| 793 void set_code_start(int32_t start) { code_start_ = start; } |
| 794 |
| 795 int32_t code_end() const { return code_end_; } |
| 796 void set_code_end(int32_t end) { code_end_ = end; } |
| 797 |
| 798 BasicBlock::RpoNumber rpo_number() const { return rpo_number_; } |
| 799 BasicBlock::RpoNumber loop_header() const { return loop_header_; } |
| 800 BasicBlock::RpoNumber loop_end() const { |
| 801 DCHECK(IsLoopHeader()); |
| 802 return loop_end_; |
| 803 } |
| 804 inline bool IsLoopHeader() const { return loop_end_.IsValid(); } |
| 805 |
| 806 typedef ZoneVector<BasicBlock::RpoNumber> Predecessors; |
| 807 Predecessors::const_iterator predecessors_begin() const { |
| 808 return predecessors_.begin(); |
| 809 } |
| 810 Predecessors::const_iterator predecessors_end() const { |
| 811 return predecessors_.end(); |
| 812 } |
| 813 size_t PredecessorCount() const { return predecessors_.size(); } |
| 814 BasicBlock::RpoNumber PredecessorAt(size_t index) const { |
| 815 return predecessors_[index]; |
| 816 } |
| 817 size_t PredecessorIndexOf(BasicBlock::RpoNumber rpo_number) const; |
| 818 |
| 819 typedef ZoneVector<BasicBlock::RpoNumber> Successors; |
| 820 size_t SuccessorCount() const { return successors_.size(); } |
| 821 Successors::const_iterator successors_begin() const { |
| 822 return successors_.begin(); |
| 823 } |
| 824 Successors::const_iterator successors_end() const { |
| 825 return successors_.end(); |
| 826 } |
| 827 |
| 828 typedef ZoneVector<PhiInstruction*> PhiInstructions; |
| 829 PhiInstructions::const_iterator phis_begin() const { return phis_.begin(); } |
| 830 PhiInstructions::const_iterator phis_end() const { return phis_.end(); } |
| 831 void AddPhi(PhiInstruction* phi); |
| 832 |
| 833 private: |
| 834 Successors successors_; |
| 835 Predecessors predecessors_; |
| 836 PhiInstructions phis_; |
| 837 // TODO(dcarney): probably dont't need this. |
| 838 BasicBlock::RpoNumber rpo_number_; |
| 839 BasicBlock::RpoNumber loop_header_; |
| 840 BasicBlock::RpoNumber loop_end_; |
| 841 int32_t code_start_; // start index of arch-specific code. |
| 842 int32_t code_end_; // end index of arch-specific code. |
| 843 }; |
| 844 |
756 typedef ZoneDeque<Constant> ConstantDeque; | 845 typedef ZoneDeque<Constant> ConstantDeque; |
757 typedef std::map<int, Constant, std::less<int>, | 846 typedef std::map<int, Constant, std::less<int>, |
758 zone_allocator<std::pair<int, Constant> > > ConstantMap; | 847 zone_allocator<std::pair<int, Constant> > > ConstantMap; |
759 | 848 |
760 typedef ZoneDeque<Instruction*> InstructionDeque; | 849 typedef ZoneDeque<Instruction*> InstructionDeque; |
761 typedef ZoneDeque<PointerMap*> PointerMapDeque; | 850 typedef ZoneDeque<PointerMap*> PointerMapDeque; |
762 typedef ZoneVector<FrameStateDescriptor*> DeoptimizationVector; | 851 typedef ZoneVector<FrameStateDescriptor*> DeoptimizationVector; |
| 852 typedef ZoneVector<InstructionBlock*> InstructionBlocks; |
763 | 853 |
764 // Represents architecture-specific generated code before, during, and after | 854 // Represents architecture-specific generated code before, during, and after |
765 // register allocation. | 855 // register allocation. |
766 // TODO(titzer): s/IsDouble/IsFloat64/ | 856 // TODO(titzer): s/IsDouble/IsFloat64/ |
767 class InstructionSequence FINAL { | 857 class InstructionSequence FINAL { |
768 public: | 858 public: |
769 InstructionSequence(Linkage* linkage, Graph* graph, Schedule* schedule); | 859 InstructionSequence(Linkage* linkage, Graph* graph, Schedule* schedule); |
770 | 860 |
771 int NextVirtualRegister() { return next_virtual_register_++; } | 861 int NextVirtualRegister() { return next_virtual_register_++; } |
772 int VirtualRegisterCount() const { return next_virtual_register_; } | 862 int VirtualRegisterCount() const { return next_virtual_register_; } |
773 | 863 |
774 int node_count() const { return node_count_; } | 864 int node_count() const { return node_count_; } |
775 | 865 |
776 int BasicBlockCount() const { | 866 int BasicBlockCount() const { |
777 return static_cast<int>(schedule_->rpo_order()->size()); | 867 return static_cast<int>(instruction_blocks_.size()); |
778 } | 868 } |
779 | 869 |
780 BasicBlock* BlockAt(int rpo_number) const { | 870 BasicBlock* BlockAt(int rpo_number) const { |
781 return (*schedule_->rpo_order())[rpo_number]; | 871 return (*schedule_->rpo_order())[rpo_number]; |
782 } | 872 } |
783 | 873 |
784 BasicBlock* GetContainingLoop(BasicBlock* block) { | 874 InstructionBlock* InstructionBlockAt(BasicBlock::RpoNumber rpo_number) { |
785 return block->loop_header(); | 875 return GetBlock(rpo_number); |
| 876 } |
| 877 |
| 878 const InstructionBlock* InstructionBlockAt( |
| 879 BasicBlock::RpoNumber rpo_number) const { |
| 880 return GetBlock(rpo_number); |
| 881 } |
| 882 |
| 883 // TODO(dcarney): move to register allocator. |
| 884 const InstructionBlock* GetContainingLoop( |
| 885 const InstructionBlock* block) const { |
| 886 BasicBlock::RpoNumber index = block->loop_header(); |
| 887 if (!index.IsValid()) return NULL; |
| 888 return instruction_blocks_[index.ToInt()]; |
786 } | 889 } |
787 | 890 |
788 BasicBlock* GetBasicBlock(int instruction_index); | 891 BasicBlock* GetBasicBlock(int instruction_index); |
| 892 const InstructionBlock* GetInstructionBlock(int instruction_index) const; |
789 | 893 |
790 int GetVirtualRegister(const Node* node); | 894 int GetVirtualRegister(const Node* node); |
791 // TODO(dcarney): find a way to remove this. | 895 // TODO(dcarney): find a way to remove this. |
792 const int* GetNodeMapForTesting() const { return node_map_; } | 896 const int* GetNodeMapForTesting() const { return node_map_; } |
793 | 897 |
794 bool IsReference(int virtual_register) const; | 898 bool IsReference(int virtual_register) const; |
795 bool IsDouble(int virtual_register) const; | 899 bool IsDouble(int virtual_register) const; |
796 | 900 |
797 void MarkAsReference(int virtual_register); | 901 void MarkAsReference(int virtual_register); |
798 void MarkAsDouble(int virtual_register); | 902 void MarkAsDouble(int virtual_register); |
(...skipping 22 matching lines...) Expand all Loading... |
821 Linkage* linkage() const { return linkage_; } | 925 Linkage* linkage() const { return linkage_; } |
822 Schedule* schedule() const { return schedule_; } | 926 Schedule* schedule() const { return schedule_; } |
823 const PointerMapDeque* pointer_maps() const { return &pointer_maps_; } | 927 const PointerMapDeque* pointer_maps() const { return &pointer_maps_; } |
824 Zone* zone() const { return zone_; } | 928 Zone* zone() const { return zone_; } |
825 | 929 |
826 // Used by the instruction selector while adding instructions. | 930 // Used by the instruction selector while adding instructions. |
827 int AddInstruction(Instruction* instr); | 931 int AddInstruction(Instruction* instr); |
828 void StartBlock(BasicBlock* block); | 932 void StartBlock(BasicBlock* block); |
829 void EndBlock(BasicBlock* block); | 933 void EndBlock(BasicBlock* block); |
830 void set_code_start(BasicBlock* block, int start) { | 934 void set_code_start(BasicBlock* block, int start) { |
831 return GetBlockData(block->GetRpoNumber()).set_code_start(start); | 935 return GetBlock(block->GetRpoNumber())->set_code_start(start); |
832 } | 936 } |
833 void set_code_end(BasicBlock* block, int end) { | 937 void set_code_end(BasicBlock* block, int end) { |
834 return GetBlockData(block->GetRpoNumber()).set_code_end(end); | 938 return GetBlock(block->GetRpoNumber())->set_code_end(end); |
835 } | 939 } |
836 // TODO(dcarney): use RpoNumber for all of the below. | 940 // TODO(dcarney): use RpoNumber for all of the below. |
837 int code_start(BasicBlock::RpoNumber rpo_number) const { | 941 int code_start(BasicBlock::RpoNumber rpo_number) const { |
838 return GetBlockData(rpo_number).code_start(); | 942 return GetBlock(rpo_number)->code_start(); |
839 } | 943 } |
840 int code_start(BasicBlock* block) const { | 944 int code_start(BasicBlock* block) const { |
841 return GetBlockData(block->GetRpoNumber()).code_start(); | 945 return GetBlock(block->GetRpoNumber())->code_start(); |
842 } | 946 } |
843 int code_end(BasicBlock* block) const { | 947 int code_end(BasicBlock* block) const { |
844 return GetBlockData(block->GetRpoNumber()).code_end(); | 948 return GetBlock(block->GetRpoNumber())->code_end(); |
845 } | 949 } |
846 int first_instruction_index(BasicBlock* block) const { | 950 int first_instruction_index(BasicBlock* block) const { |
847 return GetBlockData(block->GetRpoNumber()).first_instruction_index(); | 951 return GetBlock(block->GetRpoNumber())->first_instruction_index(); |
848 } | 952 } |
849 int last_instruction_index(BasicBlock* block) const { | 953 int last_instruction_index(BasicBlock* block) const { |
850 return GetBlockData(block->GetRpoNumber()).last_instruction_index(); | 954 return GetBlock(block->GetRpoNumber())->last_instruction_index(); |
| 955 } |
| 956 int first_instruction_index(InstructionBlock* block) const { |
| 957 return GetBlock(block->rpo_number())->first_instruction_index(); |
| 958 } |
| 959 int last_instruction_index(InstructionBlock* block) const { |
| 960 return GetBlock(block->rpo_number())->last_instruction_index(); |
851 } | 961 } |
852 | 962 |
853 int AddConstant(Node* node, Constant constant) { | 963 int AddConstant(Node* node, Constant constant) { |
854 int virtual_register = GetVirtualRegister(node); | 964 int virtual_register = GetVirtualRegister(node); |
855 DCHECK(constants_.find(virtual_register) == constants_.end()); | 965 DCHECK(constants_.find(virtual_register) == constants_.end()); |
856 constants_.insert(std::make_pair(virtual_register, constant)); | 966 constants_.insert(std::make_pair(virtual_register, constant)); |
857 return virtual_register; | 967 return virtual_register; |
858 } | 968 } |
859 Constant GetConstant(int virtual_register) const { | 969 Constant GetConstant(int virtual_register) const { |
860 ConstantMap::const_iterator it = constants_.find(virtual_register); | 970 ConstantMap::const_iterator it = constants_.find(virtual_register); |
(...skipping 24 matching lines...) Expand all Loading... |
885 private: | 995 private: |
886 explicit StateId(int id) : id_(id) {} | 996 explicit StateId(int id) : id_(id) {} |
887 int id_; | 997 int id_; |
888 }; | 998 }; |
889 | 999 |
890 StateId AddFrameStateDescriptor(FrameStateDescriptor* descriptor); | 1000 StateId AddFrameStateDescriptor(FrameStateDescriptor* descriptor); |
891 FrameStateDescriptor* GetFrameStateDescriptor(StateId deoptimization_id); | 1001 FrameStateDescriptor* GetFrameStateDescriptor(StateId deoptimization_id); |
892 int GetFrameStateDescriptorCount(); | 1002 int GetFrameStateDescriptorCount(); |
893 | 1003 |
894 private: | 1004 private: |
895 class BlockData { | 1005 InstructionBlock* GetBlock(BasicBlock::RpoNumber rpo_number) const { |
896 public: | 1006 return instruction_blocks_[rpo_number.ToSize()]; |
897 BlockData() : code_start_(-1), code_end_(-1) {} | |
898 // Instruction indexes (used by the register allocator). | |
899 int first_instruction_index() const { | |
900 DCHECK(code_start_ >= 0); | |
901 DCHECK(code_end_ > 0); | |
902 DCHECK(code_end_ >= code_start_); | |
903 return code_start_; | |
904 } | |
905 int last_instruction_index() const { | |
906 DCHECK(code_start_ >= 0); | |
907 DCHECK(code_end_ > 0); | |
908 DCHECK(code_end_ >= code_start_); | |
909 return code_end_ - 1; | |
910 } | |
911 | |
912 int32_t code_start() const { return code_start_; } | |
913 void set_code_start(int32_t start) { code_start_ = start; } | |
914 | |
915 int32_t code_end() const { return code_end_; } | |
916 void set_code_end(int32_t end) { code_end_ = end; } | |
917 | |
918 private: | |
919 int32_t code_start_; // start index of arch-specific code. | |
920 int32_t code_end_; // end index of arch-specific code. | |
921 }; | |
922 | |
923 const BlockData& GetBlockData(BasicBlock::RpoNumber rpo_number) const { | |
924 return block_data_[rpo_number.ToSize()]; | |
925 } | |
926 BlockData& GetBlockData(BasicBlock::RpoNumber rpo_number) { | |
927 return block_data_[rpo_number.ToSize()]; | |
928 } | 1007 } |
929 | 1008 |
930 friend std::ostream& operator<<(std::ostream& os, | 1009 friend std::ostream& operator<<(std::ostream& os, |
931 const InstructionSequence& code); | 1010 const InstructionSequence& code); |
932 | 1011 |
933 typedef std::set<int, std::less<int>, ZoneIntAllocator> VirtualRegisterSet; | 1012 typedef std::set<int, std::less<int>, ZoneIntAllocator> VirtualRegisterSet; |
934 typedef ZoneVector<BlockData> BlockDataVector; | |
935 | 1013 |
936 Zone* zone_; | 1014 Zone* zone_; |
937 int node_count_; | 1015 int node_count_; |
938 int* node_map_; | 1016 int* node_map_; |
939 BlockDataVector block_data_; | 1017 InstructionBlocks instruction_blocks_; |
940 Linkage* linkage_; | 1018 Linkage* linkage_; |
941 Schedule* schedule_; | 1019 Schedule* schedule_; |
942 ConstantMap constants_; | 1020 ConstantMap constants_; |
943 ConstantDeque immediates_; | 1021 ConstantDeque immediates_; |
944 InstructionDeque instructions_; | 1022 InstructionDeque instructions_; |
945 int next_virtual_register_; | 1023 int next_virtual_register_; |
946 PointerMapDeque pointer_maps_; | 1024 PointerMapDeque pointer_maps_; |
947 VirtualRegisterSet doubles_; | 1025 VirtualRegisterSet doubles_; |
948 VirtualRegisterSet references_; | 1026 VirtualRegisterSet references_; |
949 Frame frame_; | 1027 Frame frame_; |
950 DeoptimizationVector deoptimization_entries_; | 1028 DeoptimizationVector deoptimization_entries_; |
951 }; | 1029 }; |
952 | 1030 |
953 std::ostream& operator<<(std::ostream& os, const InstructionSequence& code); | 1031 std::ostream& operator<<(std::ostream& os, const InstructionSequence& code); |
954 | 1032 |
955 } // namespace compiler | 1033 } // namespace compiler |
956 } // namespace internal | 1034 } // namespace internal |
957 } // namespace v8 | 1035 } // namespace v8 |
958 | 1036 |
959 #endif // V8_COMPILER_INSTRUCTION_H_ | 1037 #endif // V8_COMPILER_INSTRUCTION_H_ |
OLD | NEW |