| 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 774 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 785 | 785 |
| 786 // Functions required in all concrete instruction classes. | 786 // Functions required in all concrete instruction classes. |
| 787 #define DECLARE_INSTRUCTION(type) \ | 787 #define DECLARE_INSTRUCTION(type) \ |
| 788 virtual Instruction* Accept(FlowGraphVisitor* visitor); \ | 788 virtual Instruction* Accept(FlowGraphVisitor* visitor); \ |
| 789 virtual bool Is##type() const { return true; } \ | 789 virtual bool Is##type() const { return true; } \ |
| 790 virtual type##Instr* As##type() { return this; } \ | 790 virtual type##Instr* As##type() { return this; } \ |
| 791 | 791 |
| 792 | 792 |
| 793 class Instruction : public ZoneAllocated { | 793 class Instruction : public ZoneAllocated { |
| 794 public: | 794 public: |
| 795 Instruction() : mark_(false) { } | 795 Instruction() { } |
| 796 | 796 |
| 797 virtual bool IsBlockEntry() const { return false; } | 797 virtual bool IsBlockEntry() const { return false; } |
| 798 BlockEntryInstr* AsBlockEntry() { | 798 BlockEntryInstr* AsBlockEntry() { |
| 799 return IsBlockEntry() ? reinterpret_cast<BlockEntryInstr*>(this) : NULL; | 799 return IsBlockEntry() ? reinterpret_cast<BlockEntryInstr*>(this) : NULL; |
| 800 } | 800 } |
| 801 | 801 |
| 802 // Visiting support. | 802 // Visiting support. |
| 803 virtual Instruction* Accept(FlowGraphVisitor* visitor) = 0; | 803 virtual Instruction* Accept(FlowGraphVisitor* visitor) = 0; |
| 804 | 804 |
| 805 virtual void SetSuccessor(Instruction* instr) = 0; | 805 virtual void SetSuccessor(Instruction* instr) = 0; |
| 806 // Perform a postorder traversal of the instruction graph reachable from | 806 // Perform a postorder traversal of the instruction graph reachable from |
| 807 // this instruction. Accumulate basic block entries in the order visited | 807 // this instruction. Accumulate basic block entries in the order visited |
| 808 // in the in/out parameter 'block_entries'. | 808 // in the in/out parameter 'block_entries'. |
| 809 virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries) = 0; | 809 virtual void DepthFirstSearch( |
| 810 | 810 GrowableArray<BlockEntryInstr*>* preorder, |
| 811 // Mark bit to support non-reentrant recursive traversal (i.e., | 811 GrowableArray<BlockEntryInstr*>* postorder) = 0; |
| 812 // identification of cycles). Before and after a traversal, all the nodes | |
| 813 // must have the same mark. | |
| 814 bool mark() const { return mark_; } | |
| 815 void flip_mark() { mark_ = !mark_; } | |
| 816 | 812 |
| 817 #define INSTRUCTION_TYPE_CHECK(type) \ | 813 #define INSTRUCTION_TYPE_CHECK(type) \ |
| 818 virtual bool Is##type() const { return false; } \ | 814 virtual bool Is##type() const { return false; } \ |
| 819 virtual type##Instr* As##type() { return NULL; } | 815 virtual type##Instr* As##type() { return NULL; } |
| 820 FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK) | 816 FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK) |
| 821 #undef INSTRUCTION_TYPE_CHECK | 817 #undef INSTRUCTION_TYPE_CHECK |
| 822 | 818 |
| 823 private: | 819 private: |
| 824 bool mark_; | |
| 825 | |
| 826 DISALLOW_COPY_AND_ASSIGN(Instruction); | 820 DISALLOW_COPY_AND_ASSIGN(Instruction); |
| 827 }; | 821 }; |
| 828 | 822 |
| 829 | 823 |
| 830 // Basic block entries are administrative nodes. Joins are the only nodes | 824 // Basic block entries are administrative nodes. Joins are the only nodes |
| 831 // with multiple predecessors. Targets are the other basic block entries. | 825 // with multiple predecessors. Targets are the other basic block entries. |
| 832 // The types enforce edge-split form---joins are forbidden as the successors | 826 // The types enforce edge-split form---joins are forbidden as the successors |
| 833 // of branches. | 827 // of branches. |
| 834 class BlockEntryInstr : public Instruction { | 828 class BlockEntryInstr : public Instruction { |
| 835 public: | 829 public: |
| 836 virtual bool IsBlockEntry() const { return true; } | 830 virtual bool IsBlockEntry() const { return true; } |
| 837 | 831 |
| 838 intptr_t block_number() const { return block_number_; } | 832 intptr_t preorder_number() const { return preorder_number_; } |
| 839 void set_block_number(intptr_t number) { block_number_ = number; } | 833 void set_preorder_number(intptr_t number) { preorder_number_ = number; } |
| 834 |
| 835 intptr_t postorder_number() const { return postorder_number_; } |
| 836 void set_postorder_number(intptr_t number) { postorder_number_ = number; } |
| 840 | 837 |
| 841 protected: | 838 protected: |
| 842 BlockEntryInstr() : Instruction(), block_number_(-1) { } | 839 BlockEntryInstr() : preorder_number_(-1), postorder_number_(-1) { } |
| 843 | 840 |
| 844 private: | 841 private: |
| 845 intptr_t block_number_; | 842 intptr_t preorder_number_; |
| 843 intptr_t postorder_number_; |
| 846 | 844 |
| 847 DISALLOW_COPY_AND_ASSIGN(BlockEntryInstr); | 845 DISALLOW_COPY_AND_ASSIGN(BlockEntryInstr); |
| 848 }; | 846 }; |
| 849 | 847 |
| 850 | 848 |
| 851 class JoinEntryInstr : public BlockEntryInstr { | 849 class JoinEntryInstr : public BlockEntryInstr { |
| 852 public: | 850 public: |
| 853 JoinEntryInstr() : BlockEntryInstr(), successor_(NULL) { } | 851 JoinEntryInstr() : BlockEntryInstr(), successor_(NULL) { } |
| 854 | 852 |
| 855 DECLARE_INSTRUCTION(JoinEntry) | 853 DECLARE_INSTRUCTION(JoinEntry) |
| 856 | 854 |
| 857 virtual void SetSuccessor(Instruction* instr) { | 855 virtual void SetSuccessor(Instruction* instr) { |
| 858 ASSERT(successor_ == NULL); | 856 ASSERT(successor_ == NULL); |
| 859 successor_ = instr; | 857 successor_ = instr; |
| 860 } | 858 } |
| 861 | 859 |
| 862 virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries); | 860 virtual void DepthFirstSearch( |
| 861 GrowableArray<BlockEntryInstr*>* preorder, |
| 862 GrowableArray<BlockEntryInstr*>* postorder); |
| 863 | 863 |
| 864 private: | 864 private: |
| 865 Instruction* successor_; | 865 Instruction* successor_; |
| 866 | 866 |
| 867 DISALLOW_COPY_AND_ASSIGN(JoinEntryInstr); | 867 DISALLOW_COPY_AND_ASSIGN(JoinEntryInstr); |
| 868 }; | 868 }; |
| 869 | 869 |
| 870 | 870 |
| 871 class TargetEntryInstr : public BlockEntryInstr { | 871 class TargetEntryInstr : public BlockEntryInstr { |
| 872 public: | 872 public: |
| 873 TargetEntryInstr() : BlockEntryInstr(), successor_(NULL) { | 873 TargetEntryInstr() : BlockEntryInstr(), successor_(NULL) { |
| 874 } | 874 } |
| 875 | 875 |
| 876 DECLARE_INSTRUCTION(TargetEntry) | 876 DECLARE_INSTRUCTION(TargetEntry) |
| 877 | 877 |
| 878 virtual void SetSuccessor(Instruction* instr) { | 878 virtual void SetSuccessor(Instruction* instr) { |
| 879 ASSERT(successor_ == NULL); | 879 ASSERT(successor_ == NULL); |
| 880 successor_ = instr; | 880 successor_ = instr; |
| 881 } | 881 } |
| 882 | 882 |
| 883 virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries); | 883 virtual void DepthFirstSearch( |
| 884 GrowableArray<BlockEntryInstr*>* preorder, |
| 885 GrowableArray<BlockEntryInstr*>* postorder); |
| 884 | 886 |
| 885 private: | 887 private: |
| 886 Instruction* successor_; | 888 Instruction* successor_; |
| 887 | 889 |
| 888 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr); | 890 DISALLOW_COPY_AND_ASSIGN(TargetEntryInstr); |
| 889 }; | 891 }; |
| 890 | 892 |
| 891 | 893 |
| 892 // The non-optimizing compiler assumes that there is exactly one use of | 894 // The non-optimizing compiler assumes that there is exactly one use of |
| 893 // every temporary so they can be deallocated at their use. Some AST nodes, | 895 // every temporary so they can be deallocated at their use. Some AST nodes, |
| 894 // e.g., expr0[expr1]++, violate this assumption (there are two uses of each | 896 // e.g., expr0[expr1]++, violate this assumption (there are two uses of each |
| 895 // of the values expr0 and expr1). | 897 // of the values expr0 and expr1). |
| 896 // | 898 // |
| 897 // PickTemp is used to name (with 'destination') a copy of a live temporary | 899 // PickTemp is used to name (with 'destination') a copy of a live temporary |
| 898 // (named 'source') without counting as the use of the source. | 900 // (named 'source') without counting as the use of the source. |
| 899 class PickTempInstr : public Instruction { | 901 class PickTempInstr : public Instruction { |
| 900 public: | 902 public: |
| 901 PickTempInstr(intptr_t dst, intptr_t src) | 903 PickTempInstr(intptr_t dst, intptr_t src) |
| 902 : Instruction(), destination_(dst), source_(src), successor_(NULL) { } | 904 : destination_(dst), source_(src), successor_(NULL) { } |
| 903 | 905 |
| 904 DECLARE_INSTRUCTION(PickTemp) | 906 DECLARE_INSTRUCTION(PickTemp) |
| 905 | 907 |
| 906 intptr_t destination() const { return destination_; } | 908 intptr_t destination() const { return destination_; } |
| 907 intptr_t source() const { return source_; } | 909 intptr_t source() const { return source_; } |
| 908 | 910 |
| 909 virtual void SetSuccessor(Instruction* instr) { | 911 virtual void SetSuccessor(Instruction* instr) { |
| 910 ASSERT(successor_ == NULL && instr != NULL); | 912 ASSERT(successor_ == NULL && instr != NULL); |
| 911 successor_ = instr; | 913 successor_ = instr; |
| 912 } | 914 } |
| 913 | 915 |
| 914 virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries); | 916 virtual void DepthFirstSearch( |
| 917 GrowableArray<BlockEntryInstr*>* preorder, |
| 918 GrowableArray<BlockEntryInstr*>* postorder); |
| 915 | 919 |
| 916 private: | 920 private: |
| 917 const intptr_t destination_; | 921 const intptr_t destination_; |
| 918 const intptr_t source_; | 922 const intptr_t source_; |
| 919 Instruction* successor_; | 923 Instruction* successor_; |
| 920 | 924 |
| 921 DISALLOW_COPY_AND_ASSIGN(PickTempInstr); | 925 DISALLOW_COPY_AND_ASSIGN(PickTempInstr); |
| 922 }; | 926 }; |
| 923 | 927 |
| 924 | 928 |
| 925 // The non-optimizing compiler assumes that temporary definitions and uses | 929 // The non-optimizing compiler assumes that temporary definitions and uses |
| 926 // obey a stack discipline, so they can be allocated and deallocated with | 930 // obey a stack discipline, so they can be allocated and deallocated with |
| 927 // push and pop. Some Some AST nodes, e.g., expr++, violate this assumption | 931 // push and pop. Some Some AST nodes, e.g., expr++, violate this assumption |
| 928 // (the value expr+1 is produced after the value of expr, and also consumed | 932 // (the value expr+1 is produced after the value of expr, and also consumed |
| 929 // after it). | 933 // after it). |
| 930 // | 934 // |
| 931 // We 'preallocate' temporaries (named with 'destination') such as the one | 935 // We 'preallocate' temporaries (named with 'destination') such as the one |
| 932 // for expr+1 and use TuckTemp to mutate them by overwriting them with a | 936 // for expr+1 and use TuckTemp to mutate them by overwriting them with a |
| 933 // copy of a temporary (named with 'source'). | 937 // copy of a temporary (named with 'source'). |
| 934 class TuckTempInstr : public Instruction { | 938 class TuckTempInstr : public Instruction { |
| 935 public: | 939 public: |
| 936 TuckTempInstr(intptr_t dst, intptr_t src) | 940 TuckTempInstr(intptr_t dst, intptr_t src) |
| 937 : Instruction(), destination_(dst), source_(src), successor_(NULL) { } | 941 : destination_(dst), source_(src), successor_(NULL) { } |
| 938 | 942 |
| 939 DECLARE_INSTRUCTION(TuckTemp) | 943 DECLARE_INSTRUCTION(TuckTemp) |
| 940 | 944 |
| 941 intptr_t destination() const { return destination_; } | 945 intptr_t destination() const { return destination_; } |
| 942 intptr_t source() const { return source_; } | 946 intptr_t source() const { return source_; } |
| 943 | 947 |
| 944 virtual void SetSuccessor(Instruction* instr) { | 948 virtual void SetSuccessor(Instruction* instr) { |
| 945 ASSERT(successor_ == NULL && instr != NULL); | 949 ASSERT(successor_ == NULL && instr != NULL); |
| 946 successor_ = instr; | 950 successor_ = instr; |
| 947 } | 951 } |
| 948 | 952 |
| 949 virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries); | 953 virtual void DepthFirstSearch( |
| 954 GrowableArray<BlockEntryInstr*>* preorder, |
| 955 GrowableArray<BlockEntryInstr*>* postorder); |
| 950 | 956 |
| 951 private: | 957 private: |
| 952 const intptr_t destination_; | 958 const intptr_t destination_; |
| 953 const intptr_t source_; | 959 const intptr_t source_; |
| 954 Instruction* successor_; | 960 Instruction* successor_; |
| 955 | 961 |
| 956 DISALLOW_COPY_AND_ASSIGN(TuckTempInstr); | 962 DISALLOW_COPY_AND_ASSIGN(TuckTempInstr); |
| 957 }; | 963 }; |
| 958 | 964 |
| 959 | 965 |
| 960 class DoInstr : public Instruction { | 966 class DoInstr : public Instruction { |
| 961 public: | 967 public: |
| 962 explicit DoInstr(Computation* comp) | 968 explicit DoInstr(Computation* comp) |
| 963 : Instruction(), computation_(comp), successor_(NULL) { } | 969 : computation_(comp), successor_(NULL) { } |
| 964 | 970 |
| 965 DECLARE_INSTRUCTION(Do) | 971 DECLARE_INSTRUCTION(Do) |
| 966 | 972 |
| 967 Computation* computation() const { return computation_; } | 973 Computation* computation() const { return computation_; } |
| 968 | 974 |
| 969 virtual void SetSuccessor(Instruction* instr) { | 975 virtual void SetSuccessor(Instruction* instr) { |
| 970 ASSERT(successor_ == NULL); | 976 ASSERT(successor_ == NULL); |
| 971 successor_ = instr; | 977 successor_ = instr; |
| 972 } | 978 } |
| 973 | 979 |
| 974 virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries); | 980 virtual void DepthFirstSearch( |
| 981 GrowableArray<BlockEntryInstr*>* preorder, |
| 982 GrowableArray<BlockEntryInstr*>* postorder); |
| 975 | 983 |
| 976 private: | 984 private: |
| 977 Computation* computation_; | 985 Computation* computation_; |
| 978 Instruction* successor_; | 986 Instruction* successor_; |
| 979 | 987 |
| 980 DISALLOW_COPY_AND_ASSIGN(DoInstr); | 988 DISALLOW_COPY_AND_ASSIGN(DoInstr); |
| 981 }; | 989 }; |
| 982 | 990 |
| 983 | 991 |
| 984 class BindInstr : public Instruction { | 992 class BindInstr : public Instruction { |
| 985 public: | 993 public: |
| 986 BindInstr(intptr_t temp_index, Computation* computation) | 994 BindInstr(intptr_t temp_index, Computation* computation) |
| 987 : Instruction(), | 995 : temp_index_(temp_index), computation_(computation), successor_(NULL) { } |
| 988 temp_index_(temp_index), | |
| 989 computation_(computation), | |
| 990 successor_(NULL) { } | |
| 991 | 996 |
| 992 DECLARE_INSTRUCTION(Bind) | 997 DECLARE_INSTRUCTION(Bind) |
| 993 | 998 |
| 994 intptr_t temp_index() const { return temp_index_; } | 999 intptr_t temp_index() const { return temp_index_; } |
| 995 Computation* computation() const { return computation_; } | 1000 Computation* computation() const { return computation_; } |
| 996 | 1001 |
| 997 virtual void SetSuccessor(Instruction* instr) { | 1002 virtual void SetSuccessor(Instruction* instr) { |
| 998 ASSERT(successor_ == NULL); | 1003 ASSERT(successor_ == NULL); |
| 999 successor_ = instr; | 1004 successor_ = instr; |
| 1000 } | 1005 } |
| 1001 | 1006 |
| 1002 virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries); | 1007 virtual void DepthFirstSearch( |
| 1008 GrowableArray<BlockEntryInstr*>* preorder, |
| 1009 GrowableArray<BlockEntryInstr*>* postorder); |
| 1003 | 1010 |
| 1004 private: | 1011 private: |
| 1005 const intptr_t temp_index_; | 1012 const intptr_t temp_index_; |
| 1006 Computation* computation_; | 1013 Computation* computation_; |
| 1007 Instruction* successor_; | 1014 Instruction* successor_; |
| 1008 | 1015 |
| 1009 DISALLOW_COPY_AND_ASSIGN(BindInstr); | 1016 DISALLOW_COPY_AND_ASSIGN(BindInstr); |
| 1010 }; | 1017 }; |
| 1011 | 1018 |
| 1012 | 1019 |
| 1013 class ReturnInstr : public Instruction { | 1020 class ReturnInstr : public Instruction { |
| 1014 public: | 1021 public: |
| 1015 ReturnInstr(Value* value, intptr_t token_index) | 1022 ReturnInstr(Value* value, intptr_t token_index) |
| 1016 : Instruction(), value_(value), token_index_(token_index) { | 1023 : value_(value), token_index_(token_index) { |
| 1017 ASSERT(value_ != NULL); | 1024 ASSERT(value_ != NULL); |
| 1018 } | 1025 } |
| 1019 | 1026 |
| 1020 DECLARE_INSTRUCTION(Return) | 1027 DECLARE_INSTRUCTION(Return) |
| 1021 | 1028 |
| 1022 Value* value() const { return value_; } | 1029 Value* value() const { return value_; } |
| 1023 intptr_t token_index() const { return token_index_; } | 1030 intptr_t token_index() const { return token_index_; } |
| 1024 | 1031 |
| 1025 virtual void SetSuccessor(Instruction* instr) { UNREACHABLE(); } | 1032 virtual void SetSuccessor(Instruction* instr) { UNREACHABLE(); } |
| 1026 | 1033 |
| 1027 virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries); | 1034 virtual void DepthFirstSearch( |
| 1035 GrowableArray<BlockEntryInstr*>* preorder, |
| 1036 GrowableArray<BlockEntryInstr*>* postorder); |
| 1028 | 1037 |
| 1029 private: | 1038 private: |
| 1030 Value* value_; | 1039 Value* value_; |
| 1031 intptr_t token_index_; | 1040 intptr_t token_index_; |
| 1032 | 1041 |
| 1033 DISALLOW_COPY_AND_ASSIGN(ReturnInstr); | 1042 DISALLOW_COPY_AND_ASSIGN(ReturnInstr); |
| 1034 }; | 1043 }; |
| 1035 | 1044 |
| 1036 | 1045 |
| 1037 class ThrowInstr : public Instruction { | 1046 class ThrowInstr : public Instruction { |
| 1038 public: | 1047 public: |
| 1039 ThrowInstr(intptr_t node_id, intptr_t token_index, Value* exception) | 1048 ThrowInstr(intptr_t node_id, intptr_t token_index, Value* exception) |
| 1040 : Instruction(), | 1049 : node_id_(node_id), token_index_(token_index), exception_(exception) { |
| 1041 node_id_(node_id), | |
| 1042 token_index_(token_index), | |
| 1043 exception_(exception) { | |
| 1044 ASSERT(exception_ != NULL); | 1050 ASSERT(exception_ != NULL); |
| 1045 } | 1051 } |
| 1046 | 1052 |
| 1047 DECLARE_INSTRUCTION(Throw) | 1053 DECLARE_INSTRUCTION(Throw) |
| 1048 | 1054 |
| 1049 intptr_t node_id() const { return node_id_; } | 1055 intptr_t node_id() const { return node_id_; } |
| 1050 intptr_t token_index() const { return token_index_; } | 1056 intptr_t token_index() const { return token_index_; } |
| 1051 Value* exception() const { return exception_; } | 1057 Value* exception() const { return exception_; } |
| 1052 | 1058 |
| 1053 virtual void SetSuccessor(Instruction* instr) { UNREACHABLE(); } | 1059 virtual void SetSuccessor(Instruction* instr) { UNREACHABLE(); } |
| 1054 | 1060 |
| 1055 virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries); | 1061 virtual void DepthFirstSearch( |
| 1062 GrowableArray<BlockEntryInstr*>* preorder, |
| 1063 GrowableArray<BlockEntryInstr*>* postorder); |
| 1056 | 1064 |
| 1057 private: | 1065 private: |
| 1058 intptr_t node_id_; | 1066 intptr_t node_id_; |
| 1059 intptr_t token_index_; | 1067 intptr_t token_index_; |
| 1060 Value* exception_; | 1068 Value* exception_; |
| 1061 | 1069 |
| 1062 DISALLOW_COPY_AND_ASSIGN(ThrowInstr); | 1070 DISALLOW_COPY_AND_ASSIGN(ThrowInstr); |
| 1063 }; | 1071 }; |
| 1064 | 1072 |
| 1065 | 1073 |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1079 | 1087 |
| 1080 DECLARE_INSTRUCTION(ReThrow) | 1088 DECLARE_INSTRUCTION(ReThrow) |
| 1081 | 1089 |
| 1082 intptr_t node_id() const { return node_id_; } | 1090 intptr_t node_id() const { return node_id_; } |
| 1083 intptr_t token_index() const { return token_index_; } | 1091 intptr_t token_index() const { return token_index_; } |
| 1084 Value* exception() const { return exception_; } | 1092 Value* exception() const { return exception_; } |
| 1085 Value* stack_trace() const { return stack_trace_; } | 1093 Value* stack_trace() const { return stack_trace_; } |
| 1086 | 1094 |
| 1087 virtual void SetSuccessor(Instruction* instr) { UNREACHABLE(); } | 1095 virtual void SetSuccessor(Instruction* instr) { UNREACHABLE(); } |
| 1088 | 1096 |
| 1089 virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries); | 1097 virtual void DepthFirstSearch( |
| 1098 GrowableArray<BlockEntryInstr*>* preorder, |
| 1099 GrowableArray<BlockEntryInstr*>* postorder); |
| 1090 | 1100 |
| 1091 private: | 1101 private: |
| 1092 intptr_t node_id_; | 1102 intptr_t node_id_; |
| 1093 intptr_t token_index_; | 1103 intptr_t token_index_; |
| 1094 Value* exception_; | 1104 Value* exception_; |
| 1095 Value* stack_trace_; | 1105 Value* stack_trace_; |
| 1096 | 1106 |
| 1097 DISALLOW_COPY_AND_ASSIGN(ReThrowInstr); | 1107 DISALLOW_COPY_AND_ASSIGN(ReThrowInstr); |
| 1098 }; | 1108 }; |
| 1099 | 1109 |
| 1100 | 1110 |
| 1101 class BranchInstr : public Instruction { | 1111 class BranchInstr : public Instruction { |
| 1102 public: | 1112 public: |
| 1103 explicit BranchInstr(Value* value) | 1113 explicit BranchInstr(Value* value) |
| 1104 : Instruction(), | 1114 : value_(value), |
| 1105 value_(value), | |
| 1106 true_successor_(NULL), | 1115 true_successor_(NULL), |
| 1107 false_successor_(NULL) { } | 1116 false_successor_(NULL) { } |
| 1108 | 1117 |
| 1109 DECLARE_INSTRUCTION(Branch) | 1118 DECLARE_INSTRUCTION(Branch) |
| 1110 | 1119 |
| 1111 Value* value() const { return value_; } | 1120 Value* value() const { return value_; } |
| 1112 BlockEntryInstr* true_successor() const { return true_successor_; } | 1121 BlockEntryInstr* true_successor() const { return true_successor_; } |
| 1113 BlockEntryInstr* false_successor() const { return false_successor_; } | 1122 BlockEntryInstr* false_successor() const { return false_successor_; } |
| 1114 | 1123 |
| 1115 BlockEntryInstr** true_successor_address() { return &true_successor_; } | 1124 BlockEntryInstr** true_successor_address() { return &true_successor_; } |
| 1116 BlockEntryInstr** false_successor_address() { return &false_successor_; } | 1125 BlockEntryInstr** false_successor_address() { return &false_successor_; } |
| 1117 | 1126 |
| 1118 virtual void SetSuccessor(Instruction* instr) { UNREACHABLE(); } | 1127 virtual void SetSuccessor(Instruction* instr) { UNREACHABLE(); } |
| 1119 | 1128 |
| 1120 virtual void Postorder(GrowableArray<BlockEntryInstr*>* block_entries); | 1129 virtual void DepthFirstSearch( |
| 1130 GrowableArray<BlockEntryInstr*>* preorder, |
| 1131 GrowableArray<BlockEntryInstr*>* postorder); |
| 1121 | 1132 |
| 1122 private: | 1133 private: |
| 1123 Value* value_; | 1134 Value* value_; |
| 1124 BlockEntryInstr* true_successor_; | 1135 BlockEntryInstr* true_successor_; |
| 1125 BlockEntryInstr* false_successor_; | 1136 BlockEntryInstr* false_successor_; |
| 1126 | 1137 |
| 1127 DISALLOW_COPY_AND_ASSIGN(BranchInstr); | 1138 DISALLOW_COPY_AND_ASSIGN(BranchInstr); |
| 1128 }; | 1139 }; |
| 1129 | 1140 |
| 1130 #undef DECLARE_INSTRUCTION | 1141 #undef DECLARE_INSTRUCTION |
| 1131 | 1142 |
| 1132 | 1143 |
| 1133 // Visitor base class to visit each instruction and computation in a flow | 1144 // Visitor base class to visit each instruction and computation in a flow |
| 1134 // graph as defined by a reversed list of basic blocks. | 1145 // graph as defined by a reversed list of basic blocks. |
| 1135 class FlowGraphVisitor : public ValueObject { | 1146 class FlowGraphVisitor : public ValueObject { |
| 1136 public: | 1147 public: |
| 1137 FlowGraphVisitor() { } | 1148 explicit FlowGraphVisitor(const GrowableArray<BlockEntryInstr*>& block_order) |
| 1149 : block_order_(block_order) { } |
| 1138 virtual ~FlowGraphVisitor() { } | 1150 virtual ~FlowGraphVisitor() { } |
| 1139 | 1151 |
| 1140 // Visit each block in the array list in reverse, and for each block its | 1152 // Visit each block in the block order, and for each block its |
| 1141 // instructions in order from the block entry to exit. | 1153 // instructions in order from the block entry to exit. |
| 1142 virtual void VisitBlocks(const GrowableArray<BlockEntryInstr*>& block_order); | 1154 virtual void VisitBlocks(); |
| 1143 | 1155 |
| 1144 // Visit functions for instruction and computation classes, with empty | 1156 // Visit functions for instruction and computation classes, with empty |
| 1145 // default implementations. | 1157 // default implementations. |
| 1146 #define DECLARE_VISIT_COMPUTATION(ShortName, ClassName) \ | 1158 #define DECLARE_VISIT_COMPUTATION(ShortName, ClassName) \ |
| 1147 virtual void Visit##ShortName(ClassName* comp) { } | 1159 virtual void Visit##ShortName(ClassName* comp) { } |
| 1148 | 1160 |
| 1149 #define DECLARE_VISIT_INSTRUCTION(ShortName) \ | 1161 #define DECLARE_VISIT_INSTRUCTION(ShortName) \ |
| 1150 virtual void Visit##ShortName(ShortName##Instr* instr) { } | 1162 virtual void Visit##ShortName(ShortName##Instr* instr) { } |
| 1151 | 1163 |
| 1152 FOR_EACH_COMPUTATION(DECLARE_VISIT_COMPUTATION) | 1164 FOR_EACH_COMPUTATION(DECLARE_VISIT_COMPUTATION) |
| 1153 FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION) | 1165 FOR_EACH_INSTRUCTION(DECLARE_VISIT_INSTRUCTION) |
| 1154 | 1166 |
| 1155 #undef DECLARE_VISIT_COMPUTATION | 1167 #undef DECLARE_VISIT_COMPUTATION |
| 1156 #undef DECLARE_VISIT_INSTRUCTION | 1168 #undef DECLARE_VISIT_INSTRUCTION |
| 1157 | 1169 |
| 1170 protected: |
| 1171 // Map a block number in a forward iteration into the block number in the |
| 1172 // corresponding reverse iteration. Used to obtain an index into |
| 1173 // block_order for reverse iterations. |
| 1174 intptr_t reverse_index(intptr_t index) { |
| 1175 return block_order_.length() - index - 1; |
| 1176 } |
| 1177 |
| 1178 const GrowableArray<BlockEntryInstr*>& block_order_; |
| 1179 |
| 1158 private: | 1180 private: |
| 1159 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); | 1181 DISALLOW_COPY_AND_ASSIGN(FlowGraphVisitor); |
| 1160 }; | 1182 }; |
| 1161 | 1183 |
| 1162 | 1184 |
| 1163 } // namespace dart | 1185 } // namespace dart |
| 1164 | 1186 |
| 1165 #endif // VM_INTERMEDIATE_LANGUAGE_H_ | 1187 #endif // VM_INTERMEDIATE_LANGUAGE_H_ |
| OLD | NEW |