]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/rtl.h
cse: Change return type of predicate functions from int to bool
[thirdparty/gcc.git] / gcc / rtl.h
index a450a04c2374fbd8227bbaf01c5ff21758aaa7a8..caef74a75b2c0e99c4079019cb78451bcc6c32c5 100644 (file)
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1,5 +1,5 @@
 /* Register Transfer Language (RTL) definitions for GCC
-   Copyright (C) 1987-2017 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,11 @@ 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.
      This expression might be larger than the memory reference itself.
      (In other words, the MEM might access only part of the object.)  */
@@ -154,11 +161,11 @@ struct GTY(()) mem_attrs
 
   /* The offset of the memory reference from the start of EXPR.
      Only valid if OFFSET_KNOWN_P.  */
-  HOST_WIDE_INT offset;
+  poly_int64 offset;
 
   /* The size of the memory reference in bytes.  Only valid if
      SIZE_KNOWN_P.  */
-  HOST_WIDE_INT size;
+  poly_int64 size;
 
   /* The alias set of the memory reference.  */
   alias_set_type alias;
@@ -185,9 +192,10 @@ 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.  */
-  HOST_WIDE_INT offset;                /* Offset from start of DECL.  */
+  poly_int64 offset;           /* Offset from start of DECL.  */
 };
 
 /* Common union for an element of an rtx.  */
@@ -196,6 +204,7 @@ union rtunion
 {
   int rt_int;
   unsigned int rt_uint;
+  poly_uint16_pod rt_subreg;
   const char *rt_str;
   rtx rt_rtx;
   rtvec rt_rtvec;
@@ -205,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;
 };
 
@@ -280,6 +289,10 @@ struct GTY((variable_size)) hwivec_def {
 #define CWI_PUT_NUM_ELEM(RTX, NUM)                                     \
   (RTL_FLAG_CHECK1("CWI_PUT_NUM_ELEM", (RTX), CONST_WIDE_INT)->u2.num_elem = (NUM))
 
+struct GTY((variable_size)) const_poly_int_def {
+  trailing_wide_ints<NUM_POLY_INT_COEFFS> coeffs;
+};
+
 /* RTL expression ("rtx").  */
 
 /* The GTY "desc" and "tag" options below are a kludge: we need a desc
@@ -298,11 +311,11 @@ struct GTY((variable_size)) hwivec_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.
@@ -310,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.
@@ -330,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;
@@ -346,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.
@@ -370,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
@@ -379,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;
 
@@ -411,6 +424,19 @@ struct GTY((desc("0"), tag("0"),
     /* In a CONST_WIDE_INT (aka hwivec_def), this is the number of
        HOST_WIDE_INTs in the hwivec_def.  */
     unsigned int num_elem;
+
+    /* Information about a CONST_VECTOR.  */
+    struct
+    {
+      /* The value of CONST_VECTOR_NPATTERNS.  */
+      unsigned int npatterns : 16;
+
+      /* The value of CONST_VECTOR_NELTS_PER_PATTERN.  */
+      unsigned int nelts_per_pattern : 8;
+
+      /* For future expansion.  */
+      unsigned int unused : 8;
+    } const_vector;
   } GTY ((skip)) u2;
 
   /* The first element of the operands of this rtx.
@@ -424,13 +450,15 @@ struct GTY((desc("0"), tag("0"),
     struct real_value rv;
     struct fixed_value fv;
     struct hwivec_def hwiv;
+    struct const_poly_int_def cpi;
   } 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
+struct GTY(()) rtx_expr_list : public rtx_def
 {
+private:
   /* No extra fields, but adds invariant: (GET_CODE (X) == EXPR_LIST).  */
 
 public:
