n the beginning we make a pass
     through CFG and calculating the conservative solution for the info in
     basic blocks.  When this scheduler will be switched to use dataflow,
     this can be unified as df gives us both per basic block and per
     instruction info.  Actually, we don't do that pass and just hope
     for the best.  */
  regset reg_sets;

  regset reg_clobbers;

  regset reg_uses;
};

#define IDATA_TYPE(ID) ((ID)->type)
#define IDATA_LHS(ID) ((ID)->lhs)
#define IDATA_RHS(ID) ((ID)->rhs)
#define IDATA_REG_SETS(ID) ((ID)->reg_sets)
#define IDATA_REG_USES(ID) ((ID)->reg_uses)
#define IDATA_REG_CLOBBERS(ID) ((ID)->reg_clobbers)

/* Type to represent all needed info to emit an insn.
   This is a virtual equivalent of the insn.
   Every insn in the stream has an associated vinsn.  This is used
   to reduce memory consumption basing on the fact that many insns
   don't change through the scheduler.

   vinsn can be either normal or unique.
   * Normal vinsn is the one, that can be cloned multiple times and typically
   corresponds to normal instruction.

   * Unique vinsn derivates from CALL, ASM, JUMP (for a while) and other
   unusual stuff.  Such a vinsn is described by its INSN field, which is a
   reference to the original instruction.  */
struct vinsn_def
{
  /* Associated insn.  */
  rtx_insn *insn_rtx;

  /* Its description.  */
  struct idata_def id;

  /* Hash of vinsn.  It is computed either from pattern or from rhs using
     hash_rtx.  It is not placed in ID for faster compares.  */
  unsigned hash;

  /* Hash of the insn_rtx pattern.  */
  unsigned hash_rtx;

  /* Smart pointer counter.  */
  int count;

  /* Cached cost of the vinsn.  To access it please use vinsn_cost ().  */
  int cost;

  /* Mark insns that may trap so we don't move them through jumps.  */
  bool may_trap_p;
};

#define VINSN_INSN_RTX(VI) ((VI)->insn_rtx)
#define VINSN_PATTERN(VI) (PATTERN (VINSN_INSN_RTX (VI)))

#define VINSN_ID(VI) (&((VI)->id))
#define VINSN_HASH(VI) ((VI)->hash)
#define VINSN_HASH_RTX(VI) ((VI)->hash_rtx)
#define VINSN_TYPE(VI) (IDATA_TYPE (VINSN_ID (VI)))
#define VINSN_SEPARABLE_P(VI) (VINSN_TYPE (VI) == SET)
#define VINSN_CLONABLE_P(VI) (VINSN_SEPARABLE_P (VI) || VINSN_TYPE (VI) == USE)
#define VINSN_UNIQUE_P(VI) (!VINSN_CLONABLE_P (VI))
#define VINSN_LHS(VI) (IDATA_LHS (VINSN_ID (VI)))
#define VINSN_RHS(VI) (IDATA_RHS (VINSN_ID (VI)))
#define VINSN_REG_SETS(VI) (IDATA_REG_SETS (VINSN_ID (VI)))
#define VINSN_REG_USES(VI) (IDATA_REG_USES (VINSN_ID (VI)))
#define VINSN_REG_CLOBBERS(VI) (IDATA_REG_CLOBBERS (VINSN_ID (VI)))
#define VINSN_COUNT(VI) ((VI)->count)
#define VINSN_MAY_TRAP_P(VI) ((VI)->may_trap_p)
