Mercurial > hg > CbC > CbC_gcc
diff 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 |
line wrap: on
line diff
--- a/gcc/sel-sched-ir.h Sun Feb 07 18:28:00 2010 +0900 +++ b/gcc/sel-sched-ir.h Fri Feb 12 23:39:51 2010 +0900 @@ -1,6 +1,6 @@ /* Instruction scheduling pass. This file contains definitions used internally in the scheduler. - Copyright (C) 2006, 2007, 2008 Free Software Foundation, Inc. + Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc. This file is part of GCC. @@ -68,7 +68,7 @@ #define ILIST_INSN(L) (_XLIST_X (L)) #define ILIST_NEXT(L) (_XLIST_NEXT (L)) -/* This lists possible transformations that done locally, i.e. in +/* This lists possible transformations that done locally, i.e. in moveup_expr. */ enum local_trans_type { @@ -76,7 +76,7 @@ TRANS_SPECULATION }; -/* This struct is used to record the history of expression's +/* This struct is used to record the history of expression's transformations. */ struct expr_history_def_1 { @@ -114,8 +114,8 @@ control on scheduling. */ int spec; - /* Degree of speculativeness measured as probability of executing - instruction's original basic block given relative to + /* Degree of speculativeness measured as probability of executing + instruction's original basic block given relative to the current scheduling point. */ int usefulness; @@ -128,7 +128,7 @@ /* Number of times the insn was scheduled. */ int sched_times; - /* A basic block index this was originated from. Zero when there is + /* A basic block index this was originated from. Zero when there is more than one originator. */ int orig_bb_index; @@ -140,23 +140,23 @@ (used only during move_op ()). */ ds_t spec_to_check_ds; - /* Cycle on which original insn was scheduled. Zero when it has not yet + /* Cycle on which original insn was scheduled. Zero when it has not yet been scheduled or more than one originator. */ int orig_sched_cycle; /* This vector contains the history of insn's transformations. */ VEC(expr_history_def, heap) *history_of_changes; - /* True (1) when original target (register or memory) of this instruction + /* True (1) when original target (register or memory) of this instruction is available for scheduling, false otherwise. -1 means we're not sure; please run find_used_regs to clarify. */ signed char target_available; - /* True when this expression needs a speculation check to be scheduled. + /* True when this expression needs a speculation check to be scheduled. This is used during find_used_regs. */ BOOL_BITFIELD needs_spec_check_p : 1; - /* True when the expression was substituted. Used for statistical + /* True when the expression was substituted. Used for statistical purposes. */ BOOL_BITFIELD was_substituted : 1; @@ -195,7 +195,7 @@ #define EXPR_CANT_MOVE(EXPR) ((EXPR)->cant_move) #define EXPR_WAS_CHANGED(EXPR) (VEC_length (expr_history_def, \ - EXPR_HISTORY_OF_CHANGES (EXPR)) > 0) + EXPR_HISTORY_OF_CHANGES (EXPR)) > 0) /* Insn definition for list of original insns in find_used_regs. */ struct _def @@ -204,7 +204,7 @@ /* FIXME: Get rid of CROSSES_CALL in each def, since if we're moving up rhs from two different places, but only one of the code motion paths - crosses a call, we can't use any of the call_used_regs, no matter which + crosses a call, we can't use any of the call_used_regs, no matter which path or whether all paths crosses a call. Thus we should move CROSSES_CALL to static params. */ bool crosses_call; @@ -232,7 +232,7 @@ /* This set moved to the fence. */ av_set_t av1; - + /* Deps context at this boundary. As long as we have one boundary per fence, this is just a pointer to the same deps context as in the corresponding fence. */ @@ -286,7 +286,7 @@ /* A vector of insns that are scheduled but not yet completed. */ VEC (rtx,gc) *executing_insns; - /* A vector indexed by UIDs that caches the earliest cycle on which + /* A vector indexed by UIDs that caches the earliest cycle on which an insn can be scheduled on this fence. */ int *ready_ticks; @@ -464,7 +464,7 @@ #define _FOR_EACH_1(TYPE, ELEM, I, LP) \ for (_list_iter_start (&(I), (LP), true); \ _list_iter_cond_##TYPE (*(I).lp, &(ELEM)); \ - _list_iter_next (&(I))) + _list_iter_next (&(I))) /* _xlist_t functions. */ @@ -666,7 +666,7 @@ #define VINSN_MAY_TRAP_P(VI) ((VI)->may_trap_p) -/* An entry of the hashtable describing transformations happened when +/* An entry of the hashtable describing transformations happened when moving up through an insn. */ struct transformed_insns { @@ -709,18 +709,18 @@ /* An INSN_UID bit is set when deps analysis result is already known. */ bitmap analyzed_deps; - /* An INSN_UID bit is set when a hard dep was found, not set when + /* An INSN_UID bit is set when a hard dep was found, not set when no dependence is found. This is meaningful only when the analyzed_deps bitmap has its bit set. */ bitmap found_deps; - /* An INSN_UID bit is set when this is a bookkeeping insn generated from + /* An INSN_UID bit is set when this is a bookkeeping insn generated from a parent with this uid. */ bitmap originators; /* A hashtable caching the result of insn transformations through this one. */ htab_t transformed_insns; - + /* A context incapsulating this insn. */ struct deps deps_context; @@ -767,8 +767,8 @@ #define INSN_ASM_P(INSN) (SID (INSN)->asm_p) #define INSN_SCHED_NEXT(INSN) (SID (INSN)->sched_next) #define INSN_ANALYZED_DEPS(INSN) (SID (INSN)->analyzed_deps) -#define INSN_FOUND_DEPS(INSN) (SID (INSN)->found_deps) -#define INSN_DEPS_CONTEXT(INSN) (SID (INSN)->deps_context) +#define INSN_FOUND_DEPS(INSN) (SID (INSN)->found_deps) +#define INSN_DEPS_CONTEXT(INSN) (SID (INSN)->deps_context) #define INSN_ORIGINATORS(INSN) (SID (INSN)->originators) #define INSN_ORIGINATORS_BY_UID(UID) (SID_BY_UID (UID)->originators) #define INSN_TRANSFORMED_INSNS(INSN) (SID (INSN)->transformed_insns) @@ -898,7 +898,7 @@ #define BB_LV_SET_VALID_P(BB) (SEL_GLOBAL_BB_INFO (BB)->lv_set_valid_p) /* Per basic block data for the region. */ -typedef struct +typedef struct { /* This insn stream is constructed in such a way that it should be traversed by PREV_INSN field - (*not* NEXT_INSN). */ @@ -947,11 +947,11 @@ extern bool enable_moveup_set_path_p; extern bool pipelining_p; extern bool bookkeeping_p; -extern int max_insns_to_rename; +extern int max_insns_to_rename; extern bool preheader_removed; /* Software lookahead window size. - According to the results in Nakatani and Ebcioglu [1993], window size of 16 + According to the results in Nakatani and Ebcioglu [1993], window size of 16 is enough to extract most ILP in integer code. */ #define MAX_WS (PARAM_VALUE (PARAM_SELSCHED_MAX_LOOKAHEAD)) @@ -969,7 +969,7 @@ /* The previous edge saved after skipping empty blocks. */ edge e2; - + /* Edge iterator used when there are successors in other basic blocks. */ edge_iterator ei; @@ -979,8 +979,8 @@ /* Flags that are passed to the iterator. We return only successors that comply to these flags. */ short flags; - - /* When flags include SUCCS_ALL, this will be set to the exact type + + /* When flags include SUCCS_ALL, this will be set to the exact type of the sucessor we're traversing now. */ short current_flags; @@ -998,7 +998,7 @@ /* Successors that correspond to the flags. */ insn_vec_t succs_ok; - /* Their probabilities. As of now, we don't need this for other + /* Their probabilities. As of now, we don't need this for other successors. */ VEC(int,heap) *probs_ok; @@ -1019,6 +1019,7 @@ extern basic_block after_recovery; extern insn_t sel_bb_head (basic_block); +extern insn_t sel_bb_end (basic_block); extern bool sel_bb_empty_p (basic_block); extern bool in_current_region_p (basic_block); @@ -1026,7 +1027,7 @@ static inline bool inner_loop_header_p (basic_block bb) { - struct loop *inner_loop; + struct loop *inner_loop; if (!current_loop_nest) return false; @@ -1047,7 +1048,7 @@ return true; } - return false; + return false; } /* Return exit edges of LOOP, filtering out edges with the same dest bb. */ @@ -1065,7 +1066,7 @@ int i; edge e; bool was_dest = false; - + for (i = 0; VEC_iterate (edge, edges, i, e); i++) if (e->dest == exit->e->dest) { @@ -1079,10 +1080,31 @@ return edges; } -/* Collect all loop exits recursively, skipping empty BBs between them. +static bool +sel_bb_empty_or_nop_p (basic_block bb) +{ + insn_t first = sel_bb_head (bb), last; + + if (first == NULL_RTX) + return true; + + if (!INSN_NOP_P (first)) + return false; + + if (bb == EXIT_BLOCK_PTR) + return false; + + last = sel_bb_end (bb); + if (first != last) + return false; + + return true; +} + +/* Collect all loop exits recursively, skipping empty BBs between them. E.g. if BB is a loop header which has several loop exits, traverse all of them and if any of them turns out to be another loop header - (after skipping empty BBs), add its loop exits to the resulting vector + (after skipping empty BBs), add its loop exits to the resulting vector as well. */ static inline VEC(edge, heap) * get_all_loop_exits (basic_block bb) @@ -1091,7 +1113,7 @@ /* If bb is empty, and we're skipping to loop exits, then consider bb as a possible gate to the inner loop now. */ - while (sel_bb_empty_p (bb) + while (sel_bb_empty_or_nop_p (bb) && in_current_region_p (bb)) { bb = single_succ (bb); @@ -1107,12 +1129,12 @@ struct loop *pred_loop = NULL; int i; edge e; - + for (this_loop = bb->loop_father; this_loop && this_loop != current_loop_nest; this_loop = loop_outer (this_loop)) pred_loop = this_loop; - + this_loop = pred_loop; gcc_assert (this_loop != NULL); @@ -1123,17 +1145,17 @@ if (in_current_region_p (e->dest)) { VEC(edge, heap) *next_exits = get_all_loop_exits (e->dest); - + if (next_exits) { int j; edge ne; - + /* Add all loop exits for the current edge into the resulting vector. */ for (j = 0; VEC_iterate (edge, next_exits, j, ne); j++) VEC_safe_push (edge, heap, exits, ne); - + /* Remove the original edge. */ VEC_ordered_remove (edge, exits, i); @@ -1159,7 +1181,7 @@ /* Include successors that are outside of the current region. */ #define SUCCS_OUT (4) -/* When pipelining of the outer loops is enabled, skip innermost loops +/* When pipelining of the outer loops is enabled, skip innermost loops to their exits. */ #define SUCCS_SKIP_TO_LOOP_EXITS (8) @@ -1222,7 +1244,7 @@ } else { - while (1) + while (1) { edge e_tmp = NULL; @@ -1231,12 +1253,12 @@ { do { - VEC_iterate (edge, ip->loop_exits, + VEC_iterate (edge, ip->loop_exits, ip->current_exit, e_tmp); ip->current_exit++; } while (e_tmp && !check (e_tmp, ip)); - + if (!e_tmp) VEC_free (edge, heap, ip->loop_exits); } @@ -1256,8 +1278,8 @@ /* Consider bb as a possible loop header. */ if ((ip->flags & SUCCS_SKIP_TO_LOOP_EXITS) && flag_sel_sched_pipelining_outer_loops - && (!in_current_region_p (bb) - || BLOCK_TO_BB (ip->bb->index) + && (!in_current_region_p (bb) + || BLOCK_TO_BB (ip->bb->index) < BLOCK_TO_BB (bb->index))) { /* Get all loop exits recursively. */ @@ -1266,7 +1288,7 @@ if (ip->loop_exits) { ip->current_exit = 0; - /* Move the iterator now, because we won't do + /* Move the iterator now, because we won't do succ_iter_next until loop exits will end. */ ei_next (&(ip->ei)); break; @@ -1350,35 +1372,51 @@ while (1) { if (!sel_bb_empty_p (bb)) - break; - - if (!in_current_region_p (bb) + { + edge ne; + basic_block nbb; + + if (!sel_bb_empty_or_nop_p (bb)) + break; + + ne = EDGE_SUCC (bb, 0); + nbb = ne->dest; + + if (!in_current_region_p (nbb) + && !(flags & SUCCS_OUT)) + break; + + e2 = ne; + bb = nbb; + continue; + } + + if (!in_current_region_p (bb) && !(flags & SUCCS_OUT)) return false; + if (EDGE_COUNT (bb->succs) == 0) + return false; + e2 = EDGE_SUCC (bb, 0); bb = e2->dest; - - /* This couldn't happen inside a region. */ - gcc_assert (! in_current_region_p (bb) - || (flags & SUCCS_OUT)); } - + /* Save the second edge for later checks. */ ip->e2 = e2; if (in_current_region_p (bb)) { - /* BLOCK_TO_BB sets topological order of the region here. - It is important to use real predecessor here, which is ip->bb, - as we may well have e1->src outside current region, + /* BLOCK_TO_BB sets topological order of the region here. + It is important to use real predecessor here, which is ip->bb, + as we may well have e1->src outside current region, when skipping to loop exits. */ bool succeeds_in_top_order = (BLOCK_TO_BB (ip->bb->index) < BLOCK_TO_BB (bb->index)); /* This is true for the all cases except the last one. */ ip->current_flags = SUCCS_NORMAL; - + /* We are advancing forward in the region, as usual. */ if (succeeds_in_top_order) { @@ -1388,9 +1426,9 @@ return !!(flags & SUCCS_NORMAL); } - /* This is a back edge. During pipelining we ignore back edges, + /* This is a back edge. During pipelining we ignore back edges, but only when it leads to the same loop. It can lead to the header - of the outer loop, which will also be the preheader of + of the outer loop, which will also be the preheader of the current loop. */ if (pipelining_p && e1->src->loop_father == bb->loop_father) @@ -1425,12 +1463,12 @@ case 0: return bb->next_bb; - case 1: + case 1: return single_succ (bb); case 2: return FALLTHRU_EDGE (bb)->dest; - + default: return bb->next_bb; } @@ -1474,7 +1512,7 @@ extern void free_regset_pool (void); extern insn_t get_nop_from_pool (insn_t); -extern void return_nop_to_pool (insn_t); +extern void return_nop_to_pool (insn_t, bool); extern void free_nop_pool (void); /* Vinsns functions. */ @@ -1498,11 +1536,11 @@ extern void merge_expr (expr_t, expr_t, insn_t); extern void clear_expr (expr_t); extern unsigned expr_dest_regno (expr_t); -extern rtx expr_dest_reg (expr_t); -extern int find_in_history_vect (VEC(expr_history_def, heap) *, +extern rtx expr_dest_reg (expr_t); +extern int find_in_history_vect (VEC(expr_history_def, heap) *, rtx, vinsn_t, bool); -extern void insert_in_history_vect (VEC(expr_history_def, heap) **, - unsigned, enum local_trans_type, +extern void insert_in_history_vect (VEC(expr_history_def, heap) **, + unsigned, enum local_trans_type, vinsn_t, vinsn_t, ds_t); extern void mark_unavailable_targets (av_set_t, av_set_t, regset); extern int speculate_expr (expr_t, ds_t); @@ -1584,7 +1622,6 @@ extern void sel_init_pipelining (void); extern void sel_finish_pipelining (void); extern void sel_sched_region (int); -extern void sel_find_rgns (void); extern loop_p get_loop_nest_for_rgn (unsigned int); extern bool considered_for_pipelining_p (struct loop *); extern void make_region_from_loop_preheader (VEC(basic_block, heap) **); @@ -1609,6 +1646,7 @@ extern void free_lv_sets (void); extern void setup_nop_and_exit_insns (void); extern void free_nop_and_exit_insns (void); +extern void free_data_for_scheduled_insn (insn_t); extern void setup_nop_vinsn (void); extern void free_nop_vinsn (void); extern void sel_set_sched_flags (void);