@@ -449,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:
@@ -481,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:
@@ -513,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:
@@ -547,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)
@@ -558,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)
@@ -569,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:
@@ -596,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)
@@ -609,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)
@@ -620,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
@@ -637,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)
@@ -648,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)
@@ -659,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)
@@ -734,6 +762,7 @@ struct GTY(()) rtvec_def {
 #define CASE_CONST_UNIQUE \
    case CONST_INT: \
    case CONST_WIDE_INT: \
+   case CONST_POLY_INT: \
    case CONST_DOUBLE: \
    case CONST_FIXED
 
@@ -741,6 +770,7 @@ struct GTY(()) rtvec_def {
 #define CASE_CONST_ANY \
    case CONST_INT: \
    case CONST_WIDE_INT: \
+   case CONST_POLY_INT: \
    case CONST_DOUBLE: \
    case CONST_FIXED: \
    case CONST_VECTOR
@@ -773,6 +803,11 @@ struct GTY(()) rtvec_def {
 /* Predicate yielding nonzero iff X is an rtx for a constant integer.  */
 #define CONST_WIDE_INT_P(X) (GET_CODE (X) == CONST_WIDE_INT)
 
+/* Predicate yielding nonzero iff X is an rtx for a polynomial constant
+   integer.  */
+#define CONST_POLY_INT_P(X) \
+  (NUM_POLY_INT_COEFFS > 1 && GET_CODE (X) == CONST_POLY_INT)
+
 /* Predicate yielding nonzero iff X is an rtx for a constant fixed-point.  */
 #define CONST_FIXED_P(X) (GET_CODE (X) == CONST_FIXED)
 
@@ -797,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)
 
@@ -806,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)
 
@@ -813,14 +856,18 @@ 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
+/* Nonzero if DEBUG_BIND_INSN_P may possibly hold.  */
+#define MAY_HAVE_DEBUG_BIND_INSNS flag_var_tracking_assignments
 /* Nonzero if DEBUG_INSN_P may possibly hold.  */
-#define MAY_HAVE_DEBUG_INSNS (flag_var_tracking_assignments)
+#define MAY_HAVE_DEBUG_INSNS                                   \
+  (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)
@@ -1021,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)
@@ -1068,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))                                \
@@ -1158,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;
@@ -1176,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])
@@ -1316,6 +1380,7 @@ extern void rtl_check_failed_flag (const char *, const_rtx, const char *,
 
 #define XCINT(RTX, N, C)      (RTL_CHECKC1 (RTX, N, C).rt_int)
 #define XCUINT(RTX, N, C)     (RTL_CHECKC1 (RTX, N, C).rt_uint)
+#define XCSUBREG(RTX, N, C)   (RTL_CHECKC1 (RTX, N, C).rt_subreg)
 #define XCSTR(RTX, N, C)      (RTL_CHECKC1 (RTX, N, C).rt_str)
 #define XCEXP(RTX, N, C)      (RTL_CHECKC1 (RTX, N, C).rt_rtx)
 #define XCVEC(RTX, N, C)      (RTL_CHECKC1 (RTX, N, C).rt_rtvec)
@@ -1329,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.  */
@@ -1577,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
@@ -1604,6 +1676,7 @@ extern const char * const reg_note_name[];
 #define NOTE_EH_HANDLER(INSN)  XCINT (INSN, 3, NOTE)
 #define NOTE_BASIC_BLOCK(INSN) XCBBDEF (INSN, 3, NOTE)
 #define NOTE_VAR_LOCATION(INSN)        XCEXP (INSN, 3, NOTE)
+#define NOTE_MARKER_LOCATION(INSN) XCUINT (INSN, 3, NOTE)
 #define NOTE_CFI(INSN)         XCCFI (INSN, 3, NOTE)
 #define NOTE_LABEL_NUMBER(INSN)        XCINT (INSN, 3, NOTE)
 
@@ -1615,6 +1688,13 @@ extern const char * const reg_note_name[];
 #define NOTE_INSN_BASIC_BLOCK_P(INSN) \
   (NOTE_P (INSN) && NOTE_KIND (INSN) == NOTE_INSN_BASIC_BLOCK)
 
+/* Nonzero if INSN is a debug nonbind marker note,
+   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_INLINE_ENTRY))
+
 /* Variable declaration and the location of a variable.  */
 #define PAT_VAR_LOCATION_DECL(PAT) (XCTREE ((PAT), 0, VAR_LOCATION))
 #define PAT_VAR_LOCATION_LOC(PAT) (XCEXP ((PAT), 1, VAR_LOCATION))
@@ -1634,8 +1714,43 @@ extern const char * const reg_note_name[];
 #define NOTE_VAR_LOCATION_STATUS(NOTE) \
   PAT_VAR_LOCATION_STATUS (NOTE_VAR_LOCATION (NOTE))
 
+/* Evaluate to TRUE if INSN is a debug insn that denotes a variable
+   location/value tracking annotation.  */
+#define DEBUG_BIND_INSN_P(INSN)                        \
+  (DEBUG_INSN_P (INSN)                         \
+   && (GET_CODE (PATTERN (INSN))               \
+       == VAR_LOCATION))
+/* Evaluate to TRUE if INSN is a debug insn that denotes a program
+   source location marker.  */
+#define DEBUG_MARKER_INSN_P(INSN)              \
+  (DEBUG_INSN_P (INSN)                         \
+   && (GET_CODE (PATTERN (INSN))               \
+       != VAR_LOCATION))
+/* Evaluate to the marker kind.  */
+#define INSN_DEBUG_MARKER_KIND(INSN)             \
+  (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
+   the representation, so that it's easier to get rid of the abuse of
+   the mode to hold the marker kind.  Other marker types are
+   envisioned, so a single bit flag won't do; maybe separate RTL codes
+   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) PATTERN (INSN)
+#define INSN_VAR_LOCATION(INSN) \
+  (RTL_FLAG_CHECK1 ("INSN_VAR_LOCATION", PATTERN (INSN), VAR_LOCATION))
+/* A pointer to the VAR_LOCATION rtx in a DEBUG_INSN.  */
+#define INSN_VAR_LOCATION_PTR(INSN) \
+  (&PATTERN (INSN))
 
 /* Accessors for a tree-expanded var location debug insn.  */
 #define INSN_VAR_LOCATION_DECL(INSN) \
@@ -1695,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)
 
