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