| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef VM_INTERMEDIATE_LANGUAGE_H_ | 5 #ifndef VM_INTERMEDIATE_LANGUAGE_H_ |
| 6 #define VM_INTERMEDIATE_LANGUAGE_H_ | 6 #define VM_INTERMEDIATE_LANGUAGE_H_ |
| 7 | 7 |
| 8 #include "vm/allocation.h" | 8 #include "vm/allocation.h" |
| 9 #include "vm/ast.h" | 9 #include "vm/ast.h" |
| 10 #include "vm/growable_array.h" | 10 #include "vm/growable_array.h" |
| (...skipping 637 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 648 virtual BlockEntryInstr* PredecessorAt(intptr_t index) const = 0; | 648 virtual BlockEntryInstr* PredecessorAt(intptr_t index) const = 0; |
| 649 virtual void PrepareEntry(FlowGraphCompiler* compiler) = 0; | 649 virtual void PrepareEntry(FlowGraphCompiler* compiler) = 0; |
| 650 | 650 |
| 651 intptr_t preorder_number() const { return preorder_number_; } | 651 intptr_t preorder_number() const { return preorder_number_; } |
| 652 void set_preorder_number(intptr_t number) { preorder_number_ = number; } | 652 void set_preorder_number(intptr_t number) { preorder_number_ = number; } |
| 653 | 653 |
| 654 intptr_t postorder_number() const { return postorder_number_; } | 654 intptr_t postorder_number() const { return postorder_number_; } |
| 655 void set_postorder_number(intptr_t number) { postorder_number_ = number; } | 655 void set_postorder_number(intptr_t number) { postorder_number_ = number; } |
| 656 | 656 |
| 657 intptr_t block_id() const { return block_id_; } | 657 intptr_t block_id() const { return block_id_; } |
| 658 void set_block_id(intptr_t value) { block_id_ = value; } | |
| 659 | 658 |
| 660 void set_start_pos(intptr_t pos) { start_pos_ = pos; } | 659 void set_start_pos(intptr_t pos) { start_pos_ = pos; } |
| 661 intptr_t start_pos() const { return start_pos_; } | 660 intptr_t start_pos() const { return start_pos_; } |
| 662 void set_end_pos(intptr_t pos) { end_pos_ = pos; } | 661 void set_end_pos(intptr_t pos) { end_pos_ = pos; } |
| 663 intptr_t end_pos() const { return end_pos_; } | 662 intptr_t end_pos() const { return end_pos_; } |
| 664 | 663 |
| 665 BlockEntryInstr* dominator() const { return dominator_; } | 664 BlockEntryInstr* dominator() const { return dominator_; } |
| 666 void set_dominator(BlockEntryInstr* instr) { dominator_ = instr; } | 665 void set_dominator(BlockEntryInstr* instr) { dominator_ = instr; } |
| 667 | 666 |
| 668 const GrowableArray<BlockEntryInstr*>& dominated_blocks() { | 667 const GrowableArray<BlockEntryInstr*>& dominated_blocks() { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 717 virtual bool HasSideEffect() const { return false; } | 716 virtual bool HasSideEffect() const { return false; } |
| 718 | 717 |
| 719 intptr_t try_index() const { return try_index_; } | 718 intptr_t try_index() const { return try_index_; } |
| 720 | 719 |
| 721 BitVector* loop_info() const { return loop_info_; } | 720 BitVector* loop_info() const { return loop_info_; } |
| 722 void set_loop_info(BitVector* loop_info) { | 721 void set_loop_info(BitVector* loop_info) { |
| 723 loop_info_ = loop_info; | 722 loop_info_ = loop_info; |
| 724 } | 723 } |
| 725 | 724 |
| 726 protected: | 725 protected: |
| 727 explicit BlockEntryInstr(intptr_t try_index) | 726 BlockEntryInstr(intptr_t block_id, intptr_t try_index) |
| 728 : try_index_(try_index), | 727 : block_id_(block_id), |
| 728 try_index_(try_index), |
| 729 preorder_number_(-1), | 729 preorder_number_(-1), |
| 730 postorder_number_(-1), | 730 postorder_number_(-1), |
| 731 block_id_(-1), | |
| 732 dominator_(NULL), | 731 dominator_(NULL), |
| 733 dominated_blocks_(1), | 732 dominated_blocks_(1), |
| 734 last_instruction_(NULL), | 733 last_instruction_(NULL), |
| 735 parallel_move_(NULL), | 734 parallel_move_(NULL), |
| 736 loop_info_(NULL) { } | 735 loop_info_(NULL) { } |
| 737 | 736 |
| 738 private: | 737 private: |
| 739 virtual void ClearPredecessors() = 0; | 738 virtual void ClearPredecessors() = 0; |
| 740 virtual void AddPredecessor(BlockEntryInstr* predecessor) = 0; | 739 virtual void AddPredecessor(BlockEntryInstr* predecessor) = 0; |
| 741 | 740 |
| 741 const intptr_t block_id_; |
| 742 const intptr_t try_index_; | 742 const intptr_t try_index_; |
| 743 intptr_t preorder_number_; | 743 intptr_t preorder_number_; |
| 744 intptr_t postorder_number_; | 744 intptr_t postorder_number_; |
| 745 // Starting and ending lifetime positions for this block. Used by | 745 // Starting and ending lifetime positions for this block. Used by |
| 746 // the linear scan register allocator. | 746 // the linear scan register allocator. |
| 747 intptr_t block_id_; | |
| 748 intptr_t start_pos_; | 747 intptr_t start_pos_; |
| 749 intptr_t end_pos_; | 748 intptr_t end_pos_; |
| 750 BlockEntryInstr* dominator_; // Immediate dominator, NULL for graph entry. | 749 BlockEntryInstr* dominator_; // Immediate dominator, NULL for graph entry. |
| 751 // TODO(fschneider): Optimize the case of one child to save space. | 750 // TODO(fschneider): Optimize the case of one child to save space. |
| 752 GrowableArray<BlockEntryInstr*> dominated_blocks_; | 751 GrowableArray<BlockEntryInstr*> dominated_blocks_; |
| 753 Instruction* last_instruction_; | 752 Instruction* last_instruction_; |
| 754 | 753 |
| 755 // Parallel move that will be used by linear scan register allocator to | 754 // Parallel move that will be used by linear scan register allocator to |
| 756 // connect live ranges at the start of the block. | 755 // connect live ranges at the start of the block. |
| 757 ParallelMoveInstr* parallel_move_; | 756 ParallelMoveInstr* parallel_move_; |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 867 GrowableArray<TargetEntryInstr*> catch_entries_; | 866 GrowableArray<TargetEntryInstr*> catch_entries_; |
| 868 GrowableArray<Definition*> initial_definitions_; | 867 GrowableArray<Definition*> initial_definitions_; |
| 869 intptr_t spill_slot_count_; | 868 intptr_t spill_slot_count_; |
| 870 | 869 |
| 871 DISALLOW_COPY_AND_ASSIGN(GraphEntryInstr); | 870 DISALLOW_COPY_AND_ASSIGN(GraphEntryInstr); |
| 872 }; | 871 }; |
| 873 | 872 |
| 874 | 873 |
| 875 class JoinEntryInstr : public BlockEntryInstr { | 874 class JoinEntryInstr : public BlockEntryInstr { |
| 876 public: | 875 public: |
| 877 explicit JoinEntryInstr(intptr_t try_index) | 876 JoinEntryInstr(intptr_t block_id, intptr_t try_index) |
| 878 : BlockEntryInstr(try_index), | 877 : BlockEntryInstr(block_id, try_index), |
| 879 predecessors_(2), // Two is the assumed to be the common case. | 878 predecessors_(2), // Two is the assumed to be the common case. |
| 880 phis_(NULL), | 879 phis_(NULL), |
| 881 phi_count_(0) { } | 880 phi_count_(0) { } |
| 882 | 881 |
| 883 DECLARE_INSTRUCTION(JoinEntry) | 882 DECLARE_INSTRUCTION(JoinEntry) |
| 884 | 883 |
| 885 virtual intptr_t PredecessorCount() const { return predecessors_.length(); } | 884 virtual intptr_t PredecessorCount() const { return predecessors_.length(); } |
| 886 virtual BlockEntryInstr* PredecessorAt(intptr_t index) const { | 885 virtual BlockEntryInstr* PredecessorAt(intptr_t index) const { |
| 887 return predecessors_[index]; | 886 return predecessors_[index]; |
| 888 } | 887 } |
| 889 | 888 |
| 890 // Returns -1 if pred is not in the list. | 889 // Returns -1 if pred is not in the list. |
| 891 intptr_t IndexOfPredecessor(BlockEntryInstr* pred) const; | 890 intptr_t IndexOfPredecessor(BlockEntryInstr* pred) const; |
| 892 | 891 |
| 893 ZoneGrowableArray<PhiInstr*>* phis() const { return phis_; } | 892 ZoneGrowableArray<PhiInstr*>* phis() const { return phis_; } |
| 894 | 893 |
| 895 virtual void PrepareEntry(FlowGraphCompiler* compiler); | 894 virtual void PrepareEntry(FlowGraphCompiler* compiler); |
| 896 | 895 |
| 897 void InsertPhi(intptr_t var_index, intptr_t var_count); | 896 void InsertPhi(intptr_t var_index, intptr_t var_count); |
| 898 void RemoveDeadPhis(); | 897 void RemoveDeadPhis(); |
| 899 | 898 |
| 900 intptr_t phi_count() const { return phi_count_; } | 899 intptr_t phi_count() const { return phi_count_; } |
| 901 | 900 |
| 902 virtual void PrintTo(BufferFormatter* f) const; | 901 virtual void PrintTo(BufferFormatter* f) const; |
| 903 virtual void PrintToVisualizer(BufferFormatter* f) const; | 902 virtual void PrintToVisualizer(BufferFormatter* f) const; |
| 904 | 903 |
| 905 // After recomputing predecessors to eliminate unreachable ones, | |
| 906 // reorganize phi inputs to match the predecessor order and to eliminate | |
| 907 // unreachable inputs. | |
| 908 void EliminateUnreachablePhiInputs(); | |
| 909 | |
| 910 private: | 904 private: |
| 911 virtual void ClearPredecessors() { | 905 virtual void ClearPredecessors() { predecessors_.Clear(); } |
| 912 // Keep a 'backup' of any existing predecessors to enable garbage | 906 virtual void AddPredecessor(BlockEntryInstr* predecessor); |
| 913 // collection of phis after eliminating unreachable code and recomputing | |
| 914 // predecessors. | |
| 915 stale_predecessors_.Clear(); | |
| 916 stale_predecessors_.AddArray(predecessors_); | |
| 917 predecessors_.Clear(); | |
| 918 } | |
| 919 virtual void AddPredecessor(BlockEntryInstr* predecessor) { | |
| 920 predecessors_.Add(predecessor); | |
| 921 } | |
| 922 | 907 |
| 923 GrowableArray<BlockEntryInstr*> predecessors_; | 908 GrowableArray<BlockEntryInstr*> predecessors_; |
| 924 ZoneGrowableArray<PhiInstr*>* phis_; | 909 ZoneGrowableArray<PhiInstr*>* phis_; |
| 925 intptr_t phi_count_; | 910 intptr_t phi_count_; |
| 926 GrowableArray<BlockEntryInstr*> stale_predecessors_; | |
| 927 | 911 |
| 928 DISALLOW_COPY_AND_ASSIGN(JoinEntryInstr); | 912 DISALLOW_COPY_AND_ASSIGN(JoinEntryInstr); |
| 929 }; | 913 }; |
| 930 | 914 |
| 931 | 915 |
| 932 class TargetEntryInstr : public BlockEntryInstr { | 916 class TargetEntryInstr : public BlockEntryInstr { |
| 933 public: | 917 public: |
| 934 explicit TargetEntryInstr(intptr_t try_index) | 918 TargetEntryInstr(intptr_t block_id, intptr_t try_index) |
| 935 : BlockEntryInstr(try_index), | 919 : BlockEntryInstr(block_id, try_index), |
| 936 predecessor_(NULL), | 920 predecessor_(NULL), |
| 937 catch_try_index_(CatchClauseNode::kInvalidTryIndex) { } | 921 catch_try_index_(CatchClauseNode::kInvalidTryIndex) { } |
| 938 | 922 |
| 939 // Used for exception catch entries. | |
| 940 TargetEntryInstr(intptr_t try_index, intptr_t catch_try_index) | |
| 941 : BlockEntryInstr(try_index), | |
| 942 predecessor_(NULL), | |
| 943 catch_try_index_(catch_try_index) { } | |
| 944 | |
| 945 DECLARE_INSTRUCTION(TargetEntry) | 923 DECLARE_INSTRUCTION(TargetEntry) |
| 946 | 924 |
| 947 virtual intptr_t PredecessorCount() const { | 925 virtual intptr_t PredecessorCount() const { |
| 948 return (predecessor_ == NULL) ? 0 : 1; | 926 return (predecessor_ == NULL) ? 0 : 1; |
| 949 } | 927 } |
| 950 virtual BlockEntryInstr* PredecessorAt(intptr_t index) const { | 928 virtual BlockEntryInstr* PredecessorAt(intptr_t index) const { |
| 951 ASSERT((index == 0) && (predecessor_ != NULL)); | 929 ASSERT((index == 0) && (predecessor_ != NULL)); |
| 952 return predecessor_; | 930 return predecessor_; |
| 953 } | 931 } |
| 954 | 932 |
| 955 // Returns true if this Block is an entry of a catch handler. | 933 // Returns true if this Block is an entry of a catch handler. |
| 956 bool IsCatchEntry() const { | 934 bool IsCatchEntry() const { |
| 957 return catch_try_index_ != CatchClauseNode::kInvalidTryIndex; | 935 return catch_try_index_ != CatchClauseNode::kInvalidTryIndex; |
| 958 } | 936 } |
| 959 | 937 |
| 960 // Returns try index for the try block to which this catch handler | 938 // Returns try index for the try block to which this catch handler |
| 961 // corresponds. | 939 // corresponds. |
| 962 intptr_t catch_try_index() const { | 940 intptr_t catch_try_index() const { |
| 963 ASSERT(IsCatchEntry()); | 941 ASSERT(IsCatchEntry()); |
| 964 return catch_try_index_; | 942 return catch_try_index_; |
| 965 } | 943 } |
| 944 void set_catch_try_index(intptr_t index) { catch_try_index_ = index; } |
| 966 | 945 |
| 967 virtual void PrepareEntry(FlowGraphCompiler* compiler); | 946 virtual void PrepareEntry(FlowGraphCompiler* compiler); |
| 968 | 947 |
| 969 virtual void PrintTo(BufferFormatter* f) const; | 948 virtual void PrintTo(BufferFormatter* f) const; |
| 970 virtual void PrintToVisualizer(BufferFormatter* f) const; | 949 virtual void PrintToVisualizer(BufferFormatter* f) const; |
| 971 | 950 |
| 972 private: | 951 private: |
| 973 virtual void ClearPredecessors() { predecessor_ = NULL; } | 952 virtual void ClearPredecessors() { predecessor_ = NULL; } |
| 974 virtual void AddPredecessor(BlockEntryInstr* predecessor) { | 953 virtual void AddPredecessor(BlockEntryInstr* predecessor) { |
| 975 ASSERT(predecessor_ == NULL); | 954 ASSERT(predecessor_ == NULL); |
| 976 predecessor_ = predecessor; | 955 predecessor_ = predecessor; |
| 977 } | 956 } |
| 978 | 957 |
| 979 BlockEntryInstr* predecessor_; | 958 BlockEntryInstr* predecessor_; |
| 980 const intptr_t catch_try_index_; | 959 intptr_t catch_try_index_; |
| 981 | 960 |
| 982 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr); | 961 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr); |
| 983 }; | 962 }; |
| 984 | 963 |
| 985 | 964 |
| 986 // Abstract super-class of all instructions that define a value (Bind, Phi). | 965 // Abstract super-class of all instructions that define a value (Bind, Phi). |
| 987 class Definition : public Instruction { | 966 class Definition : public Instruction { |
| 988 public: | 967 public: |
| 989 enum UseKind { kEffect, kValue }; | 968 enum UseKind { kEffect, kValue }; |
| 990 | 969 |
| (...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1120 virtual intptr_t GetPropagatedCid(); | 1099 virtual intptr_t GetPropagatedCid(); |
| 1121 | 1100 |
| 1122 virtual intptr_t ArgumentCount() const { return 0; } | 1101 virtual intptr_t ArgumentCount() const { return 0; } |
| 1123 | 1102 |
| 1124 intptr_t InputCount() const { return inputs_.length(); } | 1103 intptr_t InputCount() const { return inputs_.length(); } |
| 1125 | 1104 |
| 1126 Value* InputAt(intptr_t i) const { return inputs_[i]; } | 1105 Value* InputAt(intptr_t i) const { return inputs_[i]; } |
| 1127 | 1106 |
| 1128 void SetInputAt(intptr_t i, Value* value) { inputs_[i] = value; } | 1107 void SetInputAt(intptr_t i, Value* value) { inputs_[i] = value; } |
| 1129 | 1108 |
| 1109 void RemoveInputAt(intptr_t i) { inputs_.Remove(i); } |
| 1110 |
| 1130 virtual bool CanDeoptimize() const { return false; } | 1111 virtual bool CanDeoptimize() const { return false; } |
| 1131 | 1112 |
| 1132 virtual bool HasSideEffect() const { return false; } | 1113 virtual bool HasSideEffect() const { return false; } |
| 1133 | 1114 |
| 1134 // TODO(regis): This helper will be removed once we support type sets. | 1115 // TODO(regis): This helper will be removed once we support type sets. |
| 1135 RawAbstractType* LeastSpecificInputType() const; | 1116 RawAbstractType* LeastSpecificInputType() const; |
| 1136 | 1117 |
| 1137 // Phi is alive if it reaches a non-environment use. | 1118 // Phi is alive if it reaches a non-environment use. |
| 1138 bool is_alive() const { return is_alive_; } | 1119 bool is_alive() const { return is_alive_; } |
| 1139 void mark_alive() { is_alive_ = true; } | 1120 void mark_alive() { is_alive_ = true; } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 1159 UNREACHABLE(); | 1140 UNREACHABLE(); |
| 1160 return kIllegalCid; | 1141 return kIllegalCid; |
| 1161 } | 1142 } |
| 1162 | 1143 |
| 1163 DECLARE_INSTRUCTION(Phi) | 1144 DECLARE_INSTRUCTION(Phi) |
| 1164 | 1145 |
| 1165 virtual void PrintTo(BufferFormatter* f) const; | 1146 virtual void PrintTo(BufferFormatter* f) const; |
| 1166 virtual void PrintToVisualizer(BufferFormatter* f) const; | 1147 virtual void PrintToVisualizer(BufferFormatter* f) const; |
| 1167 | 1148 |
| 1168 private: | 1149 private: |
| 1169 friend class JoinEntryInstr; // Direct access to inputs_ array. | |
| 1170 | |
| 1171 JoinEntryInstr* block_; | 1150 JoinEntryInstr* block_; |
| 1172 GrowableArray<Value*> inputs_; | 1151 GrowableArray<Value*> inputs_; |
| 1173 bool is_alive_; | 1152 bool is_alive_; |
| 1174 Representation representation_; | 1153 Representation representation_; |
| 1175 | 1154 |
| 1176 DISALLOW_COPY_AND_ASSIGN(PhiInstr); | 1155 DISALLOW_COPY_AND_ASSIGN(PhiInstr); |
| 1177 }; | 1156 }; |
| 1178 | 1157 |
| 1179 | 1158 |
| 1180 class ParameterInstr : public Definition { | 1159 class ParameterInstr : public Definition { |
| (...skipping 2478 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3659 ForwardInstructionIterator* current_iterator_; | 3638 ForwardInstructionIterator* current_iterator_; |
| 3660 | 3639 |
| 3661 private: | 3640 private: |
| 3662 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 3641 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
| 3663 }; | 3642 }; |
| 3664 | 3643 |
| 3665 | 3644 |
| 3666 } // namespace dart | 3645 } // namespace dart |
| 3667 | 3646 |
| 3668 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 3647 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
| OLD | NEW |