@@ -1749,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)
@@ -1782,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));
@@ -1790,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;
@@ -1813,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);
@@ -1828,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);
@@ -1854,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))
@@ -1871,6 +1993,12 @@ set_regno_raw (rtx x, unsigned int regno, unsigned int nregs)
 #define CONST_WIDE_INT_NUNITS(RTX) CWI_GET_NUM_ELEM (RTX)
 #define CONST_WIDE_INT_ELT(RTX, N) CWI_ELT (RTX, N)
 
+/* For a CONST_POLY_INT, CONST_POLY_INT_COEFFS gives access to the
+   individual coefficients, in the form of a trailing_wide_ints structure.  */
+#define CONST_POLY_INT_COEFFS(RTX) \
+  (RTL_FLAG_CHECK1("CONST_POLY_INT_COEFFS", (RTX), \
+                  CONST_POLY_INT)->u.cpi.coeffs)
+
 /* For a CONST_DOUBLE:
 #if TARGET_SUPPORTS_WIDE_INT == 0
    For a VOIDmode, there are two integers CONST_DOUBLE_LOW is the
@@ -1891,18 +2019,43 @@ set_regno_raw (rtx x, unsigned int regno, unsigned int nregs)
   ((HOST_WIDE_INT) (CONST_FIXED_VALUE (r)->data.low))
 
 /* For a CONST_VECTOR, return element #n.  */
