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->GetRpoNumber()).set_code_start(start); |
| 829 } |
| 830 void set_code_end(BasicBlock* block, int end) { |
| 831 return GetBlockData(block->GetRpoNumber()).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->GetRpoNumber()).code_start(); |
| 839 } |
| 840 int code_end(BasicBlock* block) const { |
| 841 return GetBlockData(block->GetRpoNumber()).code_end(); |
| 842 } |
| 843 int first_instruction_index(BasicBlock* block) const { |
| 844 return GetBlockData(block->GetRpoNumber()).first_instruction_index(); |
| 845 } |
| 846 int last_instruction_index(BasicBlock* block) const { |
| 847 return GetBlockData(block->GetRpoNumber()).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 BlockData& GetBlockData(BasicBlock::RpoNumber rpo_number) { |
| 924 return block_data_[rpo_number.ToSize()]; |
| 925 } |
| 926 |
871 friend std::ostream& operator<<(std::ostream& os, | 927 friend std::ostream& operator<<(std::ostream& os, |
872 const InstructionSequence& code); | 928 const InstructionSequence& code); |
873 | 929 |
874 typedef std::set<int, std::less<int>, ZoneIntAllocator> VirtualRegisterSet; | 930 typedef std::set<int, std::less<int>, ZoneIntAllocator> VirtualRegisterSet; |
| 931 typedef ZoneVector<BlockData> BlockDataVector; |
875 | 932 |
876 Zone* zone_; | 933 Zone* zone_; |
877 int node_count_; | 934 int node_count_; |
878 int* node_map_; | 935 int* node_map_; |
| 936 BlockDataVector block_data_; |
879 Linkage* linkage_; | 937 Linkage* linkage_; |
880 Schedule* schedule_; | 938 Schedule* schedule_; |
881 ConstantMap constants_; | 939 ConstantMap constants_; |
882 ConstantDeque immediates_; | 940 ConstantDeque immediates_; |
883 InstructionDeque instructions_; | 941 InstructionDeque instructions_; |
884 int next_virtual_register_; | 942 int next_virtual_register_; |
885 PointerMapDeque pointer_maps_; | 943 PointerMapDeque pointer_maps_; |
886 VirtualRegisterSet doubles_; | 944 VirtualRegisterSet doubles_; |
887 VirtualRegisterSet references_; | 945 VirtualRegisterSet references_; |
888 Frame frame_; | 946 Frame frame_; |
889 DeoptimizationVector deoptimization_entries_; | 947 DeoptimizationVector deoptimization_entries_; |
890 }; | 948 }; |
891 | 949 |
892 std::ostream& operator<<(std::ostream& os, const InstructionSequence& code); | 950 std::ostream& operator<<(std::ostream& os, const InstructionSequence& code); |
893 | 951 |
894 } // namespace compiler | 952 } // namespace compiler |
895 } // namespace internal | 953 } // namespace internal |
896 } // namespace v8 | 954 } // namespace v8 |
897 | 955 |
898 #endif // V8_COMPILER_INSTRUCTION_H_ | 956 #endif // V8_COMPILER_INSTRUCTION_H_ |
OLD | NEW |