IA MCU psABI support: changes to libraries
[gcc.git] / gcc / rtl.h
index a4b5e10673f32c3635d4da306f719697054f0ed9..d74c20fbed10d21c56c9e55d5794764282e02496 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1,5 +1,5 @@
 /* Register Transfer Language (RTL) definitions for GCC
-   Copyright (C) 1987-2014 Free Software Foundation, Inc.
+   Copyright (C) 1987-2015 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -20,18 +20,25 @@ along with GCC; see the file COPYING3.  If not see
 #ifndef GCC_RTL_H
 #define GCC_RTL_H
 
-#include <utility>
-#include "statistics.h"
-#include "machmode.h"
-#include "input.h"
+/* This file is occasionally included by generator files which expect
+   machmode.h and other files to exist and would not normally have been
+   included by coretypes.h.  */
+#ifdef GENERATOR_FILE
+#include "machmode.h"     
+#include "signop.h"
+#include "wide-int.h"
+#include "double-int.h"
 #include "real.h"
-#include "vec.h"
 #include "fixed-value.h"
-#include "alias.h"
-#include "hashtab.h"
-#include "wide-int.h"
-#include "flags.h"
+#include "statistics.h"
+#include "vec.h"
+#include "hash-table.h"
+#include "hash-set.h"
+#include "input.h"
 #include "is-a.h"
+#endif  /* GENERATOR_FILE */
+
+#include "flags.h"
 
 /* Value used by some passes to "recognize" noop moves as valid
  instructions.  */
@@ -182,7 +189,7 @@ struct GTY(()) mem_attrs
    object in the low part of a 4-byte register, the OFFSET field
    will be -3 rather than 0.  */
 
-struct GTY(()) reg_attrs {
+struct GTY((for_user)) reg_attrs {
   tree decl;                   /* decl corresponding to REG.  */
   HOST_WIDE_INT offset;                /* Offset from start of DECL.  */
 };
@@ -196,17 +203,29 @@ union rtunion
   const char *rt_str;
   rtx rt_rtx;
   rtvec rt_rtvec;
-  enum machine_mode rt_type;
+  machine_mode rt_type;
   addr_diff_vec_flags rt_addr_diff_vec_flags;
   struct cselib_val *rt_cselib;
   tree rt_tree;
   basic_block rt_bb;
   mem_attrs *rt_mem;
-  reg_attrs *rt_reg;
   struct constant_descriptor_rtx *rt_constant;
   struct dw_cfi_node *rt_cfi;
 };
 
+/* Describes the properties of a REG.  */
+struct GTY(()) reg_info {
+  /* The value of REGNO.  */
+  unsigned int regno;
+
+  /* The value of REG_NREGS.  */
+  unsigned int nregs : 8;
+  unsigned int unused : 24;
+
+  /* The value of REG_ATTRS.  */
+  reg_attrs *attrs;
+};
+
 /* This structure remembers the position of a SYMBOL_REF within an
    object_block structure.  A SYMBOL_REF only provides this information
    if SYMBOL_REF_HAS_BLOCK_INFO_P is true.  */
@@ -224,7 +243,7 @@ struct GTY(()) block_symbol {
 
 /* Describes a group of objects that are to be placed together in such
    a way that their relative positions are known.  */
-struct GTY(()) object_block {
+struct GTY((for_user)) object_block {
   /* The section in which these objects should be placed.  */
   section *sect;
 
@@ -297,7 +316,8 @@ struct GTY((desc("0"), tag("0"),
      In a CODE_LABEL, part of the two-bit alternate entry field.
      1 in a CONCAT is VAL_EXPR_IS_COPIED in var-tracking.c.
      1 in a VALUE is SP_BASED_VALUE_P in cselib.c.
-     1 in a SUBREG generated by LRA for reload insns.  */
+     1 in a SUBREG generated by LRA for reload insns.
+     1 in a CALL for calls instrumented by Pointer Bounds Checker.  */
   unsigned int jump : 1;
   /* In a CODE_LABEL, part of the two-bit alternate entry field.
      1 in a MEM if it cannot trap.
@@ -395,6 +415,7 @@ struct GTY((desc("0"), tag("0"),
   union u {
     rtunion fld[1];
     HOST_WIDE_INT hwint[1];
+    struct reg_info reg;
     struct block_symbol block_sym;
     struct real_value rv;
     struct fixed_value fv;
@@ -402,8 +423,95 @@ struct GTY((desc("0"), tag("0"),
   } GTY ((special ("rtx_def"), desc ("GET_CODE (&%0)"))) u;
 };
 
+/* A node for constructing singly-linked lists of rtx.  */
+
+class GTY(()) rtx_expr_list : public rtx_def
+{
+  /* No extra fields, but adds invariant: (GET_CODE (X) == EXPR_LIST).  */
+
+public:
+  /* Get next in list.  */
+  rtx_expr_list *next () const;
+
+  /* Get at the underlying rtx.  */
+  rtx element () const;
+};
+
+template <>
+template <>
+inline bool
+is_a_helper <rtx_expr_list *>::test (rtx rt)
+{
+  return rt->code == EXPR_LIST;
+}
+
+class GTY(()) rtx_insn_list : public rtx_def
+{
+  /* No extra fields, but adds invariant: (GET_CODE (X) == INSN_LIST).
+
+     This is an instance of:
+
+       DEF_RTL_EXPR(INSN_LIST, "insn_list", "ue", RTX_EXTRA)
+
+     i.e. a node for constructing singly-linked lists of rtx_insn *, where
+     the list is "external" to the insn (as opposed to the doubly-linked
+     list embedded within rtx_insn itself).  */
+
+public:
+  /* Get next in list.  */
+  rtx_insn_list *next () const;
+
+  /* Get at the underlying instruction.  */
+  rtx_insn *insn () const;
+
+};
+
+template <>
+template <>
+inline bool
+is_a_helper <rtx_insn_list *>::test (rtx rt)
+{
+  return rt->code == INSN_LIST;
+}
+
+/* A node with invariant GET_CODE (X) == SEQUENCE i.e. a vector of rtx,
+   typically (but not always) of rtx_insn *, used in the late passes.  */
+
+class GTY(()) rtx_sequence : public rtx_def
+{
+  /* No extra fields, but adds invariant: (GET_CODE (X) == SEQUENCE).  */
+
+public:
+  /* Get number of elements in sequence.  */
+  int len () const;
+
+  /* Get i-th element of the sequence.  */
+  rtx element (int index) const;
+
+  /* Get i-th element of the sequence, with a checked cast to
+     rtx_insn *.  */
+  rtx_insn *insn (int index) const;
+};
+
+template <>
+template <>
+inline bool
+is_a_helper <rtx_sequence *>::test (rtx rt)
+{
+  return rt->code == SEQUENCE;
+}
+
+template <>
+template <>
+inline bool
+is_a_helper <const rtx_sequence *>::test (const_rtx rt)
+{
+  return rt->code == SEQUENCE;
+}
+
 class GTY(()) rtx_insn : public rtx_def
 {
+public:
   /* No extra fields, but adds the invariant:
 
      (INSN_P (X)
@@ -419,6 +527,18 @@ class GTY(()) rtx_insn : public rtx_def
     i.e. we have an rtx that has an INSN_UID field and can be part of
     a linked list of insns.
   */
+
+  /* Returns true if this insn has been deleted.  */
+
+  bool deleted () const { return volatil; }
+
+  /* Mark this insn as deleted.  */
+
+  void set_deleted () { volatil = true; }
+
+  /* Mark this insn as not deleted.  */
+
+  void set_undeleted () { volatil = false; }
 };
 
 /* Subclasses of rtx_insn.  */
@@ -447,6 +567,7 @@ class GTY(()) rtx_nonjump_insn : public rtx_insn
 
 class GTY(()) rtx_jump_insn : public rtx_insn
 {
+public:
   /* No extra fields, but adds the invariant:
        JUMP_P (X) aka (GET_CODE (X) == JUMP_INSN)
      i.e. an instruction that can possibly jump.
@@ -454,6 +575,21 @@ class GTY(()) rtx_jump_insn : public rtx_insn
      This is an instance of:
        DEF_RTL_EXPR(JUMP_INSN, "jump_insn", "uuBeiie0", RTX_INSN)
      from rtl.def.  */
+
+  /* Returns jump target of this instruction.  The returned value is not
+     necessarily a code label: it may also be a RETURN or SIMPLE_RETURN
+     expression.  Also, when the code label is marked "deleted", it is
+     replaced by a NOTE.  In some cases the value is NULL_RTX.  */
+
+  inline rtx jump_label () const;
+
+  /* Returns jump target cast to rtx_code_label *.  */
+
+  inline rtx_code_label *jump_target () const;
+
+  /* Set jump target.  */
+
+  inline void set_jump_target (rtx_code_label *);
 };
 
 class GTY(()) rtx_call_insn : public rtx_insn
@@ -479,6 +615,21 @@ class GTY(()) rtx_jump_table_data : public rtx_insn
      This is an instance of:
        DEF_RTL_EXPR(JUMP_TABLE_DATA, "jump_table_data", "uuBe0000", RTX_INSN)
      from rtl.def.  */
+
+public:
+
+  /* This can be either:
+
+       (a) a table of absolute jumps, in which case PATTERN (this) is an
+           ADDR_VEC with arg 0 a vector of labels, or
+
+       (b) a table of relative jumps (e.g. for -fPIC), in which case
+           PATTERN (this) is an ADDR_DIFF_VEC, with arg 0 a LABEL_REF and
+          arg 1 the vector of labels.
+
+     This method gets the underlying vec.  */
+
+  inline rtvec get_labels () const;
 };
 
 class GTY(()) rtx_barrier : public rtx_insn
@@ -534,17 +685,17 @@ class GTY(()) rtx_note : public rtx_insn
                       || JUMP_TABLE_DATA_P (X)         \
                       || BARRIER_P (X)                 \
                       || LABEL_P (X))                  \
-                     && PREV_INSN (X) != NULL           \
-                     && NEXT_INSN (PREV_INSN (X)) == X  \
-                     ? PREV_INSN (X) : NULL)
+                    && PREV_INSN (as_a <rtx_insn *> (X)) != NULL       \
+                     && NEXT_INSN (PREV_INSN (as_a <rtx_insn *> (X))) == X \
+                     ? PREV_INSN (as_a <rtx_insn *> (X)) : NULL)
 
 /* Define macros to access the `code' field of the rtx.  */
 
 #define GET_CODE(RTX)      ((enum rtx_code) (RTX)->code)
 #define PUT_CODE(RTX, CODE) ((RTX)->code = (CODE))
 
-#define GET_MODE(RTX)      ((enum machine_mode) (RTX)->mode)
-#define PUT_MODE(RTX, MODE) ((RTX)->mode = (MODE))
+#define GET_MODE(RTX)          ((machine_mode) (RTX)->mode)
+#define PUT_MODE_RAW(RTX, MODE)        ((RTX)->mode = (MODE))
 
 /* RTL vector.  These appear inside RTX's when there is a need
    for a variable number of things.  The principle use is inside
@@ -675,6 +826,9 @@ struct GTY(()) rtvec_def {
 /* Predicate yielding nonzero iff X is a data for a jump table.  */
 #define JUMP_TABLE_DATA_P(INSN) (GET_CODE (INSN) == JUMP_TABLE_DATA)
 
+/* Predicate yielding nonzero iff RTX is a subreg.  */
+#define SUBREG_P(RTX) (GET_CODE (RTX) == SUBREG)
+
 template <>
 template <>
 inline bool
@@ -723,6 +877,14 @@ is_a_helper <rtx_jump_insn *>::test (rtx rt)
   return JUMP_P (rt);
 }
 