-#define CONST_VECTOR_ELT(RTX, N) XCVECEXP (RTX, 0, N, CONST_VECTOR)
+#define CONST_VECTOR_ELT(RTX, N) const_vector_elt (RTX, N)
+
+/* See rtl.texi for a description of these macros.  */
+#define CONST_VECTOR_NPATTERNS(RTX) \
+ (RTL_FLAG_CHECK1 ("CONST_VECTOR_NPATTERNS", (RTX), CONST_VECTOR) \
+  ->u2.const_vector.npatterns)
+
+#define CONST_VECTOR_NELTS_PER_PATTERN(RTX) \
+ (RTL_FLAG_CHECK1 ("CONST_VECTOR_NELTS_PER_PATTERN", (RTX), CONST_VECTOR) \
+  ->u2.const_vector.nelts_per_pattern)
+
+#define CONST_VECTOR_DUPLICATE_P(RTX) \
+  (CONST_VECTOR_NELTS_PER_PATTERN (RTX) == 1)
+
+#define CONST_VECTOR_STEPPED_P(RTX) \
+  (CONST_VECTOR_NELTS_PER_PATTERN (RTX) == 3)
+
+#define CONST_VECTOR_ENCODED_ELT(RTX, N) XCVECEXP (RTX, 0, N, CONST_VECTOR)
+
+/* Return the number of elements encoded directly in a CONST_VECTOR.  */
+
+inline unsigned int
+const_vector_encoded_nelts (const_rtx x)
+{
+  return CONST_VECTOR_NPATTERNS (x) * CONST_VECTOR_NELTS_PER_PATTERN (x);
+}
 
 /* For a CONST_VECTOR, return the number of elements in a vector.  */
-#define CONST_VECTOR_NUNITS(RTX) XCVECLEN (RTX, 0, CONST_VECTOR)
+#define CONST_VECTOR_NUNITS(RTX) GET_MODE_NUNITS (GET_MODE (RTX))
 
 /* For a SUBREG rtx, SUBREG_REG extracts the value we want a subreg of.
    SUBREG_BYTE extracts the byte-number.  */
 
 #define SUBREG_REG(RTX) XCEXP (RTX, 0, SUBREG)
-#define SUBREG_BYTE(RTX) XCUINT (RTX, 1, 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.  */
@@ -1914,7 +2067,7 @@ set_regno_raw (rtx x, unsigned int regno, unsigned int nregs)
 
 /* Return true if CODE always has VOIDmode.  */
 
