/* Instruction scheduling pass. This file contains definitions used
internally in the scheduler.
- Copyright (C) 1992-2014 Free Software Foundation, Inc.
+ Copyright (C) 1992-2015 Free Software Foundation, Inc.
This file is part of GCC.
#ifdef INSN_SCHEDULING
#include "df.h"
-#include "basic-block.h"
/* Identificator of a scheduler pass. */
enum sched_pass_id_t { SCHED_PASS_UNKNOWN, SCHED_RGN_PASS, SCHED_EBB_PASS,
};
typedef vec<basic_block> bb_vec_t;
-typedef vec<rtx> insn_vec_t;
-typedef vec<rtx> rtx_vec_t;
+typedef vec<rtx_insn *> insn_vec_t;
+typedef vec<rtx_insn *> rtx_vec_t;
extern void sched_init_bbs (void);
extern void sched_extend_luids (void);
-extern void sched_init_insn_luid (rtx);
+extern void sched_init_insn_luid (rtx_insn *);
extern void sched_init_luids (bb_vec_t);
extern void sched_finish_luids (void);
extern void *xrecalloc (void *, size_t, size_t, size_t);
-extern void reemit_notes (rtx);
+extern void reemit_notes (rtx_insn *);
/* Functions in haifa-sched.c. */
extern int haifa_classify_insn (const_rtx);
struct _dep
{
/* Producer. */
- rtx pro;
+ rtx_insn *pro;
/* Consumer. */
- rtx con;
+ rtx_insn *con;
/* If nonnull, holds a pointer to information about how to break the
dependency by making a replacement in one of the insns. There is
typedef struct _dep dep_def;
typedef dep_def *dep_t;
-extern rtx_insn *DEP_PRO (dep_t dep);
-extern rtx_insn *DEP_CON (dep_t dep);
-extern rtx& SET_DEP_PRO (dep_t dep);
-extern rtx& SET_DEP_CON (dep_t dep);
+#define DEP_PRO(D) ((D)->pro)
+#define DEP_CON(D) ((D)->con)
#define DEP_TYPE(D) ((D)->type)
#define DEP_STATUS(D) ((D)->status)
#define DEP_COST(D) ((D)->cost)
/* 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 init_dep_1 (dep_t, rtx_insn *, rtx_insn *, enum reg_note, ds_t);
+extern void init_dep (dep_t, rtx_insn *, rtx_insn *, enum reg_note);
extern void sd_debug_dep (dep_t);
/* Insns which affect pseudo-registers. */
struct deps_reg
{
- rtx uses;
- rtx sets;
- rtx implicit_sets;
- rtx control_uses;
- rtx clobbers;
+ rtx_insn_list *uses;
+ rtx_insn_list *sets;
+ rtx_insn_list *implicit_sets;
+ rtx_insn_list *control_uses;
+ rtx_insn_list *clobbers;
int uses_length;
int clobbers_length;
};
to a list more than once. */
/* An INSN_LIST containing all insns with pending read operations. */
- rtx pending_read_insns;
+ rtx_insn_list *pending_read_insns;
/* An EXPR_LIST containing all MEM rtx's which are pending reads. */
- rtx pending_read_mems;
+ rtx_expr_list *pending_read_mems;
/* An INSN_LIST containing all insns with pending write operations. */
- rtx pending_write_insns;
+ rtx_insn_list *pending_write_insns;
/* An EXPR_LIST containing all MEM rtx's which are pending writes. */
- rtx pending_write_mems;
+ rtx_expr_list *pending_write_mems;
/* An INSN_LIST containing all jump insns. */
- rtx pending_jump_insns;
+ rtx_insn_list *pending_jump_insns;
/* We must prevent the above lists from ever growing too large since
the number of dependencies produced is at least O(N*N),
alias analysis, this restriction can be relaxed.
This may also be an INSN that writes memory if the pending lists grow
too large. */
- rtx last_pending_memory_flush;
+ rtx_insn_list *last_pending_memory_flush;
/* A list of the last function calls we have seen. We use a list to
represent last function calls from multiple predecessor blocks.
Used to prevent register lifetimes from expanding unnecessarily. */
- rtx last_function_call;
+ rtx_insn_list *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;
+ rtx_insn_list *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
scheduling is done. */
- rtx sched_before_next_call;
+ rtx_insn_list *sched_before_next_call;
/* Similarly, a list of insns which should not cross a branch. */
- rtx sched_before_next_jump;
+ rtx_insn_list *sched_before_next_jump;
/* Used to keep post-call pseudo/hard reg movements together with
the call. */
/* For a conditional insn, a list of insns that could set the condition
register. Used when generating control dependencies. */
- rtx cond_deps;
+ rtx_insn_list *cond_deps;
/* True if the condition in 'cond' should be reversed to get the actual
condition. */
/* Regno used in the insn. */
int regno;
/* Insn using the regno. */
- rtx insn;
+ rtx_insn *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_set_data *next_insn_set;
};
+enum autopref_multipass_data_status {
+ /* Entry is irrelevant for auto-prefetcher. */
+ AUTOPREF_MULTIPASS_DATA_IRRELEVANT = -2,
+ /* Entry is uninitialized. */
+ AUTOPREF_MULTIPASS_DATA_UNINITIALIZED = -1,
+ /* Entry is relevant for auto-prefetcher and insn can be delayed
+ to allow another insn through. */
+ AUTOPREF_MULTIPASS_DATA_NORMAL = 0,
+ /* Entry is relevant for auto-prefetcher, but insn should not be
+ delayed as that will break scheduling. */
+ AUTOPREF_MULTIPASS_DATA_DONT_DELAY = 1
+};
+
+/* Data for modeling cache auto-prefetcher. */
+struct autopref_multipass_data_
+{
+ /* Base part of memory address. */
+ rtx base;
+ /* Memory offset. */
+ int offset;
+ /* Entry status. */
+ enum autopref_multipass_data_status status;
+};
+typedef struct autopref_multipass_data_ autopref_multipass_data_def;
+typedef autopref_multipass_data_def *autopref_multipass_data_t;
+
struct _haifa_insn_data
{
/* We can't place 'struct _deps_list' into h_i_d instead of deps_list_t
/* A priority for each insn. */
int priority;
+ /* The fusion priority for each insn. */
+ int fusion_priority;
+
/* The minimum clock tick at which the insn becomes ready. This is
used to note timing constraints for the insns in the pending list. */
int tick;
pressure excess (between source and target). */
int reg_pressure_excess_cost_change;
int model_index;
+
+ /* Original order of insns in the ready list. */
+ int rfs_debug_orig_order;
+
+ /* The deciding reason for INSN's place in the ready list. */
+ int last_rfs_win;
+
+ /* Two entries for cache auto-prefetcher model: one for mem reads,
+ and one for mem writes. */
+ autopref_multipass_data_def autopref_multipass_data[2];
};
typedef struct _haifa_insn_data haifa_insn_data_def;
/* 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_FUSION_PRIORITY(INSN) (HID (INSN)->fusion_priority)
#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)
(HID (INSN)->reg_pressure_excess_cost_change)
#define INSN_PRIORITY_STATUS(INSN) (HID (INSN)->priority_status)
#define INSN_MODEL_INDEX(INSN) (HID (INSN)->model_index)
+#define INSN_AUTOPREF_MULTIPASS_DATA(INSN) \
+ (HID (INSN)->autopref_multipass_data)
typedef struct _haifa_deps_insn_data haifa_deps_insn_data_def;
typedef haifa_deps_insn_data_def *haifa_deps_insn_data_t;
void (*compute_jump_reg_dependencies) (rtx, regset);
/* Start analyzing insn. */
- void (*start_insn) (rtx);
+ void (*start_insn) (rtx_insn *);
/* Finish analyzing insn. */
void (*finish_insn) (void);
/* Note memory dependence of type DS between MEM1 and MEM2 (which is
in the INSN2). */
- void (*note_mem_dep) (rtx mem1, rtx mem2, rtx insn2, ds_t ds);
+ void (*note_mem_dep) (rtx mem1, rtx mem2, rtx_insn *insn2, ds_t ds);
/* Note a dependence of type DS from the INSN. */
- void (*note_dep) (rtx, ds_t ds);
+ void (*note_dep) (rtx_insn *, ds_t ds);
/* Nonzero if we should use cselib for better alias analysis. This
must be 0 if the dependency information is used after sched_analyze
/* Functions in sched-deps.c. */
-extern rtx sched_get_reverse_condition_uncached (const_rtx);
-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 rtx sched_get_reverse_condition_uncached (const rtx_insn *);
+extern bool sched_insns_conditions_mutex_p (const rtx_insn *,
+ const rtx_insn *);
+extern bool sched_insn_is_legitimate_for_speculation_p (const rtx_insn *, ds_t);
extern void add_dependence (rtx_insn *, rtx_insn *, enum reg_note);
extern void sched_analyze (struct deps_desc *, rtx_insn *, rtx_insn *);
extern void init_deps (struct deps_desc *, bool);
extern void init_deps_global (void);
extern void finish_deps_global (void);
extern void deps_analyze_insn (struct deps_desc *, rtx_insn *);
-extern void remove_from_deps (struct deps_desc *, rtx);
-extern void init_insn_reg_pressure_info (rtx);
+extern void remove_from_deps (struct deps_desc *, rtx_insn *);
+extern void init_insn_reg_pressure_info (rtx_insn *);
extern dw_t get_dep_weak (ds_t, ds_t);
extern ds_t set_dep_weak (ds_t, ds_t, dw_t);
extern void maybe_extend_reg_info_p (void);
-extern void deps_start_bb (struct deps_desc *, rtx);
+extern void deps_start_bb (struct deps_desc *, rtx_insn *);
extern enum reg_note ds_to_dt (ds_t);
extern bool deps_pools_are_empty_p (void);
-extern void sched_free_deps (rtx, rtx, bool);
+extern void sched_free_deps (rtx_insn *, rtx_insn *, bool);
extern void extend_dependency_caches (int, bool);
extern void debug_ds (ds_t);
extern int haifa_classify_insn (const_rtx);
extern void get_ebb_head_tail (basic_block, basic_block,
rtx_insn **, rtx_insn **);
-extern int no_real_insns_p (const_rtx, const_rtx);
+extern int no_real_insns_p (const rtx_insn *, const rtx_insn *);
-extern int insn_cost (rtx);
+extern int insn_cost (rtx_insn *);
extern int dep_cost_1 (dep_t, dw_t);
extern int dep_cost (dep_t);
-extern int set_priorities (rtx, rtx);
+extern int set_priorities (rtx_insn *, rtx_insn *);
-extern void sched_setup_bb_reg_pressure_info (basic_block, rtx);
+extern void sched_setup_bb_reg_pressure_info (basic_block, rtx_insn *);
extern bool schedule_block (basic_block *, state_t);
extern int cycle_issued_insns;
extern int issue_rate;
extern int dfa_lookahead;
-extern void ready_sort (struct ready_list *);
+extern int autopref_multipass_dfa_lookahead_guard (rtx_insn *, int);
+
extern rtx_insn *ready_element (struct ready_list *, int);
extern rtx_insn **ready_lastpos (struct ready_list *);
extern void sched_extend_ready_list (int);
extern void sched_finish_ready_list (void);
extern void sched_change_pattern (rtx, rtx);
-extern int sched_speculate_insn (rtx, ds_t, rtx *);
+extern int sched_speculate_insn (rtx_insn *, ds_t, rtx *);
extern void unlink_bb_notes (basic_block, basic_block);
extern void add_block (basic_block, basic_block);
extern rtx_note *bb_note (basic_block);
-extern void concat_note_lists (rtx, rtx *);
+extern void concat_note_lists (rtx_insn *, rtx_insn **);
extern rtx_insn *sched_emit_insn (rtx);
-extern rtx get_ready_element (int);
+extern rtx_insn *get_ready_element (int);
extern int number_in_ready (void);
\f
/* Types and functions in sched-ebb.c. */
extern void set_modulo_params (int, int, int, int);
extern void record_delay_slot_pair (rtx_insn *, rtx_insn *, int, int);
-extern rtx real_insn_for_shadow (rtx);
+extern rtx_insn *real_insn_for_shadow (rtx_insn *);
extern void discard_delay_pairs_above (int);
extern void free_delay_pairs (void);
extern void add_delay_dependencies (rtx_insn *);
extern void rgn_make_new_region_out_of_new_block (basic_block);
extern void compute_priorities (void);
-extern void increase_insn_priority (rtx, int);
+extern void increase_insn_priority (rtx_insn *, int);
extern void debug_rgn_dependencies (int);
-extern void debug_dependencies (rtx, rtx);
+extern void debug_dependencies (rtx_insn *, rtx_insn *);
extern void free_rgn_deps (void);
extern int contributes_to_priority (rtx_insn *, rtx_insn *);
extern void extend_rgns (int *, int *, sbitmap, int *);
extern int sd_lists_size (const_rtx, sd_list_types_def);
extern bool sd_lists_empty_p (const_rtx, sd_list_types_def);
-extern void sd_init_insn (rtx);
-extern void sd_finish_insn (rtx);
+extern void sd_init_insn (rtx_insn *);
+extern void sd_finish_insn (rtx_insn *);
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_unresolve_dep (sd_iterator_def);
-extern void sd_copy_back_deps (rtx, rtx, bool);
+extern void sd_copy_back_deps (rtx_insn *, rtx_insn *, bool);
extern void sd_delete_dep (sd_iterator_def);
extern void sd_debug_lists (rtx, sd_list_types_def);
+/* Macros and declarations for scheduling fusion. */
+#define FUSION_MAX_PRIORITY (INT_MAX)
+extern bool sched_fusion;
+
#endif /* INSN_SCHEDULING */
#endif /* GCC_SCHED_INT_H */