+template <>
+template <>
+inline bool
+is_a_helper <rtx_jump_insn *>::test (rtx_insn *insn)
+{
+  return JUMP_P (insn);
+}
+
 template <>
 template <>
 inline bool
@@ -953,6 +1115,13 @@ is_a_helper <rtx_note *>::test (rtx_insn *insn)
                                 __LINE__, __FUNCTION__);               \
    &_rtx->u.fv; })
 
+#define REG_CHECK(RTX) __extension__                                   \
+({ __typeof (RTX) const _rtx = (RTX);                                  \
+   if (GET_CODE (_rtx) != REG)                                         \
+     rtl_check_failed_code1 (_rtx, REG,  __FILE__, __LINE__,           \
+                            __FUNCTION__);                             \
+   &_rtx->u.reg; })
+
 #define BLOCK_SYMBOL_CHECK(RTX) __extension__                          \
 ({ __typeof (RTX) const _symbol = (RTX);                               \
    const unsigned int flags = SYMBOL_REF_FLAGS (_symbol);              \
@@ -981,7 +1150,7 @@ extern void rtl_check_failed_code1 (const_rtx, enum rtx_code, const char *,
 extern void rtl_check_failed_code2 (const_rtx, enum rtx_code, enum rtx_code,
                                    const char *, int, const char *)
     ATTRIBUTE_NORETURN;
-extern void rtl_check_failed_code_mode (const_rtx, enum rtx_code, enum machine_mode,
+extern void rtl_check_failed_code_mode (const_rtx, enum rtx_code, machine_mode,
                                        bool, const char *, int, const char *)
     ATTRIBUTE_NORETURN;
 extern void rtl_check_failed_block_symbol (const char *, int, const char *)
@@ -1007,6 +1176,7 @@ extern void rtvec_check_failed_bounds (const_rtvec, int, const char *, int,
 #define XCNMWINT(RTX, N, C, M)     ((RTX)->u.hwint[N])
 #define XCNMPRV(RTX, C, M)         (&(RTX)->u.rv)
 #define XCNMPFV(RTX, C, M)         (&(RTX)->u.fv)
+#define REG_CHECK(RTX)             (&(RTX)->u.reg)
 #define BLOCK_SYMBOL_CHECK(RTX)            (&(RTX)->u.block_sym)
 #define HWIVEC_CHECK(RTX,C)        (&(RTX)->u.hwiv)
 
@@ -1131,7 +1301,6 @@ extern void rtl_check_failed_flag (const char *, const_rtx, const char *,
 #define X0ADVFLAGS(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_addr_diff_vec_flags)
 #define X0CSELIB(RTX, N)   (RTL_CHECK1 (RTX, N, '0').rt_cselib)
 #define X0MEMATTR(RTX, N)  (RTL_CHECKC1 (RTX, N, MEM).rt_mem)
-#define X0REGATTR(RTX, N)  (RTL_CHECKC1 (RTX, N, REG).rt_reg)
 #define X0CONSTANT(RTX, N) (RTL_CHECK1 (RTX, N, '0').rt_constant)
 
 /* Access a '0' field with any type.  */
@@ -1153,12 +1322,65 @@ extern void rtl_check_failed_flag (const char *, const_rtx, const char *,
 
 #define XC2EXP(RTX, N, C1, C2)      (RTL_CHECKC2 (RTX, N, C1, C2).rt_rtx)
 \f
+
+/* Methods of rtx_expr_list.  */
+
+inline rtx_expr_list *rtx_expr_list::next () const
+{
+  rtx tmp = XEXP (this, 1);
+  return safe_as_a <rtx_expr_list *> (tmp);
+}
+
+inline rtx rtx_expr_list::element () const
+{
+  return XEXP (this, 0);
+}
+
+/* Methods of rtx_insn_list.  */
+
+inline rtx_insn_list *rtx_insn_list::next () const
+{
+  rtx tmp = XEXP (this, 1);
+  return safe_as_a <rtx_insn_list *> (tmp);
+}
+
+inline rtx_insn *rtx_insn_list::insn () const
+{
+  rtx tmp = XEXP (this, 0);
+  return safe_as_a <rtx_insn *> (tmp);
+}
+
+/* Methods of rtx_sequence.  */
+
+inline int rtx_sequence::len () const
+{
+  return XVECLEN (this, 0);
+}
+
+inline rtx rtx_sequence::element (int index) const
+{
+  return XVECEXP (this, 0, index);
+}
+
+inline rtx_insn *rtx_sequence::insn (int index) const
+{
+  return as_a <rtx_insn *> (XVECEXP (this, 0, index));
+}
+
 /* ACCESS MACROS for particular fields of insns.  */
 
 /* Holds a unique number for each insn.
    These are not necessarily sequentially increasing.  */
-#define INSN_UID(INSN) \
-  (RTL_INSN_CHAIN_FLAG_CHECK ("INSN_UID", (INSN))->u2.insn_uid)
+inline int INSN_UID (const_rtx insn)
+{
+  return RTL_INSN_CHAIN_FLAG_CHECK ("INSN_UID",
+                                   (insn))->u2.insn_uid;
+}
+inline int& INSN_UID (rtx insn)
+{
+  return RTL_INSN_CHAIN_FLAG_CHECK ("INSN_UID",
+                                   (insn))->u2.insn_uid;
+}
 
 /* Chain insns together in sequence.  */
 
@@ -1167,54 +1389,91 @@ extern void rtl_check_failed_flag (const char *, const_rtx, const char *,
    and an lvalue form:
      SET_NEXT_INSN/SET_PREV_INSN.  */
 
-inline rtx_insn *PREV_INSN (const_rtx insn)
+inline rtx_insn *PREV_INSN (const rtx_insn *insn)
 {
   rtx prev = XEXP (insn, 0);
   return safe_as_a <rtx_insn *> (prev);
 }
 
-inline rtx& SET_PREV_INSN (rtx insn)
+inline rtx& SET_PREV_INSN (rtx_insn *insn)
 {
   return XEXP (insn, 0);
 }
 
-inline rtx_insn *NEXT_INSN (const_rtx insn)
+inline rtx_insn *NEXT_INSN (const rtx_insn *insn)
 {
   rtx next = XEXP (insn, 1);
   return safe_as_a <rtx_insn *> (next);
 }
 
-inline rtx& SET_NEXT_INSN (rtx insn)
+inline rtx& SET_NEXT_INSN (rtx_insn *insn)
 {
   return XEXP (insn, 1);
 }
 
-#define BLOCK_FOR_INSN(INSN) XBBDEF (INSN, 2)
+inline basic_block BLOCK_FOR_INSN (const_rtx insn)
+{
+  return XBBDEF (insn, 2);
+}
+
+inline basic_block& BLOCK_FOR_INSN (rtx insn)
+{
+  return XBBDEF (insn, 2);
+}
+
+inline void set_block_for_insn (rtx_insn *insn, basic_block bb)
+{
+  BLOCK_FOR_INSN (insn) = bb;
+}
 
 /* The body of an insn.  */
-#define PATTERN(INSN)  XEXP (INSN, 3)
+inline rtx PATTERN (const_rtx insn)
+{
+  return XEXP (insn, 3);
+}
+
+inline rtx& PATTERN (rtx insn)
+{
+  return XEXP (insn, 3);
+}
+
+inline unsigned int INSN_LOCATION (const rtx_insn *insn)
+{
+  return XUINT (insn, 4);
+}
 
-#define INSN_LOCATION(INSN) XUINT (INSN, 4)
+inline unsigned int& INSN_LOCATION (rtx_insn *insn)
+{
+  return XUINT (insn, 4);
+}
 
-#define INSN_HAS_LOCATION(INSN) ((LOCATION_LOCUS (INSN_LOCATION (INSN)))\
-  != UNKNOWN_LOCATION)
+inline bool INSN_HAS_LOCATION (const rtx_insn *insn)
+{
+  return LOCATION_LOCUS (INSN_LOCATION (insn)) != UNKNOWN_LOCATION;
+}
 
 /* LOCATION of an RTX if relevant.  */
 #define RTL_LOCATION(X) (INSN_P (X) ? \
-                        INSN_LOCATION (X) : UNKNOWN_LOCATION)
+                        INSN_LOCATION (as_a <rtx_insn *> (X)) \
+                        : UNKNOWN_LOCATION)
 
 /* Code number of instruction, from when it was recognized.
    -1 means this instruction has not been recognized yet.  */
 #define INSN_CODE(INSN) XINT (INSN, 5)
 
+inline rtvec rtx_jump_table_data::get_labels () const
+{
+  rtx pat = PATTERN (this);
+  if (GET_CODE (pat) == ADDR_VEC)
+    return XVEC (pat, 0);
+  else
+    return XVEC (pat, 1); /* presumably an ADDR_DIFF_VEC */
+}
+
 #define RTX_FRAME_RELATED_P(RTX)                                       \
   (RTL_FLAG_CHECK6 ("RTX_FRAME_RELATED_P", (RTX), DEBUG_INSN, INSN,    \
                    CALL_INSN, JUMP_INSN, BARRIER, SET)->frame_related)
 
-/* 1 if RTX is an insn that has been deleted.  */
-#define INSN_DELETED_P(RTX)                                            \
-  (RTL_INSN_CHAIN_FLAG_CHECK ("INSN_DELETED_P", (RTX))->volatil)
-
 /* 1 if JUMP RTX is a crossing jump.  */
 #define CROSSING_JUMP_P(RTX) \
   (RTL_FLAG_CHECK1 ("CROSSING_JUMP_P", (RTX), JUMP_INSN)->jump)
@@ -1284,7 +1543,7 @@ enum reg_note
 /* Define macros to extract and insert the reg-note kind in an EXPR_LIST.  */
 #define REG_NOTE_KIND(LINK) ((enum reg_note) GET_MODE (LINK))
 #define PUT_REG_NOTE_KIND(LINK, KIND) \
-  PUT_MODE (LINK, (enum machine_mode) (KIND))
+  PUT_MODE_RAW (LINK, (machine_mode) (KIND))
 
 /* Names for REG_NOTE's in EXPR_LIST insn's.  */
 
@@ -1469,17 +1728,46 @@ enum label_kind
    be decremented and possibly the label can be deleted.  */
 #define JUMP_LABEL(INSN)   XCEXP (INSN, 7, JUMP_INSN)
 
+inline rtx_insn *JUMP_LABEL_AS_INSN (const rtx_insn *insn)
+{
+  return safe_as_a <rtx_insn *> (JUMP_LABEL (insn));
+}
+
+/* Methods of rtx_jump_insn.  */
+
+inline rtx rtx_jump_insn::jump_label () const
+{
+  return JUMP_LABEL (this);
+}
+
+inline rtx_code_label *rtx_jump_insn::jump_target () const
+{
+  return safe_as_a <rtx_code_label *> (JUMP_LABEL (this));
+}
+
+inline void rtx_jump_insn::set_jump_target (rtx_code_label *target)
+{
+  JUMP_LABEL (this) = target;
+}
+
 /* Once basic blocks are found, each CODE_LABEL starts a chain that
    goes through all the LABEL_REFs that jump to that label.  The chain
    eventually winds up at the CODE_LABEL: it is circular.  */
 #define LABEL_REFS(LABEL) XCEXP (LABEL, 3, CODE_LABEL)
+
+/* Get the label that a LABEL_REF references.  */
+#define LABEL_REF_LABEL(LABREF) XCEXP (LABREF, 0, LABEL_REF)
+
 \f
 /* For a REG rtx, REGNO extracts the register number.  REGNO can only
    be used on RHS.  Use SET_REGNO to change the value.  */
 #define REGNO(RTX) (rhs_regno(RTX))
-#define SET_REGNO(RTX,N) \
-  (df_ref_change_reg_with_loc (REGNO (RTX), N, RTX), XCUINT (RTX, 0, REG) = N)
-#define SET_REGNO_RAW(RTX,N) (XCUINT (RTX, 0, REG) = N)
+#define SET_REGNO(RTX, N) (df_ref_change_reg_with_loc (RTX, N))
+
+/* Return the number of consecutive registers in a REG.  This is always
+   1 for pseudo registers and is determined by HARD_REGNO_NREGS for
+   hard registers.  */
+#define REG_NREGS(RTX) (REG_CHECK (RTX)->nregs)
 
 /* ORIGINAL_REGNO holds the number the register originally had; for a
    pseudo register turned into a hard reg this will hold the old pseudo
@@ -1491,9 +1779,25 @@ enum label_kind
 static inline unsigned int
 rhs_regno (const_rtx x)
 {
-  return XCUINT (x, 0, REG);
+  return REG_CHECK (x)->regno;
+}
+
+/* Return the final register in REG X plus one.  */
+static inline unsigned int
+END_REGNO (const_rtx x)
+{
+  return REGNO (x) + REG_NREGS (x);
 }
 
+/* Change the REGNO and REG_NREGS of REG X to the specified values,
+   bypassing the df machinery.  */
+static inline void
+set_regno_raw (rtx x, unsigned int regno, unsigned int nregs)
+{
+  reg_info *reg = REG_CHECK (x);
+  reg->regno = regno;
+  reg->nregs = nregs;
+}
 
 /* 1 if RTX is a reg or parallel that is the current function's return
    value.  */
@@ -1571,6 +1875,14 @@ rhs_regno (const_rtx x)
    not to use an rtx with this cost under any circumstances.  */
 #define MAX_COST INT_MAX
 
+/* Return true if CODE always has VOIDmode.  */
+
+static inline bool
+always_void_p (enum rtx_code code)
+{
+  return code == SET;
+}
+
 /* A structure to hold all available cost information about an rtl
    expression.  */
 struct full_rtx_costs
@@ -1618,13 +1930,71 @@ costs_add_n_insns (struct full_rtx_costs *c, int n)
   c->size += COSTS_N_INSNS (n);
 }
 
+/* Describes the shape of a subreg:
+
+   inner_mode == the mode of the SUBREG_REG
+   offset     == the SUBREG_BYTE
+   outer_mode == the mode of the SUBREG itself.  */
+struct subreg_shape {
+  subreg_shape (machine_mode, unsigned int, machine_mode);
+  bool operator == (const subreg_shape &) const;
+  bool operator != (const subreg_shape &) const;
+  unsigned int unique_id () const;
+
+  machine_mode inner_mode;
+  unsigned int offset;
+  machine_mode outer_mode;
+};
+
+inline
+subreg_shape::subreg_shape (machine_mode inner_mode_in,
+                           unsigned int offset_in,
+                           machine_mode outer_mode_in)
+  : inner_mode (inner_mode_in), offset (offset_in), outer_mode (outer_mode_in)
+{}
+
+inline bool
+subreg_shape::operator == (const subreg_shape &other) const
+{
+  return (inner_mode == other.inner_mode
+         && offset == other.offset
+         && outer_mode == other.outer_mode);
+}
+
+inline bool
+subreg_shape::operator != (const subreg_shape &other) const
+{
+  return !operator == (other);
+}
+
+/* Return an integer that uniquely identifies this shape.  Structures
+   like rtx_def assume that a mode can fit in an 8-bit bitfield and no
+   current mode is anywhere near being 65536 bytes in size, so the
+   id comfortably fits in an int.  */
+
+inline unsigned int
+subreg_shape::unique_id () const
+{
+  STATIC_ASSERT (MAX_MACHINE_MODE <= 256);
+  return (int) inner_mode + ((int) outer_mode << 8) + (offset << 16);
+}
+
+/* Return the shape of a SUBREG rtx.  */
+
+static inline subreg_shape
+shape_of_subreg (const_rtx x)
+{
+  return subreg_shape (GET_MODE (SUBREG_REG (x)),
+                      SUBREG_BYTE (x), GET_MODE (x));
+}
+
 /* Information about an address.  This structure is supposed to be able
    to represent all supported target addresses.  Please extend it if it
    is not yet general enough.  */
 struct address_info {
   /* The mode of the value being addressed, or VOIDmode if this is
      a load-address operation with no known address mode.  */
-  enum machine_mode mode;
+  machine_mode mode;
 
   /* The address space.  */
   addr_space_t as;
@@ -1692,7 +2062,7 @@ struct address_info {
 /* This is used to bundle an rtx and a mode together so that the pair
    can be used with the wi:: routines.  If we ever put modes into rtx
    integer constants, this should go away and then just pass an rtx in.  */
-typedef std::pair <rtx, enum machine_mode> rtx_mode_t;
+typedef std::pair <rtx, machine_mode> rtx_mode_t;
 
 namespace wi
 {
@@ -1750,13 +2120,13 @@ wi::int_traits <rtx_mode_t>::decompose (HOST_WIDE_INT *,
 
 namespace wi
 {
-  hwi_with_prec shwi (HOST_WIDE_INT, enum machine_mode mode);
-  wide_int min_value (enum machine_mode, signop);
-  wide_int max_value (enum machine_mode, signop);
+  hwi_with_prec shwi (HOST_WIDE_INT, machine_mode mode);
+  wide_int min_value (machine_mode, signop);
+  wide_int max_value (machine_mode, signop);
 }
 
 inline wi::hwi_with_prec
-wi::shwi (HOST_WIDE_INT val, enum machine_mode mode)
+wi::shwi (HOST_WIDE_INT val, machine_mode mode)
 {
   return shwi (val, GET_MODE_PRECISION (mode));
 }
@@ -1764,7 +2134,7 @@ wi::shwi (HOST_WIDE_INT val, enum machine_mode mode)
 /* Produce the smallest number that is represented in MODE.  The precision
    is taken from MODE and the sign from SGN.  */
 inline wide_int
-wi::min_value (enum machine_mode mode, signop sgn)
+wi::min_value (machine_mode mode, signop sgn)
 {
   return min_value (GET_MODE_PRECISION (mode), sgn);
 }
@@ -1772,37 +2142,37 @@ wi::min_value (enum machine_mode mode, signop sgn)
 /* Produce the largest number that is represented in MODE.  The precision
    is taken from MODE and the sign from SGN.  */
 inline wide_int
-wi::max_value (enum machine_mode mode, signop sgn)
+wi::max_value (machine_mode mode, signop sgn)
 {
   return max_value (GET_MODE_PRECISION (mode), sgn);
 }
 
 extern void init_rtlanal (void);
 extern int rtx_cost (rtx, enum rtx_code, int, bool);
-extern int address_cost (rtx, enum machine_mode, addr_space_t, bool);
+extern int address_cost (rtx, machine_mode, addr_space_t, bool);
 extern void get_full_rtx_cost (rtx, enum rtx_code, int,
                               struct full_rtx_costs *);
 extern unsigned int subreg_lsb (const_rtx);
-extern unsigned int subreg_lsb_1 (enum machine_mode, enum machine_mode,
+extern unsigned int subreg_lsb_1 (machine_mode, machine_mode,
                                  unsigned int);
-extern unsigned int subreg_regno_offset        (unsigned int, enum machine_mode,
-                                        unsigned int, enum machine_mode);
-extern bool subreg_offset_representable_p (unsigned int, enum machine_mode,
-                                          unsigned int, enum machine_mode);
+extern unsigned int subreg_regno_offset        (unsigned int, machine_mode,
+                                        unsigned int, machine_mode);
+extern bool subreg_offset_representable_p (unsigned int, machine_mode,
+                                          unsigned int, machine_mode);
 extern unsigned int subreg_regno (const_rtx);
-extern int simplify_subreg_regno (unsigned int, enum machine_mode,
-                                 unsigned int, enum machine_mode);
+extern int simplify_subreg_regno (unsigned int, machine_mode,
+                                 unsigned int, machine_mode);
 extern unsigned int subreg_nregs (const_rtx);
 extern unsigned int subreg_nregs_with_regno (unsigned int, const_rtx);
-extern unsigned HOST_WIDE_INT nonzero_bits (const_rtx, enum machine_mode);
-extern unsigned int num_sign_bit_copies (const_rtx, enum machine_mode);
+extern unsigned HOST_WIDE_INT nonzero_bits (const_rtx, machine_mode);
+extern unsigned int num_sign_bit_copies (const_rtx, machine_mode);
 extern bool constant_pool_constant_p (rtx);
-extern bool truncated_to_mode (enum machine_mode, const_rtx);
-extern int low_bitmask_len (enum machine_mode, unsigned HOST_WIDE_INT);
+extern bool truncated_to_mode (machine_mode, const_rtx);
+extern int low_bitmask_len (machine_mode, unsigned HOST_WIDE_INT);
 extern void split_double (rtx, rtx *, rtx *);
 extern rtx *strip_address_mutations (rtx *, enum rtx_code * = 0);
 extern void decompose_address (struct address_info *, rtx *,
-                              enum machine_mode, addr_space_t, enum rtx_code);
+                              machine_mode, addr_space_t, enum rtx_code);
 extern void decompose_lea_address (struct address_info *, rtx *);
 extern void decompose_mem_address (struct address_info *, rtx);
 extern void update_address (struct address_info *);
@@ -1932,6 +2302,10 @@ do {                                                                     \
 #define LRA_SUBREG_P(RTX)      \
   (RTL_FLAG_CHECK1 ("LRA_SUBREG_P", (RTX), SUBREG)->jump)
 
+/* True if call is instrumented by Pointer Bounds Checker.  */
+#define CALL_EXPR_WITH_BOUNDS_P(RTX) \
+  (RTL_FLAG_CHECK1 ("CALL_EXPR_WITH_BOUNDS_P", (RTX), CALL)->jump)
+
 /* Access various components of an ASM_OPERANDS rtx.  */
 
 #define ASM_OPERANDS_TEMPLATE(RTX) XCSTR (RTX, 0, ASM_OPERANDS)
@@ -1978,7 +2352,7 @@ do {                                                                      \
 
 /* The register attribute block.  We provide access macros for each value
    in the block and provide defaults if none specified.  */
-#define REG_ATTRS(RTX) X0REGATTR (RTX, 1)
+#define REG_ATTRS(RTX) (REG_CHECK (RTX)->attrs)
 
 #ifndef GENERATOR_FILE
 /* For a MEM rtx, the alias set.  If 0, this MEM is not in any alias
@@ -2274,8 +2648,8 @@ extern int currently_expanding_to_rtl;
 /* Generally useful functions.  */
 
 /* In explow.c */
-extern HOST_WIDE_INT trunc_int_for_mode        (HOST_WIDE_INT, enum machine_mode);
-extern rtx plus_constant (enum machine_mode, rtx, HOST_WIDE_INT, bool = false);
+extern HOST_WIDE_INT trunc_int_for_mode        (HOST_WIDE_INT, machine_mode);
+extern rtx plus_constant (machine_mode, rtx, HOST_WIDE_INT, bool = false);
 
 /* In rtl.c */
 extern rtx rtx_alloc_stat (RTX_CODE MEM_STAT_DECL);
@@ -2291,6 +2665,7 @@ extern rtvec rtvec_alloc (int);
 extern rtvec shallow_copy_rtvec (rtvec);
 extern bool shared_const_p (const_rtx);
 extern rtx copy_rtx (rtx);
+extern enum rtx_code classify_insn (rtx);
 extern void dump_rtx_statistics (void);
 
 /* In emit-rtl.c */
@@ -2304,102 +2679,94 @@ extern int rtx_equal_p (const_rtx, const_rtx);
 
 /* In emit-rtl.c */
 extern rtvec gen_rtvec_v (int, rtx *);
-extern rtx gen_reg_rtx (enum machine_mode);
-extern rtx gen_rtx_REG_offset (rtx, enum machine_mode, unsigned int, int);
-extern rtx gen_reg_rtx_offset (rtx, enum machine_mode, int);
+extern rtvec gen_rtvec_v (int, rtx_insn **);
+extern rtx gen_reg_rtx (machine_mode);
+extern rtx gen_rtx_REG_offset (rtx, machine_mode, unsigned int, int);
+extern rtx gen_reg_rtx_offset (rtx, machine_mode, int);
 extern rtx gen_reg_rtx_and_attrs (rtx);
 extern rtx_code_label *gen_label_rtx (void);
-extern rtx gen_lowpart_common (enum machine_mode, rtx);
+extern rtx gen_lowpart_common (machine_mode, rtx);
 
 /* In cse.c */
-extern rtx gen_lowpart_if_possible (enum machine_mode, rtx);
+extern rtx gen_lowpart_if_possible (machine_mode, rtx);
 
 /* In emit-rtl.c */
-extern rtx gen_highpart (enum machine_mode, rtx);
-extern rtx gen_highpart_mode (enum machine_mode, enum machine_mode, rtx);
-extern rtx operand_subword (rtx, unsigned int, int, enum machine_mode);
+extern rtx gen_highpart (machine_mode, rtx);
+extern rtx gen_highpart_mode (machine_mode, machine_mode, rtx);
+extern rtx operand_subword (rtx, unsigned int, int, machine_mode);
 
 /* In emit-rtl.c */
-extern rtx operand_subword_force (rtx, unsigned int, enum machine_mode);
+extern rtx operand_subword_force (rtx, unsigned int, machine_mode);
 extern bool paradoxical_subreg_p (const_rtx);
 extern int subreg_lowpart_p (const_rtx);
-extern unsigned int subreg_lowpart_offset (enum machine_mode,
-                                          enum machine_mode);
-extern unsigned int subreg_highpart_offset (enum machine_mode,
-                                           enum machine_mode);
-extern int byte_lowpart_offset (enum machine_mode, enum machine_mode);
+extern unsigned int subreg_lowpart_offset (machine_mode,
+                                          machine_mode);
+extern unsigned int subreg_highpart_offset (machine_mode,
+                                           machine_mode);
+extern int byte_lowpart_offset (machine_mode, machine_mode);
 extern rtx make_safe_from (rtx, rtx);
-extern rtx convert_memory_address_addr_space (enum machine_mode, rtx,
+extern rtx convert_memory_address_addr_space (machine_mode, rtx,
                                              addr_space_t);
 #define convert_memory_address(to_mode,x) \
        convert_memory_address_addr_space ((to_mode), (x), ADDR_SPACE_GENERIC)
 extern const char *get_insn_name (int);
-extern rtx get_last_insn_anywhere (void);
-extern rtx get_first_nonnote_insn (void);
-extern rtx get_last_nonnote_insn (void);
+extern rtx_insn *get_last_insn_anywhere (void);
+extern rtx_insn *get_first_nonnote_insn (void);
+extern rtx_insn *get_last_nonnote_insn (void);
 extern void start_sequence (void);
-extern void push_to_sequence (rtx);
-extern void push_to_sequence2 (rtx, rtx);
+extern void push_to_sequence (rtx_insn *);
+extern void push_to_sequence2 (rtx_insn *, rtx_insn *);
 extern void end_sequence (void);
 #if TARGET_SUPPORTS_WIDE_INT == 0
 extern double_int rtx_to_double_int (const_rtx);
 #endif
 extern void cwi_output_hex (FILE *, const_rtx);
 #ifndef GENERATOR_FILE
-extern rtx immed_wide_int_const (const wide_int_ref &, enum machine_mode);
+extern rtx immed_wide_int_const (const wide_int_ref &, machine_mode);
 #endif
 #if TARGET_SUPPORTS_WIDE_INT == 0
 extern rtx immed_double_const (HOST_WIDE_INT, HOST_WIDE_INT,
-                              enum machine_mode);
+                              machine_mode);
 #endif
 
 /* In loop-iv.c  */
 
-extern rtx lowpart_subreg (enum machine_mode, rtx, enum machine_mode);
+extern rtx lowpart_subreg (machine_mode, rtx, machine_mode);
 
 /* In varasm.c  */
-extern rtx force_const_mem (enum machine_mode, rtx);
+extern rtx force_const_mem (machine_mode, rtx);
 
 /* In varasm.c  */
 
 struct function;
-extern rtx get_pool_constant (rtx);
+extern rtx get_pool_constant (const_rtx);
 extern rtx get_pool_constant_mark (rtx, bool *);
-extern enum machine_mode get_pool_mode (const_rtx);
+extern machine_mode get_pool_mode (const_rtx);
 extern rtx simplify_subtraction (rtx);
 extern void decide_function_section (tree);
 
-/* In function.c  */
-extern rtx assign_stack_local (enum machine_mode, HOST_WIDE_INT, int);
-#define ASLK_REDUCE_ALIGN 1
-#define ASLK_RECORD_PAD 2
-extern rtx assign_stack_local_1 (enum machine_mode, HOST_WIDE_INT, int, int);
-extern rtx assign_stack_temp (enum machine_mode, HOST_WIDE_INT);
-extern rtx assign_stack_temp_for_type (enum machine_mode, HOST_WIDE_INT, tree);
-extern rtx assign_temp (tree, int, int);
-
 /* In emit-rtl.c */
 extern rtx_insn *emit_insn_before (rtx, rtx);
-extern rtx_insn *emit_insn_before_noloc (rtx, rtx, basic_block);
-extern rtx_insn *emit_insn_before_setloc (rtx, rtx, int);
-extern rtx_insn *emit_jump_insn_before (rtx, rtx);
-extern rtx_insn *emit_jump_insn_before_noloc (rtx, rtx);
-extern rtx_insn *emit_jump_insn_before_setloc (rtx, rtx, int);
-extern rtx_insn *emit_call_insn_before (rtx, rtx);
-extern rtx_insn *emit_call_insn_before_noloc (rtx, rtx);
-extern rtx_insn *emit_call_insn_before_setloc (rtx, rtx, int);
-extern rtx_insn *emit_debug_insn_before (rtx, rtx);
+extern rtx_insn *emit_insn_before_noloc (rtx, rtx_insn *, basic_block);
+extern rtx_insn *emit_insn_before_setloc (rtx, rtx_insn *, int);
+extern rtx_jump_insn *emit_jump_insn_before (rtx, rtx);
+extern rtx_jump_insn *emit_jump_insn_before_noloc (rtx, rtx_insn *);
+extern rtx_jump_insn *emit_jump_insn_before_setloc (rtx, rtx_insn *, int);
+extern rtx_insn *emit_call_insn_before (rtx, rtx_insn *);
+extern rtx_insn *emit_call_insn_before_noloc (rtx, rtx_insn *);
+extern rtx_insn *emit_call_insn_before_setloc (rtx, rtx_insn *, int);
+extern rtx_insn *emit_debug_insn_before (rtx, rtx_insn *);
 extern rtx_insn *emit_debug_insn_before_noloc (rtx, rtx);
 extern rtx_insn *emit_debug_insn_before_setloc (rtx, rtx, int);
 extern rtx_barrier *emit_barrier_before (rtx);
-extern rtx_insn *emit_label_before (rtx, rtx);
-extern rtx_note *emit_note_before (enum insn_note, rtx);
+extern rtx_code_label *emit_label_before (rtx, rtx_insn *);
+extern rtx_note *emit_note_before (enum insn_note, rtx_insn *);
 extern rtx_insn *emit_insn_after (rtx, rtx);
 extern rtx_insn *emit_insn_after_noloc (rtx, rtx, basic_block);
 extern rtx_insn *emit_insn_after_setloc (rtx, rtx, int);
-extern rtx_insn *emit_jump_insn_after (rtx, rtx);
-extern rtx_insn *emit_jump_insn_after_noloc (rtx, rtx);
-extern rtx_insn *emit_jump_insn_after_setloc (rtx, rtx, int);
+extern rtx_jump_insn *emit_jump_insn_after (rtx, rtx);
+extern rtx_jump_insn *emit_jump_insn_after_noloc (rtx, rtx);
+extern rtx_jump_insn *emit_jump_insn_after_setloc (rtx, rtx, int);
 extern rtx_insn *emit_call_insn_after (rtx, rtx);
 extern rtx_insn *emit_call_insn_after_noloc (rtx, rtx);
 extern rtx_insn *emit_call_insn_after_setloc (rtx, rtx, int);
@@ -2407,13 +2774,13 @@ extern rtx_insn *emit_debug_insn_after (rtx, rtx);
 extern rtx_insn *emit_debug_insn_after_noloc (rtx, rtx);
 extern rtx_insn *emit_debug_insn_after_setloc (rtx, rtx, int);
 extern rtx_barrier *emit_barrier_after (rtx);
-extern rtx_insn *emit_label_after (rtx, rtx);
-extern rtx_note *emit_note_after (enum insn_note, rtx);
+extern rtx_insn *emit_label_after (rtx, rtx_insn *);
+extern rtx_note *emit_note_after (enum insn_note, rtx_insn *);
 extern rtx_insn *emit_insn (rtx);
 extern rtx_insn *emit_debug_insn (rtx);
 extern rtx_insn *emit_jump_insn (rtx);
 extern rtx_insn *emit_call_insn (rtx);
-extern rtx_insn *emit_label (rtx);
+extern rtx_code_label *emit_label (rtx);
 extern rtx_jump_table_data *emit_jump_table_data (rtx);
 extern rtx_barrier *emit_barrier (void);
 extern rtx_note *emit_note (enum insn_note);
@@ -2425,12 +2792,12 @@ extern rtx_insn *emit_use (rtx);
 extern rtx_insn *make_insn_raw (rtx);
 extern void add_function_usage_to (rtx, rtx);
 extern rtx_call_insn *last_call_insn (void);
-extern rtx_insn *previous_insn (rtx);
-extern rtx_insn *next_insn (rtx);
+extern rtx_insn *previous_insn (rtx_insn *);
+extern rtx_insn *next_insn (rtx_insn *);
 extern rtx_insn *prev_nonnote_insn (rtx);
 extern rtx_insn *prev_nonnote_insn_bb (rtx);
 extern rtx_insn *next_nonnote_insn (rtx);
-extern rtx_insn *next_nonnote_insn_bb (rtx);
+extern rtx_insn *next_nonnote_insn_bb (rtx_insn *);
 extern rtx_insn *prev_nondebug_insn (rtx);
 extern rtx_insn *next_nondebug_insn (rtx);
 extern rtx_insn *prev_nonnote_nondebug_insn (rtx);
@@ -2441,13 +2808,13 @@ extern rtx_insn *prev_active_insn (rtx);
 extern rtx_insn *next_active_insn (rtx);
 extern int active_insn_p (const_rtx);
 extern rtx_insn *next_cc0_user (rtx);
-extern rtx_insn *prev_cc0_setter (rtx);
+extern rtx_insn *prev_cc0_setter (rtx_insn *);
 
 /* In emit-rtl.c  */
-extern int insn_line (const_rtx);
-extern const char * insn_file (const_rtx);
-extern tree insn_scope (const_rtx);
-extern expanded_location insn_location (const_rtx);
+extern int insn_line (const rtx_insn *);
+extern const char * insn_file (const rtx_insn *);
+extern tree insn_scope (const rtx_insn *);
+extern expanded_location insn_location (const rtx_insn *);
 extern location_t prologue_location, epilogue_location;
 
 /* In jump.c */
@@ -2456,7 +2823,7 @@ extern enum rtx_code reverse_condition_maybe_unordered (enum rtx_code);
 extern enum rtx_code swap_condition (enum rtx_code);
 extern enum rtx_code unsigned_condition (enum rtx_code);
 extern enum rtx_code signed_condition (enum rtx_code);
-extern void mark_jump_label (rtx, rtx, int);
+extern void mark_jump_label (rtx, rtx_insn *, int);
 
 /* In jump.c */
 extern rtx_insn *delete_related_insns (rtx);
@@ -2465,37 +2832,37 @@ extern rtx_insn *delete_related_insns (rtx);
 extern rtx *find_constant_term_loc (rtx *);
 
 /* In emit-rtl.c  */
-extern rtx_insn *try_split (rtx, rtx, int);
+extern rtx_insn *try_split (rtx, rtx_insn *, int);
 extern int split_branch_probability;
 
-/* In unknown file  */
-extern rtx split_insns (rtx, rtx);
+/* In insn-recog.c (generated by genrecog).  */
+extern rtx_insn *split_insns (rtx, rtx_insn *);
 
 /* In simplify-rtx.c  */
-extern rtx simplify_const_unary_operation (enum rtx_code, enum machine_mode,
-                                          rtx, enum machine_mode);
-extern rtx simplify_unary_operation (enum rtx_code, enum machine_mode, rtx,
-                                    enum machine_mode);
-extern rtx simplify_const_binary_operation (enum rtx_code, enum machine_mode,
+extern rtx simplify_const_unary_operation (enum rtx_code, machine_mode,
+                                          rtx, machine_mode);
+extern rtx simplify_unary_operation (enum rtx_code, machine_mode, rtx,
+                                    machine_mode);
+extern rtx simplify_const_binary_operation (enum rtx_code, machine_mode,
                                            rtx, rtx);
-extern rtx simplify_binary_operation (enum rtx_code, enum machine_mode, rtx,
+extern rtx simplify_binary_operation (enum rtx_code, machine_mode, rtx,
                                      rtx);
-extern rtx simplify_ternary_operation (enum rtx_code, enum machine_mode,
-                                      enum machine_mode, rtx, rtx, rtx);
+extern rtx simplify_ternary_operation (enum rtx_code, machine_mode,
+                                      machine_mode, rtx, rtx, rtx);
 extern rtx simplify_const_relational_operation (enum rtx_code,
-                                               enum machine_mode, rtx, rtx);
-extern rtx simplify_relational_operation (enum rtx_code, enum machine_mode,
-                                         enum machine_mode, rtx, rtx);
-extern rtx simplify_gen_binary (enum rtx_code, enum machine_mode, rtx, rtx);
-extern rtx simplify_gen_unary (enum rtx_code, enum machine_mode, rtx,
-                              enum machine_mode);
-extern rtx simplify_gen_ternary (enum rtx_code, enum machine_mode,
-                                enum machine_mode, rtx, rtx, rtx);
-extern rtx simplify_gen_relational (enum rtx_code, enum machine_mode,
-                                   enum machine_mode, rtx, rtx);
-extern rtx simplify_subreg (enum machine_mode, rtx, enum machine_mode,
+                                               machine_mode, rtx, rtx);
+extern rtx simplify_relational_operation (enum rtx_code, machine_mode,
+                                         machine_mode, rtx, rtx);
+extern rtx simplify_gen_binary (enum rtx_code, machine_mode, rtx, rtx);
+extern rtx simplify_gen_unary (enum rtx_code, machine_mode, rtx,
+                              machine_mode);
+extern rtx simplify_gen_ternary (enum rtx_code, machine_mode,
+                                machine_mode, rtx, rtx, rtx);
+extern rtx simplify_gen_relational (enum rtx_code, machine_mode,
+                                   machine_mode, rtx, rtx);
+extern rtx simplify_subreg (machine_mode, rtx, machine_mode,
                            unsigned int);
-extern rtx simplify_gen_subreg (enum machine_mode, rtx, enum machine_mode,
+extern rtx simplify_gen_subreg (machine_mode, rtx, machine_mode,
                                unsigned int);
 extern rtx simplify_replace_fn_rtx (rtx, const_rtx,
                                    rtx (*fn) (rtx, const_rtx, void *), void *);
@@ -2503,16 +2870,19 @@ extern rtx simplify_replace_rtx (rtx, const_rtx, rtx);
 extern rtx simplify_rtx (const_rtx);
 extern rtx avoid_constant_pool_reference (rtx);
 extern rtx delegitimize_mem_from_attrs (rtx);
-extern bool mode_signbit_p (enum machine_mode, const_rtx);
-extern bool val_signbit_p (enum machine_mode, unsigned HOST_WIDE_INT);
-extern bool val_signbit_known_set_p (enum machine_mode,
+extern bool mode_signbit_p (machine_mode, const_rtx);
+extern bool val_signbit_p (machine_mode, unsigned HOST_WIDE_INT);
+extern bool val_signbit_known_set_p (machine_mode,
                                     unsigned HOST_WIDE_INT);
-extern bool val_signbit_known_clear_p (enum machine_mode,
+extern bool val_signbit_known_clear_p (machine_mode,
                                       unsigned HOST_WIDE_INT);
 
 /* In reginfo.c  */
-extern enum machine_mode choose_hard_reg_mode (unsigned int, unsigned int,
+extern machine_mode choose_hard_reg_mode (unsigned int, unsigned int,
                                               bool);
+#ifdef HARD_CONST
+extern const HARD_REG_SET &simplifiable_subregs (const subreg_shape &);
+#endif
 
 /* In emit-rtl.c  */
 extern rtx set_for_reg_notes (rtx);
@@ -2522,22 +2892,23 @@ extern void set_insn_deleted (rtx);
 
 /* Functions in rtlanal.c */
 
-/* Single set is implemented as macro for performance reasons.  */
-#define single_set(I) (INSN_P (I) \
-                      ? (GET_CODE (PATTERN (I)) == SET \
-                         ? PATTERN (I) : single_set_1 (I)) \
-                      : NULL_RTX)
-#define single_set_1(I) single_set_2 (I, PATTERN (I))
+extern rtx single_set_2 (const rtx_insn *, const_rtx);
+
+/* Handle the cheap and common cases inline for performance.  */
 
-/* Structure used for passing data to REPLACE_LABEL.  */
-struct replace_label_data
+inline rtx single_set (const rtx_insn *insn)
 {
-  rtx r1;
-  rtx r2;
-  bool update_label_nuses;
-};
+  if (!INSN_P (insn))
+    return NULL_RTX;
+
+  if (GET_CODE (PATTERN (insn)) == SET)
+    return PATTERN (insn);
 
-extern enum machine_mode get_address_mode (rtx mem);
+  /* Defer to the more expensive case.  */
+  return single_set_2 (insn, PATTERN (insn));
+}
+
+extern machine_mode get_address_mode (rtx mem);
 extern int rtx_addr_can_trap_p (const_rtx);
 extern bool nonzero_address_p (const_rtx);
 extern int rtx_unstable_p (const_rtx);
@@ -2552,26 +2923,25 @@ extern bool unsigned_reg_p (rtx);
 extern int reg_mentioned_p (const_rtx, const_rtx);
 extern int count_occurrences (const_rtx, const_rtx, int);
 extern int reg_referenced_p (const_rtx, const_rtx);
-extern int reg_used_between_p (const_rtx, const_rtx, const_rtx);
-extern int reg_set_between_p (const_rtx, const_rtx, const_rtx);
+extern int reg_used_between_p (const_rtx, const rtx_insn *, const rtx_insn *);
+extern int reg_set_between_p (const_rtx, const rtx_insn *, const rtx_insn *);
 extern int commutative_operand_precedence (rtx);
 extern bool swap_commutative_operands_p (rtx, rtx);
-extern int modified_between_p (const_rtx, const_rtx, const_rtx);
-extern int no_labels_between_p (const_rtx, const_rtx);
+extern int modified_between_p (const_rtx, const rtx_insn *, const rtx_insn *);
+extern int no_labels_between_p (const rtx_insn *, const rtx_insn *);
 extern int modified_in_p (const_rtx, const_rtx);
 extern int reg_set_p (const_rtx, const_rtx);
-extern rtx single_set_2 (const_rtx, const_rtx);
 extern int multiple_sets (const_rtx);
 extern int set_noop_p (const_rtx);
-extern int noop_move_p (const_rtx);
-extern rtx find_last_value (rtx, rtx *, rtx, int);
-extern int refers_to_regno_p (unsigned int, unsigned int, const_rtx, rtx *);
+extern int noop_move_p (const rtx_insn *);
+extern bool refers_to_regno_p (unsigned int, unsigned int, const_rtx, rtx *);
 extern int reg_overlap_mentioned_p (const_rtx, const_rtx);
 extern const_rtx set_of (const_rtx, const_rtx);
 extern void record_hard_reg_sets (rtx, const_rtx, void *);
 extern void record_hard_reg_uses (rtx *, void *);
 #ifdef HARD_CONST
-extern void find_all_hard_reg_sets (const_rtx, HARD_REG_SET *, bool);
+extern void find_all_hard_regs (const_rtx, HARD_REG_SET *);
+extern void find_all_hard_reg_sets (const rtx_insn *, HARD_REG_SET *, bool);
 #endif
 extern void note_stores (const_rtx, void (*) (rtx, const_rtx, void *), void *);
 extern void note_uses (rtx *, void (*) (rtx *, void *), void *);
@@ -2580,15 +2950,15 @@ extern int dead_or_set_regno_p (const_rtx, unsigned int);
 extern rtx find_reg_note (const_rtx, enum reg_note, const_rtx);
 extern rtx find_regno_note (const_rtx, enum reg_note, unsigned int);
 extern rtx find_reg_equal_equiv_note (const_rtx);
-extern rtx find_constant_src (const_rtx);
+extern rtx find_constant_src (const rtx_insn *);
 extern int find_reg_fusage (const_rtx, enum rtx_code, const_rtx);
 extern int find_regno_fusage (const_rtx, enum rtx_code, unsigned int);
 extern rtx alloc_reg_note (enum reg_note, rtx, rtx);
 extern void add_reg_note (rtx, enum reg_note, rtx);
 extern void add_int_reg_note (rtx, enum reg_note, int);
-extern void add_shallow_copy_of_reg_note (rtx, rtx);
+extern void add_shallow_copy_of_reg_note (rtx_insn *, rtx);
 extern void remove_note (rtx, const_rtx);
-extern void remove_reg_equal_equiv_notes (rtx);
+extern void remove_reg_equal_equiv_notes (rtx_insn *);
 extern void remove_reg_equal_equiv_notes_for_regno (unsigned int);
 extern int side_effects_p (const_rtx);
 extern int volatile_refs_p (const_rtx);
@@ -2600,90 +2970,99 @@ extern bool can_throw_internal (const_rtx);
 extern bool can_throw_external (const_rtx);
 extern bool insn_could_throw_p (const_rtx);
 extern bool insn_nothrow_p (const_rtx);
-extern bool can_nonlocal_goto (const_rtx);
-extern void copy_reg_eh_region_note_forward (rtx, rtx, rtx);
-extern void copy_reg_eh_region_note_backward (rtx, rtx, rtx);
+extern bool can_nonlocal_goto (const rtx_insn *);
+extern void copy_reg_eh_region_note_forward (rtx, rtx_insn *, rtx);
+extern void copy_reg_eh_region_note_backward (rtx, rtx_insn *, rtx);
 extern int inequality_comparisons_p (const_rtx);
 extern rtx replace_rtx (rtx, rtx, rtx);
-extern int replace_label (rtx *, void *);
-extern int rtx_referenced_p (rtx, rtx);
-extern bool tablejump_p (const_rtx, rtx *, rtx_jump_table_data **);
-extern int computed_jump_p (const_rtx);
-extern bool tls_referenced_p (rtx);
-
-typedef int (*rtx_function) (rtx *, void *);
-extern int for_each_rtx (rtx *, rtx_function, void *);
-extern int for_each_rtx_in_insn (rtx_insn **, rtx_function, void *);
+extern void replace_label (rtx *, rtx, rtx, bool);
+extern void replace_label_in_insn (rtx_insn *, rtx, rtx, bool);
+extern bool rtx_referenced_p (const_rtx, const_rtx);
+extern bool tablejump_p (const rtx_insn *, rtx *, rtx_jump_table_data **);
+extern int computed_jump_p (const rtx_insn *);
+extern bool tls_referenced_p (const_rtx);
+
+/* Overload for refers_to_regno_p for checking a single register.  */
+inline bool
+refers_to_regno_p (unsigned int regnum, const_rtx x, rtx* loc = NULL)
+{
+  return refers_to_regno_p (regnum, regnum + 1, x, loc);
+}
 
 /* Callback for for_each_inc_dec, to process the autoinc operation OP
    within MEM that sets DEST to SRC + SRCOFF, or SRC if SRCOFF is
    NULL.  The callback is passed the same opaque ARG passed to
    for_each_inc_dec.  Return zero to continue looking for other
-   autoinc operations, -1 to skip OP's operands, and any other value
-   to interrupt the traversal and return that value to the caller of
-   for_each_inc_dec.  */
+   autoinc operations or any other value to interrupt the traversal and
+   return that value to the caller of for_each_inc_dec.  */
 typedef int (*for_each_inc_dec_fn) (rtx mem, rtx op, rtx dest, rtx src,
                                    rtx srcoff, void *arg);
-extern int for_each_inc_dec (rtx *, for_each_inc_dec_fn, void *arg);
+extern int for_each_inc_dec (rtx, for_each_inc_dec_fn, void *arg);
 
 typedef int (*rtx_equal_p_callback_function) (const_rtx *, const_rtx *,
                                               rtx *, rtx *);
 extern int rtx_equal_p_cb (const_rtx, const_rtx,
                            rtx_equal_p_callback_function);
 
-typedef int (*hash_rtx_callback_function) (const_rtx, enum machine_mode, rtx *,
-                                           enum machine_mode *);
-extern unsigned hash_rtx_cb (const_rtx, enum machine_mode, int *, int *,
+typedef int (*hash_rtx_callback_function) (const_rtx, machine_mode, rtx *,
+                                           machine_mode *);
+extern unsigned hash_rtx_cb (const_rtx, machine_mode, int *, int *,
                              bool, hash_rtx_callback_function);
 
 extern rtx regno_use_in (unsigned int, rtx);
 extern int auto_inc_p (const_rtx);
-extern int in_expr_list_p (const_rtx, const_rtx);
-extern void remove_node_from_expr_list (const_rtx, rtx *);
+extern bool in_insn_list_p (const rtx_insn_list *, const rtx_insn *);
+extern void remove_node_from_expr_list (const_rtx, rtx_expr_list **);
+extern void remove_node_from_insn_list (const rtx_insn *, rtx_insn_list **);
 extern int loc_mentioned_in_p (rtx *, const_rtx);
-extern rtx_insn *find_first_parameter_load (rtx, rtx);
-extern bool keep_with_call_p (const_rtx);
-extern bool label_is_jump_target_p (const_rtx, const_rtx);
+extern rtx_insn *find_first_parameter_load (rtx_insn *, rtx_insn *);
+extern bool keep_with_call_p (const rtx_insn *);
+extern bool label_is_jump_target_p (const_rtx, const rtx_insn *);
 extern int insn_rtx_cost (rtx, bool);
+extern unsigned seq_cost (const rtx_insn *, bool);
 
 /* Given an insn and condition, return a canonical description of
    the test being made.  */
-extern rtx canonicalize_condition (rtx, rtx, int, rtx *, rtx, int, int);
+extern rtx canonicalize_condition (rtx_insn *, rtx, int, rtx_insn **, rtx,
+                                  int, int);
 
 /* Given a JUMP_INSN, return a canonical description of the test
    being made.  */
-extern rtx get_condition (rtx, rtx *, int, int);
+extern rtx get_condition (rtx_insn *, rtx_insn **, int, int);
 
 /* Information about a subreg of a hard register.  */
 struct subreg_info
 {
   /* Offset of first hard register involved in the subreg.  */
   int offset;
-  /* Number of hard registers involved in the subreg.  */
+  /* Number of hard registers involved in the subreg.  In the case of
+     a paradoxical subreg, this is the number of registers that would
+     be modified by writing to the subreg; some of them may be don't-care
+     when reading from the subreg.  */
   int nregs;
   /* Whether this subreg can be represented as a hard reg with the new
-     mode.  */
+     mode (by adding OFFSET to the original hard register).  */
   bool representable_p;
 };
 
-extern void subreg_get_info (unsigned int, enum machine_mode,
-                            unsigned int, enum machine_mode,
+extern void subreg_get_info (unsigned int, machine_mode,
+                            unsigned int, machine_mode,
                             struct subreg_info *);
 
 /* lists.c */
 
-extern void free_EXPR_LIST_list (rtx *);
-extern void free_INSN_LIST_list (rtx *);
+extern void free_EXPR_LIST_list (rtx_expr_list **);
+extern void free_INSN_LIST_list (rtx_insn_list **);
 extern void free_EXPR_LIST_node (rtx);
 extern void free_INSN_LIST_node (rtx);
-extern rtx alloc_INSN_LIST (rtx, rtx);
-extern rtx copy_INSN_LIST (rtx);
-extern rtx concat_INSN_LIST (rtx, rtx);
-extern rtx alloc_EXPR_LIST (int, rtx, rtx);
-extern void remove_free_INSN_LIST_elem (rtx, rtx *);
+extern rtx_insn_list *alloc_INSN_LIST (rtx, rtx);
+extern rtx_insn_list *copy_INSN_LIST (rtx_insn_list *);
+extern rtx_insn_list *concat_INSN_LIST (rtx_insn_list *, rtx_insn_list *);
+extern rtx_expr_list *alloc_EXPR_LIST (int, rtx, rtx);
+extern void remove_free_INSN_LIST_elem (rtx_insn *, rtx_insn_list **);
 extern rtx remove_list_elem (rtx, rtx *);
-extern rtx remove_free_INSN_LIST_node (rtx *);
-extern rtx remove_free_EXPR_LIST_node (rtx *);
+extern rtx_insn *remove_free_INSN_LIST_node (rtx_insn_list **);
+extern rtx remove_free_EXPR_LIST_node (rtx_expr_list **);
 
 
 /* reginfo.c */
@@ -2699,7 +3078,7 @@ extern void finish_subregs_of_mode (void);
 extern rtx extract_asm_operands (rtx);
 extern int asm_noperands (const_rtx);
 extern const char *decode_asm_operands (rtx, rtx *, rtx **, const char **,
-                                       enum machine_mode *, location_t *);
+                                       machine_mode *, location_t *);
 extern void get_referenced_operands (const char *, bool *, unsigned int);
 
 extern enum reg_class reg_preferred_class (int);
@@ -2737,6 +3116,7 @@ extern GTY(()) rtx pc_rtx;
 extern GTY(()) rtx cc0_rtx;
 extern GTY(()) rtx ret_rtx;
 extern GTY(()) rtx simple_return_rtx;
+extern GTY(()) rtx_insn *invalid_insn_rtx;
 
 /* If HARD_FRAME_POINTER_REGNUM is defined, then a special dummy reg
    is used to represent the frame pointer.  This is because the
@@ -2893,15 +3273,35 @@ get_mem_attrs (const_rtx x)
    generation functions included above do the raw handling.  If you
    add to this list, modify special_rtx in gengenrtl.c as well.  */
 
-extern rtx gen_rtx_CONST_INT (enum machine_mode, HOST_WIDE_INT);
-extern rtx gen_rtx_CONST_VECTOR (enum machine_mode, rtvec);
-extern rtx gen_raw_REG (enum machine_mode, int);
-extern rtx gen_rtx_REG (enum machine_mode, unsigned);
-extern rtx gen_rtx_SUBREG (enum machine_mode, rtx, int);
-extern rtx gen_rtx_MEM (enum machine_mode, rtx);
-extern rtx gen_rtx_VAR_LOCATION (enum machine_mode, tree, rtx,
+extern rtx_expr_list *gen_rtx_EXPR_LIST (machine_mode, rtx, rtx);
+extern rtx_insn_list *gen_rtx_INSN_LIST (machine_mode, rtx, rtx);
+extern rtx_insn *
+gen_rtx_INSN (machine_mode mode, rtx_insn *prev_insn, rtx_insn *next_insn,
+             basic_block bb, rtx pattern, int location, int code,
+             rtx reg_notes);
+extern rtx gen_rtx_CONST_INT (machine_mode, HOST_WIDE_INT);
+extern rtx gen_rtx_CONST_VECTOR (machine_mode, rtvec);
+extern void set_mode_and_regno (rtx, machine_mode, unsigned int);
+extern rtx gen_raw_REG (machine_mode, unsigned int);
+extern rtx gen_rtx_REG (machine_mode, unsigned int);
+extern rtx gen_rtx_SUBREG (machine_mode, rtx, int);
+extern rtx gen_rtx_MEM (machine_mode, rtx);
+extern rtx gen_rtx_VAR_LOCATION (machine_mode, tree, rtx,
                                 enum var_init_status);
 
+#ifdef GENERATOR_FILE
+#define PUT_MODE(RTX, MODE) PUT_MODE_RAW (RTX, MODE)
+#else
+static inline void
+PUT_MODE (rtx x, machine_mode mode)
+{
+  if (REG_P (x))
+    set_mode_and_regno (x, mode, REGNO (x));
+  else
+    PUT_MODE_RAW (x, mode);
+}
+#endif
+
 #define GEN_INT(N)  gen_rtx_CONST_INT (VOIDmode, (N))
 
 /* Virtual registers are used during RTL generation to refer to locations into
@@ -3029,54 +3429,54 @@ extern int rtx_to_tree_code (enum rtx_code);
 /* In cse.c */
 extern int delete_trivially_dead_insns (rtx_insn *, int);
 extern int exp_equiv_p (const_rtx, const_rtx, int, bool);
-extern unsigned hash_rtx (const_rtx x, enum machine_mode, int *, int *, bool);
+extern unsigned hash_rtx (const_rtx x, machine_mode, int *, int *, bool);
 
 /* In dse.c */
-extern bool check_for_inc_dec (rtx insn);
+extern bool check_for_inc_dec (rtx_insn *insn);
 
 /* In jump.c */
 extern int comparison_dominates_p (enum rtx_code, enum rtx_code);
-extern bool jump_to_label_p (rtx);
-extern int condjump_p (const_rtx);
-extern int any_condjump_p (const_rtx);
-extern int any_uncondjump_p (const_rtx);
-extern rtx pc_set (const_rtx);
-extern rtx condjump_label (const_rtx);
-extern int simplejump_p (const_rtx);
-extern int returnjump_p (rtx);
-extern int eh_returnjump_p (rtx);
-extern int onlyjump_p (const_rtx);
+extern bool jump_to_label_p (const rtx_insn *);
+extern int condjump_p (const rtx_insn *);
+extern int any_condjump_p (const rtx_insn *);
+extern int any_uncondjump_p (const rtx_insn *);
+extern rtx pc_set (const rtx_insn *);
+extern rtx condjump_label (const rtx_insn *);
+extern int simplejump_p (const rtx_insn *);
+extern int returnjump_p (const rtx_insn *);
+extern int eh_returnjump_p (rtx_insn *);
+extern int onlyjump_p (const rtx_insn *);
 extern int only_sets_cc0_p (const_rtx);
 extern int sets_cc0_p (const_rtx);
-extern int invert_jump_1 (rtx, rtx);
-extern int invert_jump (rtx, rtx, int);
+extern int invert_jump_1 (rtx_jump_insn *, rtx);
+extern int invert_jump (rtx_jump_insn *, rtx, int);
 extern int rtx_renumbered_equal_p (const_rtx, const_rtx);
 extern int true_regnum (const_rtx);
 extern unsigned int reg_or_subregno (const_rtx);
-extern int redirect_jump_1 (rtx, rtx);
-extern void redirect_jump_2 (rtx, rtx, rtx, int, int);
-extern int redirect_jump (rtx, rtx, int);
+extern int redirect_jump_1 (rtx_insn *, rtx);
+extern void redirect_jump_2 (rtx_jump_insn *, rtx, rtx, int, int);
+extern int redirect_jump (rtx_jump_insn *, rtx, int);
 extern void rebuild_jump_labels (rtx_insn *);
 extern void rebuild_jump_labels_chain (rtx_insn *);
-extern rtx reversed_comparison (const_rtx, enum machine_mode);
+extern rtx reversed_comparison (const_rtx, machine_mode);
 extern enum rtx_code reversed_comparison_code (const_rtx, const_rtx);
 extern enum rtx_code reversed_comparison_code_parts (enum rtx_code, const_rtx,
                                                     const_rtx, const_rtx);
 extern void delete_for_peephole (rtx_insn *, rtx_insn *);
-extern int condjump_in_parallel_p (const_rtx);
+extern int condjump_in_parallel_p (const rtx_insn *);
 
 /* In emit-rtl.c.  */
 extern int max_reg_num (void);
 extern int max_label_num (void);
 extern int get_first_label_num (void);
 extern void maybe_set_first_label_num (rtx);
-extern void delete_insns_since (rtx);
+extern void delete_insns_since (rtx_insn *);
 extern void mark_reg_pointer (rtx, int);
 extern void mark_user_reg (rtx);
 extern void reset_used_flags (rtx);
 extern void set_used_flags (rtx);
-extern void reorder_insns (rtx, rtx, rtx);
-extern void reorder_insns_nobb (rtx, rtx, rtx);
+extern void reorder_insns (rtx_insn *, rtx_insn *, rtx_insn *);
+extern void reorder_insns_nobb (rtx_insn *, rtx_insn *, rtx_insn *);
 extern int get_max_insn_count (void);
 extern int in_sequence_p (void);
 extern void init_emit (void);
@@ -3085,39 +3485,31 @@ extern void init_derived_machine_modes (void);
 extern void init_emit_once (void);
 extern void push_topmost_sequence (void);
 extern void pop_topmost_sequence (void);
-extern void set_new_first_and_last_insn (rtx, rtx);
+extern void set_new_first_and_last_insn (rtx_insn *, rtx_insn *);
 extern unsigned int unshare_all_rtl (void);
-extern void unshare_all_rtl_again (rtx);
-extern void unshare_all_rtl_in_chain (rtx);
+extern void unshare_all_rtl_again (rtx_insn *);
+extern void unshare_all_rtl_in_chain (rtx_insn *);
 extern void verify_rtl_sharing (void);
-extern void add_insn (rtx);
+extern void add_insn (rtx_insn *);
 extern void add_insn_before (rtx, rtx, basic_block);
 extern void add_insn_after (rtx, rtx, basic_block);
 extern void remove_insn (rtx);
-extern rtx_insn *emit (rtx);
-extern void delete_insn (rtx);
-extern rtx_insn *entry_of_function (void);
+extern rtx_insn *emit (rtx, bool = true);
 extern void emit_insn_at_entry (rtx);
-extern void delete_insn_chain (rtx, rtx, bool);
-extern rtx_insn *unlink_insn_chain (rtx, rtx);
-extern void delete_insn_and_edges (rtx);
-extern rtx gen_lowpart_SUBREG (enum machine_mode, rtx);
-extern rtx gen_const_mem (enum machine_mode, rtx);
-extern rtx gen_frame_mem (enum machine_mode, rtx);
-extern rtx gen_tmp_stack_mem (enum machine_mode, rtx);
-extern bool validate_subreg (enum machine_mode, enum machine_mode,
+extern rtx gen_lowpart_SUBREG (machine_mode, rtx);
+extern rtx gen_const_mem (machine_mode, rtx);
+extern rtx gen_frame_mem (machine_mode, rtx);
+extern rtx gen_tmp_stack_mem (machine_mode, rtx);
+extern bool validate_subreg (machine_mode, machine_mode,
                             const_rtx, unsigned int);
 
 /* In combine.c  */
-extern unsigned int extended_count (const_rtx, enum machine_mode, int);
-extern rtx remove_death (unsigned int, rtx);
+extern unsigned int extended_count (const_rtx, machine_mode, int);
+extern rtx remove_death (unsigned int, rtx_insn *);
 extern void dump_combine_stats (FILE *);
 extern void dump_combine_total_stats (FILE *);
 extern rtx make_compound_operation (rtx, enum rtx_code);
 
-/* In cfgcleanup.c  */
-extern void delete_dead_jumptables (void);
-
 /* In sched-rgn.c.  */
 extern void schedule_insns (void);
 
@@ -3134,7 +3526,7 @@ extern void debug (const rtx_def *ptr);
 extern void debug_rtx (const_rtx);
 extern void debug_rtx_list (const rtx_insn *, int);
 extern void debug_rtx_range (const rtx_insn *, const rtx_insn *);
-extern const_rtx debug_rtx_find (const rtx_insn *, int);
+extern const rtx_insn *debug_rtx_find (const rtx_insn *, int);
 extern void print_mem_expr (FILE *, const_tree);
 extern void print_rtl (FILE *, const_rtx);
 extern void print_simple_rtl (FILE *, const_rtx);
@@ -3146,22 +3538,15 @@ extern void print_inline_rtx (FILE *, const_rtx, int);
    not be in sched-vis.c but in rtl.c, because they are not only used
    by the scheduler anymore but for all "slim" RTL dumping.  */
 extern void dump_value_slim (FILE *, const_rtx, int);
-extern void dump_insn_slim (FILE *, const_rtx);
-extern void dump_rtl_slim (FILE *, const_rtx, const_rtx, int, int);
+extern void dump_insn_slim (FILE *, const rtx_insn *);
+extern void dump_rtl_slim (FILE *, const rtx_insn *, const rtx_insn *,
+                          int, int);
 extern void print_value (pretty_printer *, const_rtx, int);
 extern void print_pattern (pretty_printer *, const_rtx, int);
 extern void print_insn (pretty_printer *, const_rtx, int);
 extern void rtl_dump_bb_for_graph (pretty_printer *, basic_block);
 extern const char *str_pattern_slim (const_rtx);
 
-/* In function.c */
-extern void reposition_prologue_and_epilogue_notes (void);
-extern int prologue_epilogue_contains (const_rtx);
-extern int sibcall_epilogue_contains (const_rtx);
-extern void update_temp_slot_address (rtx, rtx);
-extern void maybe_copy_prologue_epilogue_insn (rtx, rtx);
-extern void set_return_jump_label (rtx);
-
 /* In stmt.c */
 extern void expand_null_return (void);
 extern void expand_naked_return (void);
@@ -3170,12 +3555,8 @@ extern void emit_jump (rtx);
 /* In expr.c */
 extern rtx move_by_pieces (rtx, rtx, unsigned HOST_WIDE_INT,
                           unsigned int, int);
-extern HOST_WIDE_INT find_args_size_adjust (rtx);
-extern int fixup_args_size_notes (rtx, rtx, int);
-
-/* In cfgrtl.c */
-extern void print_rtl_with_bb (FILE *, const_rtx, int);
-extern rtx_insn *duplicate_insn_chain (rtx, rtx);
+extern HOST_WIDE_INT find_args_size_adjust (rtx_insn *);
+extern int fixup_args_size_notes (rtx_insn *, rtx_insn *, int);
 
 /* In expmed.c */
 extern void init_expmed (void);
@@ -3186,7 +3567,7 @@ extern void expand_dec (rtx, rtx);
 extern void init_lower_subreg (void);
 
 /* In gcse.c */
-extern bool can_copy_p (enum machine_mode);
+extern bool can_copy_p (machine_mode);
 extern bool can_assign_to_reg_without_clobbers_p (rtx);
 extern rtx fis_get_condition (rtx_insn *);
 
@@ -3209,7 +3590,9 @@ extern void init_reg_sets (void);
 extern void regclass (rtx, int);
 extern void reg_scan (rtx_insn *, unsigned int);
 extern void fix_register (const char *, int, int);
-extern bool invalid_mode_change_p (unsigned int, enum reg_class);
+#ifdef HARD_CONST
+extern const HARD_REG_SET *valid_mode_changes_for_regno (unsigned int);
+#endif
 
 /* In reload1.c */
 extern int function_invariant_p (const_rtx);
@@ -3225,10 +3608,10 @@ enum libcall_type
   LCT_RETURNS_TWICE = 5
 };
 
-extern void emit_library_call (rtx, enum libcall_type, enum machine_mode, int,
+extern void emit_library_call (rtx, enum libcall_type, machine_mode, int,
                               ...);
 extern rtx emit_library_call_value (rtx, rtx, enum libcall_type,
-                                   enum machine_mode, int, ...);
+                                   machine_mode, int, ...);
 
 /* In varasm.c */
 extern void init_varasm_once (void);
@@ -3240,14 +3623,14 @@ extern bool read_rtx (const char *, rtx *);
 
 /* In alias.c */
 extern rtx canon_rtx (rtx);
-extern int true_dependence (const_rtx, enum machine_mode, const_rtx);
+extern int true_dependence (const_rtx, machine_mode, const_rtx);
 extern rtx get_addr (rtx);
-extern int canon_true_dependence (const_rtx, enum machine_mode, rtx,
+extern int canon_true_dependence (const_rtx, machine_mode, rtx,
                                  const_rtx, rtx);
 extern int read_dependence (const_rtx, const_rtx);
 extern int anti_dependence (const_rtx, const_rtx);
 extern int canon_anti_dependence (const_rtx, bool,
-                                 const_rtx, enum machine_mode, rtx);
+                                 const_rtx, machine_mode, rtx);
 extern int output_dependence (const_rtx, const_rtx);
 extern int may_alias_p (const_rtx, const_rtx);
 extern void init_alias_target (void);
@@ -3257,7 +3640,7 @@ extern void vt_equate_reg_base_value (const_rtx, const_rtx);
 extern bool memory_modified_in_insn_p (const_rtx, const_rtx);
 extern bool memory_must_be_modified_in_insn_p (const_rtx, const_rtx);
 extern bool may_be_sp_based_p (rtx);
-extern rtx gen_hard_reg_clobber (enum machine_mode, unsigned int);
+extern rtx gen_hard_reg_clobber (machine_mode, unsigned int);
 extern rtx get_reg_known_value (unsigned int);
 extern bool get_reg_known_equiv_p (unsigned int);
 extern rtx get_reg_base_value (unsigned int);
@@ -3269,15 +3652,11 @@ extern int stack_regs_mentioned (const_rtx insn);
 /* In toplev.c */
 extern GTY(()) rtx stack_limit_rtx;
 
-/* In predict.c */
-extern void invert_br_probabilities (rtx);
-extern bool expensive_function_p (int);
-
 /* In var-tracking.c */
 extern unsigned int variable_tracking_main (void);
 
 /* In stor-layout.c.  */
-extern void get_mode_bounds (enum machine_mode, int, enum machine_mode,
+extern void get_mode_bounds (machine_mode, int, machine_mode,
                             rtx *, rtx *);
 
 /* In loop-iv.c  */
@@ -3291,13 +3670,13 @@ extern int asm_str_count (const char *templ);
 \f
 struct rtl_hooks
 {
-  rtx (*gen_lowpart) (enum machine_mode, rtx);
-  rtx (*gen_lowpart_no_emit) (enum machine_mode, rtx);
-  rtx (*reg_nonzero_bits) (const_rtx, enum machine_mode, const_rtx, enum machine_mode,
+  rtx (*gen_lowpart) (machine_mode, rtx);
+  rtx (*gen_lowpart_no_emit) (machine_mode, rtx);
+  rtx (*reg_nonzero_bits) (const_rtx, machine_mode, const_rtx, machine_mode,
                           unsigned HOST_WIDE_INT, unsigned HOST_WIDE_INT *);
-  rtx (*reg_num_sign_bit_copies) (const_rtx, enum machine_mode, const_rtx, enum machine_mode,
+  rtx (*reg_num_sign_bit_copies) (const_rtx, machine_mode, const_rtx, machine_mode,
                                  unsigned int, unsigned int *);
-  bool (*reg_truncated_to_mode) (enum machine_mode, const_rtx);
+  bool (*reg_truncated_to_mode) (machine_mode, const_rtx);
 
   /* Whenever you add entries here, make sure you adjust rtlhooks-def.h.  */
 };
@@ -3315,8 +3694,6 @@ extern void insn_locations_init (void);
 extern void insn_locations_finalize (void);
 extern void set_curr_insn_location (location_t);
 extern location_t curr_insn_location (void);
-extern bool optimize_insn_for_size_p (void);
-extern bool optimize_insn_for_speed_p (void);
 
 /* rtl-error.c */
 extern void _fatal_insn_not_found (const_rtx, const char *, int, const char *)
@@ -3332,5 +3709,21 @@ extern void _fatal_insn (const char *, const_rtx, const char *, int, const char
 /* reginfo.c */
 extern tree GTY(()) global_regs_decl[FIRST_PSEUDO_REGISTER];
 
+#ifdef HARD_CONST
+/* Information about the function that is propagated by the RTL backend.
+   Available only for functions that has been already assembled.  */
+
+struct GTY(()) cgraph_rtl_info {
+   unsigned int preferred_incoming_stack_boundary;
+
+  /* Call unsaved hard registers really used by the corresponding
+     function (including ones used by functions called by the
+     function).  */
+  HARD_REG_SET function_used_regs;
+  /* Set if function_used_regs is valid.  */
+  unsigned function_used_regs_valid: 1;
+};
+#endif
+
 
 #endif /* ! GCC_RTL_H */