-static inline bool
+inline bool
 always_void_p (enum rtx_code code)
 {
   return code == SET;
@@ -1929,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;
@@ -1937,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;
@@ -1946,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)
 {
@@ -1960,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);
@@ -1972,20 +2125,21 @@ 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 {
-  subreg_shape (machine_mode, unsigned int, machine_mode);
+class subreg_shape {
+public:
+  subreg_shape (machine_mode, poly_uint16, machine_mode);
   bool operator == (const subreg_shape &) const;
   bool operator != (const subreg_shape &) const;
-  unsigned int unique_id () const;
+  unsigned HOST_WIDE_INT unique_id () const;
 
   machine_mode inner_mode;
-  unsigned int offset;
+  poly_uint16 offset;
   machine_mode outer_mode;
 };
 
 inline
 subreg_shape::subreg_shape (machine_mode inner_mode_in,
-                           unsigned int offset_in,
+                           poly_uint16 offset_in,
                            machine_mode outer_mode_in)
   : inner_mode (inner_mode_in), offset (offset_in), outer_mode (outer_mode_in)
 {}
@@ -1994,7 +2148,7 @@ inline bool
 subreg_shape::operator == (const subreg_shape &other) const
 {
   return (inner_mode == other.inner_mode
-         && offset == other.offset
+         && known_eq (offset, other.offset)
          && outer_mode == other.outer_mode);
 }
 
@@ -2009,16 +2163,21 @@ subreg_shape::operator != (const subreg_shape &other) const
    current mode is anywhere near being 65536 bytes in size, so the
    id comfortably fits in an int.  */
 
-inline unsigned int
+inline unsigned HOST_WIDE_INT
 subreg_shape::unique_id () const
 {
-  STATIC_ASSERT (MAX_MACHINE_MODE <= 256);
-  return (int) inner_mode + ((int) outer_mode << 8) + (offset << 16);
+  { 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);
+  for (int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
+    res += (HOST_WIDE_INT) offset.coeffs[i] << ((1 + i) * 16);
+  return res;
 }
 
 /* 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)),
@@ -2184,40 +2343,137 @@ wi::max_value (machine_mode mode, signop sgn)
   return max_value (GET_MODE_PRECISION (as_a <scalar_mode> (mode)), sgn);
 }
 
+namespace wi
+{
+  typedef poly_int<NUM_POLY_INT_COEFFS,
+                  generic_wide_int <wide_int_ref_storage <false, false> > >
+    rtx_to_poly_wide_ref;
+  rtx_to_poly_wide_ref to_poly_wide (const_rtx, machine_mode);
+}
+
+/* Return the value of a CONST_POLY_INT in its native precision.  */
+
+inline wi::rtx_to_poly_wide_ref
+const_poly_int_value (const_rtx x)
+{
+  poly_int<NUM_POLY_INT_COEFFS, WIDE_INT_REF_FOR (wide_int)> res;
+  for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
+    res.coeffs[i] = CONST_POLY_INT_COEFFS (x)[i];
+  return res;
+}
+
+/* Return true if X is a scalar integer or a CONST_POLY_INT.  The value
+   can then be extracted using wi::to_poly_wide.  */
+
+inline bool
+poly_int_rtx_p (const_rtx x)
+{
+  return CONST_SCALAR_INT_P (x) || CONST_POLY_INT_P (x);
+}
+
+/* Access X (which satisfies poly_int_rtx_p) as a poly_wide_int.
+   MODE is the mode of X.  */
+
+inline wi::rtx_to_poly_wide_ref
+wi::to_poly_wide (const_rtx x, machine_mode mode)
+{
+  if (CONST_POLY_INT_P (x))
+    return const_poly_int_value (x);
+  return rtx_mode_t (const_cast<rtx> (x), mode);
+}
+
+/* Return the value of X as a poly_int64.  */
+
+inline poly_int64
+rtx_to_poly_int64 (const_rtx x)
+{
+  if (CONST_POLY_INT_P (x))
+    {
+      poly_int64 res;
+      for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
+       res.coeffs[i] = CONST_POLY_INT_COEFFS (x)[i].to_shwi ();
+      return res;
+    }
+  return INTVAL (x);
+}
+
+/* Return true if arbitrary value X is an integer constant that can
+   be represented as a poly_int64.  Store the value in *RES if so,
+   otherwise leave it unmodified.  */
+
+inline bool
+poly_int_rtx_p (const_rtx x, poly_int64_pod *res)
+{
+  if (CONST_INT_P (x))
+    {
+      *res = INTVAL (x);
+      return true;
+    }
+  if (CONST_POLY_INT_P (x))
+    {
+      for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
+       if (!wi::fits_shwi_p (CONST_POLY_INT_COEFFS (x)[i]))
+         return false;
+      for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
+       res->coeffs[i] = CONST_POLY_INT_COEFFS (x)[i].to_shwi ();
+      return true;
+    }
+  return false;
+}
+
 extern void init_rtlanal (void);
 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 unsigned int subreg_lsb (const_rtx);
-extern unsigned int subreg_lsb_1 (machine_mode, machine_mode,
-                                 unsigned int);
-extern unsigned int subreg_size_offset_from_lsb (unsigned int, unsigned int,
-                                                unsigned int);
+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_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
    the inner value.  This is the inverse of subreg_lsb_1 (which converts
    byte offsets to bit shifts).  */
 
-inline unsigned int
+inline poly_uint64
 subreg_offset_from_lsb (machine_mode outer_mode,
                        machine_mode inner_mode,
-                       unsigned int lsb_shift)
+                       poly_uint64 lsb_shift)
 {
   return subreg_size_offset_from_lsb (GET_MODE_SIZE (outer_mode),
                                      GET_MODE_SIZE (inner_mode), lsb_shift);
 }
 
-extern unsigned int subreg_regno_offset        (unsigned int, machine_mode,
-                                        unsigned int, machine_mode);
+extern unsigned int subreg_regno_offset (unsigned int, machine_mode,
+                                        poly_uint64, machine_mode);
 extern bool subreg_offset_representable_p (unsigned int, machine_mode,
-                                          unsigned int, machine_mode);
+                                          poly_uint64, machine_mode);
 extern unsigned int subreg_regno (const_rtx);
 extern int simplify_subreg_regno (unsigned int, machine_mode,
-                                 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);
@@ -2325,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)
@@ -2468,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)
@@ -2676,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);
@@ -2684,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);
@@ -2694,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);
@@ -2702,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);
@@ -2719,12 +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 rtx plus_constant (machine_mode, rtx, HOST_WIDE_INT, bool = false);
+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)                           \
@@ -2732,28 +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);
+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 && rtvec_all_equal_p (XVEC (x, 0));
+  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.
@@ -2765,12 +3031,28 @@ const_vec_duplicate_p (T x, T *elt)
 {
   if (const_vec_duplicate_p (x))
     {
-      *elt = CONST_VECTOR_ELT (x, 0);
+      *elt = CONST_VECTOR_ENCODED_ELT (x, 0);
       return true;
     }
   return false;
 }
 
