]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/rtl.h
print-rtl: Change return type of two print functions from int to void
[thirdparty/gcc.git] / gcc / rtl.h
index 71a81a211f185e5ee8a719e3ba7931874f34c8f7..4c993e8270839ef2778c292c053b80b77ea71a43 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1,5 +1,5 @@
 /* Register Transfer Language (RTL) definitions for GCC
-   Copyright (C) 1987-2018 Free Software Foundation, Inc.
+   Copyright (C) 1987-2023 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -36,6 +36,8 @@ along with GCC; see the file COPYING3.  If not see
 
 #include "hard-reg-set.h"
 
+class predefined_function_abi;
+
 /* Value used by some passes to "recognize" noop moves as valid
  instructions.  */
 #define NOOP_MOVE_INSN_CODE    INT_MAX
@@ -61,6 +63,8 @@ enum rtx_code  {
 # define NON_GENERATOR_NUM_RTX_CODE ((int) MATCH_OPERAND)
 #endif
 
+#define RTX_CODE_BITSIZE 8
+
 /* Register Transfer Language EXPRESSIONS CODE CLASSES */
 
 enum rtx_class  {
@@ -145,8 +149,9 @@ struct addr_diff_vec_flags
 /* Structure used to describe the attributes of a MEM.  These are hashed
    so MEMs that the same attributes share a data structure.  This means
    they cannot be modified in place.  */
-struct GTY(()) mem_attrs
+class GTY(()) mem_attrs
 {
+public:
   mem_attrs ();
 
   /* The expression that the MEM accesses, or null if not known.
@@ -187,7 +192,8 @@ 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((for_user)) reg_attrs {
+class GTY((for_user)) reg_attrs {
+public:
   tree decl;                   /* decl corresponding to REG.  */
   poly_int64 offset;           /* Offset from start of DECL.  */
 };
@@ -208,7 +214,7 @@ union rtunion
   tree rt_tree;
   basic_block rt_bb;
   mem_attrs *rt_mem;
-  struct constant_descriptor_rtx *rt_constant;
+  class constant_descriptor_rtx *rt_constant;
   struct dw_cfi_node *rt_cfi;
 };
 
@@ -305,11 +311,11 @@ struct GTY((variable_size)) const_poly_int_def {
 struct GTY((desc("0"), tag("0"),
            chain_next ("RTX_NEXT (&%h)"),
            chain_prev ("RTX_PREV (&%h)"))) rtx_def {
-  /* The kind of expression this is.  */
-  ENUM_BITFIELD(rtx_code) code: 16;
-
   /* The kind of value the expression has.  */
-  ENUM_BITFIELD(machine_mode) mode : 8;
+  ENUM_BITFIELD(machine_mode) mode : MACHINE_MODE_BITSIZE;
+
+  /* The kind of expression this is.  */
+  ENUM_BITFIELD(rtx_code) code: RTX_CODE_BITSIZE;
 
   /* 1 in a MEM if we should keep the alias set for this mem unchanged
      when we access a component.
@@ -317,17 +323,17 @@ struct GTY((desc("0"), tag("0"),
      1 in a CALL_INSN if it is a sibling call.
      1 in a SET that is for a return.
      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 CONCAT is VAL_EXPR_IS_COPIED in var-tracking.cc.
+     1 in a VALUE is SP_BASED_VALUE_P in cselib.cc.
      1 in a SUBREG generated by LRA for reload insns.
      1 in a REG if this is a static chain register.
-     1 in a CALL for calls instrumented by Pointer Bounds Checker.
      Dumped as "/j" in RTL dumps.  */
   unsigned int jump : 1;
   /* In a CODE_LABEL, part of the two-bit alternate entry field.
      1 in a MEM if it cannot trap.
      1 in a CALL_INSN logically equivalent to
        ECF_LOOPING_CONST_OR_PURE and DECL_LOOPING_CONST_OR_PURE_P.
+     1 in a VALUE is SP_DERIVED_VALUE_P in cselib.cc.
      Dumped as "/c" in RTL dumps.  */
   unsigned int call : 1;
   /* 1 in a REG, MEM, or CONCAT if the value is set at most once, anywhere.
@@ -337,8 +343,8 @@ struct GTY((desc("0"), tag("0"),
      1 in a CALL_INSN logically equivalent to ECF_CONST and TREE_READONLY.
      1 in a NOTE, or EXPR_LIST for a const call.
      1 in a JUMP_INSN of an annulling branch.
-     1 in a CONCAT is VAL_EXPR_IS_CLOBBERED in var-tracking.c.
-     1 in a preserved VALUE is PRESERVED_VALUE_P in cselib.c.
+     1 in a CONCAT is VAL_EXPR_IS_CLOBBERED in var-tracking.cc.
+     1 in a preserved VALUE is PRESERVED_VALUE_P in cselib.cc.
      1 in a clobber temporarily created for LRA.
      Dumped as "/u" in RTL dumps.  */
   unsigned int unchanging : 1;
@@ -353,7 +359,7 @@ struct GTY((desc("0"), tag("0"),
      In a SYMBOL_REF, this flag is used for machine-specific purposes.
      In a PREFETCH, this flag indicates that it should be considered a
      scheduling barrier.
-     1 in a CONCAT is VAL_NEEDS_RESOLUTION in var-tracking.c.
+     1 in a CONCAT is VAL_NEEDS_RESOLUTION in var-tracking.cc.
      Dumped as "/v" in RTL dumps.  */
   unsigned int volatil : 1;
   /* 1 in a REG if the register is used only in exit code a loop.
@@ -377,8 +383,8 @@ struct GTY((desc("0"), tag("0"),
      in `leaf_renumber_regs_insn'.
      1 in a SYMBOL_REF, means that emit_library_call
      has used it as the function.
-     1 in a CONCAT is VAL_HOLDS_TRACK_EXPR in var-tracking.c.
-     1 in a VALUE or DEBUG_EXPR is VALUE_RECURSED_INTO in var-tracking.c.  */
+     1 in a CONCAT is VAL_HOLDS_TRACK_EXPR in var-tracking.cc.
+     1 in a VALUE or DEBUG_EXPR is VALUE_RECURSED_INTO in var-tracking.cc.  */
   unsigned int used : 1;
   /* 1 in an INSN or a SET if this rtx is related to the call frame,
      either changing how we compute the frame address or saving and
@@ -386,14 +392,14 @@ struct GTY((desc("0"), tag("0"),
      1 in a REG or MEM if it is a pointer.
      1 in a SYMBOL_REF if it addresses something in the per-function
      constant string pool.
-     1 in a VALUE is VALUE_CHANGED in var-tracking.c.
+     1 in a VALUE is VALUE_CHANGED in var-tracking.cc.
      Dumped as "/f" in RTL dumps.  */
   unsigned frame_related : 1;
   /* 1 in a REG or PARALLEL that is the current function's return value.
      1 in a SYMBOL_REF for a weak symbol.
      1 in a CALL_INSN logically equivalent to ECF_PURE and DECL_PURE_P.
-     1 in a CONCAT is VAL_EXPR_HAS_REVERSE in var-tracking.c.
-     1 in a VALUE or DEBUG_EXPR is NO_LOC_P in var-tracking.c.
+     1 in a CONCAT is VAL_EXPR_HAS_REVERSE in var-tracking.cc.
+     1 in a VALUE or DEBUG_EXPR is NO_LOC_P in var-tracking.cc.
      Dumped as "/i" in RTL dumps.  */
   unsigned return_val : 1;
 
@@ -450,8 +456,9 @@ struct GTY((desc("0"), tag("0"),
 
 /* A node for constructing singly-linked lists of rtx.  */
 
-class GTY(()) rtx_expr_list : public rtx_def
+struct GTY(()) rtx_expr_list : public rtx_def
 {
+private:
   /* No extra fields, but adds invariant: (GET_CODE (X) == EXPR_LIST).  */
 
 public:
@@ -470,8 +477,9 @@ is_a_helper <rtx_expr_list *>::test (rtx rt)
   return rt->code == EXPR_LIST;
 }
 
-class GTY(()) rtx_insn_list : public rtx_def
+struct GTY(()) rtx_insn_list : public rtx_def
 {
+private:
   /* No extra fields, but adds invariant: (GET_CODE (X) == INSN_LIST).
 
      This is an instance of:
@@ -502,8 +510,9 @@ is_a_helper <rtx_insn_list *>::test (rtx rt)
 /* 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
+struct GTY(()) rtx_sequence : public rtx_def
 {
+private:
   /* No extra fields, but adds invariant: (GET_CODE (X) == SEQUENCE).  */
 
 public:
@@ -534,7 +543,7 @@ is_a_helper <const rtx_sequence *>::test (const_rtx rt)
   return rt->code == SEQUENCE;
 }
 
-class GTY(()) rtx_insn : public rtx_def
+struct GTY(()) rtx_insn : public rtx_def
 {
 public:
   /* No extra fields, but adds the invariant:
@@ -568,7 +577,7 @@ public:
 
 /* Subclasses of rtx_insn.  */
 
-class GTY(()) rtx_debug_insn : public rtx_insn
+struct GTY(()) rtx_debug_insn : public rtx_insn
 {
   /* No extra fields, but adds the invariant:
        DEBUG_INSN_P (X) aka (GET_CODE (X) == DEBUG_INSN)
@@ -579,7 +588,7 @@ class GTY(()) rtx_debug_insn : public rtx_insn
      from rtl.def.  */
 };
 
-class GTY(()) rtx_nonjump_insn : public rtx_insn
+struct GTY(()) rtx_nonjump_insn : public rtx_insn
 {
   /* No extra fields, but adds the invariant:
        NONJUMP_INSN_P (X) aka (GET_CODE (X) == INSN)
@@ -590,7 +599,7 @@ class GTY(()) rtx_nonjump_insn : public rtx_insn
      from rtl.def.  */
 };
 
-class GTY(()) rtx_jump_insn : public rtx_insn
+struct GTY(()) rtx_jump_insn : public rtx_insn
 {
 public:
   /* No extra fields, but adds the invariant:
@@ -617,7 +626,7 @@ public:
   inline void set_jump_target (rtx_code_label *);
 };
 
-class GTY(()) rtx_call_insn : public rtx_insn
+struct GTY(()) rtx_call_insn : public rtx_insn
 {
   /* No extra fields, but adds the invariant:
        CALL_P (X) aka (GET_CODE (X) == CALL_INSN)
@@ -630,7 +639,7 @@ class GTY(()) rtx_call_insn : public rtx_insn
      from rtl.def.  */
 };
 
-class GTY(()) rtx_jump_table_data : public rtx_insn
+struct GTY(()) rtx_jump_table_data : public rtx_insn
 {
   /* No extra fields, but adds the invariant:
        JUMP_TABLE_DATA_P (X) aka (GET_CODE (INSN) == JUMP_TABLE_DATA)
@@ -641,8 +650,6 @@ class GTY(()) rtx_jump_table_data : public rtx_insn
        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
@@ -658,7 +665,7 @@ public:
   inline scalar_int_mode get_data_mode () const;
 };
 
-class GTY(()) rtx_barrier : public rtx_insn
+struct GTY(()) rtx_barrier : public rtx_insn
 {
   /* No extra fields, but adds the invariant:
        BARRIER_P (X) aka (GET_CODE (X) == BARRIER)
@@ -669,7 +676,7 @@ class GTY(()) rtx_barrier : public rtx_insn
      from rtl.def.  */
 };
 
-class GTY(()) rtx_code_label : public rtx_insn
+struct GTY(()) rtx_code_label : public rtx_insn
 {
   /* No extra fields, but adds the invariant:
        LABEL_P (X) aka (GET_CODE (X) == CODE_LABEL)
@@ -680,7 +687,7 @@ class GTY(()) rtx_code_label : public rtx_insn
      from rtl.def.  */
 };
 
-class GTY(()) rtx_note : public rtx_insn
+struct GTY(()) rtx_note : public rtx_insn
 {
   /* No extra fields, but adds the invariant:
        NOTE_P(X) aka (GET_CODE (X) == NOTE)
@@ -825,6 +832,9 @@ struct GTY(()) rtvec_def {
 #define CONST_DOUBLE_AS_FLOAT_P(X) \
   (GET_CODE (X) == CONST_DOUBLE && GET_MODE (X) != VOIDmode)
 
+/* Predicate yielding nonzero iff X is an rtx for a constant vector.  */
+#define CONST_VECTOR_P(X) (GET_CODE (X) == CONST_VECTOR)
+
 /* Predicate yielding nonzero iff X is a label insn.  */
 #define LABEL_P(X) (GET_CODE (X) == CODE_LABEL)
 
@@ -834,6 +844,11 @@ struct GTY(()) rtvec_def {
 /* Predicate yielding nonzero iff X is a call insn.  */
 #define CALL_P(X) (GET_CODE (X) == CALL_INSN)
 
+/* 1 if RTX is a call_insn for a fake call.
+   CALL_INSN use "used" flag to indicate it's a fake call.  */
+#define FAKE_CALL_P(RTX)                                        \
+  (RTL_FLAG_CHECK1 ("FAKE_CALL_P", (RTX), CALL_INSN)->used)
+
 /* Predicate yielding nonzero iff X is an insn that cannot jump.  */
 #define NONJUMP_INSN_P(X) (GET_CODE (X) == INSN)
 
@@ -841,7 +856,7 @@ struct GTY(()) rtvec_def {
 #define DEBUG_INSN_P(X) (GET_CODE (X) == DEBUG_INSN)
 
 /* Predicate yielding nonzero iff X is an insn that is not a debug insn.  */
-#define NONDEBUG_INSN_P(X) (INSN_P (X) && !DEBUG_INSN_P (X))
+#define NONDEBUG_INSN_P(X) (NONJUMP_INSN_P (X) || JUMP_P (X) || CALL_P (X))
 
 /* Nonzero if DEBUG_MARKER_INSN_P may possibly hold.  */
 #define MAY_HAVE_DEBUG_MARKER_INSNS debug_nonbind_markers_p
@@ -852,8 +867,7 @@ struct GTY(()) rtvec_def {
   (MAY_HAVE_DEBUG_MARKER_INSNS || MAY_HAVE_DEBUG_BIND_INSNS)
 
 /* Predicate yielding nonzero iff X is a real insn.  */
-#define INSN_P(X) \
-  (NONJUMP_INSN_P (X) || DEBUG_INSN_P (X) || JUMP_P (X) || CALL_P (X))
+#define INSN_P(X) (NONDEBUG_INSN_P (X) || DEBUG_INSN_P (X))
 
 /* Predicate yielding nonzero iff X is a note insn.  */
 #define NOTE_P(X) (GET_CODE (X) == NOTE)
@@ -1054,6 +1068,10 @@ is_a_helper <rtx_note *>::test (rtx_insn *insn)
 #define CONSTANT_P(X)   \
   (GET_RTX_CLASS (GET_CODE (X)) == RTX_CONST_OBJ)
 
+/* 1 if X is a LABEL_REF.  */
+#define LABEL_REF_P(X)  \
+  (GET_CODE (X) == LABEL_REF)
+
 /* 1 if X can be used to represent an object.  */
 #define OBJECT_P(X)                                                    \
   ((GET_RTX_CLASS (GET_CODE (X)) & RTX_OBJ_MASK) == RTX_OBJ_RESULT)
@@ -1101,6 +1119,14 @@ is_a_helper <rtx_note *>::test (rtx_insn *insn)
                               __FUNCTION__); \
      &_rtx->u.fld[_n]; }))
 
+#define RTL_CHECKC3(RTX, N, C1, C2, C3) __extension__                  \
+(*({ __typeof (RTX) const _rtx = (RTX); const int _n = (N);            \
+     const enum rtx_code _code = GET_CODE (_rtx);                      \
+     if (_code != (C1) && _code != (C2) && _code != (C3))              \
+       rtl_check_failed_code3 (_rtx, (C1), (C2), (C3), __FILE__,       \
+                              __LINE__, __FUNCTION__);                 \
+     &_rtx->u.fld[_n]; }))
+
 #define RTVEC_ELT(RTVEC, I) __extension__                              \
 (*({ __typeof (RTVEC) const _rtvec = (RTVEC); const int _i = (I);      \
      if (_i < 0 || _i >= GET_NUM_ELEM (_rtvec))                                \
@@ -1191,6 +1217,10 @@ 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 ATTRIBUTE_COLD;
+extern void rtl_check_failed_code3 (const_rtx, enum rtx_code, enum rtx_code,
+                                   enum rtx_code, const char *, int,
+                                   const char *)
+    ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
 extern void rtl_check_failed_code_mode (const_rtx, enum rtx_code, machine_mode,
                                        bool, const char *, int, const char *)
     ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
@@ -1209,6 +1239,7 @@ extern void rtvec_check_failed_bounds (const_rtvec, int, const char *, int,
 #define RTL_CHECK2(RTX, N, C1, C2)  ((RTX)->u.fld[N])
 #define RTL_CHECKC1(RTX, N, C)     ((RTX)->u.fld[N])
 #define RTL_CHECKC2(RTX, N, C1, C2) ((RTX)->u.fld[N])
+#define RTL_CHECKC3(RTX, N, C1, C2, C3) ((RTX)->u.fld[N])
 #define RTVEC_ELT(RTVEC, I)        ((RTVEC)->elem[I])
 #define XWINT(RTX, N)              ((RTX)->u.hwint[N])
 #define CWI_ELT(RTX, I)                    ((RTX)->u.hwiv.elem[I])
@@ -1363,6 +1394,7 @@ extern void rtl_check_failed_flag (const char *, const_rtx, const char *,
 #define XCVECLEN(RTX, N, C)    GET_NUM_ELEM (XCVEC (RTX, N, C))
 
 #define XC2EXP(RTX, N, C1, C2)      (RTL_CHECKC2 (RTX, N, C1, C2).rt_rtx)
+#define XC3EXP(RTX, N, C1, C2, C3)  (RTL_CHECKC3 (RTX, N, C1, C2, C3).rt_rtx)
 \f
 
 /* Methods of rtx_expr_list.  */
@@ -1611,12 +1643,18 @@ extern const char * const reg_note_name[];
 #define GET_REG_NOTE_NAME(MODE) (reg_note_name[(int) (MODE)])
 
 /* This field is only present on CALL_INSNs.  It holds a chain of EXPR_LIST of
-   USE and CLOBBER expressions.
+   USE, CLOBBER and SET expressions.
      USE expressions list the registers filled with arguments that
    are passed to the function.
      CLOBBER expressions document the registers explicitly clobbered
    by this CALL_INSN.
-     Pseudo registers can not be mentioned in this list.  */
+     SET expressions say that the return value of the call (the SET_DEST)
+   is equivalent to a value available before the call (the SET_SRC).
+   This kind of SET is used when the return value is predictable in
+   advance.  It is purely an optimisation hint; unlike USEs and CLOBBERs,
+   it does not affect register liveness.
+
+     Pseudo registers cannot be mentioned in this list.  */
 #define CALL_INSN_FUNCTION_USAGE(INSN) XEXP(INSN, 7)
 
 /* The label-number of a code-label.  The assembler label
@@ -1654,7 +1692,8 @@ extern const char * const reg_note_name[];
    for which NOTE_MARKER_LOCATION can be used.  */
 #define NOTE_MARKER_P(INSN)                            \
   (NOTE_P (INSN) &&                                    \
-   (NOTE_KIND (INSN) == NOTE_INSN_BEGIN_STMT))
+   (NOTE_KIND (INSN) == NOTE_INSN_BEGIN_STMT           \
+    || NOTE_KIND (INSN) == NOTE_INSN_INLINE_ENTRY))
 
 /* Variable declaration and the location of a variable.  */
 #define PAT_VAR_LOCATION_DECL(PAT) (XCTREE ((PAT), 0, VAR_LOCATION))
@@ -1692,6 +1731,8 @@ extern const char * const reg_note_name[];
   (GET_CODE (PATTERN (INSN)) == DEBUG_MARKER     \
    ? (GET_MODE (PATTERN (INSN)) == VOIDmode      \
       ? NOTE_INSN_BEGIN_STMT                     \
+      : GET_MODE (PATTERN (INSN)) == BLKmode     \
+      ? NOTE_INSN_INLINE_ENTRY                   \
       : (enum insn_note)-1)                      \
    : (enum insn_note)-1)
 /* Create patterns for debug markers.  These and the above abstract
@@ -1701,6 +1742,8 @@ extern const char * const reg_note_name[];
    wouldn't be a problem.  */
 #define GEN_RTX_DEBUG_MARKER_BEGIN_STMT_PAT() \
   gen_rtx_DEBUG_MARKER (VOIDmode)
+#define GEN_RTX_DEBUG_MARKER_INLINE_ENTRY_PAT() \
+  gen_rtx_DEBUG_MARKER (BLKmode)
 
 /* The VAR_LOCATION rtx in a DEBUG_INSN.  */
 #define INSN_VAR_LOCATION(INSN) \
@@ -1767,7 +1810,7 @@ extern const char * const note_insn_name[NOTE_INSN_MAX];
    in the input source code.  */
 #define LABEL_NAME(RTX) XCSTR (RTX, 6, CODE_LABEL)
 
-/* In jump.c, each label contains a count of the number
+/* In jump.cc, each label contains a count of the number
    of LABEL_REFs that point at it, so unused labels can be deleted.  */
 #define LABEL_NUSES(RTX) XCINT (RTX, 4, CODE_LABEL)
 
@@ -1821,7 +1864,7 @@ enum label_kind
 
 #define LABEL_ALT_ENTRY_P(LABEL) (LABEL_KIND (LABEL) != LABEL_NORMAL)
 
-/* In jump.c, each JUMP_INSN can point to a label that it can jump to,
+/* In jump.cc, each JUMP_INSN can point to a label that it can jump to,
    so that if the JUMP_INSN is deleted, the label's LABEL_NUSES can
    be decremented and possibly the label can be deleted.  */
 #define JUMP_LABEL(INSN)   XCEXP (INSN, 7, JUMP_INSN)
@@ -1854,7 +1897,7 @@ inline void rtx_jump_insn::set_jump_target (rtx_code_label *target)
 #define LABEL_REFS(LABEL) XCEXP (LABEL, 3, CODE_LABEL)
 
 /* Get the label that a LABEL_REF references.  */
-static inline rtx_insn *
+inline rtx_insn *
 label_ref_label (const_rtx ref)
 {
   return as_a<rtx_insn *> (XCEXP (ref, 0, LABEL_REF));
@@ -1862,7 +1905,7 @@ label_ref_label (const_rtx ref)
 
 /* Set the label that LABEL_REF ref refers to.  */
 
-static inline void
+inline void
 set_label_ref_label (rtx ref, rtx_insn *label)
 {
   XCEXP (ref, 0, LABEL_REF) = label;
@@ -1885,14 +1928,14 @@ set_label_ref_label (rtx ref, rtx_insn *label)
   (RTL_FLAG_CHECK1 ("ORIGINAL_REGNO", (RTX), REG)->u2.original_regno)
 
 /* Force the REGNO macro to only be used on the lhs.  */
-static inline unsigned int
+inline unsigned int
 rhs_regno (const_rtx x)
 {
   return REG_CHECK (x)->regno;
 }
 
 /* Return the final register in REG X plus one.  */
-static inline unsigned int
+inline unsigned int
 END_REGNO (const_rtx x)
 {
   return REGNO (x) + REG_NREGS (x);
@@ -1900,7 +1943,7 @@ END_REGNO (const_rtx x)
 
 /* Change the REGNO and REG_NREGS of REG X to the specified values,
    bypassing the df machinery.  */
-static inline void
+inline void
 set_regno_raw (rtx x, unsigned int regno, unsigned int nregs)
 {
   reg_info *reg = REG_CHECK (x);
@@ -1926,11 +1969,18 @@ set_regno_raw (rtx x, unsigned int regno, unsigned int nregs)
   (RTL_FLAG_CHECK1 ("MEM_POINTER", (RTX), MEM)->frame_related)
 
 /* 1 if the given register REG corresponds to a hard register.  */
-#define HARD_REGISTER_P(REG) (HARD_REGISTER_NUM_P (REGNO (REG)))
+#define HARD_REGISTER_P(REG) HARD_REGISTER_NUM_P (REGNO (REG))
 
 /* 1 if the given register number REG_NO corresponds to a hard register.  */
 #define HARD_REGISTER_NUM_P(REG_NO) ((REG_NO) < FIRST_PSEUDO_REGISTER)
 
+/* 1 if the given register REG corresponds to a virtual register.  */
+#define VIRTUAL_REGISTER_P(REG) VIRTUAL_REGISTER_NUM_P (REGNO (REG))
+
+/* 1 if the given register number REG_NO corresponds to a virtual register.  */
+#define VIRTUAL_REGISTER_NUM_P(REG_NO)                                 \
+  IN_RANGE (REG_NO, FIRST_VIRTUAL_REGISTER, LAST_VIRTUAL_REGISTER)
+
 /* For a CONST_INT rtx, INTVAL extracts the integer.  */
 #define INTVAL(RTX) XCWINT (RTX, 0, CONST_INT)
 #define UINTVAL(RTX) ((unsigned HOST_WIDE_INT) INTVAL (RTX))
@@ -2005,7 +2055,7 @@ const_vector_encoded_nelts (const_rtx x)
 #define SUBREG_REG(RTX) XCEXP (RTX, 0, SUBREG)
 #define SUBREG_BYTE(RTX) XCSUBREG (RTX, 1, SUBREG)
 
-/* in rtlanal.c */
+/* in rtlanal.cc */
 /* Return the right cost to give to an operation
    to make the cost of the corresponding register-to-register instruction
    N times that of a fast register-to-register instruction.  */
@@ -2017,7 +2067,7 @@ const_vector_encoded_nelts (const_rtx x)
 
 /* Return true if CODE always has VOIDmode.  */
 
-static inline bool
+inline bool
 always_void_p (enum rtx_code code)
 {
   return code == SET;
@@ -2032,7 +2082,7 @@ struct full_rtx_costs
 };
 
 /* Initialize a full_rtx_costs structure C to the maximum cost.  */
-static inline void
+inline void
 init_costs_to_max (struct full_rtx_costs *c)
 {
   c->speed = MAX_COST;
@@ -2040,7 +2090,7 @@ init_costs_to_max (struct full_rtx_costs *c)
 }
 
 /* Initialize a full_rtx_costs structure C to zero cost.  */
-static inline void
+inline void
 init_costs_to_zero (struct full_rtx_costs *c)
 {
   c->speed = 0;
@@ -2049,7 +2099,7 @@ init_costs_to_zero (struct full_rtx_costs *c)
 
 /* Compare two full_rtx_costs structures A and B, returning true
    if A < B when optimizing for speed.  */
-static inline bool
+inline bool
 costs_lt_p (struct full_rtx_costs *a, struct full_rtx_costs *b,
            bool speed)
 {
@@ -2063,7 +2113,7 @@ costs_lt_p (struct full_rtx_costs *a, struct full_rtx_costs *b,
 
 /* Increase both members of the full_rtx_costs structure C by the
    cost of N insns.  */
-static inline void
+inline void
 costs_add_n_insns (struct full_rtx_costs *c, int n)
 {
   c->speed += COSTS_N_INSNS (n);
@@ -2075,7 +2125,8 @@ costs_add_n_insns (struct full_rtx_costs *c, int n)
    inner_mode == the mode of the SUBREG_REG
    offset     == the SUBREG_BYTE
    outer_mode == the mode of the SUBREG itself.  */
-struct subreg_shape {
+class subreg_shape {
+public:
   subreg_shape (machine_mode, poly_uint16, machine_mode);
   bool operator == (const subreg_shape &) const;
   bool operator != (const subreg_shape &) const;
@@ -2115,7 +2166,7 @@ subreg_shape::operator != (const subreg_shape &other) const
 inline unsigned HOST_WIDE_INT
 subreg_shape::unique_id () const
 {
-  { STATIC_ASSERT (MAX_MACHINE_MODE <= 256); }
+  { STATIC_ASSERT (MAX_MACHINE_MODE <= (1 << MACHINE_MODE_BITSIZE)); }
   { STATIC_ASSERT (NUM_POLY_INT_COEFFS <= 3); }
   { STATIC_ASSERT (sizeof (offset.coeffs[0]) <= 2); }
   int res = (int) inner_mode + ((int) outer_mode << 8);
@@ -2126,7 +2177,7 @@ subreg_shape::unique_id () const
 
 /* Return the shape of a SUBREG rtx.  */
 
-static inline subreg_shape
+inline subreg_shape
 shape_of_subreg (const_rtx x)
 {
   return subreg_shape (GET_MODE (SUBREG_REG (x)),
@@ -2375,12 +2426,30 @@ extern int rtx_cost (rtx, machine_mode, enum rtx_code, int, bool);
 extern int address_cost (rtx, machine_mode, addr_space_t, bool);
 extern void get_full_rtx_cost (rtx, machine_mode, enum rtx_code, int,
                               struct full_rtx_costs *);
+extern bool native_encode_rtx (machine_mode, rtx, vec<target_unit> &,
+                              unsigned int, unsigned int);
+extern rtx native_decode_rtx (machine_mode, const vec<target_unit> &,
+                             unsigned int);
+extern rtx native_decode_vector_rtx (machine_mode, const vec<target_unit> &,
+                                    unsigned int, unsigned int, unsigned int);
 extern poly_uint64 subreg_lsb (const_rtx);
-extern poly_uint64 subreg_lsb_1 (machine_mode, machine_mode, poly_uint64);
+extern poly_uint64 subreg_size_lsb (poly_uint64, poly_uint64, poly_uint64);
 extern poly_uint64 subreg_size_offset_from_lsb (poly_uint64, poly_uint64,
                                                poly_uint64);
 extern bool read_modify_subreg_p (const_rtx);
 
+/* Given a subreg's OUTER_MODE, INNER_MODE, and SUBREG_BYTE, return the
+   bit offset at which the subreg begins (counting from the least significant
+   bit of the operand).  */
+
+inline poly_uint64
+subreg_lsb_1 (machine_mode outer_mode, machine_mode inner_mode,
+             poly_uint64 subreg_byte)
+{
+  return subreg_size_lsb (GET_MODE_SIZE (outer_mode),
+                         GET_MODE_SIZE (inner_mode), subreg_byte);
+}
+
 /* Return the subreg byte offset for a subreg whose outer mode is
    OUTER_MODE, whose inner mode is INNER_MODE, and where there are
    LSB_SHIFT *bits* between the lsb of the outer value and the lsb of
@@ -2403,6 +2472,8 @@ extern bool subreg_offset_representable_p (unsigned int, machine_mode,
 extern unsigned int subreg_regno (const_rtx);
 extern int simplify_subreg_regno (unsigned int, machine_mode,
                                  poly_uint64, machine_mode);
+extern int lowpart_subreg_regno (unsigned int, machine_mode,
+                                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, machine_mode);
@@ -2510,10 +2581,6 @@ 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)
@@ -2653,7 +2720,7 @@ do {                                                                      \
   (RTL_FLAG_CHECK1 ("CONSTANT_POOL_ADDRESS_P", (RTX), SYMBOL_REF)->unchanging)
 
 /* 1 if RTX is a symbol_ref that addresses a value in the file's
-   tree constant pool.  This information is private to varasm.c.  */
+   tree constant pool.  This information is private to varasm.cc.  */
 #define TREE_CONSTANT_POOL_ADDRESS_P(RTX)                              \
   (RTL_FLAG_CHECK1 ("TREE_CONSTANT_POOL_ADDRESS_P",                    \
                    (RTX), SYMBOL_REF)->frame_related)
@@ -2861,7 +2928,7 @@ extern int currently_expanding_to_rtl;
 /* Return the cost of SET X.  SPEED_P is true if optimizing for speed
    rather than size.  */
 
-static inline int
+inline int
 set_rtx_cost (rtx x, bool speed_p)
 {
   return rtx_cost (x, VOIDmode, INSN, 4, speed_p);
@@ -2869,7 +2936,7 @@ set_rtx_cost (rtx x, bool speed_p)
 
 /* Like set_rtx_cost, but return both the speed and size costs in C.  */
 
-static inline void
+inline void
 get_full_set_rtx_cost (rtx x, struct full_rtx_costs *c)
 {
   get_full_rtx_cost (x, VOIDmode, INSN, 4, c);
@@ -2879,7 +2946,7 @@ get_full_set_rtx_cost (rtx x, struct full_rtx_costs *c)
    of a register move.  SPEED_P is true if optimizing for speed rather
    than size.  */
 
-static inline int
+inline int
 set_src_cost (rtx x, machine_mode mode, bool speed_p)
 {
   return rtx_cost (x, mode, SET, 1, speed_p);
@@ -2887,7 +2954,7 @@ set_src_cost (rtx x, machine_mode mode, bool speed_p)
 
 /* Like set_src_cost, but return both the speed and size costs in C.  */
 
-static inline void
+inline void
 get_full_set_src_cost (rtx x, machine_mode mode, struct full_rtx_costs *c)
 {
   get_full_rtx_cost (x, mode, SET, 1, c);
@@ -2904,14 +2971,23 @@ get_full_set_src_cost (rtx x, machine_mode mode, struct full_rtx_costs *c)
    && IN_RANGE ((SIZE), 1, (unsigned HOST_WIDE_INT) (RANGE) \
                           - (unsigned HOST_WIDE_INT)(POS)))
 
-/* In explow.c */
+/* In explow.cc */
 extern HOST_WIDE_INT trunc_int_for_mode        (HOST_WIDE_INT, machine_mode);
 extern poly_int64 trunc_int_for_mode (poly_int64, machine_mode);
 extern rtx plus_constant (machine_mode, rtx, poly_int64, bool = false);
 extern HOST_WIDE_INT get_stack_check_protect (void);
 
-/* In rtl.c */
+/* In rtl.cc */
 extern rtx rtx_alloc (RTX_CODE CXX_MEM_STAT_INFO);
+inline rtx
+rtx_init (rtx rt, RTX_CODE code)
+{
+  memset (rt, 0, RTX_HDR_SIZE);
+  PUT_CODE (rt, code);
+  return rt;
+}
+#define rtx_alloca(code) \
+  rtx_init ((rtx) alloca (RTX_CODE_SIZE ((code))), (code))
 extern rtx rtx_alloc_stat_v (RTX_CODE MEM_STAT_DECL, int);
 #define rtx_alloc_v(c, SZ) rtx_alloc_stat_v (c MEM_STAT_INFO, SZ)
 #define const_wide_int_alloc(NWORDS)                           \
@@ -2919,40 +2995,31 @@ extern rtx rtx_alloc_stat_v (RTX_CODE MEM_STAT_DECL, int);
               (sizeof (struct hwivec_def)                      \
                + ((NWORDS)-1) * sizeof (HOST_WIDE_INT)))       \
 
-extern rtvec rtvec_alloc (int);
+extern rtvec rtvec_alloc (size_t);
 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 */
+/* In emit-rtl.cc */
 extern rtx copy_rtx_if_shared (rtx);
 
-/* In rtl.c */
+/* In rtl.cc */
 extern unsigned int rtx_size (const_rtx);
 extern rtx shallow_copy_rtx (const_rtx CXX_MEM_STAT_INFO);
 extern int rtx_equal_p (const_rtx, const_rtx);
 extern bool rtvec_all_equal_p (const_rtvec);
-
-/* Return true if X is some form of vector constant.  */
-
-inline bool
-const_vec_p (const_rtx x)
-{
-  return VECTOR_MODE_P (GET_MODE (x)) && CONSTANT_P (x);
-}
+extern bool rtvec_series_p (rtvec, int);
 
 /* Return true if X is a vector constant with a duplicated element value.  */
 
 inline bool
 const_vec_duplicate_p (const_rtx x)
 {
-  return ((GET_CODE (x) == CONST_VECTOR
-          && CONST_VECTOR_NPATTERNS (x) == 1
-          && CONST_VECTOR_DUPLICATE_P (x))
-         || (GET_CODE (x) == CONST
-             && GET_CODE (XEXP (x, 0)) == VEC_DUPLICATE));
+  return (GET_CODE (x) == CONST_VECTOR
+         && CONST_VECTOR_NPATTERNS (x) == 1
+         && CONST_VECTOR_DUPLICATE_P (x));
 }
 
 /* Return true if X is a vector constant with a duplicated element value.
@@ -2962,20 +3029,11 @@ template <typename T>
 inline bool
 const_vec_duplicate_p (T x, T *elt)
 {
-  if (GET_CODE (x) == CONST_VECTOR
-      && CONST_VECTOR_NPATTERNS (x) == 1
-      && CONST_VECTOR_DUPLICATE_P (x))
+  if (const_vec_duplicate_p (x))
     {
       *elt = CONST_VECTOR_ENCODED_ELT (x, 0);
       return true;
     }
-  if (GET_CODE (x) == CONST
-      && GET_CODE (XEXP (x, 0)) == VEC_DUPLICATE
-      && !VECTOR_MODE_P (GET_MODE (XEXP (XEXP (x, 0), 0))))
-    {
-      *elt = XEXP (XEXP (x, 0), 0);
-      return true;
-    }
   return false;
 }
 
@@ -3002,16 +3060,12 @@ template <typename T>
 inline T
 unwrap_const_vec_duplicate (T x)
 {
-  if (GET_CODE (x) == CONST_VECTOR
-      && CONST_VECTOR_NPATTERNS (x) == 1
-      && CONST_VECTOR_DUPLICATE_P (x))
-    return CONST_VECTOR_ENCODED_ELT (x, 0);
-  if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == VEC_DUPLICATE)
-    return XEXP (XEXP (x, 0), 0);
+  if (const_vec_duplicate_p (x))
+    x = CONST_VECTOR_ELT (x, 0);
   return x;
 }
 
-/* In emit-rtl.c.  */
+/* In emit-rtl.cc.  */
 extern wide_int const_vector_int_elt (const_rtx, unsigned int);
 extern rtx const_vector_elt (const_rtx, unsigned int);
 extern bool const_vec_series_p_1 (const_rtx, rtx *, rtx *);
@@ -3030,12 +3084,6 @@ const_vec_series_p (const_rtx x, rtx *base_out, rtx *step_out)
       && CONST_VECTOR_NPATTERNS (x) == 1
       && !CONST_VECTOR_DUPLICATE_P (x))
     return const_vec_series_p_1 (x, base_out, step_out);
-  if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == VEC_SERIES)
-    {
-      *base_out = XEXP (XEXP (x, 0), 0);
-      *step_out = XEXP (XEXP (x, 0), 1);
-      return true;
-    }
   return false;
 }
 
@@ -3059,6 +3107,23 @@ vec_series_p (const_rtx x, rtx *base_out, rtx *step_out)
   return const_vec_series_p (x, base_out, step_out);
 }
 
+/* Return true if CONST_VECTORs X and Y, which are known to have the same mode,
+   also have the same encoding.  This means that they are equal whenever their
+   operands are equal.  */
+
+inline bool
+same_vector_encodings_p (const_rtx x, const_rtx y)
+{
+  /* Don't be fussy about the encoding of constant-length vectors,
+     since XVECEXP (X, 0) and XVECEXP (Y, 0) list all the elements anyway.  */
+  if (poly_uint64 (CONST_VECTOR_NUNITS (x)).is_constant ())
+    return true;
+
+  return (CONST_VECTOR_NPATTERNS (x) == CONST_VECTOR_NPATTERNS (y)
+         && (CONST_VECTOR_NELTS_PER_PATTERN (x)
+             == CONST_VECTOR_NELTS_PER_PATTERN (y)));
+}
+
 /* Return the unpromoted (outer) mode of SUBREG_PROMOTED_VAR_P subreg X.  */
 
 inline scalar_int_mode
@@ -3077,7 +3142,7 @@ subreg_promoted_mode (rtx x)
   return as_a <scalar_int_mode> (GET_MODE (SUBREG_REG (x)));
 }
 
-/* In emit-rtl.c */
+/* In emit-rtl.cc */
 extern rtvec gen_rtvec_v (int, rtx *);
 extern rtvec gen_rtvec_v (int, rtx_insn **);
 extern rtx gen_reg_rtx (machine_mode);
@@ -3087,17 +3152,17 @@ extern rtx gen_reg_rtx_and_attrs (rtx);
 extern rtx_code_label *gen_label_rtx (void);
 extern rtx gen_lowpart_common (machine_mode, rtx);
 
-/* In cse.c */
+/* In cse.cc */
 extern rtx gen_lowpart_if_possible (machine_mode, rtx);
 
-/* In emit-rtl.c */
+/* In emit-rtl.cc */
 extern rtx gen_highpart (machine_mode, rtx);
 extern rtx gen_highpart_mode (machine_mode, machine_mode, rtx);
 extern rtx operand_subword (rtx, poly_uint64, int, machine_mode);
 
-/* In emit-rtl.c */
+/* In emit-rtl.cc */
 extern rtx operand_subword_force (rtx, poly_uint64, machine_mode);
-extern int subreg_lowpart_p (const_rtx);
+extern bool subreg_lowpart_p (const_rtx);
 extern poly_uint64 subreg_size_lowpart_offset (poly_uint64, poly_uint64);
 
 /* Return true if a subreg of mode OUTERMODE would only access part of
@@ -3230,10 +3295,10 @@ extern rtx immed_double_const (HOST_WIDE_INT, HOST_WIDE_INT,
 #endif
 extern rtx immed_wide_int_const (const poly_wide_int_ref &, machine_mode);
 
-/* In varasm.c  */
+/* In varasm.cc  */
 extern rtx force_const_mem (machine_mode, rtx);
 
-/* In varasm.c  */
+/* In varasm.cc  */
 
 struct function;
 extern rtx get_pool_constant (const_rtx);
@@ -3242,36 +3307,37 @@ extern fixed_size_mode get_pool_mode (const_rtx);
 extern rtx simplify_subtraction (rtx);
 extern void decide_function_section (tree);
 
-/* In emit-rtl.c */
-extern rtx_insn *emit_insn_before (rtx, rtx);
+/* In emit-rtl.cc */
+extern rtx_insn *emit_insn_before (rtx, rtx_insn *);
 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_insn *emit_insn_before_setloc (rtx, rtx_insn *, location_t);
+extern rtx_jump_insn *emit_jump_insn_before (rtx, rtx_insn *);
 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_jump_insn *emit_jump_insn_before_setloc (rtx, rtx_insn *,
+                                                   location_t);
 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_call_insn_before_setloc (rtx, rtx_insn *, location_t);
 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_code_label *emit_label_before (rtx, rtx_insn *);
+extern rtx_insn *emit_debug_insn_before_noloc (rtx, rtx_insn *);
+extern rtx_insn *emit_debug_insn_before_setloc (rtx, rtx_insn *, location_t);
+extern rtx_barrier *emit_barrier_before (rtx_insn *);
+extern rtx_code_label *emit_label_before (rtx_code_label *, 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_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);
-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_insn *);
+extern rtx_insn *emit_insn_after (rtx, rtx_insn *);
+extern rtx_insn *emit_insn_after_noloc (rtx, rtx_insn *, basic_block);
+extern rtx_insn *emit_insn_after_setloc (rtx, rtx_insn *, location_t);
+extern rtx_jump_insn *emit_jump_insn_after (rtx, rtx_insn *);
+extern rtx_jump_insn *emit_jump_insn_after_noloc (rtx, rtx_insn *);
+extern rtx_jump_insn *emit_jump_insn_after_setloc (rtx, rtx_insn *, location_t);
+extern rtx_insn *emit_call_insn_after (rtx, rtx_insn *);
+extern rtx_insn *emit_call_insn_after_noloc (rtx, rtx_insn *);
+extern rtx_insn *emit_call_insn_after_setloc (rtx, rtx_insn *, location_t);
+extern rtx_insn *emit_debug_insn_after (rtx, rtx_insn *);
+extern rtx_insn *emit_debug_insn_after_noloc (rtx, rtx_insn *);
+extern rtx_insn *emit_debug_insn_after_setloc (rtx, rtx_insn *, location_t);
+extern rtx_barrier *emit_barrier_after (rtx_insn *);
+extern rtx_insn *emit_label_after (rtx_insn *, 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);
@@ -3300,21 +3366,22 @@ extern rtx_insn *prev_nonnote_nondebug_insn_bb (rtx_insn *);
 extern rtx_insn *next_nonnote_nondebug_insn (rtx_insn *);
 extern rtx_insn *next_nonnote_nondebug_insn_bb (rtx_insn *);
 extern rtx_insn *prev_real_insn (rtx_insn *);
-extern rtx_insn *next_real_insn (rtx);
+extern rtx_insn *next_real_insn (rtx_insn *);
+extern rtx_insn *prev_real_nondebug_insn (rtx_insn *);
+extern rtx_insn *next_real_nondebug_insn (rtx);
 extern rtx_insn *prev_active_insn (rtx_insn *);
 extern rtx_insn *next_active_insn (rtx_insn *);
-extern int active_insn_p (const rtx_insn *);
-extern rtx_insn *next_cc0_user (rtx_insn *);
-extern rtx_insn *prev_cc0_setter (rtx_insn *);
+extern bool active_insn_p (const rtx_insn *);
 
-/* In emit-rtl.c  */
+/* In emit-rtl.cc  */
 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 int insn_discriminator (const rtx_insn *);
 extern location_t prologue_location, epilogue_location;
 
-/* In jump.c */
+/* In jump.cc */
 extern enum rtx_code reverse_condition (enum rtx_code);
 extern enum rtx_code reverse_condition_maybe_unordered (enum rtx_code);
 extern enum rtx_code swap_condition (enum rtx_code);
@@ -3322,43 +3389,180 @@ 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_insn *, int);
 
-/* In jump.c */
+/* Return true if integer comparison operator CODE interprets its operands
+   as unsigned.  */
+
+inline bool
+unsigned_condition_p (enum rtx_code code)
+{
+  return unsigned_condition (code) == code;
+}
+
+/* In jump.cc */
 extern rtx_insn *delete_related_insns (rtx);
 
-/* In recog.c  */
+/* In recog.cc  */
 extern rtx *find_constant_term_loc (rtx *);
 
-/* In emit-rtl.c  */
+/* In emit-rtl.cc  */
 extern rtx_insn *try_split (rtx, rtx_insn *, int);
 
-/* In insn-recog.c (generated by genrecog).  */
+/* In insn-recog.cc (generated by genrecog).  */
 extern rtx_insn *split_insns (rtx, rtx_insn *);
 
-/* In simplify-rtx.c  */
+/* In simplify-rtx.cc  */
+
+/* A class that records the context in which a simplification
+   is being mode.  */
+class simplify_context
+{
+public:
+  rtx simplify_unary_operation (rtx_code, machine_mode, rtx, machine_mode);
+  rtx simplify_binary_operation (rtx_code, machine_mode, rtx, rtx);
+  rtx simplify_ternary_operation (rtx_code, machine_mode, machine_mode,
+                                 rtx, rtx, rtx);
+  rtx simplify_relational_operation (rtx_code, machine_mode, machine_mode,
+                                    rtx, rtx);
+  rtx simplify_subreg (machine_mode, rtx, machine_mode, poly_uint64);
+
+  rtx lowpart_subreg (machine_mode, rtx, machine_mode);
+
+  rtx simplify_merge_mask (rtx, rtx, int);
+
+  rtx simplify_gen_unary (rtx_code, machine_mode, rtx, machine_mode);
+  rtx simplify_gen_binary (rtx_code, machine_mode, rtx, rtx);
+  rtx simplify_gen_ternary (rtx_code, machine_mode, machine_mode,
+                           rtx, rtx, rtx);
+  rtx simplify_gen_relational (rtx_code, machine_mode, machine_mode, rtx, rtx);
+  rtx simplify_gen_subreg (machine_mode, rtx, machine_mode, poly_uint64);
+  rtx simplify_gen_vec_select (rtx, unsigned int);
+
+  /* Tracks the level of MEM nesting for the value being simplified:
+     0 means the value is not in a MEM, >0 means it is.  This is needed
+     because the canonical representation of multiplication is different
+     inside a MEM than outside.  */
+  unsigned int mem_depth = 0;
+
+  /* Tracks number of simplify_associative_operation calls performed during
+     outermost simplify* call.  */
+  unsigned int assoc_count = 0;
+
+  /* Limit for the above number, return NULL from
+     simplify_associative_operation after we reach that assoc_count.  */
+  static const unsigned int max_assoc_count = 64;
+
+private:
+  rtx simplify_truncation (machine_mode, rtx, machine_mode);
+  rtx simplify_byte_swapping_operation (rtx_code, machine_mode, rtx, rtx);
+  rtx simplify_associative_operation (rtx_code, machine_mode, rtx, rtx);
+  rtx simplify_distributive_operation (rtx_code, machine_mode, rtx, rtx);
+  rtx simplify_logical_relational_operation (rtx_code, machine_mode, rtx, rtx);
+  rtx simplify_binary_operation_series (rtx_code, machine_mode, rtx, rtx);
+  rtx simplify_distribute_over_subregs (rtx_code, machine_mode, rtx, rtx);
+  rtx simplify_shift_const_int (rtx_code, machine_mode, rtx, unsigned int);
+  rtx simplify_plus_minus (rtx_code, machine_mode, rtx, rtx);
+  rtx simplify_cond_clz_ctz (rtx, rtx_code, rtx, rtx);
+
+  rtx simplify_unary_operation_1 (rtx_code, machine_mode, rtx);
+  rtx simplify_binary_operation_1 (rtx_code, machine_mode, rtx, rtx, rtx, rtx);
+  rtx simplify_ternary_operation_1 (rtx_code, machine_mode, machine_mode,
+                                   rtx, rtx, rtx);
+  rtx simplify_relational_operation_1 (rtx_code, machine_mode, machine_mode,
+                                      rtx, rtx);
+};
+
+inline rtx
+simplify_unary_operation (rtx_code code, machine_mode mode, rtx op,
+                         machine_mode op_mode)
+{
+  return simplify_context ().simplify_unary_operation (code, mode, op,
+                                                      op_mode);
+}
+
+inline rtx
+simplify_binary_operation (rtx_code code, machine_mode mode, rtx op0, rtx op1)
+{
+  return simplify_context ().simplify_binary_operation (code, mode, op0, op1);
+}
+
+inline rtx
+simplify_ternary_operation (rtx_code code, machine_mode mode,
+                           machine_mode op0_mode, rtx op0, rtx op1, rtx op2)
+{
+  return simplify_context ().simplify_ternary_operation (code, mode, op0_mode,
+                                                        op0, op1, op2);
+}
+
+inline rtx
+simplify_relational_operation (rtx_code code, machine_mode mode,
+                              machine_mode op_mode, rtx op0, rtx op1)
+{
+  return simplify_context ().simplify_relational_operation (code, mode,
+                                                           op_mode, op0, op1);
+}
+
+inline rtx
+simplify_subreg (machine_mode outermode, rtx op, machine_mode innermode,
+                poly_uint64 byte)
+{
+  return simplify_context ().simplify_subreg (outermode, op, innermode, byte);
+}
+
+inline rtx
+simplify_gen_unary (rtx_code code, machine_mode mode, rtx op,
+                   machine_mode op_mode)
+{
+  return simplify_context ().simplify_gen_unary (code, mode, op, op_mode);
+}
+
+inline rtx
+simplify_gen_binary (rtx_code code, machine_mode mode, rtx op0, rtx op1)
+{
+  return simplify_context ().simplify_gen_binary (code, mode, op0, op1);
+}
+
+inline rtx
+simplify_gen_ternary (rtx_code code, machine_mode mode, machine_mode op0_mode,
+                     rtx op0, rtx op1, rtx op2)
+{
+  return simplify_context ().simplify_gen_ternary (code, mode, op0_mode,
+                                                  op0, op1, op2);
+}
+
+inline rtx
+simplify_gen_relational (rtx_code code, machine_mode mode,
+                        machine_mode op_mode, rtx op0, rtx op1)
+{
+  return simplify_context ().simplify_gen_relational (code, mode, op_mode,
+                                                     op0, op1);
+}
+
+inline rtx
+simplify_gen_subreg (machine_mode outermode, rtx op, machine_mode innermode,
+                    poly_uint64 byte)
+{
+  return simplify_context ().simplify_gen_subreg (outermode, op,
+                                                 innermode, byte);
+}
+
+inline rtx
+simplify_gen_vec_select (rtx op, unsigned int index)
+{
+  return simplify_context ().simplify_gen_vec_select (op, index);
+}
+
+inline rtx
+lowpart_subreg (machine_mode outermode, rtx op, machine_mode innermode)
+{
+  return simplify_context ().lowpart_subreg (outermode, op, innermode);
+}
+
 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, machine_mode, 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,
                                                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, poly_uint64);
-extern rtx simplify_gen_subreg (machine_mode, rtx, machine_mode, poly_uint64);
-extern rtx lowpart_subreg (machine_mode, rtx, machine_mode);
 extern rtx simplify_replace_fn_rtx (rtx, const_rtx,
                                    rtx (*fn) (rtx, const_rtx, void *), void *);
 extern rtx simplify_replace_rtx (rtx, const_rtx, rtx);
@@ -3371,23 +3575,27 @@ extern bool val_signbit_known_set_p (machine_mode,
                                     unsigned HOST_WIDE_INT);
 extern bool val_signbit_known_clear_p (machine_mode,
                                       unsigned HOST_WIDE_INT);
+extern bool reverse_rotate_by_imm_p (machine_mode, unsigned int, rtx);
 
-/* In reginfo.c  */
+/* In reginfo.cc  */
 extern machine_mode choose_hard_reg_mode (unsigned int, unsigned int,
-                                              bool);
+                                         const predefined_function_abi *);
 extern const HARD_REG_SET &simplifiable_subregs (const subreg_shape &);
 
-/* In emit-rtl.c  */
+/* In emit-rtl.cc  */
 extern rtx set_for_reg_notes (rtx);
 extern rtx set_unique_reg_note (rtx, enum reg_note, rtx);
 extern rtx set_dst_reg_note (rtx, enum reg_note, rtx, rtx);
-extern void set_insn_deleted (rtx);
+extern void set_insn_deleted (rtx_insn *);
 
-/* Functions in rtlanal.c */
+/* Functions in rtlanal.cc */
 
 extern rtx single_set_2 (const rtx_insn *, const_rtx);
+extern rtx simple_regno_set (rtx, unsigned int);
 extern bool contains_symbol_ref_p (const_rtx);
 extern bool contains_symbolic_reference_p (const_rtx);
+extern bool contains_constant_pool_address_p (const_rtx);
+extern void add_auto_inc_notes (rtx_insn *, rtx);
 
 /* Handle the cheap and common cases inline for performance.  */
 
@@ -3404,12 +3612,13 @@ inline rtx single_set (const rtx_insn *insn)
 }
 
 extern scalar_int_mode get_address_mode (rtx mem);
-extern int rtx_addr_can_trap_p (const_rtx);
+extern bool rtx_addr_can_trap_p (const_rtx);
 extern bool nonzero_address_p (const_rtx);
-extern int rtx_unstable_p (const_rtx);
+extern bool rtx_unstable_p (const_rtx);
 extern bool rtx_varies_p (const_rtx, bool);
 extern bool rtx_addr_varies_p (const_rtx, bool);
-extern rtx get_call_rtx_from (rtx);
+extern rtx get_call_rtx_from (const rtx_insn *);
+extern tree get_call_fndecl (const rtx_insn *);
 extern HOST_WIDE_INT get_integer_term (const_rtx);
 extern rtx get_related_value (const_rtx);
 extern bool offset_within_block_p (const_rtx, HOST_WIDE_INT);
@@ -3417,37 +3626,40 @@ extern void split_const (rtx, rtx *, rtx *);
 extern rtx strip_offset (rtx, poly_int64_pod *);
 extern poly_int64 get_args_size (const_rtx);
 extern bool unsigned_reg_p (rtx);
-extern int reg_mentioned_p (const_rtx, const_rtx);
+extern bool 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_insn *, const rtx_insn *);
-extern int reg_set_between_p (const_rtx, const rtx_insn *, const rtx_insn *);
+extern bool reg_referenced_p (const_rtx, const_rtx);
+extern bool reg_used_between_p (const_rtx, const rtx_insn *, const rtx_insn *);
+extern bool 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_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 int multiple_sets (const_rtx);
-extern int set_noop_p (const_rtx);
-extern int noop_move_p (const rtx_insn *);
+extern bool modified_between_p (const_rtx, const rtx_insn *, const rtx_insn *);
+extern bool no_labels_between_p (const rtx_insn *, const rtx_insn *);
+extern bool modified_in_p (const_rtx, const_rtx);
+extern bool reg_set_p (const_rtx, const_rtx);
+extern bool multiple_sets (const_rtx);
+extern bool set_noop_p (const_rtx);
+extern bool 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 bool 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 *);
 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);
-extern void note_stores (const_rtx, void (*) (rtx, const_rtx, void *), void *);
+extern void note_pattern_stores (const_rtx,
+                                void (*) (rtx, const_rtx, void *), void *);
+extern void note_stores (const rtx_insn *,
+                        void (*) (rtx, const_rtx, void *), void *);
 extern void note_uses (rtx *, void (*) (rtx *, void *), void *);
-extern int dead_or_set_p (const rtx_insn *, const_rtx);
-extern int dead_or_set_regno_p (const rtx_insn *, unsigned int);
+extern bool dead_or_set_p (const rtx_insn *, const_rtx);
+extern bool dead_or_set_regno_p (const rtx_insn *, 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_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 bool find_reg_fusage (const_rtx, enum rtx_code, const_rtx);
+extern bool 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_insn *, enum reg_note, int);
@@ -3455,14 +3667,14 @@ extern void add_args_size_note (rtx_insn *, poly_int64);
 extern void add_shallow_copy_of_reg_note (rtx_insn *, rtx);
 extern rtx duplicate_reg_note (rtx);
 extern void remove_note (rtx_insn *, const_rtx);
-extern bool remove_reg_equal_equiv_notes (rtx_insn *);
+extern bool remove_reg_equal_equiv_notes (rtx_insn *, bool = false);
 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);
-extern int volatile_insn_p (const_rtx);
-extern int may_trap_p_1 (const_rtx, unsigned);
-extern int may_trap_p (const_rtx);
-extern int may_trap_or_fault_p (const_rtx);
+extern bool side_effects_p (const_rtx);
+extern bool volatile_refs_p (const_rtx);
+extern bool volatile_insn_p (const_rtx);
+extern bool may_trap_p_1 (const_rtx, unsigned);
+extern bool may_trap_p (const_rtx);
+extern bool may_trap_or_fault_p (const_rtx);
 extern bool can_throw_internal (const_rtx);
 extern bool can_throw_external (const_rtx);
 extern bool insn_could_throw_p (const_rtx);
@@ -3470,15 +3682,16 @@ extern bool insn_nothrow_p (const_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, bool = false);
 extern void replace_label (rtx *, rtx, rtx, bool);
 extern void replace_label_in_insn (rtx_insn *, rtx_insn *, rtx_insn *, bool);
 extern bool rtx_referenced_p (const_rtx, const_rtx);
 extern bool tablejump_p (const rtx_insn *, rtx_insn **, rtx_jump_table_data **);
-extern int computed_jump_p (const rtx_insn *);
+extern rtx tablejump_casesi_pattern (const rtx_insn *insn);
+extern bool computed_jump_p (const rtx_insn *);
 extern bool tls_referenced_p (const_rtx);
 extern bool contains_mem_rtx_p (rtx x);
+extern bool register_asm_p (const_rtx);
 
 /* Overload for refers_to_regno_p for checking a single register.  */
 inline bool
@@ -3508,11 +3721,10 @@ 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 bool auto_inc_p (const_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 bool loc_mentioned_in_p (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 *);
@@ -3548,7 +3760,7 @@ extern void subreg_get_info (unsigned int, machine_mode,
                             poly_uint64, machine_mode,
                             struct subreg_info *);
 
-/* lists.c */
+/* lists.cc */
 
 extern void free_EXPR_LIST_list (rtx_expr_list **);
 extern void free_INSN_LIST_list (rtx_insn_list **);
@@ -3564,7 +3776,7 @@ extern rtx_insn *remove_free_INSN_LIST_node (rtx_insn_list **);
 extern rtx remove_free_EXPR_LIST_node (rtx_expr_list **);
 
 
-/* reginfo.c */
+/* reginfo.cc */
 
 /* Resize reg info.  */
 extern bool resize_reg_info (void);
@@ -3572,8 +3784,9 @@ extern bool resize_reg_info (void);
 extern void free_reg_info (void);
 extern void init_subregs_of_mode (void);
 extern void finish_subregs_of_mode (void);
+extern void reginfo_cc_finalize (void);
 
-/* recog.c */
+/* recog.cc */
 extern rtx extract_asm_operands (rtx);
 extern int asm_noperands (const_rtx);
 extern const char *decode_asm_operands (rtx, rtx *, rtx **, const char **,
@@ -3612,7 +3825,6 @@ extern GTY(()) rtx const_tiny_rtx[4][(int) MAX_MACHINE_MODE];
 #define CONSTM1_RTX(MODE) (const_tiny_rtx[3][(int) (MODE)])
 
 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;
@@ -3711,7 +3923,7 @@ struct GTY(()) target_rtl {
   rtx x_static_reg_base_value[FIRST_PSEUDO_REGISTER];
 
   /* The default memory attributes for each mode.  */
-  struct mem_attrs *x_mode_mem_attrs[(int) MAX_MACHINE_MODE];
+  class mem_attrs *x_mode_mem_attrs[(int) MAX_MACHINE_MODE];
 
   /* Track if RTL has been initialized.  */
   bool target_specific_initialized;
@@ -3745,10 +3957,10 @@ extern struct target_rtl *this_target_rtl;
 
 #ifndef GENERATOR_FILE
 /* Return the attributes of a MEM rtx.  */
-static inline const struct mem_attrs *
+inline const class mem_attrs *
 get_mem_attrs (const_rtx x)
 {
-  struct mem_attrs *attrs;
+  class mem_attrs *attrs;
 
   attrs = MEM_ATTRS (x);
   if (!attrs)
@@ -3770,7 +3982,7 @@ get_mem_attrs (const_rtx x)
 
 /* There are some RTL codes that require special attention; the
    generation functions included above do the raw handling.  If you
-   add to this list, modify special_rtx in gengenrtl.c as well.  */
+   add to this list, modify special_rtx in gengenrtl.cc as well.  */
 
 extern rtx_expr_list *gen_rtx_EXPR_LIST (machine_mode, rtx, rtx);
 extern rtx_insn_list *gen_rtx_INSN_LIST (machine_mode, rtx, rtx);
@@ -3781,7 +3993,10 @@ gen_rtx_INSN (machine_mode mode, rtx_insn *prev_insn, rtx_insn *next_insn,
 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 init_raw_REG (rtx, machine_mode, unsigned int);
 extern rtx gen_raw_REG (machine_mode, unsigned int);
+#define alloca_raw_REG(mode, regno) \
+  init_raw_REG (rtx_alloca (REG), (mode), (regno))
 extern rtx gen_rtx_REG (machine_mode, unsigned int);
 extern rtx gen_rtx_SUBREG (machine_mode, rtx, poly_uint64);
 extern rtx gen_rtx_MEM (machine_mode, rtx);
@@ -3791,7 +4006,7 @@ extern rtx gen_rtx_VAR_LOCATION (machine_mode, tree, rtx,
 #ifdef GENERATOR_FILE
 #define PUT_MODE(RTX, MODE) PUT_MODE_RAW (RTX, MODE)
 #else
-static inline void
+inline void
 PUT_MODE (rtx x, machine_mode mode)
 {
   if (REG_P (x))
@@ -3872,8 +4087,7 @@ PUT_MODE (rtx x, machine_mode mode)
    || (REGNUM) == FRAME_POINTER_REGNUM         \
    || (REGNUM) == HARD_FRAME_POINTER_REGNUM    \
    || (REGNUM) == ARG_POINTER_REGNUM           \
-   || ((REGNUM) >= FIRST_VIRTUAL_REGISTER      \
-       && (REGNUM) <= LAST_VIRTUAL_POINTER_REGISTER))
+   || VIRTUAL_REGISTER_NUM_P (REGNUM))
 
 /* REGNUM never really appearing in the INSN stream.  */
 #define INVALID_REGNUM                 (~(unsigned int) 0)
@@ -3885,7 +4099,7 @@ extern rtx output_constant_def (tree, int);
 extern rtx lookup_constant_def (tree);
 
 /* Nonzero after end of reload pass.
-   Set to 1 or 0 by reload1.c.  */
+   Set to 1 or 0 by reload1.cc.  */
 
 extern int reload_completed;
 
@@ -3907,7 +4121,7 @@ extern int lra_in_progress;
 
 #ifdef STACK_REGS
 /* Nonzero after end of regstack pass.
-   Set to 1 or 0 by reg-stack.c.  */
+   Set to 1 or 0 by reg-stack.cc.  */
 extern int regstack_completed;
 #endif
 
@@ -3925,36 +4139,34 @@ extern int cse_not_expected;
 
 extern int rtx_to_tree_code (enum rtx_code);
 
-/* In cse.c */
+/* In cse.cc */
 extern int delete_trivially_dead_insns (rtx_insn *, int);
-extern int exp_equiv_p (const_rtx, const_rtx, int, bool);
+extern bool exp_equiv_p (const_rtx, const_rtx, int, bool);
 extern unsigned hash_rtx (const_rtx x, machine_mode, int *, int *, bool);
 
-/* In dse.c */
+/* In dse.cc */
 extern bool check_for_inc_dec (rtx_insn *insn);
 
-/* In jump.c */
-extern int comparison_dominates_p (enum rtx_code, enum rtx_code);
+/* In jump.cc */
+extern bool comparison_dominates_p (enum rtx_code, enum rtx_code);
 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 bool condjump_p (const rtx_insn *);
+extern bool any_condjump_p (const rtx_insn *);
+extern bool 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_jump_insn *, rtx);
-extern int invert_jump (rtx_jump_insn *, rtx, int);
-extern int rtx_renumbered_equal_p (const_rtx, const_rtx);
+extern bool simplejump_p (const rtx_insn *);
+extern bool returnjump_p (const rtx_insn *);
+extern bool eh_returnjump_p (rtx_insn *);
+extern bool onlyjump_p (const rtx_insn *);
+extern bool invert_jump_1 (rtx_jump_insn *, rtx);
+extern bool invert_jump (rtx_jump_insn *, rtx, int);
+extern bool 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_insn *, rtx);
+extern bool 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 bool 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, machine_mode);
@@ -3962,9 +4174,9 @@ extern enum rtx_code reversed_comparison_code (const_rtx, const rtx_insn *);
 extern enum rtx_code reversed_comparison_code_parts (enum rtx_code, const_rtx,
                                                     const_rtx, const rtx_insn *);
 extern void delete_for_peephole (rtx_insn *, rtx_insn *);
-extern int condjump_in_parallel_p (const rtx_insn *);
+extern bool condjump_in_parallel_p (const rtx_insn *);
 
-/* In emit-rtl.c.  */
+/* In emit-rtl.cc.  */
 extern int max_reg_num (void);
 extern int max_label_num (void);
 extern int get_first_label_num (void);
@@ -3977,7 +4189,7 @@ extern void set_used_flags (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 bool in_sequence_p (void);
 extern void init_emit (void);
 extern void init_emit_regs (void);
 extern void init_derived_machine_modes (void);
@@ -3985,14 +4197,14 @@ 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_insn *, rtx_insn *);
-extern unsigned int unshare_all_rtl (void);
+extern void unshare_all_rtl (void);
 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_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 void add_insn_before (rtx_insn *, rtx_insn *, basic_block);
+extern void add_insn_after (rtx_insn *, rtx_insn *, basic_block);
+extern void remove_insn (rtx_insn *);
 extern rtx_insn *emit (rtx, bool = true);
 extern void emit_insn_at_entry (rtx);
 extern rtx gen_lowpart_SUBREG (machine_mode, rtx);
@@ -4002,23 +4214,23 @@ extern rtx gen_tmp_stack_mem (machine_mode, rtx);
 extern bool validate_subreg (machine_mode, machine_mode,
                             const_rtx, poly_uint64);
 
-/* In combine.c  */
+/* In combine.cc  */
 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 sched-rgn.c.  */
+/* In sched-rgn.cc.  */
 extern void schedule_insns (void);
 
-/* In sched-ebb.c.  */
+/* In sched-ebb.cc.  */
 extern void schedule_ebbs (void);
 
-/* In sel-sched-dump.c.  */
+/* In sel-sched-dump.cc.  */
 extern void sel_sched_fix_param (const char *param, const char *val);
 
-/* In print-rtl.c */
+/* In print-rtl.cc */
 extern const char *print_rtx_head;
 extern void debug (const rtx_def &ref);
 extern void debug (const rtx_def *ptr);
@@ -4029,41 +4241,59 @@ 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);
-extern int print_rtl_single (FILE *, const_rtx);
-extern int print_rtl_single_with_indent (FILE *, const_rtx, int);
+extern void print_rtl_single (FILE *, const_rtx);
+extern void print_rtl_single_with_indent (FILE *, const_rtx, int);
 extern void print_inline_rtx (FILE *, const_rtx, int);
 
-/* In stmt.c */
+/* In stmt.cc */
 extern void expand_null_return (void);
 extern void expand_naked_return (void);
 extern void emit_jump (rtx);
 
-/* In expr.c */
+/* Memory operation built-ins differ by return value.  Mapping
+   of the enum values is following:
+   - RETURN_BEGIN - return destination, e.g. memcpy
+   - RETURN_END - return destination + n, e.g. mempcpy
+   - RETURN_END_MINUS_ONE - return a pointer to the terminating
+    null byte of the string, e.g. strcpy
+*/
+
+enum memop_ret
+{
+  RETURN_BEGIN,
+  RETURN_END,
+  RETURN_END_MINUS_ONE
+};
+
+/* In expr.cc */
 extern rtx move_by_pieces (rtx, rtx, unsigned HOST_WIDE_INT,
-                          unsigned int, int);
+                          unsigned int, memop_ret);
 extern poly_int64 find_args_size_adjust (rtx_insn *);
 extern poly_int64 fixup_args_size_notes (rtx_insn *, rtx_insn *, poly_int64);
 
-/* In expmed.c */
+/* In expmed.cc */
 extern void init_expmed (void);
 extern void expand_inc (rtx, rtx);
 extern void expand_dec (rtx, rtx);
 
-/* In lower-subreg.c */
+/* In lower-subreg.cc */
 extern void init_lower_subreg (void);
 
-/* In gcse.c */
+/* In gcse.cc */
 extern bool can_copy_p (machine_mode);
 extern bool can_assign_to_reg_without_clobbers_p (rtx, machine_mode);
+extern rtx_insn *prepare_copy_insn (rtx, rtx);
+
+/* In cprop.cc */
 extern rtx fis_get_condition (rtx_insn *);
 
-/* In ira.c */
+/* In ira.cc */
 extern HARD_REG_SET eliminable_regset;
 extern void mark_elimination (int, int);
 
-/* In reginfo.c */
-extern int reg_classes_intersect_p (reg_class_t, reg_class_t);
-extern int reg_class_subset_p (reg_class_t, reg_class_t);
+/* In reginfo.cc */
+extern bool reg_classes_intersect_p (reg_class_t, reg_class_t);
+extern bool reg_class_subset_p (reg_class_t, reg_class_t);
 extern void globalize_reg (tree, int);
 extern void init_reg_modes_target (void);
 extern void init_regs (void);
@@ -4076,10 +4306,10 @@ extern void reg_scan (rtx_insn *, unsigned int);
 extern void fix_register (const char *, int, int);
 extern const HARD_REG_SET *valid_mode_changes_for_regno (unsigned int);
 
-/* In reload1.c */
+/* In reload1.cc */
 extern int function_invariant_p (const_rtx);
 
-/* In calls.c */
+/* In calls.cc */
 enum libcall_type
 {
   LCT_NORMAL = 0,
@@ -4223,30 +4453,30 @@ emit_library_call_value (rtx fun, rtx value, libcall_type fn_type,
   return emit_library_call_value_1 (1, fun, value, fn_type, outmode, 4, args);
 }
 
-/* In varasm.c */
+/* In varasm.cc */
 extern void init_varasm_once (void);
 
 extern rtx make_debug_expr_from_rtl (const_rtx);
 
-/* In read-rtl.c */
+/* In read-rtl.cc */
 #ifdef GENERATOR_FILE
 extern bool read_rtx (const char *, vec<rtx> *);
 #endif
 
-/* In alias.c */
+/* In alias.cc */
 extern rtx canon_rtx (rtx);
-extern int true_dependence (const_rtx, machine_mode, const_rtx);
 extern rtx get_addr (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, machine_mode, rtx);
-extern int output_dependence (const_rtx, const_rtx);
-extern int canon_output_dependence (const_rtx, bool,
-                                   const_rtx, machine_mode, rtx);
-extern int may_alias_p (const_rtx, const_rtx);
+extern bool read_dependence (const_rtx, const_rtx);
+extern bool true_dependence (const_rtx, machine_mode, const_rtx);
+extern bool canon_true_dependence (const_rtx, machine_mode, rtx,
+                                  const_rtx, rtx);
+extern bool anti_dependence (const_rtx, const_rtx);
+extern bool canon_anti_dependence (const_rtx, bool,
+                                  const_rtx, machine_mode, rtx);
+extern bool output_dependence (const_rtx, const_rtx);
+extern bool canon_output_dependence (const_rtx, bool,
+                                    const_rtx, machine_mode, rtx);
+extern bool may_alias_p (const_rtx, const_rtx);
 extern void init_alias_target (void);
 extern void init_alias_analysis (void);
 extern void end_alias_analysis (void);
@@ -4257,27 +4487,28 @@ 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);
+extern rtx extract_mem_from_operand (rtx);
 
 #ifdef STACK_REGS
-extern int stack_regs_mentioned (const_rtx insn);
+extern bool stack_regs_mentioned (const_rtx insn);
 #endif
 
-/* In toplev.c */
+/* In toplev.cc */
 extern GTY(()) rtx stack_limit_rtx;
 
-/* In var-tracking.c */
+/* In var-tracking.cc */
 extern unsigned int variable_tracking_main (void);
 extern void delete_vta_debug_insns (bool);
 
-/* In stor-layout.c.  */
+/* In stor-layout.cc.  */
 extern void get_mode_bounds (scalar_int_mode, int,
                             scalar_int_mode, rtx *, rtx *);
 
-/* In loop-iv.c  */
+/* In loop-iv.cc  */
 extern rtx canon_condition (rtx);
 extern void simplify_using_condition (rtx, rtx *, bitmap);
 
-/* In final.c  */
+/* In final.cc  */
 extern unsigned int compute_alignments (void);
 extern void update_alignments (vec<rtx> &);
 extern int asm_str_count (const char *templ);
@@ -4308,8 +4539,9 @@ 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 void set_insn_locations (rtx_insn *, location_t);
 
-/* rtl-error.c */
+/* rtl-error.cc */
 extern void _fatal_insn_not_found (const_rtx, const char *, int, const char *)
      ATTRIBUTE_NORETURN ATTRIBUTE_COLD;
 extern void _fatal_insn (const char *, const_rtx, const char *, int, const char *)
@@ -4320,21 +4552,18 @@ extern void _fatal_insn (const char *, const_rtx, const char *, int, const char
 #define fatal_insn_not_found(insn) \
        _fatal_insn_not_found (insn, __FILE__, __LINE__, __FUNCTION__)
 
-/* reginfo.c */
+/* reginfo.cc */
 extern tree GTY(()) global_regs_decl[FIRST_PSEUDO_REGISTER];
 
 /* 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;
+  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).  */
+  /* Which registers the function clobbers, either directly or by
+     calling another function.  */
   HARD_REG_SET function_used_regs;
-  /* Set if function_used_regs is valid.  */
-  unsigned function_used_regs_valid: 1;
 };
 
 /* If loads from memories of mode MODE always sign or zero extend,
@@ -4361,12 +4590,41 @@ strip_offset_and_add (rtx x, poly_int64_pod *offset)
     {
       poly_int64 suboffset;
       x = strip_offset (x, &suboffset);
-      *offset += suboffset;
+      *offset = poly_uint64 (*offset) + suboffset;
     }
   return x;
 }
 
-/* gtype-desc.c.  */
+/* Return true if X is an operation that always operates on the full
+   registers for WORD_REGISTER_OPERATIONS architectures.  */
+
+inline bool
+word_register_operation_p (const_rtx x)
+{
+  switch (GET_CODE (x))
+    {
+    case CONST_INT:
+    case ROTATE:
+    case ROTATERT:
+    case SIGN_EXTRACT:
+    case ZERO_EXTRACT:
+      return false;
+    
+    default:
+      return true;
+    }
+}
+
+/* Holds an rtx comparison to simplify passing many parameters pertaining to a
+   single comparison.  */
+
+struct rtx_comparison {
+  rtx_code code;
+  rtx op0, op1;
+  machine_mode mode;
+};
+
+/* gtype-desc.cc.  */
 extern void gt_ggc_mx (rtx &);
 extern void gt_pch_nx (rtx &);
 extern void gt_pch_nx (rtx &, gt_pointer_operator, void *);