g_use_data
{
  /* Regno used in the insn.  */
  int regno;
  /* Insn using the regno.  */
  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_use_data *next_insn_use;
};

/* The following structure describes used sets of registers by insns.
   Registers are pseudos whose pressure 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;
};

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 offsets from the base.  */
  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
     because when h_i_d extends, addresses of the deps_list->first
     change without updating deps_list->first->next->prev_nextp.  */

  /* Logical uid gives the original ordering of the insns.  */
  int luid;

  /* 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;

  /* For insns that are scheduled at a fixed difference from another,
     this records the tick in which they must be ready.  */
  int exact_tick;

  /* INTER_TICK is used to adjust INSN_TICKs of instructions from the
     subsequent blocks in a region.  */
  int inter_tick;

  /* Used temporarily to estimate an INSN_TICK value for an insn given
     current knowledge.  */
  int tick_estimate;

  /* See comment on QUEUE_INDEX macro in haifa-sched.c.  */
  int queue_index;

  short cost;

  /* '> 0' if priority is valid,
     '== 0' if priority was not yet computed,
     '< 0' if priority in invalid and should be recomputed.  */
  signed char priority_status;

  /* Set if there's DEF-USE dependence between some speculatively
     moved load insn and this one.  */
  unsigned int fed_by_spec_load : 1;
  unsigned int is_load_insn : 1;
  /* Nonzero if this insn has negative-cost forward dependencies against
     an already scheduled insn.  */
  unsigned int feeds_backtrack_insn : 1;

  /* Nonzero if this insn is a shadow of another, scheduled after a fixed
     delay.  We only emit shadows at the end of a cycle, with no other
     real insns following them.  */
  unsigned int shadow_p : 1;

  /* Used internally in unschedule_insns_until to mark insns that must have
     their TODO_SPEC recomputed.  */
  unsigned int must_recompute_spec : 1;

  /* What speculations are necessary to apply to schedule the instruction.  */
  ds_t todo_spec;

  /* What speculations were already applied.  */
  ds_t done_spec;

  /* What speculations are checked by this instruction.  */
  ds_t check_spec;

  /* Recovery block for speculation checks.  */
  basic_block recovery_block;

  /* Original pattern of the instruction.  */
  rtx orig_pat;

  /* For insns with DEP_CONTROL dependencies, the predicated pattern if it
     was ever successfully constructed.  */
  rtx predicated_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
     pressure 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;
  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;
typedef haifa_insn_data_def *haifa_insn_data_t;


extern vec<haifa_insn_data_def> h_i_d;

#define HID(INSN) (&h_i_d[INSN_UID (INSN)])

/* 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)
#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)
#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;


extern vec<haifa_deps_insn_data_def> h_d_i_d;

#define HDID(INSN) (&h_d_i_d[INSN_LUID (INSN)])
#define INSN_DEP_COUNT(INSN)	(HDID (INSN)->dep_count)
#define HAS_INTERNAL_DEP(INSN)  (HDID (INSN)->has_internal_dep)
#define INSN_FORW_DEPS(INSN) (HDID (INSN)->forw_deps)
#define INSN_RESOLVED_BACK_DEPS(INSN) (HDID (INSN)->resolved_back_deps)
#define INSN_RESOLVED_FORW_DEPS(INSN) (HDID (INSN)->resolved_forw_deps)
#define INSN_HARD_BACK_DEPS(INSN) (HDID (INSN)->hard_back_deps)
#define INSN_SPEC_BACK_DEPS(INSN) (HDID (INSN)->spec_back_deps)
#define INSN_CACHED_COND(INSN)	(HDID (INSN)->cond)
#define INSN_REVERSE_COND(INSN) (HDID (INSN)->reverse_cond)
#define INSN_COND_DEPS(INSN)	(HDID (INSN)->cond_deps)
#define CANT_MOVE(INSN)	(HDID (INSN)->cant_move)
#define CANT_MOVE_BY_LUID(LUID)	(h_d_i_d[LUID].cant_move)


#define INSN_PRIORITY(INSN)	(HID (INSN)->priority)
#define INSN_PRIORITY_STATUS(INSN) (HID (INSN)->priority_status)
#define INSN_PRIORITY_KNOWN(INSN) (INSN_PRIORITY_STATUS (INSN) > 0)
#define TODO_SPEC(INSN) (HID (INSN)->todo_spec)
#define DONE_SPEC(INSN) (HID (INSN)->done_spec)
#define CHECK_SPEC(INSN) (HID (INSN)->check_spec)
#define RECOVERY_BLOCK(INSN) (HID (INSN)->recovery_block)
#define ORIG_PAT(INSN) (HID (INSN)->orig_pat)
#define PREDICATED_PAT(INSN) (HID (INSN)->predicated_pat)

/* INSN is either a simple or a branchy speculation check.  */
#define IS_SPECULATION_CHECK_P(INSN) \
  (sel_sched_p () ? sel_insn_is_speculation_check (INSN) : RECOVERY_BLOCK (INSN) != NULL)

/* INSN is a speculation check that will simply reexecute the speculatively
   scheduled instruction if the speculation fails.  */
#define IS_SPECULATION_SIMPLE_CHECK_P(INSN) \
  (RECOVERY_BLOCK (INSN) == EXIT_BLOCK_PTR_FOR_FN (cfun))

/* INSN is a speculation check that will branch to RECOVERY_BLOCK if the
   speculation fails.  Insns in that block will reexecute the speculatively
   scheduled code and then will return immediately after INSN thus preserving
   semantics of the program.  */
#define IS_SPECULATION_BRANCHY_CHECK_P(INSN) \
  (RECOVERY_BLOCK (INSN) != NULL             \
   && RECOVERY_BLOCK (INSN) != EXIT_BLOCK_PTR_FOR_FN (cfun))