+/* Return true if X is a vector with a duplicated element value, either
+   constant or nonconstant.  Store the duplicated element in *ELT if so.  */
+
+template <typename T>
+inline bool
+vec_duplicate_p (T x, T *elt)
+{
+  if (GET_CODE (x) == VEC_DUPLICATE
+      && !VECTOR_MODE_P (GET_MODE (XEXP (x, 0))))
+    {
+      *elt = XEXP (x, 0);
+      return true;
+    }
+  return const_vec_duplicate_p (x, elt);
+}
+
 /* If X is a vector constant with a duplicated element value, return that
    element value, otherwise return X.  */
 
@@ -2783,6 +3065,65 @@ unwrap_const_vec_duplicate (T x)
   return x;
 }
 
+/* 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 *);
+
+/* Return true if X is an integer constant vector that contains a linear
+   series of the form:
+
+   { B, B + S, B + 2 * S, B + 3 * S, ... }
+
+   for a nonzero S.  Store B and S in *BASE_OUT and *STEP_OUT on sucess.  */
+
+inline bool
+const_vec_series_p (const_rtx x, rtx *base_out, rtx *step_out)
+{
+  if (GET_CODE (x) == CONST_VECTOR
+      && CONST_VECTOR_NPATTERNS (x) == 1
+      && !CONST_VECTOR_DUPLICATE_P (x))
+    return const_vec_series_p_1 (x, base_out, step_out);
+  return false;
+}
+
+/* Return true if X is a vector that contains a linear series of the
+   form:
+
+   { B, B + S, B + 2 * S, B + 3 * S, ... }
+
+   where B and S are constant or nonconstant.  Store B and S in
+   *BASE_OUT and *STEP_OUT on sucess.  */
+
+inline bool
+vec_series_p (const_rtx x, rtx *base_out, rtx *step_out)
+{
+  if (GET_CODE (x) == VEC_SERIES)
+    {
+      *base_out = XEXP (x, 0);
+      *step_out = XEXP (x, 1);
+      return true;
+    }
+  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
@@ -2801,28 +3142,28 @@ 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);
-extern rtx gen_rtx_REG_offset (rtx, machine_mode, unsigned int, int);
+extern rtx gen_rtx_REG_offset (rtx, machine_mode, unsigned int, poly_int64);
 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 (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, unsigned int, int, machine_mode);
+extern rtx operand_subword (rtx, poly_uint64, int, machine_mode);
 
-/* In emit-rtl.c */
-extern rtx operand_subword_force (rtx, unsigned int, machine_mode);
-extern int subreg_lowpart_p (const_rtx);
-extern unsigned int subreg_size_lowpart_offset (unsigned int, unsigned int);
+/* In emit-rtl.cc */
+extern rtx operand_subword_force (rtx, poly_uint64, machine_mode);
+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
    an inner register with mode INNERMODE.  The other bits of the inner
