Mercurial > hg > CbC > CbC_gcc
comparison gcc/sel-sched-ir.h @ 55:77e2b8dfacca gcc-4.4.5
update it from 4.4.3 to 4.5.0
author | ryoma <e075725@ie.u-ryukyu.ac.jp> |
---|---|
date | Fri, 12 Feb 2010 23:39:51 +0900 |
parents | a06113de4d67 |
children | b7f97abdc517 |
comparison
equal
deleted
inserted
replaced
52:c156f1bd5cd9 | 55:77e2b8dfacca |
---|---|
1 /* Instruction scheduling pass. This file contains definitions used | 1 /* Instruction scheduling pass. This file contains definitions used |
2 internally in the scheduler. | 2 internally in the scheduler. |
3 Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc. | 3 Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc. |
4 | 4 |
5 This file is part of GCC. | 5 This file is part of GCC. |
6 | 6 |
7 GCC is free software; you can redistribute it and/or modify it under | 7 GCC is free software; you can redistribute it and/or modify it under |
8 the terms of the GNU General Public License as published by the Free | 8 the terms of the GNU General Public License as published by the Free |
66 /* List of insns. */ | 66 /* List of insns. */ |
67 typedef _xlist_t ilist_t; | 67 typedef _xlist_t ilist_t; |
68 #define ILIST_INSN(L) (_XLIST_X (L)) | 68 #define ILIST_INSN(L) (_XLIST_X (L)) |
69 #define ILIST_NEXT(L) (_XLIST_NEXT (L)) | 69 #define ILIST_NEXT(L) (_XLIST_NEXT (L)) |
70 | 70 |
71 /* This lists possible transformations that done locally, i.e. in | 71 /* This lists possible transformations that done locally, i.e. in |
72 moveup_expr. */ | 72 moveup_expr. */ |
73 enum local_trans_type | 73 enum local_trans_type |
74 { | 74 { |
75 TRANS_SUBSTITUTION, | 75 TRANS_SUBSTITUTION, |
76 TRANS_SPECULATION | 76 TRANS_SPECULATION |
77 }; | 77 }; |
78 | 78 |
79 /* This struct is used to record the history of expression's | 79 /* This struct is used to record the history of expression's |
80 transformations. */ | 80 transformations. */ |
81 struct expr_history_def_1 | 81 struct expr_history_def_1 |
82 { | 82 { |
83 /* UID of the insn. */ | 83 /* UID of the insn. */ |
84 unsigned uid; | 84 unsigned uid; |
112 conditional, thus showing only control speculativeness. In the | 112 conditional, thus showing only control speculativeness. In the |
113 future we'd like to count data spec separately to allow a better | 113 future we'd like to count data spec separately to allow a better |
114 control on scheduling. */ | 114 control on scheduling. */ |
115 int spec; | 115 int spec; |
116 | 116 |
117 /* Degree of speculativeness measured as probability of executing | 117 /* Degree of speculativeness measured as probability of executing |
118 instruction's original basic block given relative to | 118 instruction's original basic block given relative to |
119 the current scheduling point. */ | 119 the current scheduling point. */ |
120 int usefulness; | 120 int usefulness; |
121 | 121 |
122 /* A priority of this expression. */ | 122 /* A priority of this expression. */ |
123 int priority; | 123 int priority; |
126 int priority_adj; | 126 int priority_adj; |
127 | 127 |
128 /* Number of times the insn was scheduled. */ | 128 /* Number of times the insn was scheduled. */ |
129 int sched_times; | 129 int sched_times; |
130 | 130 |
131 /* A basic block index this was originated from. Zero when there is | 131 /* A basic block index this was originated from. Zero when there is |
132 more than one originator. */ | 132 more than one originator. */ |
133 int orig_bb_index; | 133 int orig_bb_index; |
134 | 134 |
135 /* Instruction should be of SPEC_DONE_DS type in order to be moved to this | 135 /* Instruction should be of SPEC_DONE_DS type in order to be moved to this |
136 point. */ | 136 point. */ |
138 | 138 |
139 /* SPEC_TO_CHECK_DS hold speculation types that should be checked | 139 /* SPEC_TO_CHECK_DS hold speculation types that should be checked |
140 (used only during move_op ()). */ | 140 (used only during move_op ()). */ |
141 ds_t spec_to_check_ds; | 141 ds_t spec_to_check_ds; |
142 | 142 |
143 /* Cycle on which original insn was scheduled. Zero when it has not yet | 143 /* Cycle on which original insn was scheduled. Zero when it has not yet |
144 been scheduled or more than one originator. */ | 144 been scheduled or more than one originator. */ |
145 int orig_sched_cycle; | 145 int orig_sched_cycle; |
146 | 146 |
147 /* This vector contains the history of insn's transformations. */ | 147 /* This vector contains the history of insn's transformations. */ |
148 VEC(expr_history_def, heap) *history_of_changes; | 148 VEC(expr_history_def, heap) *history_of_changes; |
149 | 149 |
150 /* True (1) when original target (register or memory) of this instruction | 150 /* True (1) when original target (register or memory) of this instruction |
151 is available for scheduling, false otherwise. -1 means we're not sure; | 151 is available for scheduling, false otherwise. -1 means we're not sure; |
152 please run find_used_regs to clarify. */ | 152 please run find_used_regs to clarify. */ |
153 signed char target_available; | 153 signed char target_available; |
154 | 154 |
155 /* True when this expression needs a speculation check to be scheduled. | 155 /* True when this expression needs a speculation check to be scheduled. |
156 This is used during find_used_regs. */ | 156 This is used during find_used_regs. */ |
157 BOOL_BITFIELD needs_spec_check_p : 1; | 157 BOOL_BITFIELD needs_spec_check_p : 1; |
158 | 158 |
159 /* True when the expression was substituted. Used for statistical | 159 /* True when the expression was substituted. Used for statistical |
160 purposes. */ | 160 purposes. */ |
161 BOOL_BITFIELD was_substituted : 1; | 161 BOOL_BITFIELD was_substituted : 1; |
162 | 162 |
163 /* True when the expression was renamed. */ | 163 /* True when the expression was renamed. */ |
164 BOOL_BITFIELD was_renamed : 1; | 164 BOOL_BITFIELD was_renamed : 1; |
193 #define EXPR_WAS_SUBSTITUTED(EXPR) ((EXPR)->was_substituted) | 193 #define EXPR_WAS_SUBSTITUTED(EXPR) ((EXPR)->was_substituted) |
194 #define EXPR_WAS_RENAMED(EXPR) ((EXPR)->was_renamed) | 194 #define EXPR_WAS_RENAMED(EXPR) ((EXPR)->was_renamed) |
195 #define EXPR_CANT_MOVE(EXPR) ((EXPR)->cant_move) | 195 #define EXPR_CANT_MOVE(EXPR) ((EXPR)->cant_move) |
196 | 196 |
197 #define EXPR_WAS_CHANGED(EXPR) (VEC_length (expr_history_def, \ | 197 #define EXPR_WAS_CHANGED(EXPR) (VEC_length (expr_history_def, \ |
198 EXPR_HISTORY_OF_CHANGES (EXPR)) > 0) | 198 EXPR_HISTORY_OF_CHANGES (EXPR)) > 0) |
199 | 199 |
200 /* Insn definition for list of original insns in find_used_regs. */ | 200 /* Insn definition for list of original insns in find_used_regs. */ |
201 struct _def | 201 struct _def |
202 { | 202 { |
203 insn_t orig_insn; | 203 insn_t orig_insn; |
204 | 204 |
205 /* FIXME: Get rid of CROSSES_CALL in each def, since if we're moving up | 205 /* FIXME: Get rid of CROSSES_CALL in each def, since if we're moving up |
206 rhs from two different places, but only one of the code motion paths | 206 rhs from two different places, but only one of the code motion paths |
207 crosses a call, we can't use any of the call_used_regs, no matter which | 207 crosses a call, we can't use any of the call_used_regs, no matter which |
208 path or whether all paths crosses a call. Thus we should move CROSSES_CALL | 208 path or whether all paths crosses a call. Thus we should move CROSSES_CALL |
209 to static params. */ | 209 to static params. */ |
210 bool crosses_call; | 210 bool crosses_call; |
211 }; | 211 }; |
212 typedef struct _def *def_t; | 212 typedef struct _def *def_t; |
230 /* Availability set at the boundary. */ | 230 /* Availability set at the boundary. */ |
231 av_set_t av; | 231 av_set_t av; |
232 | 232 |
233 /* This set moved to the fence. */ | 233 /* This set moved to the fence. */ |
234 av_set_t av1; | 234 av_set_t av1; |
235 | 235 |
236 /* Deps context at this boundary. As long as we have one boundary per fence, | 236 /* Deps context at this boundary. As long as we have one boundary per fence, |
237 this is just a pointer to the same deps context as in the corresponding | 237 this is just a pointer to the same deps context as in the corresponding |
238 fence. */ | 238 fence. */ |
239 deps_t dc; | 239 deps_t dc; |
240 }; | 240 }; |
284 tc_t tc; | 284 tc_t tc; |
285 | 285 |
286 /* A vector of insns that are scheduled but not yet completed. */ | 286 /* A vector of insns that are scheduled but not yet completed. */ |
287 VEC (rtx,gc) *executing_insns; | 287 VEC (rtx,gc) *executing_insns; |
288 | 288 |
289 /* A vector indexed by UIDs that caches the earliest cycle on which | 289 /* A vector indexed by UIDs that caches the earliest cycle on which |
290 an insn can be scheduled on this fence. */ | 290 an insn can be scheduled on this fence. */ |
291 int *ready_ticks; | 291 int *ready_ticks; |
292 | 292 |
293 /* Its size. */ | 293 /* Its size. */ |
294 int ready_ticks_size; | 294 int ready_ticks_size; |
462 _list_iter_next (&(I))) | 462 _list_iter_next (&(I))) |
463 | 463 |
464 #define _FOR_EACH_1(TYPE, ELEM, I, LP) \ | 464 #define _FOR_EACH_1(TYPE, ELEM, I, LP) \ |
465 for (_list_iter_start (&(I), (LP), true); \ | 465 for (_list_iter_start (&(I), (LP), true); \ |
466 _list_iter_cond_##TYPE (*(I).lp, &(ELEM)); \ | 466 _list_iter_cond_##TYPE (*(I).lp, &(ELEM)); \ |
467 _list_iter_next (&(I))) | 467 _list_iter_next (&(I))) |
468 | 468 |
469 | 469 |
470 /* _xlist_t functions. */ | 470 /* _xlist_t functions. */ |
471 | 471 |
472 static inline void | 472 static inline void |
664 #define VINSN_REG_CLOBBERS(VI) (IDATA_REG_CLOBBERS (VINSN_ID (VI))) | 664 #define VINSN_REG_CLOBBERS(VI) (IDATA_REG_CLOBBERS (VINSN_ID (VI))) |
665 #define VINSN_COUNT(VI) ((VI)->count) | 665 #define VINSN_COUNT(VI) ((VI)->count) |
666 #define VINSN_MAY_TRAP_P(VI) ((VI)->may_trap_p) | 666 #define VINSN_MAY_TRAP_P(VI) ((VI)->may_trap_p) |
667 | 667 |
668 | 668 |
669 /* An entry of the hashtable describing transformations happened when | 669 /* An entry of the hashtable describing transformations happened when |
670 moving up through an insn. */ | 670 moving up through an insn. */ |
671 struct transformed_insns | 671 struct transformed_insns |
672 { | 672 { |
673 /* Previous vinsn. Used to find the proper element. */ | 673 /* Previous vinsn. Used to find the proper element. */ |
674 vinsn_t vinsn_old; | 674 vinsn_t vinsn_old; |
707 regset live; | 707 regset live; |
708 | 708 |
709 /* An INSN_UID bit is set when deps analysis result is already known. */ | 709 /* An INSN_UID bit is set when deps analysis result is already known. */ |
710 bitmap analyzed_deps; | 710 bitmap analyzed_deps; |
711 | 711 |
712 /* An INSN_UID bit is set when a hard dep was found, not set when | 712 /* An INSN_UID bit is set when a hard dep was found, not set when |
713 no dependence is found. This is meaningful only when the analyzed_deps | 713 no dependence is found. This is meaningful only when the analyzed_deps |
714 bitmap has its bit set. */ | 714 bitmap has its bit set. */ |
715 bitmap found_deps; | 715 bitmap found_deps; |
716 | 716 |
717 /* An INSN_UID bit is set when this is a bookkeeping insn generated from | 717 /* An INSN_UID bit is set when this is a bookkeeping insn generated from |
718 a parent with this uid. */ | 718 a parent with this uid. */ |
719 bitmap originators; | 719 bitmap originators; |
720 | 720 |
721 /* A hashtable caching the result of insn transformations through this one. */ | 721 /* A hashtable caching the result of insn transformations through this one. */ |
722 htab_t transformed_insns; | 722 htab_t transformed_insns; |
723 | 723 |
724 /* A context incapsulating this insn. */ | 724 /* A context incapsulating this insn. */ |
725 struct deps deps_context; | 725 struct deps deps_context; |
726 | 726 |
727 /* This field is initialized at the beginning of scheduling and is used | 727 /* This field is initialized at the beginning of scheduling and is used |
728 to handle sched group instructions. If it is non-null, then it points | 728 to handle sched group instructions. If it is non-null, then it points |
765 extern sel_insn_data_def insn_sid (insn_t); | 765 extern sel_insn_data_def insn_sid (insn_t); |
766 | 766 |
767 #define INSN_ASM_P(INSN) (SID (INSN)->asm_p) | 767 #define INSN_ASM_P(INSN) (SID (INSN)->asm_p) |
768 #define INSN_SCHED_NEXT(INSN) (SID (INSN)->sched_next) | 768 #define INSN_SCHED_NEXT(INSN) (SID (INSN)->sched_next) |
769 #define INSN_ANALYZED_DEPS(INSN) (SID (INSN)->analyzed_deps) | 769 #define INSN_ANALYZED_DEPS(INSN) (SID (INSN)->analyzed_deps) |
770 #define INSN_FOUND_DEPS(INSN) (SID (INSN)->found_deps) | 770 #define INSN_FOUND_DEPS(INSN) (SID (INSN)->found_deps) |
771 #define INSN_DEPS_CONTEXT(INSN) (SID (INSN)->deps_context) | 771 #define INSN_DEPS_CONTEXT(INSN) (SID (INSN)->deps_context) |
772 #define INSN_ORIGINATORS(INSN) (SID (INSN)->originators) | 772 #define INSN_ORIGINATORS(INSN) (SID (INSN)->originators) |
773 #define INSN_ORIGINATORS_BY_UID(UID) (SID_BY_UID (UID)->originators) | 773 #define INSN_ORIGINATORS_BY_UID(UID) (SID_BY_UID (UID)->originators) |
774 #define INSN_TRANSFORMED_INSNS(INSN) (SID (INSN)->transformed_insns) | 774 #define INSN_TRANSFORMED_INSNS(INSN) (SID (INSN)->transformed_insns) |
775 | 775 |
776 #define INSN_EXPR(INSN) (&SID (INSN)->expr) | 776 #define INSN_EXPR(INSN) (&SID (INSN)->expr) |
896 /* Access macros. */ | 896 /* Access macros. */ |
897 #define BB_LV_SET(BB) (SEL_GLOBAL_BB_INFO (BB)->lv_set) | 897 #define BB_LV_SET(BB) (SEL_GLOBAL_BB_INFO (BB)->lv_set) |
898 #define BB_LV_SET_VALID_P(BB) (SEL_GLOBAL_BB_INFO (BB)->lv_set_valid_p) | 898 #define BB_LV_SET_VALID_P(BB) (SEL_GLOBAL_BB_INFO (BB)->lv_set_valid_p) |
899 | 899 |
900 /* Per basic block data for the region. */ | 900 /* Per basic block data for the region. */ |
901 typedef struct | 901 typedef struct |
902 { | 902 { |
903 /* This insn stream is constructed in such a way that it should be | 903 /* This insn stream is constructed in such a way that it should be |
904 traversed by PREV_INSN field - (*not* NEXT_INSN). */ | 904 traversed by PREV_INSN field - (*not* NEXT_INSN). */ |
905 rtx note_list; | 905 rtx note_list; |
906 | 906 |
945 | 945 |
946 /* Various flags. */ | 946 /* Various flags. */ |
947 extern bool enable_moveup_set_path_p; | 947 extern bool enable_moveup_set_path_p; |
948 extern bool pipelining_p; | 948 extern bool pipelining_p; |
949 extern bool bookkeeping_p; | 949 extern bool bookkeeping_p; |
950 extern int max_insns_to_rename; | 950 extern int max_insns_to_rename; |
951 extern bool preheader_removed; | 951 extern bool preheader_removed; |
952 | 952 |
953 /* Software lookahead window size. | 953 /* Software lookahead window size. |
954 According to the results in Nakatani and Ebcioglu [1993], window size of 16 | 954 According to the results in Nakatani and Ebcioglu [1993], window size of 16 |
955 is enough to extract most ILP in integer code. */ | 955 is enough to extract most ILP in integer code. */ |
956 #define MAX_WS (PARAM_VALUE (PARAM_SELSCHED_MAX_LOOKAHEAD)) | 956 #define MAX_WS (PARAM_VALUE (PARAM_SELSCHED_MAX_LOOKAHEAD)) |
957 | 957 |
958 extern regset sel_all_regs; | 958 extern regset sel_all_regs; |
959 | 959 |
967 /* An edge on which we're iterating. */ | 967 /* An edge on which we're iterating. */ |
968 edge e1; | 968 edge e1; |
969 | 969 |
970 /* The previous edge saved after skipping empty blocks. */ | 970 /* The previous edge saved after skipping empty blocks. */ |
971 edge e2; | 971 edge e2; |
972 | 972 |
973 /* Edge iterator used when there are successors in other basic blocks. */ | 973 /* Edge iterator used when there are successors in other basic blocks. */ |
974 edge_iterator ei; | 974 edge_iterator ei; |
975 | 975 |
976 /* Successor block we're traversing. */ | 976 /* Successor block we're traversing. */ |
977 basic_block bb; | 977 basic_block bb; |
978 | 978 |
979 /* Flags that are passed to the iterator. We return only successors | 979 /* Flags that are passed to the iterator. We return only successors |
980 that comply to these flags. */ | 980 that comply to these flags. */ |
981 short flags; | 981 short flags; |
982 | 982 |
983 /* When flags include SUCCS_ALL, this will be set to the exact type | 983 /* When flags include SUCCS_ALL, this will be set to the exact type |
984 of the sucessor we're traversing now. */ | 984 of the sucessor we're traversing now. */ |
985 short current_flags; | 985 short current_flags; |
986 | 986 |
987 /* If skip to loop exits, save here information about loop exits. */ | 987 /* If skip to loop exits, save here information about loop exits. */ |
988 int current_exit; | 988 int current_exit; |
996 short flags; | 996 short flags; |
997 | 997 |
998 /* Successors that correspond to the flags. */ | 998 /* Successors that correspond to the flags. */ |
999 insn_vec_t succs_ok; | 999 insn_vec_t succs_ok; |
1000 | 1000 |
1001 /* Their probabilities. As of now, we don't need this for other | 1001 /* Their probabilities. As of now, we don't need this for other |
1002 successors. */ | 1002 successors. */ |
1003 VEC(int,heap) *probs_ok; | 1003 VEC(int,heap) *probs_ok; |
1004 | 1004 |
1005 /* Other successors. */ | 1005 /* Other successors. */ |
1006 insn_vec_t succs_other; | 1006 insn_vec_t succs_other; |
1017 | 1017 |
1018 /* Some needed definitions. */ | 1018 /* Some needed definitions. */ |
1019 extern basic_block after_recovery; | 1019 extern basic_block after_recovery; |
1020 | 1020 |
1021 extern insn_t sel_bb_head (basic_block); | 1021 extern insn_t sel_bb_head (basic_block); |
1022 extern insn_t sel_bb_end (basic_block); | |
1022 extern bool sel_bb_empty_p (basic_block); | 1023 extern bool sel_bb_empty_p (basic_block); |
1023 extern bool in_current_region_p (basic_block); | 1024 extern bool in_current_region_p (basic_block); |
1024 | 1025 |
1025 /* True when BB is a header of the inner loop. */ | 1026 /* True when BB is a header of the inner loop. */ |
1026 static inline bool | 1027 static inline bool |
1027 inner_loop_header_p (basic_block bb) | 1028 inner_loop_header_p (basic_block bb) |
1028 { | 1029 { |
1029 struct loop *inner_loop; | 1030 struct loop *inner_loop; |
1030 | 1031 |
1031 if (!current_loop_nest) | 1032 if (!current_loop_nest) |
1032 return false; | 1033 return false; |
1033 | 1034 |
1034 if (bb == EXIT_BLOCK_PTR) | 1035 if (bb == EXIT_BLOCK_PTR) |
1045 /* Could be '=' here because of wrong loop depths. */ | 1046 /* Could be '=' here because of wrong loop depths. */ |
1046 gcc_assert (loop_depth (inner_loop) >= loop_depth (current_loop_nest)); | 1047 gcc_assert (loop_depth (inner_loop) >= loop_depth (current_loop_nest)); |
1047 return true; | 1048 return true; |
1048 } | 1049 } |
1049 | 1050 |
1050 return false; | 1051 return false; |
1051 } | 1052 } |
1052 | 1053 |
1053 /* Return exit edges of LOOP, filtering out edges with the same dest bb. */ | 1054 /* Return exit edges of LOOP, filtering out edges with the same dest bb. */ |
1054 static inline VEC (edge, heap) * | 1055 static inline VEC (edge, heap) * |
1055 get_loop_exit_edges_unique_dests (const struct loop *loop) | 1056 get_loop_exit_edges_unique_dests (const struct loop *loop) |
1063 for (exit = loop->exits->next; exit->e; exit = exit->next) | 1064 for (exit = loop->exits->next; exit->e; exit = exit->next) |
1064 { | 1065 { |
1065 int i; | 1066 int i; |
1066 edge e; | 1067 edge e; |
1067 bool was_dest = false; | 1068 bool was_dest = false; |
1068 | 1069 |
1069 for (i = 0; VEC_iterate (edge, edges, i, e); i++) | 1070 for (i = 0; VEC_iterate (edge, edges, i, e); i++) |
1070 if (e->dest == exit->e->dest) | 1071 if (e->dest == exit->e->dest) |
1071 { | 1072 { |
1072 was_dest = true; | 1073 was_dest = true; |
1073 break; | 1074 break; |
1077 VEC_safe_push (edge, heap, edges, exit->e); | 1078 VEC_safe_push (edge, heap, edges, exit->e); |
1078 } | 1079 } |
1079 return edges; | 1080 return edges; |
1080 } | 1081 } |
1081 | 1082 |
1082 /* Collect all loop exits recursively, skipping empty BBs between them. | 1083 static bool |
1084 sel_bb_empty_or_nop_p (basic_block bb) | |
1085 { | |
1086 insn_t first = sel_bb_head (bb), last; | |
1087 | |
1088 if (first == NULL_RTX) | |
1089 return true; | |
1090 | |
1091 if (!INSN_NOP_P (first)) | |
1092 return false; | |
1093 | |
1094 if (bb == EXIT_BLOCK_PTR) | |
1095 return false; | |
1096 | |
1097 last = sel_bb_end (bb); | |
1098 if (first != last) | |
1099 return false; | |
1100 | |
1101 return true; | |
1102 } | |
1103 | |
1104 /* Collect all loop exits recursively, skipping empty BBs between them. | |
1083 E.g. if BB is a loop header which has several loop exits, | 1105 E.g. if BB is a loop header which has several loop exits, |
1084 traverse all of them and if any of them turns out to be another loop header | 1106 traverse all of them and if any of them turns out to be another loop header |
1085 (after skipping empty BBs), add its loop exits to the resulting vector | 1107 (after skipping empty BBs), add its loop exits to the resulting vector |
1086 as well. */ | 1108 as well. */ |
1087 static inline VEC(edge, heap) * | 1109 static inline VEC(edge, heap) * |
1088 get_all_loop_exits (basic_block bb) | 1110 get_all_loop_exits (basic_block bb) |
1089 { | 1111 { |
1090 VEC(edge, heap) *exits = NULL; | 1112 VEC(edge, heap) *exits = NULL; |
1091 | 1113 |
1092 /* If bb is empty, and we're skipping to loop exits, then | 1114 /* If bb is empty, and we're skipping to loop exits, then |
1093 consider bb as a possible gate to the inner loop now. */ | 1115 consider bb as a possible gate to the inner loop now. */ |
1094 while (sel_bb_empty_p (bb) | 1116 while (sel_bb_empty_or_nop_p (bb) |
1095 && in_current_region_p (bb)) | 1117 && in_current_region_p (bb)) |
1096 { | 1118 { |
1097 bb = single_succ (bb); | 1119 bb = single_succ (bb); |
1098 | 1120 |
1099 /* This empty block could only lead outside the region. */ | 1121 /* This empty block could only lead outside the region. */ |
1105 { | 1127 { |
1106 struct loop *this_loop; | 1128 struct loop *this_loop; |
1107 struct loop *pred_loop = NULL; | 1129 struct loop *pred_loop = NULL; |
1108 int i; | 1130 int i; |
1109 edge e; | 1131 edge e; |
1110 | 1132 |
1111 for (this_loop = bb->loop_father; | 1133 for (this_loop = bb->loop_father; |
1112 this_loop && this_loop != current_loop_nest; | 1134 this_loop && this_loop != current_loop_nest; |
1113 this_loop = loop_outer (this_loop)) | 1135 this_loop = loop_outer (this_loop)) |
1114 pred_loop = this_loop; | 1136 pred_loop = this_loop; |
1115 | 1137 |
1116 this_loop = pred_loop; | 1138 this_loop = pred_loop; |
1117 gcc_assert (this_loop != NULL); | 1139 gcc_assert (this_loop != NULL); |
1118 | 1140 |
1119 exits = get_loop_exit_edges_unique_dests (this_loop); | 1141 exits = get_loop_exit_edges_unique_dests (this_loop); |
1120 | 1142 |
1121 /* Traverse all loop headers. */ | 1143 /* Traverse all loop headers. */ |
1122 for (i = 0; VEC_iterate (edge, exits, i, e); i++) | 1144 for (i = 0; VEC_iterate (edge, exits, i, e); i++) |
1123 if (in_current_region_p (e->dest)) | 1145 if (in_current_region_p (e->dest)) |
1124 { | 1146 { |
1125 VEC(edge, heap) *next_exits = get_all_loop_exits (e->dest); | 1147 VEC(edge, heap) *next_exits = get_all_loop_exits (e->dest); |
1126 | 1148 |
1127 if (next_exits) | 1149 if (next_exits) |
1128 { | 1150 { |
1129 int j; | 1151 int j; |
1130 edge ne; | 1152 edge ne; |
1131 | 1153 |
1132 /* Add all loop exits for the current edge into the | 1154 /* Add all loop exits for the current edge into the |
1133 resulting vector. */ | 1155 resulting vector. */ |
1134 for (j = 0; VEC_iterate (edge, next_exits, j, ne); j++) | 1156 for (j = 0; VEC_iterate (edge, next_exits, j, ne); j++) |
1135 VEC_safe_push (edge, heap, exits, ne); | 1157 VEC_safe_push (edge, heap, exits, ne); |
1136 | 1158 |
1137 /* Remove the original edge. */ | 1159 /* Remove the original edge. */ |
1138 VEC_ordered_remove (edge, exits, i); | 1160 VEC_ordered_remove (edge, exits, i); |
1139 | 1161 |
1140 /* Decrease the loop counter so we won't skip anything. */ | 1162 /* Decrease the loop counter so we won't skip anything. */ |
1141 i--; | 1163 i--; |
1157 #define SUCCS_BACK (2) | 1179 #define SUCCS_BACK (2) |
1158 | 1180 |
1159 /* Include successors that are outside of the current region. */ | 1181 /* Include successors that are outside of the current region. */ |
1160 #define SUCCS_OUT (4) | 1182 #define SUCCS_OUT (4) |
1161 | 1183 |
1162 /* When pipelining of the outer loops is enabled, skip innermost loops | 1184 /* When pipelining of the outer loops is enabled, skip innermost loops |
1163 to their exits. */ | 1185 to their exits. */ |
1164 #define SUCCS_SKIP_TO_LOOP_EXITS (8) | 1186 #define SUCCS_SKIP_TO_LOOP_EXITS (8) |
1165 | 1187 |
1166 /* Include all successors. */ | 1188 /* Include all successors. */ |
1167 #define SUCCS_ALL (SUCCS_NORMAL | SUCCS_BACK | SUCCS_OUT) | 1189 #define SUCCS_ALL (SUCCS_NORMAL | SUCCS_BACK | SUCCS_OUT) |
1220 ip->current_flags = SUCCS_NORMAL; | 1242 ip->current_flags = SUCCS_NORMAL; |
1221 return true; | 1243 return true; |
1222 } | 1244 } |
1223 else | 1245 else |
1224 { | 1246 { |
1225 while (1) | 1247 while (1) |
1226 { | 1248 { |
1227 edge e_tmp = NULL; | 1249 edge e_tmp = NULL; |
1228 | 1250 |
1229 /* First, try loop exits, if we have them. */ | 1251 /* First, try loop exits, if we have them. */ |
1230 if (ip->loop_exits) | 1252 if (ip->loop_exits) |
1231 { | 1253 { |
1232 do | 1254 do |
1233 { | 1255 { |
1234 VEC_iterate (edge, ip->loop_exits, | 1256 VEC_iterate (edge, ip->loop_exits, |
1235 ip->current_exit, e_tmp); | 1257 ip->current_exit, e_tmp); |
1236 ip->current_exit++; | 1258 ip->current_exit++; |
1237 } | 1259 } |
1238 while (e_tmp && !check (e_tmp, ip)); | 1260 while (e_tmp && !check (e_tmp, ip)); |
1239 | 1261 |
1240 if (!e_tmp) | 1262 if (!e_tmp) |
1241 VEC_free (edge, heap, ip->loop_exits); | 1263 VEC_free (edge, heap, ip->loop_exits); |
1242 } | 1264 } |
1243 | 1265 |
1244 /* If we have found a successor, then great. */ | 1266 /* If we have found a successor, then great. */ |
1254 basic_block bb = ip->e1->dest; | 1276 basic_block bb = ip->e1->dest; |
1255 | 1277 |
1256 /* Consider bb as a possible loop header. */ | 1278 /* Consider bb as a possible loop header. */ |
1257 if ((ip->flags & SUCCS_SKIP_TO_LOOP_EXITS) | 1279 if ((ip->flags & SUCCS_SKIP_TO_LOOP_EXITS) |
1258 && flag_sel_sched_pipelining_outer_loops | 1280 && flag_sel_sched_pipelining_outer_loops |
1259 && (!in_current_region_p (bb) | 1281 && (!in_current_region_p (bb) |
1260 || BLOCK_TO_BB (ip->bb->index) | 1282 || BLOCK_TO_BB (ip->bb->index) |
1261 < BLOCK_TO_BB (bb->index))) | 1283 < BLOCK_TO_BB (bb->index))) |
1262 { | 1284 { |
1263 /* Get all loop exits recursively. */ | 1285 /* Get all loop exits recursively. */ |
1264 ip->loop_exits = get_all_loop_exits (bb); | 1286 ip->loop_exits = get_all_loop_exits (bb); |
1265 | 1287 |
1266 if (ip->loop_exits) | 1288 if (ip->loop_exits) |
1267 { | 1289 { |
1268 ip->current_exit = 0; | 1290 ip->current_exit = 0; |
1269 /* Move the iterator now, because we won't do | 1291 /* Move the iterator now, because we won't do |
1270 succ_iter_next until loop exits will end. */ | 1292 succ_iter_next until loop exits will end. */ |
1271 ei_next (&(ip->ei)); | 1293 ei_next (&(ip->ei)); |
1272 break; | 1294 break; |
1273 } | 1295 } |
1274 } | 1296 } |
1348 | 1370 |
1349 /* Skip empty blocks, but be careful not to leave the region. */ | 1371 /* Skip empty blocks, but be careful not to leave the region. */ |
1350 while (1) | 1372 while (1) |
1351 { | 1373 { |
1352 if (!sel_bb_empty_p (bb)) | 1374 if (!sel_bb_empty_p (bb)) |
1353 break; | 1375 { |
1354 | 1376 edge ne; |
1355 if (!in_current_region_p (bb) | 1377 basic_block nbb; |
1378 | |
1379 if (!sel_bb_empty_or_nop_p (bb)) | |
1380 break; | |
1381 | |
1382 ne = EDGE_SUCC (bb, 0); | |
1383 nbb = ne->dest; | |
1384 | |
1385 if (!in_current_region_p (nbb) | |
1386 && !(flags & SUCCS_OUT)) | |
1387 break; | |
1388 | |
1389 e2 = ne; | |
1390 bb = nbb; | |
1391 continue; | |
1392 } | |
1393 | |
1394 if (!in_current_region_p (bb) | |
1356 && !(flags & SUCCS_OUT)) | 1395 && !(flags & SUCCS_OUT)) |
1357 return false; | 1396 return false; |
1358 | 1397 |
1398 if (EDGE_COUNT (bb->succs) == 0) | |
1399 return false; | |
1400 | |
1359 e2 = EDGE_SUCC (bb, 0); | 1401 e2 = EDGE_SUCC (bb, 0); |
1360 bb = e2->dest; | 1402 bb = e2->dest; |
1361 | |
1362 /* This couldn't happen inside a region. */ | |
1363 gcc_assert (! in_current_region_p (bb) | |
1364 || (flags & SUCCS_OUT)); | |
1365 } | 1403 } |
1366 | 1404 |
1367 /* Save the second edge for later checks. */ | 1405 /* Save the second edge for later checks. */ |
1368 ip->e2 = e2; | 1406 ip->e2 = e2; |
1369 | 1407 |
1370 if (in_current_region_p (bb)) | 1408 if (in_current_region_p (bb)) |
1371 { | 1409 { |
1372 /* BLOCK_TO_BB sets topological order of the region here. | 1410 /* BLOCK_TO_BB sets topological order of the region here. |
1373 It is important to use real predecessor here, which is ip->bb, | 1411 It is important to use real predecessor here, which is ip->bb, |
1374 as we may well have e1->src outside current region, | 1412 as we may well have e1->src outside current region, |
1375 when skipping to loop exits. */ | 1413 when skipping to loop exits. */ |
1376 bool succeeds_in_top_order = (BLOCK_TO_BB (ip->bb->index) | 1414 bool succeeds_in_top_order = (BLOCK_TO_BB (ip->bb->index) |
1377 < BLOCK_TO_BB (bb->index)); | 1415 < BLOCK_TO_BB (bb->index)); |
1378 | 1416 |
1379 /* This is true for the all cases except the last one. */ | 1417 /* This is true for the all cases except the last one. */ |
1380 ip->current_flags = SUCCS_NORMAL; | 1418 ip->current_flags = SUCCS_NORMAL; |
1381 | 1419 |
1382 /* We are advancing forward in the region, as usual. */ | 1420 /* We are advancing forward in the region, as usual. */ |
1383 if (succeeds_in_top_order) | 1421 if (succeeds_in_top_order) |
1384 { | 1422 { |
1385 /* We are skipping to loop exits here. */ | 1423 /* We are skipping to loop exits here. */ |
1386 gcc_assert (!src_outside_rgn | 1424 gcc_assert (!src_outside_rgn |
1387 || flag_sel_sched_pipelining_outer_loops); | 1425 || flag_sel_sched_pipelining_outer_loops); |
1388 return !!(flags & SUCCS_NORMAL); | 1426 return !!(flags & SUCCS_NORMAL); |
1389 } | 1427 } |
1390 | 1428 |
1391 /* This is a back edge. During pipelining we ignore back edges, | 1429 /* This is a back edge. During pipelining we ignore back edges, |
1392 but only when it leads to the same loop. It can lead to the header | 1430 but only when it leads to the same loop. It can lead to the header |
1393 of the outer loop, which will also be the preheader of | 1431 of the outer loop, which will also be the preheader of |
1394 the current loop. */ | 1432 the current loop. */ |
1395 if (pipelining_p | 1433 if (pipelining_p |
1396 && e1->src->loop_father == bb->loop_father) | 1434 && e1->src->loop_father == bb->loop_father) |
1397 return !!(flags & SUCCS_NORMAL); | 1435 return !!(flags & SUCCS_NORMAL); |
1398 | 1436 |
1423 switch (EDGE_COUNT (bb->succs)) | 1461 switch (EDGE_COUNT (bb->succs)) |
1424 { | 1462 { |
1425 case 0: | 1463 case 0: |
1426 return bb->next_bb; | 1464 return bb->next_bb; |
1427 | 1465 |
1428 case 1: | 1466 case 1: |
1429 return single_succ (bb); | 1467 return single_succ (bb); |
1430 | 1468 |
1431 case 2: | 1469 case 2: |
1432 return FALLTHRU_EDGE (bb)->dest; | 1470 return FALLTHRU_EDGE (bb)->dest; |
1433 | 1471 |
1434 default: | 1472 default: |
1435 return bb->next_bb; | 1473 return bb->next_bb; |
1436 } | 1474 } |
1437 | 1475 |
1438 gcc_unreachable (); | 1476 gcc_unreachable (); |
1472 extern regset get_clear_regset_from_pool (void); | 1510 extern regset get_clear_regset_from_pool (void); |
1473 extern void return_regset_to_pool (regset); | 1511 extern void return_regset_to_pool (regset); |
1474 extern void free_regset_pool (void); | 1512 extern void free_regset_pool (void); |
1475 | 1513 |
1476 extern insn_t get_nop_from_pool (insn_t); | 1514 extern insn_t get_nop_from_pool (insn_t); |
1477 extern void return_nop_to_pool (insn_t); | 1515 extern void return_nop_to_pool (insn_t, bool); |
1478 extern void free_nop_pool (void); | 1516 extern void free_nop_pool (void); |
1479 | 1517 |
1480 /* Vinsns functions. */ | 1518 /* Vinsns functions. */ |
1481 extern bool vinsn_separable_p (vinsn_t); | 1519 extern bool vinsn_separable_p (vinsn_t); |
1482 extern bool vinsn_cond_branch_p (vinsn_t); | 1520 extern bool vinsn_cond_branch_p (vinsn_t); |
1496 extern void copy_expr_onside (expr_t, expr_t); | 1534 extern void copy_expr_onside (expr_t, expr_t); |
1497 extern void merge_expr_data (expr_t, expr_t, insn_t); | 1535 extern void merge_expr_data (expr_t, expr_t, insn_t); |
1498 extern void merge_expr (expr_t, expr_t, insn_t); | 1536 extern void merge_expr (expr_t, expr_t, insn_t); |
1499 extern void clear_expr (expr_t); | 1537 extern void clear_expr (expr_t); |
1500 extern unsigned expr_dest_regno (expr_t); | 1538 extern unsigned expr_dest_regno (expr_t); |
1501 extern rtx expr_dest_reg (expr_t); | 1539 extern rtx expr_dest_reg (expr_t); |
1502 extern int find_in_history_vect (VEC(expr_history_def, heap) *, | 1540 extern int find_in_history_vect (VEC(expr_history_def, heap) *, |
1503 rtx, vinsn_t, bool); | 1541 rtx, vinsn_t, bool); |
1504 extern void insert_in_history_vect (VEC(expr_history_def, heap) **, | 1542 extern void insert_in_history_vect (VEC(expr_history_def, heap) **, |
1505 unsigned, enum local_trans_type, | 1543 unsigned, enum local_trans_type, |
1506 vinsn_t, vinsn_t, ds_t); | 1544 vinsn_t, vinsn_t, ds_t); |
1507 extern void mark_unavailable_targets (av_set_t, av_set_t, regset); | 1545 extern void mark_unavailable_targets (av_set_t, av_set_t, regset); |
1508 extern int speculate_expr (expr_t, ds_t); | 1546 extern int speculate_expr (expr_t, ds_t); |
1509 | 1547 |
1510 /* Av set functions. */ | 1548 /* Av set functions. */ |
1582 extern void sel_redirect_edge_and_branch (edge, basic_block); | 1620 extern void sel_redirect_edge_and_branch (edge, basic_block); |
1583 extern void sel_redirect_edge_and_branch_force (edge, basic_block); | 1621 extern void sel_redirect_edge_and_branch_force (edge, basic_block); |
1584 extern void sel_init_pipelining (void); | 1622 extern void sel_init_pipelining (void); |
1585 extern void sel_finish_pipelining (void); | 1623 extern void sel_finish_pipelining (void); |
1586 extern void sel_sched_region (int); | 1624 extern void sel_sched_region (int); |
1587 extern void sel_find_rgns (void); | |
1588 extern loop_p get_loop_nest_for_rgn (unsigned int); | 1625 extern loop_p get_loop_nest_for_rgn (unsigned int); |
1589 extern bool considered_for_pipelining_p (struct loop *); | 1626 extern bool considered_for_pipelining_p (struct loop *); |
1590 extern void make_region_from_loop_preheader (VEC(basic_block, heap) **); | 1627 extern void make_region_from_loop_preheader (VEC(basic_block, heap) **); |
1591 extern void sel_add_loop_preheaders (void); | 1628 extern void sel_add_loop_preheaders (void); |
1592 extern bool sel_is_loop_preheader_p (basic_block); | 1629 extern bool sel_is_loop_preheader_p (basic_block); |
1607 /* Various initialization functions. */ | 1644 /* Various initialization functions. */ |
1608 extern void init_lv_sets (void); | 1645 extern void init_lv_sets (void); |
1609 extern void free_lv_sets (void); | 1646 extern void free_lv_sets (void); |
1610 extern void setup_nop_and_exit_insns (void); | 1647 extern void setup_nop_and_exit_insns (void); |
1611 extern void free_nop_and_exit_insns (void); | 1648 extern void free_nop_and_exit_insns (void); |
1649 extern void free_data_for_scheduled_insn (insn_t); | |
1612 extern void setup_nop_vinsn (void); | 1650 extern void setup_nop_vinsn (void); |
1613 extern void free_nop_vinsn (void); | 1651 extern void free_nop_vinsn (void); |
1614 extern void sel_set_sched_flags (void); | 1652 extern void sel_set_sched_flags (void); |
1615 extern void sel_setup_sched_infos (void); | 1653 extern void sel_setup_sched_infos (void); |
1616 extern void alloc_sched_pools (void); | 1654 extern void alloc_sched_pools (void); |