| 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; } |
| 658 | 659 |
| 659 void set_start_pos(intptr_t pos) { start_pos_ = pos; } | 660 void set_start_pos(intptr_t pos) { start_pos_ = pos; } |
| 660 intptr_t start_pos() const { return start_pos_; } | 661 intptr_t start_pos() const { return start_pos_; } |
| 661 void set_end_pos(intptr_t pos) { end_pos_ = pos; } | 662 void set_end_pos(intptr_t pos) { end_pos_ = pos; } |
| 662 intptr_t end_pos() const { return end_pos_; } | 663 intptr_t end_pos() const { return end_pos_; } |
| 663 | 664 |
| 664 BlockEntryInstr* dominator() const { return dominator_; } | 665 BlockEntryInstr* dominator() const { return dominator_; } |
| 665 void set_dominator(BlockEntryInstr* instr) { dominator_ = instr; } | 666 void set_dominator(BlockEntryInstr* instr) { dominator_ = instr; } |
| 666 | 667 |
| 667 const GrowableArray<BlockEntryInstr*>& dominated_blocks() { | 668 const GrowableArray<BlockEntryInstr*>& dominated_blocks() { |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 716 virtual bool HasSideEffect() const { return false; } | 717 virtual bool HasSideEffect() const { return false; } |
| 717 | 718 |
| 718 intptr_t try_index() const { return try_index_; } | 719 intptr_t try_index() const { return try_index_; } |
| 719 | 720 |
| 720 BitVector* loop_info() const { return loop_info_; } | 721 BitVector* loop_info() const { return loop_info_; } |
| 721 void set_loop_info(BitVector* loop_info) { | 722 void set_loop_info(BitVector* loop_info) { |
| 722 loop_info_ = loop_info; | 723 loop_info_ = loop_info; |
| 723 } | 724 } |
| 724 | 725 |
| 725 protected: | 726 protected: |
| 726 BlockEntryInstr(intptr_t block_id, intptr_t try_index) | 727 explicit BlockEntryInstr(intptr_t try_index) |
| 727 : block_id_(block_id), | 728 : try_index_(try_index), |
| 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), |
| 731 dominator_(NULL), | 732 dominator_(NULL), |
| 732 dominated_blocks_(1), | 733 dominated_blocks_(1), |
| 733 last_instruction_(NULL), | 734 last_instruction_(NULL), |
| 734 parallel_move_(NULL), | 735 parallel_move_(NULL), |
| 735 loop_info_(NULL) { } | 736 loop_info_(NULL) { } |
| 736 | 737 |
| 737 private: | 738 private: |
| 738 virtual void ClearPredecessors() = 0; | 739 virtual void ClearPredecessors() = 0; |
| 739 virtual void AddPredecessor(BlockEntryInstr* predecessor) = 0; | 740 virtual void AddPredecessor(BlockEntryInstr* predecessor) = 0; |
| 740 | 741 |
| 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_; |
| 747 intptr_t start_pos_; | 748 intptr_t start_pos_; |
| 748 intptr_t end_pos_; | 749 intptr_t end_pos_; |
| 749 BlockEntryInstr* dominator_; // Immediate dominator, NULL for graph entry. | 750 BlockEntryInstr* dominator_; // Immediate dominator, NULL for graph entry. |
| 750 // TODO(fschneider): Optimize the case of one child to save space. | 751 // TODO(fschneider): Optimize the case of one child to save space. |
| 751 GrowableArray<BlockEntryInstr*> dominated_blocks_; | 752 GrowableArray<BlockEntryInstr*> dominated_blocks_; |
| 752 Instruction* last_instruction_; | 753 Instruction* last_instruction_; |
| 753 | 754 |
| 754 // Parallel move that will be used by linear scan register allocator to | 755 // Parallel move that will be used by linear scan register allocator to |
| 755 // connect live ranges at the start of the block. | 756 // connect live ranges at the start of the block. |
| 756 ParallelMoveInstr* parallel_move_; | 757 ParallelMoveInstr* parallel_move_; |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 866 GrowableArray<TargetEntryInstr*> catch_entries_; | 867 GrowableArray<TargetEntryInstr*> catch_entries_; |
| 867 GrowableArray<Definition*> initial_definitions_; | 868 GrowableArray<Definition*> initial_definitions_; |
| 868 intptr_t spill_slot_count_; | 869 intptr_t spill_slot_count_; |
| 869 | 870 |
| 870 DISALLOW_COPY_AND_ASSIGN(GraphEntryInstr); | 871 DISALLOW_COPY_AND_ASSIGN(GraphEntryInstr); |
| 871 }; | 872 }; |
| 872 | 873 |
| 873 | 874 |
| 874 class JoinEntryInstr : public BlockEntryInstr { | 875 class JoinEntryInstr : public BlockEntryInstr { |
| 875 public: | 876 public: |
| 876 JoinEntryInstr(intptr_t block_id, intptr_t try_index) | 877 explicit JoinEntryInstr(intptr_t try_index) |
| 877 : BlockEntryInstr(block_id, try_index), | 878 : BlockEntryInstr(try_index), |
| 878 predecessors_(2), // Two is the assumed to be the common case. | 879 predecessors_(2), // Two is the assumed to be the common case. |
| 879 phis_(NULL), | 880 phis_(NULL), |
| 880 phi_count_(0) { } | 881 phi_count_(0) { } |
| 881 | 882 |
| 882 DECLARE_INSTRUCTION(JoinEntry) | 883 DECLARE_INSTRUCTION(JoinEntry) |
| 883 | 884 |
| 884 virtual intptr_t PredecessorCount() const { return predecessors_.length(); } | 885 virtual intptr_t PredecessorCount() const { return predecessors_.length(); } |
| 885 virtual BlockEntryInstr* PredecessorAt(intptr_t index) const { | 886 virtual BlockEntryInstr* PredecessorAt(intptr_t index) const { |
| 886 return predecessors_[index]; | 887 return predecessors_[index]; |
| 887 } | 888 } |
| 888 | 889 |
| 889 // Returns -1 if pred is not in the list. | 890 // Returns -1 if pred is not in the list. |
| 890 intptr_t IndexOfPredecessor(BlockEntryInstr* pred) const; | 891 intptr_t IndexOfPredecessor(BlockEntryInstr* pred) const; |
| 891 | 892 |
| 892 ZoneGrowableArray<PhiInstr*>* phis() const { return phis_; } | 893 ZoneGrowableArray<PhiInstr*>* phis() const { return phis_; } |
| 893 | 894 |
| 894 virtual void PrepareEntry(FlowGraphCompiler* compiler); | 895 virtual void PrepareEntry(FlowGraphCompiler* compiler); |
| 895 | 896 |
| 896 void InsertPhi(intptr_t var_index, intptr_t var_count); | 897 void InsertPhi(intptr_t var_index, intptr_t var_count); |
| 897 void RemoveDeadPhis(); | 898 void RemoveDeadPhis(); |
| 898 | 899 |
| 899 intptr_t phi_count() const { return phi_count_; } | 900 intptr_t phi_count() const { return phi_count_; } |
| 900 | 901 |
| 901 virtual void PrintTo(BufferFormatter* f) const; | 902 virtual void PrintTo(BufferFormatter* f) const; |
| 902 virtual void PrintToVisualizer(BufferFormatter* f) const; | 903 virtual void PrintToVisualizer(BufferFormatter* f) const; |
| 903 | 904 |
| 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 |
| 904 private: | 910 private: |
| 905 virtual void ClearPredecessors() { predecessors_.Clear(); } | 911 virtual void ClearPredecessors() { |
| 906 virtual void AddPredecessor(BlockEntryInstr* predecessor); | 912 // Keep a 'backup' of any existing predecessors to enable garbage |
| 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 } |
| 907 | 922 |
| 908 GrowableArray<BlockEntryInstr*> predecessors_; | 923 GrowableArray<BlockEntryInstr*> predecessors_; |
| 909 ZoneGrowableArray<PhiInstr*>* phis_; | 924 ZoneGrowableArray<PhiInstr*>* phis_; |
| 910 intptr_t phi_count_; | 925 intptr_t phi_count_; |
| 926 GrowableArray<BlockEntryInstr*> stale_predecessors_; |
| 911 | 927 |
| 912 DISALLOW_COPY_AND_ASSIGN(JoinEntryInstr); | 928 DISALLOW_COPY_AND_ASSIGN(JoinEntryInstr); |
| 913 }; | 929 }; |
| 914 | 930 |
| 915 | 931 |
| 916 class TargetEntryInstr : public BlockEntryInstr { | 932 class TargetEntryInstr : public BlockEntryInstr { |
| 917 public: | 933 public: |
| 918 TargetEntryInstr(intptr_t block_id, intptr_t try_index) | 934 explicit TargetEntryInstr(intptr_t try_index) |
| 919 : BlockEntryInstr(block_id, try_index), | 935 : BlockEntryInstr(try_index), |
| 920 predecessor_(NULL), | 936 predecessor_(NULL), |
| 921 catch_try_index_(CatchClauseNode::kInvalidTryIndex) { } | 937 catch_try_index_(CatchClauseNode::kInvalidTryIndex) { } |
| 922 | 938 |
| 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 |
| 923 DECLARE_INSTRUCTION(TargetEntry) | 945 DECLARE_INSTRUCTION(TargetEntry) |
| 924 | 946 |
| 925 virtual intptr_t PredecessorCount() const { | 947 virtual intptr_t PredecessorCount() const { |
| 926 return (predecessor_ == NULL) ? 0 : 1; | 948 return (predecessor_ == NULL) ? 0 : 1; |
| 927 } | 949 } |
| 928 virtual BlockEntryInstr* PredecessorAt(intptr_t index) const { | 950 virtual BlockEntryInstr* PredecessorAt(intptr_t index) const { |
| 929 ASSERT((index == 0) && (predecessor_ != NULL)); | 951 ASSERT((index == 0) && (predecessor_ != NULL)); |
| 930 return predecessor_; | 952 return predecessor_; |
| 931 } | 953 } |
| 932 | 954 |
| 933 // Returns true if this Block is an entry of a catch handler. | 955 // Returns true if this Block is an entry of a catch handler. |
| 934 bool IsCatchEntry() const { | 956 bool IsCatchEntry() const { |
| 935 return catch_try_index_ != CatchClauseNode::kInvalidTryIndex; | 957 return catch_try_index_ != CatchClauseNode::kInvalidTryIndex; |
| 936 } | 958 } |
| 937 | 959 |
| 938 // Returns try index for the try block to which this catch handler | 960 // Returns try index for the try block to which this catch handler |
| 939 // corresponds. | 961 // corresponds. |
| 940 intptr_t catch_try_index() const { | 962 intptr_t catch_try_index() const { |
| 941 ASSERT(IsCatchEntry()); | 963 ASSERT(IsCatchEntry()); |
| 942 return catch_try_index_; | 964 return catch_try_index_; |
| 943 } | 965 } |
| 944 void set_catch_try_index(intptr_t index) { catch_try_index_ = index; } | |
| 945 | 966 |
| 946 virtual void PrepareEntry(FlowGraphCompiler* compiler); | 967 virtual void PrepareEntry(FlowGraphCompiler* compiler); |
| 947 | 968 |
| 948 virtual void PrintTo(BufferFormatter* f) const; | 969 virtual void PrintTo(BufferFormatter* f) const; |
| 949 virtual void PrintToVisualizer(BufferFormatter* f) const; | 970 virtual void PrintToVisualizer(BufferFormatter* f) const; |
| 950 | 971 |
| 951 private: | 972 private: |
| 952 virtual void ClearPredecessors() { predecessor_ = NULL; } | 973 virtual void ClearPredecessors() { predecessor_ = NULL; } |
| 953 virtual void AddPredecessor(BlockEntryInstr* predecessor) { | 974 virtual void AddPredecessor(BlockEntryInstr* predecessor) { |
| 954 ASSERT(predecessor_ == NULL); | 975 ASSERT(predecessor_ == NULL); |
| 955 predecessor_ = predecessor; | 976 predecessor_ = predecessor; |
| 956 } | 977 } |
| 957 | 978 |
| 958 BlockEntryInstr* predecessor_; | 979 BlockEntryInstr* predecessor_; |
| 959 intptr_t catch_try_index_; | 980 const intptr_t catch_try_index_; |
| 960 | 981 |
| 961 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr); | 982 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr); |
| 962 }; | 983 }; |
| 963 | 984 |
| 964 | 985 |
| 965 // Abstract super-class of all instructions that define a value (Bind, Phi). | 986 // Abstract super-class of all instructions that define a value (Bind, Phi). |
| 966 class Definition : public Instruction { | 987 class Definition : public Instruction { |
| 967 public: | 988 public: |
| 968 enum UseKind { kEffect, kValue }; | 989 enum UseKind { kEffect, kValue }; |
| 969 | 990 |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1138 UNREACHABLE(); | 1159 UNREACHABLE(); |
| 1139 return kIllegalCid; | 1160 return kIllegalCid; |
| 1140 } | 1161 } |
| 1141 | 1162 |
| 1142 DECLARE_INSTRUCTION(Phi) | 1163 DECLARE_INSTRUCTION(Phi) |
| 1143 | 1164 |
| 1144 virtual void PrintTo(BufferFormatter* f) const; | 1165 virtual void PrintTo(BufferFormatter* f) const; |
| 1145 virtual void PrintToVisualizer(BufferFormatter* f) const; | 1166 virtual void PrintToVisualizer(BufferFormatter* f) const; |
| 1146 | 1167 |
| 1147 private: | 1168 private: |
| 1148 friend class ConstantPropagator; // Direct access to inputs_. | 1169 friend class JoinEntryInstr; // Direct access to inputs_ array. |
| 1149 | 1170 |
| 1150 JoinEntryInstr* block_; | 1171 JoinEntryInstr* block_; |
| 1151 GrowableArray<Value*> inputs_; | 1172 GrowableArray<Value*> inputs_; |
| 1152 bool is_alive_; | 1173 bool is_alive_; |
| 1153 Representation representation_; | 1174 Representation representation_; |
| 1154 | 1175 |
| 1155 DISALLOW_COPY_AND_ASSIGN(PhiInstr); | 1176 DISALLOW_COPY_AND_ASSIGN(PhiInstr); |
| 1156 }; | 1177 }; |
| 1157 | 1178 |
| 1158 | 1179 |
| (...skipping 2479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3638 ForwardInstructionIterator* current_iterator_; | 3659 ForwardInstructionIterator* current_iterator_; |
| 3639 | 3660 |
| 3640 private: | 3661 private: |
| 3641 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 3662 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
| 3642 }; | 3663 }; |
| 3643 | 3664 |
| 3644 | 3665 |
| 3645 } // namespace dart | 3666 } // namespace dart |
| 3646 | 3667 |
| 3647 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 3668 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
| OLD | NEW |