@@ -2833,7 +3174,12 @@ extern unsigned int subreg_size_lowpart_offset (unsigned int, unsigned int);
 inline bool
 partial_subreg_p (machine_mode outermode, machine_mode innermode)
 {
-  return GET_MODE_PRECISION (outermode) < GET_MODE_PRECISION (innermode);
+  /* Modes involved in a subreg must be ordered.  In particular, we must
+     always know at compile time whether the subreg is paradoxical.  */
+  poly_int64 outer_prec = GET_MODE_PRECISION (outermode);
+  poly_int64 inner_prec = GET_MODE_PRECISION (innermode);
+  gcc_checking_assert (ordered_p (outer_prec, inner_prec));
+  return maybe_lt (outer_prec, inner_prec);
 }
 
 /* Likewise return true if X is a subreg that is smaller than the inner
@@ -2854,7 +3200,12 @@ partial_subreg_p (const_rtx x)
 inline bool
 paradoxical_subreg_p (machine_mode outermode, machine_mode innermode)
 {
-  return GET_MODE_PRECISION (outermode) > GET_MODE_PRECISION (innermode);
+  /* Modes involved in a subreg must be ordered.  In particular, we must
+     always know at compile time whether the subreg is paradoxical.  */
+  poly_int64 outer_prec = GET_MODE_PRECISION (outermode);
+  poly_int64 inner_prec = GET_MODE_PRECISION (innermode);
+  gcc_checking_assert (ordered_p (outer_prec, inner_prec));
+  return maybe_gt (outer_prec, inner_prec);
 }
 
 /* Return true if X is a paradoxical subreg, false otherwise.  */
@@ -2869,27 +3220,56 @@ paradoxical_subreg_p (const_rtx x)
 
 /* Return the SUBREG_BYTE for an OUTERMODE lowpart of an INNERMODE value.  */
 
-inline unsigned int
+inline poly_uint64
 subreg_lowpart_offset (machine_mode outermode, machine_mode innermode)
 {
   return subreg_size_lowpart_offset (GET_MODE_SIZE (outermode),
                                     GET_MODE_SIZE (innermode));
 }
 
-extern unsigned int subreg_size_highpart_offset (unsigned int, unsigned int);
+/* Given that a subreg has outer mode OUTERMODE and inner mode INNERMODE,
+   return the smaller of the two modes if they are different sizes,
+   otherwise return the outer mode.  */
+
+inline machine_mode
+narrower_subreg_mode (machine_mode outermode, machine_mode innermode)
+{
+  return paradoxical_subreg_p (outermode, innermode) ? innermode : outermode;
+}
+
+/* Given that a subreg has outer mode OUTERMODE and inner mode INNERMODE,
+   return the mode that is big enough to hold both the outer and inner
+   values.  Prefer the outer mode in the event of a tie.  */
+
+inline machine_mode
+wider_subreg_mode (machine_mode outermode, machine_mode innermode)
+{
+  return partial_subreg_p (outermode, innermode) ? innermode : outermode;
+}
+
+/* Likewise for subreg X.  */
+
+inline machine_mode
+wider_subreg_mode (const_rtx x)
+{
+  return wider_subreg_mode (GET_MODE (x), GET_MODE (SUBREG_REG (x)));
+}
+
+extern poly_uint64 subreg_size_highpart_offset (poly_uint64, poly_uint64);
 
 /* Return the SUBREG_BYTE for an OUTERMODE highpart of an INNERMODE value.  */
 
-inline unsigned int
+inline poly_uint64
 subreg_highpart_offset (machine_mode outermode, machine_mode innermode)
 {
   return subreg_size_highpart_offset (GET_MODE_SIZE (outermode),
                                      GET_MODE_SIZE (innermode));
 }
 
-extern int byte_lowpart_offset (machine_mode, machine_mode);
-extern int subreg_memory_offset (machine_mode, machine_mode, unsigned int);
-extern int subreg_memory_offset (const_rtx);
+extern poly_int64 byte_lowpart_offset (machine_mode, machine_mode);
+extern poly_int64 subreg_memory_offset (machine_mode, machine_mode,
+                                       poly_uint64);
+extern poly_int64 subreg_memory_offset (const_rtx);
 extern rtx make_safe_from (rtx, rtx);
 extern rtx convert_memory_address_addr_space_1 (scalar_int_mode, rtx,
                                                addr_space_t, bool, bool);
@@ -2909,56 +3289,55 @@ extern void end_sequence (void);
 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 &, machine_mode);
