diff options
author | Maxim Kuvyrkov <maxim@codesourcery.com> | 2007-08-14 06:40:34 +0000 |
---|---|---|
committer | Maxim Kuvyrkov <mkuvyrkov@gcc.gnu.org> | 2007-08-14 06:40:34 +0000 |
commit | e2f6ff946a121528203fcbde68fdd58942f9a57b (patch) | |
tree | d517b0ed31fd405d601bc3b37c58e656d118405d /gcc/sched-int.h | |
parent | ed7a4b4b30c6054ef0500d2fde45beba399da929 (diff) | |
download | gcc-e2f6ff946a121528203fcbde68fdd58942f9a57b.tar.gz |
sched-int.h (struct _dep): Rename field 'kind' to 'type'.
* sched-int.h (struct _dep): Rename field 'kind' to 'type'.
(DEP_KIND): Rename to DEP_TYPE. Update all uses.
(dep_def): New typedef.
(init_dep_1, sd_debug_dep): Declare functions.
(DEP_LINK_KIND): Rename to DEP_LINK_TYPE.
(debug_dep_links): Remove.
(struct _deps_list): New field 'n_links'.
(DEPS_LIST_N_LINKS): New macro.
(FOR_EACH_DEP_LINK): Remove.
(create_deps_list, free_deps_list, delete_deps_list): Remove
declaration.
(deps_list_empty_p, debug_deps_list, add_back_dep_to_deps_list): Ditto.
(find_link_by_pro_in_deps_list, find_link_by_con_in_deps_list): Ditto.
(copy_deps_list_change_con, move_dep_link): Ditto.
(struct haifa_insn_data): Split field 'back_deps' into 'hard_back_deps'
and 'spec_back_deps'. New field 'resolved_forw_deps'. Remove field
'dep_count'.
(INSN_BACK_DEPS): Remove.
(INSN_HARD_BACK_DEPS, INSN_SPEC_BACK_DEPS, INSN_RESOLVED_FORW_DEPS):
New macros.
(INSN_DEP_COUNT): Remove.
(enum DEPS_ADJUST_RESULT): Add new constant DEP_NODEP. Fix comments.
(spec_info, haifa_recovery_block_was_added_during_scheduling_p):
Declare global variables.
(deps_pools_are_empty_p, sched_free_deps): Declare functions.
(add_forw_dep, compute_forward_dependences): Remove declarations.
(add_or_update_back_dep, add_or_update_back_forw_dep): Ditto.
(add_back_forw_dep, delete_back_forw_dep): Ditto.
(debug_ds, sched_insn_is_legitimate_for_speculation_p): Declare
functions.
(SD_LIST_NONE, SD_LIST_HARD_BACK, SD_LIST_SPEC_BACK, SD_LIST_FORW): New
constants.
(SD_LIST_RES_BACK, SD_LIST_RES_FORW, SD_LIST_BACK): Ditto.
(sd_list_types_def): New typedef.
(sd_next_list): Declare function.
(struct _sd_iterator): New type.
(sd_iterator_def): New typedef.
(sd_iterator_start, sd_iterator_cond, sd_iterator_next): New inline
functions.
(FOR_EACH_DEP): New cycle wrapper.
(sd_lists_size, sd_lists_empty_p, sd_init_insn, sd_finish_insn):
Declare functions.
(sd_find_dep_between, sd_add_dep, sd_add_or_update_dep): Ditto.
(sd_resolve_dep, sd_copy_back_deps, sd_delete_dep, sd_debug_lists):
Ditto.
* sched-deps.c (init_dep_1): Make global.
(DUMP_DEP_PRO, DUMP_DEP_CON, DUMP_DEP_STATUS, DUMP_DEP_ALL): New
constants.
(dump_dep): New static function.
(dump_dep_flags): New static variable.
(sd_debug_dep): New function.
(add_to_deps_list, remove_from_deps_list): Update 'n_links' field of
the list.
(move_dep_link): Use remove_from_deps_list (), instead of
detach_dep_link ().
(dep_links_consistent_p, dump_dep_links, debug_dep_links): Remove.
(dep_link_is_detached_p): New static function.
(deps_obstack, dl_obstack, dn_obstack): Remove. Use dn_pool, dl_pool
instead.
(dn_pool, dl_pool): New alloc_pools.
(dn_pool_diff, dl_pool_diff): New static variables.
(create_dep_node, delete_dep_node): New static function.
(create_deps_list): Make it static. Use alloc_pool 'dl_pool'.
(deps_list_empty_p): Make it static. Use 'n_links' field.
(deps_pools_are_empty_p): New static function.
(alloc_deps_list, delete_deps_list): Remove.
(dump_deps_list, debug_deps_list, add_back_dep_to_deps_list): Remove.
(find_link_by_pro_in_deps_list, find_link_by_con_in_deps_list): Ditto.
(copy_deps_list_change_con): Remove. Use sd_copy_back_deps () instead.
(forward_dependency_cache): Remove.
(maybe_add_or_update_back_dep_1, add_or_update_back_dep_1): Remove
'back' from the names. Change signature to use dep_t instead of
equivalent quad.
(add_back_dep): Ditto. Make global.
(check_dep_status): Rename to check_dep ().
(sd_next_list, sd_lists_size, sd_lists_empty_p, sd_init_insn):
New functions.
(sd_finish_insn): Ditto.
(sd_find_dep_between_no_cache): New static function.
(sd_find_dep_between): New function.
(ask_dependency_caches, set_dependency_caches): New static functions.
(update_dependency_caches, change_spec_dep_to_hard, update_dep): Ditto.
(add_or_update_dep_1): Separate pieces of functionality into
ask_dependency_caches (), update_dependency_caches (),
change_spec_dep_to_hard (), update_dep ().
(get_back_and_forw_lists): New static function.
(sd_add_dep): Separate setting of dependency caches into
set_dependency_caches ().
(sd_add_or_update_dep, sd_resolve_dep, sd_copy_back_deps):
New functions.
(sd_delete_dep): Ditto.
(DUMP_LISTS_SIZE, DUMP_LISTS_DEPS, DUMP_LISTS_ALL): New constants.
(dump_lists): New static function.
(sd_debug_lists): New debug function.
(delete_all_dependences, fixup_sched_groups): Update to use
sd_* infrastructure.
(sched_analyze_2): Create data-speculative dependency only if
data-speculation is enabled.
(sched_analyze_insn): If insn cannot be speculative, make all its
dependencies non-speculative.
(sched_analyze): Use sd_init_insn ().
(add_forw_dep, compute_forward_dependencies): Remove.
(delete_dep_nodes_in_back_deps): New static function.
(sched_free_deps): New function.
(init_dependency_caches): Init alloc_pools.
(extend_depedency_caches): Update after removing of
forward_dependency_cache.
(free_dependency_caches): Ditto. Free alloc_pools.
(adjust_add_sorted_back_dep, adjust_back_add_forw_dep): Remove.
(delete_forw_dep, add_or_update_back_dep, add_or_update_back_forw_dep):
Ditto.
(add_back_forw_dep, delete_back_forw_dep): Ditto.
(add_dependence): Use init_dep ().
(get_dep_weak_1): New static function.
(get_dep_weak): Move logic to get_dep_weak_1 ().
(dump_ds): New static function moved from haifa-sched.c:
debug_spec_status ().
(debug_ds): New debug function.
(check_dep_status): Rename to check_dep (). Update to check whole
dependencies.
* haifa-sched.c (spec_info): Make global.
(added_recovery_block_p): Rename to
'haifa_recovery_block_was_added_during_current_schedule_block_p'.
(haifa_recovery_block_was_added_during_scheduling_p): New variable.
(dep_cost, priority, rank_for_schedule, schedule_insn): Update
to use new interfaces.
(ok_for_early_queue_removal): Ditto.
(schedule_block): Initialize logical uids of insns emitted by the
target.
(sched_init): Initialize new variable.
(fix_inter_tick, try_ready, fix_tick_ready): Update to use new
interfaces.
(extend_global): Initialize insn data.
(init_h_i_d): Remove code that is now handled in sd_init_insn ().
(process_insn_forw_deps_be_in_spec): Change signature. Update to use
new interfaces.
(add_to_speculative_block): Update to use new interfaces.
(create_recovery_block): Set new variables.
(create_check_block_twin, fix_recovery_deps): Update to use new
interfaces.
(sched_insn_is_legitimate_for_speculation_p): New function.
(speculate_insn): Move checking logic to
sched_insn_is_legitimate_for_speculation_p ().
(sched_remove_insn): Finalize sched-deps information of instruction.
(clear_priorities, add_jump_dependencies): Update to use new
interfaces.
(debug_spec_status): Rename to dump_ds () and move to sched-deps.c.
* sched-rgn.c (set_spec_fed, find_conditional_protection): Update
to use new interfaces.
(is_conditionally_protected, is_pfree, is_prisky) Ditto.
(new_ready): Try to use control speculation only if it is available.
(add_branch_dependences): Update to use new interfaces.
(compute_block_backward_dependences): Rename to
compute_block_dependences (). Call
targetm.sched.dependencies_evaluation_hook ().
(free_block_dependencies): New static function.
(debug_dependencies): Update to use new interfaces.
(schedule_region): Remove separate computation of forward dependencies.
Move call of targetm.sched.dependencies_evaluation_hook () to
compute_block_dependences (). Free dependencies at the end of
scheduling the region.
* sched-ebb.c (earliest_block_with_similiar_load): Update to use
new interfaces.
(add_deps_for_risky_insns): Ditto.
(schedule_ebb): Remove separate computation of forward dependencies.
Free dependencies at the end of scheduling the ebb.
* ddg.c (create_ddg_dependence): Update to use new interfaces.
(build_intra_loop_deps): Ditto. Remove separate computation of forward
dependencies. Free sched-deps dependencies.
* config/ia64/ia64.c (ia64_dependencies_evaluation_hook): Update
to use new interfaces.
(ia64_dfa_new_cycle, ia64_gen_check): Ditto.
* config/rs6000/rs6000.c (rs6000_is_costly_dependence): Update to use
new interfaces.
(is_costly_group): Ditto.
From-SVN: r127405
Diffstat (limited to 'gcc/sched-int.h')
-rw-r--r-- | gcc/sched-int.h | 250 |
1 files changed, 192 insertions, 58 deletions
diff --git a/gcc/sched-int.h b/gcc/sched-int.h index 4395800c5e8..ec5f8205a47 100644 --- a/gcc/sched-int.h +++ b/gcc/sched-int.h @@ -54,35 +54,40 @@ struct _dep /* Consumer. */ rtx con; - /* Dependency kind (aka dependency major type). This field is superseded - by STATUS below. Though, it is still in place because all the backends - use it. */ - enum reg_note kind; + /* Dependency major type. This field is superseded by STATUS below. + Though, it is still in place because some targets use it. */ + enum reg_note type; /* Dependency status. This field holds all dependency types and additional information for speculative dependencies. */ ds_t status; }; -typedef struct _dep *dep_t; + +typedef struct _dep dep_def; +typedef dep_def *dep_t; #define DEP_PRO(D) ((D)->pro) #define DEP_CON(D) ((D)->con) -#define DEP_KIND(D) ((D)->kind) +#define DEP_TYPE(D) ((D)->type) #define DEP_STATUS(D) ((D)->status) /* Functions to work with dep. */ +extern void init_dep_1 (dep_t, rtx, rtx, enum reg_note, ds_t); extern void init_dep (dep_t, rtx, rtx, enum reg_note); +extern void sd_debug_dep (dep_t); + /* Definition of this struct resides below. */ struct _dep_node; +typedef struct _dep_node *dep_node_t; /* A link in the dependency list. This is essentially an equivalent of a single {INSN, DEPS}_LIST rtx. */ struct _dep_link { /* Dep node with all the data. */ - struct _dep_node *node; + dep_node_t node; /* Next link in the list. For the last one it is NULL. */ struct _dep_link *next; @@ -107,39 +112,22 @@ typedef struct _dep_link *dep_link_t; #define DEP_LINK_DEP(N) (DEP_NODE_DEP (DEP_LINK_NODE (N))) #define DEP_LINK_PRO(N) (DEP_PRO (DEP_LINK_DEP (N))) #define DEP_LINK_CON(N) (DEP_CON (DEP_LINK_DEP (N))) -#define DEP_LINK_KIND(N) (DEP_KIND (DEP_LINK_DEP (N))) +#define DEP_LINK_TYPE(N) (DEP_TYPE (DEP_LINK_DEP (N))) #define DEP_LINK_STATUS(N) (DEP_STATUS (DEP_LINK_DEP (N))) -void debug_dep_links (dep_link_t); - /* A list of dep_links. */ struct _deps_list { + /* First element. */ dep_link_t first; + + /* Total number of elements in the list. */ + int n_links; }; typedef struct _deps_list *deps_list_t; #define DEPS_LIST_FIRST(L) ((L)->first) - -/* Macro to walk through deps_list. */ -#define FOR_EACH_DEP_LINK(LINK, LIST) \ - for ((LINK) = DEPS_LIST_FIRST (LIST); \ - (LINK) != NULL; \ - (LINK) = DEP_LINK_NEXT (LINK)) - -/* Functions to work with deps_list. */ - -deps_list_t create_deps_list (bool); -void free_deps_list (deps_list_t); -void delete_deps_list (deps_list_t); -bool deps_list_empty_p (deps_list_t); -void debug_deps_list (deps_list_t); -void add_back_dep_to_deps_list (deps_list_t, dep_t); -dep_link_t find_link_by_pro_in_deps_list (deps_list_t, rtx); -dep_link_t find_link_by_con_in_deps_list (deps_list_t, rtx); -void copy_deps_list_change_con (deps_list_t, deps_list_t, rtx); - -void move_dep_link (dep_link_t, deps_list_t); +#define DEPS_LIST_N_LINKS(L) ((L)->n_links) /* Suppose we have a dependence Y between insn pro1 and con1, where pro1 has additional dependents con0 and con2, and con1 is dependent on additional @@ -247,7 +235,6 @@ struct _dep_node /* Forward link. */ struct _dep_link forw; }; -typedef struct _dep_node *dep_node_t; #define DEP_NODE_BACK(N) (&(N)->back) #define DEP_NODE_DEP(N) (&(N)->dep) @@ -469,15 +456,17 @@ extern struct sched_info *current_sched_info; struct haifa_insn_data { - /* NB: We can't place 'struct _deps_list' here instead of deps_list_t into - h_i_d because when h_i_d extends, addresses of the deps_list->first - change without updating deps_list->first->next->prev_nextp. Thus - BACK_DEPS and RESOLVED_BACK_DEPS are allocated on the heap and FORW_DEPS - list is allocated on the obstack. */ + /* We can't place 'struct _deps_list' into h_i_d instead of deps_list_t + because when h_i_d extends, addresses of the deps_list->first + change without updating deps_list->first->next->prev_nextp. */ - /* A list of backward dependencies. The insn is a consumer of all the + /* A list of hard backward dependencies. The insn is a consumer of all the deps mentioned here. */ - deps_list_t back_deps; + deps_list_t hard_back_deps; + + /* A list of speculative (weak) dependencies. The insn is a consumer of all + the deps mentioned here. */ + deps_list_t spec_back_deps; /* A list of insns which depend on the instruction. Unlike 'back_deps', it represents forward dependencies. */ @@ -486,6 +475,11 @@ struct haifa_insn_data /* A list of scheduled producers of the instruction. Links are being moved from 'back_deps' to 'resolved_back_deps' while scheduling. */ deps_list_t resolved_back_deps; + + /* A list of scheduled consumers of the instruction. Links are being moved + from 'forw_deps' to 'resolved_forw_deps' while scheduling to fasten the + search in 'forw_deps'. */ + deps_list_t resolved_forw_deps; /* Logical uid gives the original ordering of the insns. */ int luid; @@ -493,11 +487,6 @@ struct haifa_insn_data /* A priority for each insn. */ int priority; - /* The number of incoming edges in the forward dependency graph. - As scheduling proceeds, counts are decreased. An insn moves to - the ready queue when its counter reaches zero. */ - int dep_count; - /* Number of instructions referring to this insn. */ int ref_count; @@ -553,13 +542,16 @@ extern struct haifa_insn_data *h_i_d; /* Accessor macros for h_i_d. There are more in haifa-sched.c and sched-rgn.c. */ -#define INSN_BACK_DEPS(INSN) (h_i_d[INSN_UID (INSN)].back_deps) + +#define INSN_HARD_BACK_DEPS(INSN) (h_i_d[INSN_UID (INSN)].hard_back_deps) +#define INSN_SPEC_BACK_DEPS(INSN) (h_i_d[INSN_UID (INSN)].spec_back_deps) #define INSN_FORW_DEPS(INSN) (h_i_d[INSN_UID (INSN)].forw_deps) #define INSN_RESOLVED_BACK_DEPS(INSN) \ (h_i_d[INSN_UID (INSN)].resolved_back_deps) +#define INSN_RESOLVED_FORW_DEPS(INSN) \ + (h_i_d[INSN_UID (INSN)].resolved_forw_deps) #define INSN_LUID(INSN) (h_i_d[INSN_UID (INSN)].luid) #define CANT_MOVE(insn) (h_i_d[INSN_UID (insn)].cant_move) -#define INSN_DEP_COUNT(INSN) (h_i_d[INSN_UID (INSN)].dep_count) #define INSN_PRIORITY(INSN) (h_i_d[INSN_UID (INSN)].priority) #define INSN_PRIORITY_STATUS(INSN) (h_i_d[INSN_UID (INSN)].priority_status) #define INSN_PRIORITY_KNOWN(INSN) (INSN_PRIORITY_STATUS (INSN) > 0) @@ -694,13 +686,16 @@ enum SPEC_TYPES_OFFSETS { #define HARD_DEP (DEP_ANTI << 1) /* This represents the results of calling sched-deps.c functions, - which modify dependencies. Possible choices are: a dependence - is already present and nothing has been changed; a dependence type - has been changed; brand new dependence has been created. */ + which modify dependencies. */ enum DEPS_ADJUST_RESULT { - DEP_PRESENT = 1, - DEP_CHANGED = 2, - DEP_CREATED = 3 + /* No dependence needed (e.g. producer == consumer). */ + DEP_NODEP, + /* Dependence is already present and wasn't modified. */ + DEP_PRESENT, + /* Existing dependence was modified to include additional information. */ + DEP_CHANGED, + /* New dependence has been created. */ + DEP_CREATED }; /* Represents the bits that can be set in the flags field of the @@ -731,6 +726,9 @@ enum SPEC_SCHED_FLAGS { extern FILE *sched_dump; extern int sched_verbose; +extern spec_info_t spec_info; +extern bool haifa_recovery_bb_ever_added_p; + /* Exception Free Loads: We define five classes of speculative loads: IFREE, IRISKY, @@ -816,23 +814,19 @@ extern void print_insn (char *, rtx, int); extern bool sched_insns_conditions_mutex_p (rtx, rtx); extern void add_dependence (rtx, rtx, enum reg_note); extern void sched_analyze (struct deps *, rtx, rtx); +extern bool deps_pools_are_empty_p (void); +extern void sched_free_deps (rtx, rtx, bool); extern void init_deps (struct deps *); extern void free_deps (struct deps *); extern void init_deps_global (void); extern void finish_deps_global (void); -extern void add_forw_dep (dep_link_t); -extern void compute_forward_dependences (rtx, rtx); extern void init_dependency_caches (int); extern void free_dependency_caches (void); extern void extend_dependency_caches (int, bool); -extern enum DEPS_ADJUST_RESULT add_or_update_back_dep (rtx, rtx, - enum reg_note, ds_t); -extern void add_or_update_back_forw_dep (rtx, rtx, enum reg_note, ds_t); -extern void add_back_forw_dep (rtx, rtx, enum reg_note, ds_t); -extern void delete_back_forw_dep (dep_link_t); extern dw_t get_dep_weak (ds_t, ds_t); extern ds_t set_dep_weak (ds_t, ds_t, dw_t); extern ds_t ds_merge (ds_t, ds_t); +extern void debug_ds (ds_t); /* Functions in haifa-sched.c. */ extern int haifa_classify_insn (rtx); @@ -851,11 +845,151 @@ extern void sched_finish (void); extern int try_ready (rtx); extern void * xrecalloc (void *, size_t, size_t, size_t); +extern bool sched_insn_is_legitimate_for_speculation_p (rtx, ds_t); extern void unlink_bb_notes (basic_block, basic_block); extern void add_block (basic_block, basic_block); extern rtx bb_note (basic_block); /* Functions in sched-rgn.c. */ + extern void debug_dependencies (rtx, rtx); +/* sched-deps.c interface to walk, add, search, update, resolve, delete + and debug instruction dependencies. */ + +/* Constants defining dependences lists. */ + +/* No list. */ +#define SD_LIST_NONE (0) + +/* hard_back_deps. */ +#define SD_LIST_HARD_BACK (1) + +/* spec_back_deps. */ +#define SD_LIST_SPEC_BACK (2) + +/* forw_deps. */ +#define SD_LIST_FORW (4) + +/* resolved_back_deps. */ +#define SD_LIST_RES_BACK (8) + +/* resolved_forw_deps. */ +#define SD_LIST_RES_FORW (16) + +#define SD_LIST_BACK (SD_LIST_HARD_BACK | SD_LIST_SPEC_BACK) + +/* A type to hold above flags. */ +typedef int sd_list_types_def; + +extern void sd_next_list (rtx, sd_list_types_def *, deps_list_t *, bool *); + +/* Iterator to walk through, resolve and delete dependencies. */ +struct _sd_iterator +{ + /* What lists to walk. Can be any combination of SD_LIST_* flags. */ + sd_list_types_def types; + + /* Instruction dependencies lists of which will be walked. */ + rtx insn; + + /* Pointer to the next field of the previous element. This is not + simply a pointer to the next element to allow easy deletion from the + list. When a dep is being removed from the list the iterator + will automatically advance because the value in *linkp will start + reffering to the next element. */ + dep_link_t *linkp; + + /* True if the current list is a resolved one. */ + bool resolved_p; +}; + +typedef struct _sd_iterator sd_iterator_def; + +/* ??? We can move some definitions that are used in below inline functions + out of sched-int.h to sched-deps.c provided that the below functions will + become global externals. + These definitions include: + * struct _deps_list: opaque pointer is needed at global scope. + * struct _dep_link: opaque pointer is needed at scope of sd_iterator_def. + * struct _dep_node: opaque pointer is needed at scope of + struct _deps_link. */ + +/* Return initialized iterator. */ +static inline sd_iterator_def +sd_iterator_start (rtx insn, sd_list_types_def types) +{ + /* Some dep_link a pointer to which will return NULL. */ + static dep_link_t null_link = NULL; + + sd_iterator_def i; + + i.types = types; + i.insn = insn; + i.linkp = &null_link; + + /* Avoid 'uninitialized warning'. */ + i.resolved_p = false; + + return i; +} + +/* Return the current element. */ +static inline bool +sd_iterator_cond (sd_iterator_def *it_ptr, dep_t *dep_ptr) +{ + dep_link_t link = *it_ptr->linkp; + + if (link != NULL) + { + *dep_ptr = DEP_LINK_DEP (link); + return true; + } + else + { + sd_list_types_def types = it_ptr->types; + + if (types != SD_LIST_NONE) + /* Switch to next list. */ + { + deps_list_t list; + + sd_next_list (it_ptr->insn, + &it_ptr->types, &list, &it_ptr->resolved_p); + + it_ptr->linkp = &DEPS_LIST_FIRST (list); + + return sd_iterator_cond (it_ptr, dep_ptr); + } + + *dep_ptr = NULL; + return false; + } +} + +/* Advance iterator. */ +static inline void +sd_iterator_next (sd_iterator_def *it_ptr) +{ + it_ptr->linkp = &DEP_LINK_NEXT (*it_ptr->linkp); +} + +/* A cycle wrapper. */ +#define FOR_EACH_DEP(INSN, LIST_TYPES, ITER, DEP) \ + for ((ITER) = sd_iterator_start ((INSN), (LIST_TYPES)); \ + sd_iterator_cond (&(ITER), &(DEP)); \ + sd_iterator_next (&(ITER))) + +extern int sd_lists_size (rtx, sd_list_types_def); +extern bool sd_lists_empty_p (rtx, sd_list_types_def); +extern void sd_init_insn (rtx); +extern void sd_finish_insn (rtx); +extern dep_t sd_find_dep_between (rtx, rtx, bool); +extern void sd_add_dep (dep_t, bool); +extern enum DEPS_ADJUST_RESULT sd_add_or_update_dep (dep_t, bool); +extern void sd_resolve_dep (sd_iterator_def); +extern void sd_copy_back_deps (rtx, rtx, bool); +extern void sd_delete_dep (sd_iterator_def); +extern void sd_debug_lists (rtx, sd_list_types_def); + #endif /* GCC_SCHED_INT_H */ |