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 |