-#endif
 #if TARGET_SUPPORTS_WIDE_INT == 0
 extern rtx immed_double_const (HOST_WIDE_INT, HOST_WIDE_INT,
                               machine_mode);
 #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);
 extern rtx get_pool_constant_mark (rtx, bool *);
-extern machine_mode get_pool_mode (const_rtx);
+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);
@@ -2979,29 +3358,30 @@ extern rtx_call_insn *last_call_insn (void);
 extern rtx_insn *previous_insn (rtx_insn *);
 extern rtx_insn *next_insn (rtx_insn *);
 extern rtx_insn *prev_nonnote_insn (rtx_insn *);
-extern rtx_insn *prev_nonnote_insn_bb (rtx_insn *);
 extern rtx_insn *next_nonnote_insn (rtx_insn *);
-extern rtx_insn *next_nonnote_insn_bb (rtx_insn *);
 extern rtx_insn *prev_nondebug_insn (rtx_insn *);
 extern rtx_insn *next_nondebug_insn (rtx_insn *);
 extern rtx_insn *prev_nonnote_nondebug_insn (rtx_insn *);
+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);
@@ -3009,45 +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,
-                           unsigned int);
-extern rtx simplify_gen_subreg (machine_mode, rtx, machine_mode,
-                               unsigned int);
-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);
@@ -3060,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.  */
 
@@ -3093,62 +3612,69 @@ 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);
 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);
+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);
@@ -3156,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
@@ -3194,15 +3721,15 @@ 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 *);
-extern int insn_rtx_cost (rtx, bool);
+extern int pattern_cost (rtx, bool);
+extern int insn_cost (rtx_insn *, bool);
 extern unsigned seq_cost (const rtx_insn *, bool);
 
 /* Given an insn and condition, return a canonical description of
@@ -3230,10 +3757,10 @@ struct subreg_info
 };
 
 extern void subreg_get_info (unsigned int, machine_mode,
-                            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 **);
@@ -3249,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);
@@ -3257,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 **,
@@ -3297,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;
@@ -3396,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;
@@ -3430,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)
@@ -3455,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);
@@ -3466,9 +3993,12 @@ 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, int);
+extern rtx gen_rtx_SUBREG (machine_mode, rtx, poly_uint64);
 extern rtx gen_rtx_MEM (machine_mode, rtx);
 extern rtx gen_rtx_VAR_LOCATION (machine_mode, tree, rtx,
                                 enum var_init_status);
@@ -3476,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))
@@ -3557,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)
@@ -3570,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;
 
@@ -3592,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
 
@@ -3610,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);
@@ -3647,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);
@@ -3662,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);
@@ -3670,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);
@@ -3685,25 +4212,25 @@ 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);
+                            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);
@@ -3718,35 +4245,53 @@ extern int print_rtl_single (FILE *, const_rtx);
 extern int 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);
-extern HOST_WIDE_INT find_args_size_adjust (rtx_insn *);
-extern int fixup_args_size_notes (rtx_insn *, rtx_insn *, 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 */
+/* In reginfo.cc */
 extern int reg_classes_intersect_p (reg_class_t, reg_class_t);
 extern int reg_class_subset_p (reg_class_t, reg_class_t);
 extern void globalize_reg (tree, int);
@@ -3761,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,
@@ -3908,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);
@@ -3942,26 +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);
 #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);
@@ -3992,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 *)
@@ -4004,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,
@@ -4035,7 +4580,51 @@ load_extend_op (machine_mode mode)
   return UNKNOWN;
 }
 
-/* gtype-desc.c.  */
+/* If X is a PLUS of a base and a constant offset, add the constant to *OFFSET
+   and return the base.  Return X otherwise.  */
+
+inline rtx
+strip_offset_and_add (rtx x, poly_int64_pod *offset)
+{
+  if (GET_CODE (x) == PLUS)
+    {
+      poly_int64 suboffset;
+      x = strip_offset (x, &suboffset);
+      *offset = poly_uint64 (*offset) + suboffset;
+    }
+  return x;
+}
+
+/* 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 *);