| Index: gcc/gcc/sched-int.h
|
| diff --git a/gcc/gcc/sched-int.h b/gcc/gcc/sched-int.h
|
| index f7a54b6712768b6c010e56aebea7f0f09187934b..147e264848aa3aaa5bd6415c059ce34cdd57ee73 100644
|
| --- a/gcc/gcc/sched-int.h
|
| +++ b/gcc/gcc/sched-int.h
|
| @@ -1,7 +1,8 @@
|
| /* Instruction scheduling pass. This file contains definitions used
|
| internally in the scheduler.
|
| Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
|
| - 2001, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
|
| + 2001, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
|
| + Free Software Foundation, Inc.
|
|
|
| This file is part of GCC.
|
|
|
| @@ -180,13 +181,15 @@ extern bool sel_insn_is_speculation_check (rtx);
|
| FIRST is the index of the element with the highest priority; i.e. the
|
| last one in the ready list, since elements are ordered by ascending
|
| priority.
|
| - N_READY determines how many insns are on the ready list. */
|
| + N_READY determines how many insns are on the ready list.
|
| + N_DEBUG determines how many debug insns are on the ready list. */
|
| struct ready_list
|
| {
|
| rtx *vec;
|
| int veclen;
|
| int first;
|
| int n_ready;
|
| + int n_debug;
|
| };
|
|
|
| extern char *ready_try;
|
| @@ -425,8 +428,27 @@ enum reg_pending_barrier_mode
|
| TRUE_BARRIER
|
| };
|
|
|
| +/* Whether a register movement is associated with a call. */
|
| +enum post_call_group
|
| +{
|
| + not_post_call,
|
| + post_call,
|
| + post_call_initial
|
| +};
|
| +
|
| +/* Insns which affect pseudo-registers. */
|
| +struct deps_reg
|
| +{
|
| + rtx uses;
|
| + rtx sets;
|
| + rtx implicit_sets;
|
| + rtx clobbers;
|
| + int uses_length;
|
| + int clobbers_length;
|
| +};
|
| +
|
| /* Describe state of dependencies used during sched_analyze phase. */
|
| -struct deps
|
| +struct deps_desc
|
| {
|
| /* The *_insns and *_mems are paired lists. Each pending memory operation
|
| will have a pointer to the MEM rtx on one list and a pointer to the
|
| @@ -480,6 +502,12 @@ struct deps
|
| Used to prevent register lifetimes from expanding unnecessarily. */
|
| rtx last_function_call;
|
|
|
| + /* A list of the last function calls that may not return normally
|
| + we have seen. We use a list to represent last function calls from
|
| + multiple predecessor blocks. Used to prevent moving trapping insns
|
| + across such calls. */
|
| + rtx last_function_call_may_noreturn;
|
| +
|
| /* A list of insns which use a pseudo register that does not already
|
| cross a call. We create dependencies between each of those insn
|
| and the next call insn, to ensure that they won't cross a call after
|
| @@ -488,7 +516,10 @@ struct deps
|
|
|
| /* Used to keep post-call pseudo/hard reg movements together with
|
| the call. */
|
| - enum { not_post_call, post_call, post_call_initial } in_post_call_group_p;
|
| + enum post_call_group in_post_call_group_p;
|
| +
|
| + /* The last debug insn we've seen. */
|
| + rtx last_debug_insn;
|
|
|
| /* The maximum register number for the following arrays. Before reload
|
| this is max_reg_num; after reload it is FIRST_PSEUDO_REGISTER. */
|
| @@ -498,14 +529,7 @@ struct deps
|
| N within the current basic block; or zero, if there is no
|
| such insn. Needed for new registers which may be introduced
|
| by splitting insns. */
|
| - struct deps_reg
|
| - {
|
| - rtx uses;
|
| - rtx sets;
|
| - rtx clobbers;
|
| - int uses_length;
|
| - int clobbers_length;
|
| - } *reg_last;
|
| + struct deps_reg *reg_last;
|
|
|
| /* Element N is set for each register that has any nonzero element
|
| in reg_last[N].{uses,sets,clobbers}. */
|
| @@ -517,12 +541,12 @@ struct deps
|
| /* Shows the last value of reg_pending_barrier associated with the insn. */
|
| enum reg_pending_barrier_mode last_reg_pending_barrier;
|
|
|
| - /* True when this context should be treated as a readonly by
|
| + /* True when this context should be treated as a readonly by
|
| the analysis. */
|
| BOOL_BITFIELD readonly : 1;
|
| };
|
|
|
| -typedef struct deps *deps_t;
|
| +typedef struct deps_desc *deps_t;
|
|
|
| /* This structure holds some state of the current scheduling pass, and
|
| contains some function pointers that abstract out some of the non-generic
|
| @@ -539,7 +563,7 @@ struct haifa_sched_info
|
| int (*can_schedule_ready_p) (rtx);
|
| /* Return nonzero if there are more insns that should be scheduled. */
|
| int (*schedule_more_p) (void);
|
| - /* Called after an insn has all its hard dependencies resolved.
|
| + /* Called after an insn has all its hard dependencies resolved.
|
| Adjusts status of instruction (which is passed through second parameter)
|
| to indicate if instruction should be moved to the ready list or the
|
| queue, or if it should silently discard it (until next resolved
|
| @@ -558,6 +582,10 @@ struct haifa_sched_info
|
| calculations. */
|
| int (*contributes_to_priority) (rtx, rtx);
|
|
|
| + /* Return true if scheduling insn (passed as the parameter) will trigger
|
| + finish of scheduling current block. */
|
| + bool (*insn_finishes_block_p) (rtx);
|
| +
|
| /* The boundaries of the set of insns to be scheduled. */
|
| rtx prev_head, next_tail;
|
|
|
| @@ -574,7 +602,7 @@ struct haifa_sched_info
|
| /* Hooks to support speculative scheduling. */
|
|
|
| /* Called to notify frontend that instruction is being added (second
|
| - parameter == 0) or removed (second parameter == 1). */
|
| + parameter == 0) or removed (second parameter == 1). */
|
| void (*add_remove_insn) (rtx, int);
|
|
|
| /* Called to notify frontend that instruction is being scheduled.
|
| @@ -621,6 +649,14 @@ extern spec_info_t spec_info;
|
|
|
| extern struct haifa_sched_info *current_sched_info;
|
|
|
| +/* Do register pressure sensitive insn scheduling if the flag is set
|
| + up. */
|
| +extern bool sched_pressure_p;
|
| +
|
| +/* Map regno -> its cover class. The map defined only when
|
| + SCHED_PRESSURE_P is true. */
|
| +extern enum reg_class *sched_regno_cover_class;
|
| +
|
| /* Indexed by INSN_UID, the collection of all data associated with
|
| a single instruction. */
|
|
|
| @@ -666,6 +702,52 @@ struct _haifa_deps_insn_data
|
| unsigned int cant_move : 1;
|
| };
|
|
|
| +/* Bits used for storing values of the fields in the following
|
| + structure. */
|
| +#define INCREASE_BITS 8
|
| +
|
| +/* The structure describes how the corresponding insn increases the
|
| + register pressure for each cover class. */
|
| +struct reg_pressure_data
|
| +{
|
| + /* Pressure increase for given class because of clobber. */
|
| + unsigned int clobber_increase : INCREASE_BITS;
|
| + /* Increase in register pressure for given class because of register
|
| + sets. */
|
| + unsigned int set_increase : INCREASE_BITS;
|
| + /* Pressure increase for given class because of unused register
|
| + set. */
|
| + unsigned int unused_set_increase : INCREASE_BITS;
|
| + /* Pressure change: #sets - #deaths. */
|
| + int change : INCREASE_BITS;
|
| +};
|
| +
|
| +/* The following structure describes usage of registers by insns. */
|
| +struct reg_use_data
|
| +{
|
| + /* Regno used in the insn. */
|
| + int regno;
|
| + /* Insn using the regno. */
|
| + rtx insn;
|
| + /* Cyclic list of elements with the same regno. */
|
| + struct reg_use_data *next_regno_use;
|
| + /* List of elements with the same insn. */
|
| + struct reg_use_data *next_insn_use;
|
| +};
|
| +
|
| +/* The following structure describes used sets of registers by insns.
|
| + Registers are pseudos whose cover class is not NO_REGS or hard
|
| + registers available for allocations. */
|
| +struct reg_set_data
|
| +{
|
| + /* Regno used in the insn. */
|
| + int regno;
|
| + /* Insn setting the regno. */
|
| + rtx insn;
|
| + /* List of elements with the same insn. */
|
| + struct reg_set_data *next_insn_set;
|
| +};
|
| +
|
| struct _haifa_insn_data
|
| {
|
| /* We can't place 'struct _deps_list' into h_i_d instead of deps_list_t
|
| @@ -685,16 +767,12 @@ struct _haifa_insn_data
|
| /* INTER_TICK is used to adjust INSN_TICKs of instructions from the
|
| subsequent blocks in a region. */
|
| int inter_tick;
|
| -
|
| +
|
| /* See comment on QUEUE_INDEX macro in haifa-sched.c. */
|
| int queue_index;
|
|
|
| short cost;
|
|
|
| - /* This weight is an estimation of the insn's contribution to
|
| - register pressure. */
|
| - short reg_weight;
|
| -
|
| /* Set if there's DEF-USE dependence between some speculatively
|
| moved load insn and this one. */
|
| unsigned int fed_by_spec_load : 1;
|
| @@ -709,7 +787,7 @@ struct _haifa_insn_data
|
| ds_t todo_spec;
|
|
|
| /* What speculations were already applied. */
|
| - ds_t done_spec;
|
| + ds_t done_spec;
|
|
|
| /* What speculations are checked by this instruction. */
|
| ds_t check_spec;
|
| @@ -719,6 +797,26 @@ struct _haifa_insn_data
|
|
|
| /* Original pattern of the instruction. */
|
| rtx orig_pat;
|
| +
|
| + /* The following array contains info how the insn increases register
|
| + pressure. There is an element for each cover class of pseudos
|
| + referenced in insns. */
|
| + struct reg_pressure_data *reg_pressure;
|
| + /* The following array contains maximal reg pressure between last
|
| + scheduled insn and given insn. There is an element for each
|
| + cover class of pseudos referenced in insns. This info updated
|
| + after scheduling each insn for each insn between the two
|
| + mentioned insns. */
|
| + int *max_reg_pressure;
|
| + /* The following list contains info about used pseudos and hard
|
| + registers available for allocation. */
|
| + struct reg_use_data *reg_use_list;
|
| + /* The following list contains info about set pseudos and hard
|
| + registers available for allocation. */
|
| + struct reg_set_data *reg_set_list;
|
| + /* Info about how scheduling the insn changes cost of register
|
| + pressure excess (between source and target). */
|
| + int reg_pressure_excess_cost_change;
|
| };
|
|
|
| typedef struct _haifa_insn_data haifa_insn_data_def;
|
| @@ -734,7 +832,12 @@ extern VEC(haifa_insn_data_def, heap) *h_i_d;
|
| /* Accessor macros for h_i_d. There are more in haifa-sched.c and
|
| sched-rgn.c. */
|
| #define INSN_PRIORITY(INSN) (HID (INSN)->priority)
|
| -#define INSN_REG_WEIGHT(INSN) (HID (INSN)->reg_weight)
|
| +#define INSN_REG_PRESSURE(INSN) (HID (INSN)->reg_pressure)
|
| +#define INSN_MAX_REG_PRESSURE(INSN) (HID (INSN)->max_reg_pressure)
|
| +#define INSN_REG_USE_LIST(INSN) (HID (INSN)->reg_use_list)
|
| +#define INSN_REG_SET_LIST(INSN) (HID (INSN)->reg_set_list)
|
| +#define INSN_REG_PRESSURE_EXCESS_COST_CHANGE(INSN) \
|
| + (HID (INSN)->reg_pressure_excess_cost_change)
|
| #define INSN_PRIORITY_STATUS(INSN) (HID (INSN)->priority_status)
|
|
|
| typedef struct _haifa_deps_insn_data haifa_deps_insn_data_def;
|
| @@ -784,6 +887,23 @@ extern VEC(haifa_deps_insn_data_def, heap) *h_d_i_d;
|
| #define IS_SPECULATION_BRANCHY_CHECK_P(INSN) \
|
| (RECOVERY_BLOCK (INSN) != NULL && RECOVERY_BLOCK (INSN) != EXIT_BLOCK_PTR)
|
|
|
| +/* The unchanging bit tracks whether a debug insn is to be handled
|
| + like an insn (i.e., schedule it) or like a note (e.g., it is next
|
| + to a basic block boundary. */
|
| +#define DEBUG_INSN_SCHED_P(insn) \
|
| + (RTL_FLAG_CHECK1("DEBUG_INSN_SCHED_P", (insn), DEBUG_INSN)->unchanging)
|
| +
|
| +/* True if INSN is a debug insn that is next to a basic block
|
| + boundary, i.e., it is to be handled by the scheduler like a
|
| + note. */
|
| +#define BOUNDARY_DEBUG_INSN_P(insn) \
|
| + (DEBUG_INSN_P (insn) && !DEBUG_INSN_SCHED_P (insn))
|
| +/* True if INSN is a debug insn that is not next to a basic block
|
| + boundary, i.e., it is to be handled by the scheduler like an
|
| + insn. */
|
| +#define SCHEDULE_DEBUG_INSN_P(insn) \
|
| + (DEBUG_INSN_P (insn) && DEBUG_INSN_SCHED_P (insn))
|
| +
|
| /* Dep status (aka ds_t) of the link encapsulates information, that is needed
|
| for speculative scheduling. Namely, it is 4 integers in the range
|
| [0, MAX_DEP_WEAK] and 3 bits.
|
| @@ -891,7 +1011,7 @@ enum SPEC_TYPES_OFFSETS {
|
| Therefore, it can appear only in TODO_SPEC field of an instruction. */
|
| #define HARD_DEP (DEP_ANTI << 1)
|
|
|
| -/* This represents the results of calling sched-deps.c functions,
|
| +/* This represents the results of calling sched-deps.c functions,
|
| which modify dependencies. */
|
| enum DEPS_ADJUST_RESULT {
|
| /* No dependence needed (e.g. producer == consumer). */
|
| @@ -904,7 +1024,7 @@ enum DEPS_ADJUST_RESULT {
|
| DEP_CREATED
|
| };
|
|
|
| -/* Represents the bits that can be set in the flags field of the
|
| +/* Represents the bits that can be set in the flags field of the
|
| sched_info structure. */
|
| enum SCHED_FLAGS {
|
| /* If set, generate links between instruction as DEPS_LIST.
|
| @@ -1078,13 +1198,14 @@ extern struct sched_deps_info_def *sched_deps_info;
|
| extern bool sched_insns_conditions_mutex_p (const_rtx, const_rtx);
|
| extern bool sched_insn_is_legitimate_for_speculation_p (const_rtx, ds_t);
|
| extern void add_dependence (rtx, rtx, enum reg_note);
|
| -extern void sched_analyze (struct deps *, rtx, rtx);
|
| -extern void init_deps (struct deps *);
|
| -extern void free_deps (struct deps *);
|
| +extern void sched_analyze (struct deps_desc *, rtx, rtx);
|
| +extern void init_deps (struct deps_desc *, bool);
|
| +extern void init_deps_reg_last (struct deps_desc *);
|
| +extern void free_deps (struct deps_desc *);
|
| extern void init_deps_global (void);
|
| extern void finish_deps_global (void);
|
| -extern void deps_analyze_insn (struct deps *, rtx);
|
| -extern void remove_from_deps (struct deps *, rtx);
|
| +extern void deps_analyze_insn (struct deps_desc *, rtx);
|
| +extern void remove_from_deps (struct deps_desc *, rtx);
|
|
|
| extern dw_t get_dep_weak_1 (ds_t, ds_t);
|
| extern dw_t get_dep_weak (ds_t, ds_t);
|
| @@ -1106,7 +1227,7 @@ extern void haifa_note_reg_use (int);
|
|
|
| extern void maybe_extend_reg_info_p (void);
|
|
|
| -extern void deps_start_bb (struct deps *, rtx);
|
| +extern void deps_start_bb (struct deps_desc *, rtx);
|
| extern enum reg_note ds_to_dt (ds_t);
|
|
|
| extern bool deps_pools_are_empty_p (void);
|
| @@ -1115,7 +1236,9 @@ extern void extend_dependency_caches (int, bool);
|
|
|
| extern void debug_ds (ds_t);
|
|
|
| +
|
| /* Functions in haifa-sched.c. */
|
| +extern void sched_init_region_reg_pressure_info (void);
|
| extern int haifa_classify_insn (const_rtx);
|
| extern void get_ebb_head_tail (basic_block, basic_block, rtx *, rtx *);
|
| extern int no_real_insns_p (const_rtx, const_rtx);
|
| @@ -1125,6 +1248,7 @@ extern int dep_cost_1 (dep_t, dw_t);
|
| extern int dep_cost (dep_t);
|
| extern int set_priorities (rtx, rtx);
|
|
|
| +extern void sched_setup_bb_reg_pressure_info (basic_block, rtx);
|
| extern void schedule_block (basic_block *);
|
|
|
| extern int cycle_issued_insns;
|
| @@ -1172,6 +1296,11 @@ extern int *rgn_bb_table;
|
| extern int *block_to_bb;
|
| extern int *containing_rgn;
|
|
|
| +/* Often used short-hand in the scheduler. The rest of the compiler uses
|
| + BLOCK_FOR_INSN(INSN) and an indirect reference to get the basic block
|
| + number ("index"). For historical reasons, the scheduler does not. */
|
| +#define BLOCK_NUM(INSN) (BLOCK_FOR_INSN (INSN)->index + 0)
|
| +
|
| #define RGN_NR_BLOCKS(rgn) (rgn_table[rgn].rgn_nr_blocks)
|
| #define RGN_BLOCKS(rgn) (rgn_table[rgn].rgn_blocks)
|
| #define RGN_DONT_CALC_DEPS(rgn) (rgn_table[rgn].dont_calc_deps)
|
| @@ -1205,10 +1334,10 @@ extern void compute_priorities (void);
|
| extern void increase_insn_priority (rtx, int);
|
| extern void debug_rgn_dependencies (int);
|
| extern void debug_dependencies (rtx, rtx);
|
| -extern void free_rgn_deps (void);
|
| +extern void free_rgn_deps (void);
|
| extern int contributes_to_priority (rtx, rtx);
|
| extern void extend_rgns (int *, int *, sbitmap, int *);
|
| -extern void deps_join (struct deps *, struct deps *);
|
| +extern void deps_join (struct deps_desc *, struct deps_desc *);
|
|
|
| extern void rgn_setup_common_sched_info (void);
|
| extern void rgn_setup_sched_infos (void);
|
| @@ -1326,7 +1455,8 @@ sd_iterator_cond (sd_iterator_def *it_ptr, dep_t *dep_ptr)
|
|
|
| it_ptr->linkp = &DEPS_LIST_FIRST (list);
|
|
|
| - return sd_iterator_cond (it_ptr, dep_ptr);
|
| + if (list)
|
| + return sd_iterator_cond (it_ptr, dep_ptr);
|
| }
|
|
|
| *dep_ptr = NULL;
|
| @@ -1361,7 +1491,7 @@ extern void sd_debug_lists (rtx, sd_list_types_def);
|
|
|
| #endif /* INSN_SCHEDULING */
|
|
|
| -/* Functions in sched-vis.c. These must be outside INSN_SCHEDULING as
|
| +/* Functions in sched-vis.c. These must be outside INSN_SCHEDULING as
|
| sched-vis.c is compiled always. */
|
| extern void print_insn (char *, const_rtx, int);
|
| extern void print_pattern (char *, const_rtx, int);
|
|
|