OSDN Git Service

Fix another mips typo.
[pf3gnuchains/gcc-fork.git] / gcc / cse.c
index 3bdbf03..47708e2 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -43,6 +43,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "except.h"
 #include "target.h"
 #include "params.h"
 #include "except.h"
 #include "target.h"
 #include "params.h"
+#include "rtlhooks-def.h"
 
 /* The basic idea of common subexpression elimination is to go
    through the code, keeping a record of expressions that would
 
 /* The basic idea of common subexpression elimination is to go
    through the code, keeping a record of expressions that would
@@ -484,10 +485,16 @@ struct table_elt
    register (hard registers may require `do_not_record' to be set).  */
 
 #define HASH(X, M)     \
    register (hard registers may require `do_not_record' to be set).  */
 
 #define HASH(X, M)     \
- ((GET_CODE (X) == REG && REGNO (X) >= FIRST_PSEUDO_REGISTER   \
+ ((REG_P (X) && REGNO (X) >= FIRST_PSEUDO_REGISTER     \
   ? (((unsigned) REG << 7) + (unsigned) REG_QTY (REGNO (X)))   \
   : canon_hash (X, M)) & HASH_MASK)
 
   ? (((unsigned) REG << 7) + (unsigned) REG_QTY (REGNO (X)))   \
   : canon_hash (X, M)) & HASH_MASK)
 
+/* Like HASH, but without side-effects.  */
+#define SAFE_HASH(X, M)        \
+ ((REG_P (X) && REGNO (X) >= FIRST_PSEUDO_REGISTER     \
+  ? (((unsigned) REG << 7) + (unsigned) REG_QTY (REGNO (X)))   \
+  : safe_hash (X, M)) & HASH_MASK)
+
 /* Determine whether register number N is considered a fixed register for the
    purpose of approximating register costs.
    It is desirable to replace other regs with fixed regs, to reduce need for
 /* Determine whether register number N is considered a fixed register for the
    purpose of approximating register costs.
    It is desirable to replace other regs with fixed regs, to reduce need for
@@ -509,8 +516,8 @@ struct table_elt
    || ((N) < FIRST_PSEUDO_REGISTER                                     \
        && FIXED_REGNO_P (N) && REGNO_REG_CLASS (N) != NO_REGS))
 
    || ((N) < FIRST_PSEUDO_REGISTER                                     \
        && FIXED_REGNO_P (N) && REGNO_REG_CLASS (N) != NO_REGS))
 
-#define COST(X) (GET_CODE (X) == REG ? 0 : notreg_cost (X, SET))
-#define COST_IN(X,OUTER) (GET_CODE (X) == REG ? 0 : notreg_cost (X, OUTER))
+#define COST(X) (REG_P (X) ? 0 : notreg_cost (X, SET))
+#define COST_IN(X,OUTER) (REG_P (X) ? 0 : notreg_cost (X, OUTER))
 
 /* Get the info associated with register N.  */
 
 
 /* Get the info associated with register N.  */
 
@@ -593,7 +600,7 @@ struct cse_basic_block_data
       /* Whether it should be taken or not.  AROUND is the same as taken
         except that it is used when the destination label is not preceded
        by a BARRIER.  */
       /* Whether it should be taken or not.  AROUND is the same as taken
         except that it is used when the destination label is not preceded
        by a BARRIER.  */
-      enum taken {TAKEN, NOT_TAKEN, AROUND} status;
+      enum taken {PATH_TAKEN, PATH_NOT_TAKEN, PATH_AROUND} status;
     } *path;
 };
 
     } *path;
 };
 
@@ -601,7 +608,7 @@ static bool fixed_base_plus_p (rtx x);
 static int notreg_cost (rtx, enum rtx_code);
 static int approx_reg_cost_1 (rtx *, void *);
 static int approx_reg_cost (rtx);
 static int notreg_cost (rtx, enum rtx_code);
 static int approx_reg_cost_1 (rtx *, void *);
 static int approx_reg_cost (rtx);
-static int preferrable (int, int, int, int);
+static int preferable (int, int, int, int);
 static void new_basic_block (void);
 static void make_new_qty (unsigned int, enum machine_mode);
 static void make_regs_eqv (unsigned int, unsigned int);
 static void new_basic_block (void);
 static void make_new_qty (unsigned int, enum machine_mode);
 static void make_regs_eqv (unsigned int, unsigned int);
@@ -624,10 +631,11 @@ static void rehash_using_reg (rtx);
 static void invalidate_memory (void);
 static void invalidate_for_call (void);
 static rtx use_related_value (rtx, struct table_elt *);
 static void invalidate_memory (void);
 static void invalidate_for_call (void);
 static rtx use_related_value (rtx, struct table_elt *);
-static unsigned canon_hash (rtx, enum machine_mode);
-static unsigned canon_hash_string (const char *);
-static unsigned safe_hash (rtx, enum machine_mode);
-static int exp_equiv_p (rtx, rtx, int, int);
+
+static inline unsigned canon_hash (rtx, enum machine_mode);
+static inline unsigned safe_hash (rtx, enum machine_mode);
+static unsigned hash_rtx_string (const char *);
+
 static rtx canon_reg (rtx, rtx);
 static void find_best_addr (rtx, rtx *, enum machine_mode);
 static enum rtx_code find_comparison_args (enum rtx_code, rtx *, rtx *,
 static rtx canon_reg (rtx, rtx);
 static void find_best_addr (rtx, rtx *, enum machine_mode);
 static enum rtx_code find_comparison_args (enum rtx_code, rtx *, rtx *,
@@ -639,6 +647,8 @@ static void record_jump_equiv (rtx, int);
 static void record_jump_cond (enum rtx_code, enum machine_mode, rtx, rtx,
                              int);
 static void cse_insn (rtx, rtx);
 static void record_jump_cond (enum rtx_code, enum machine_mode, rtx, rtx,
                              int);
 static void cse_insn (rtx, rtx);
+static void cse_end_of_basic_block (rtx, struct cse_basic_block_data *,
+                                   int, int, int);
 static int addr_affects_sp_p (rtx);
 static void invalidate_from_clobbers (rtx);
 static rtx cse_process_notes (rtx, rtx);
 static int addr_affects_sp_p (rtx);
 static void invalidate_from_clobbers (rtx);
 static rtx cse_process_notes (rtx, rtx);
@@ -662,6 +672,12 @@ static int cse_change_cc_mode (rtx *, void *);
 static void cse_change_cc_mode_insns (rtx, rtx, rtx);
 static enum machine_mode cse_cc_succs (basic_block, rtx, rtx, bool);
 \f
 static void cse_change_cc_mode_insns (rtx, rtx, rtx);
 static enum machine_mode cse_cc_succs (basic_block, rtx, rtx, bool);
 \f
+
+#undef RTL_HOOKS_GEN_LOWPART
+#define RTL_HOOKS_GEN_LOWPART          gen_lowpart_if_possible
+
+static const struct rtl_hooks cse_rtl_hooks = RTL_HOOKS_INITIALIZER;
+\f
 /* Nonzero if X has the form (PLUS frame-pointer integer).  We check for
    virtual regs here because the simplify_*_operation routines are called
    by integrate.c, which is called before virtual register instantiation.  */
 /* Nonzero if X has the form (PLUS frame-pointer integer).  We check for
    virtual regs here because the simplify_*_operation routines are called
    by integrate.c, which is called before virtual register instantiation.  */
@@ -686,9 +702,6 @@ fixed_base_plus_p (rtx x)
        return false;
       return fixed_base_plus_p (XEXP (x, 0));
 
        return false;
       return fixed_base_plus_p (XEXP (x, 0));
 
-    case ADDRESSOF:
-      return true;
-
     default:
       return false;
     }
     default:
       return false;
     }
@@ -720,7 +733,7 @@ approx_reg_cost_1 (rtx *xp, void *data)
   rtx x = *xp;
   int *cost_p = data;
 
   rtx x = *xp;
   int *cost_p = data;
 
-  if (x && GET_CODE (x) == REG)
+  if (x && REG_P (x))
     {
       unsigned int regno = REGNO (x);
 
     {
       unsigned int regno = REGNO (x);
 
@@ -761,7 +774,7 @@ approx_reg_cost (rtx x)
    Return a positive value if A is less desirable, or 0 if the two are
    equally good.  */
 static int
    Return a positive value if A is less desirable, or 0 if the two are
    equally good.  */
 static int
-preferrable (int cost_a, int regcost_a, int cost_b, int regcost_b)
+preferable (int cost_a, int regcost_a, int cost_b, int regcost_b)
 {
   /* First, get rid of cases involving expressions that are entirely
      unwanted.  */
 {
   /* First, get rid of cases involving expressions that are entirely
      unwanted.  */
@@ -798,7 +811,7 @@ static int
 notreg_cost (rtx x, enum rtx_code outer)
 {
   return ((GET_CODE (x) == SUBREG
 notreg_cost (rtx x, enum rtx_code outer)
 {
   return ((GET_CODE (x) == SUBREG
-          && GET_CODE (SUBREG_REG (x)) == REG
+          && REG_P (SUBREG_REG (x))
           && GET_MODE_CLASS (GET_MODE (x)) == MODE_INT
           && GET_MODE_CLASS (GET_MODE (SUBREG_REG (x))) == MODE_INT
           && (GET_MODE_SIZE (GET_MODE (x))
           && GET_MODE_CLASS (GET_MODE (x)) == MODE_INT
           && GET_MODE_CLASS (GET_MODE (SUBREG_REG (x))) == MODE_INT
           && (GET_MODE_SIZE (GET_MODE (x))
@@ -810,109 +823,6 @@ notreg_cost (rtx x, enum rtx_code outer)
          : rtx_cost (x, outer) * 2);
 }
 
          : rtx_cost (x, outer) * 2);
 }
 
-/* Return an estimate of the cost of computing rtx X.
-   One use is in cse, to decide which expression to keep in the hash table.
-   Another is in rtl generation, to pick the cheapest way to multiply.
-   Other uses like the latter are expected in the future.  */
-
-int
-rtx_cost (rtx x, enum rtx_code outer_code ATTRIBUTE_UNUSED)
-{
-  int i, j;
-  enum rtx_code code;
-  const char *fmt;
-  int total;
-
-  if (x == 0)
-    return 0;
-
-  /* Compute the default costs of certain things.
-     Note that targetm.rtx_costs can override the defaults.  */
-
-  code = GET_CODE (x);
-  switch (code)
-    {
-    case MULT:
-      total = COSTS_N_INSNS (5);
-      break;
-    case DIV:
-    case UDIV:
-    case MOD:
-    case UMOD:
-      total = COSTS_N_INSNS (7);
-      break;
-    case USE:
-      /* Used in loop.c and combine.c as a marker.  */
-      total = 0;
-      break;
-    default:
-      total = COSTS_N_INSNS (1);
-    }
-
-  switch (code)
-    {
-    case REG:
-      return 0;
-
-    case SUBREG:
-      /* If we can't tie these modes, make this expensive.  The larger
-        the mode, the more expensive it is.  */
-      if (! MODES_TIEABLE_P (GET_MODE (x), GET_MODE (SUBREG_REG (x))))
-       return COSTS_N_INSNS (2
-                             + GET_MODE_SIZE (GET_MODE (x)) / UNITS_PER_WORD);
-      break;
-
-    default:
-      if ((*targetm.rtx_costs) (x, code, outer_code, &total))
-       return total;
-      break;
-    }
-
-  /* Sum the costs of the sub-rtx's, plus cost of this operation,
-     which is already in total.  */
-
-  fmt = GET_RTX_FORMAT (code);
-  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
-    if (fmt[i] == 'e')
-      total += rtx_cost (XEXP (x, i), code);
-    else if (fmt[i] == 'E')
-      for (j = 0; j < XVECLEN (x, i); j++)
-       total += rtx_cost (XVECEXP (x, i, j), code);
-
-  return total;
-}
-\f
-/* Return cost of address expression X.
-   Expect that X is properly formed address reference.  */
-
-int
-address_cost (rtx x, enum machine_mode mode)
-{
-  /* The address_cost target hook does not deal with ADDRESSOF nodes.  But,
-     during CSE, such nodes are present.  Using an ADDRESSOF node which
-     refers to the address of a REG is a good thing because we can then
-     turn (MEM (ADDRESSSOF (REG))) into just plain REG.  */
-
-  if (GET_CODE (x) == ADDRESSOF && REG_P (XEXP ((x), 0)))
-    return -1;
-
-  /* We may be asked for cost of various unusual addresses, such as operands
-     of push instruction.  It is not worthwhile to complicate writing
-     of the target hook by such cases.  */
-
-  if (!memory_address_p (mode, x))
-    return 1000;
-
-  return (*targetm.address_cost) (x);
-}
-
-/* If the target doesn't override, compute the cost as with arithmetic.  */
-
-int
-default_address_cost (rtx x)
-{
-  return rtx_cost (x, MEM);
-}
 \f
 static struct cse_reg_info *
 get_cse_reg_info (unsigned int regno)
 \f
 static struct cse_reg_info *
 get_cse_reg_info (unsigned int regno)
@@ -1180,7 +1090,7 @@ mention_regs (rtx x)
   /* If this is a SUBREG, we don't want to discard other SUBREGs of the same
      pseudo if they don't use overlapping words.  We handle only pseudos
      here for simplicity.  */
   /* If this is a SUBREG, we don't want to discard other SUBREGs of the same
      pseudo if they don't use overlapping words.  We handle only pseudos
      here for simplicity.  */
-  if (code == SUBREG && GET_CODE (SUBREG_REG (x)) == REG
+  if (code == SUBREG && REG_P (SUBREG_REG (x))
       && REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER)
     {
       unsigned int i = REGNO (SUBREG_REG (x));
       && REGNO (SUBREG_REG (x)) >= FIRST_PSEUDO_REGISTER)
     {
       unsigned int i = REGNO (SUBREG_REG (x));
@@ -1214,9 +1124,9 @@ mention_regs (rtx x)
      call that expensive function in the most common case where the only
      use of the register is in the comparison.  */
 
      call that expensive function in the most common case where the only
      use of the register is in the comparison.  */
 
-  if (code == COMPARE || GET_RTX_CLASS (code) == '<')
+  if (code == COMPARE || COMPARISON_P (x))
     {
     {
-      if (GET_CODE (XEXP (x, 0)) == REG
+      if (REG_P (XEXP (x, 0))
          && ! REGNO_QTY_VALID_P (REGNO (XEXP (x, 0))))
        if (insert_regs (XEXP (x, 0), NULL, 0))
          {
          && ! REGNO_QTY_VALID_P (REGNO (XEXP (x, 0))))
        if (insert_regs (XEXP (x, 0), NULL, 0))
          {
@@ -1224,7 +1134,7 @@ mention_regs (rtx x)
            changed = 1;
          }
 
            changed = 1;
          }
 
-      if (GET_CODE (XEXP (x, 1)) == REG
+      if (REG_P (XEXP (x, 1))
          && ! REGNO_QTY_VALID_P (REGNO (XEXP (x, 1))))
        if (insert_regs (XEXP (x, 1), NULL, 0))
          {
          && ! REGNO_QTY_VALID_P (REGNO (XEXP (x, 1))))
        if (insert_regs (XEXP (x, 1), NULL, 0))
          {
@@ -1257,7 +1167,7 @@ mention_regs (rtx x)
 static int
 insert_regs (rtx x, struct table_elt *classp, int modified)
 {
 static int
 insert_regs (rtx x, struct table_elt *classp, int modified)
 {
-  if (GET_CODE (x) == REG)
+  if (REG_P (x))
     {
       unsigned int regno = REGNO (x);
       int qty_valid;
     {
       unsigned int regno = REGNO (x);
       int qty_valid;
@@ -1280,7 +1190,7 @@ insert_regs (rtx x, struct table_elt *classp, int modified)
            for (classp = classp->first_same_value;
                 classp != 0;
                 classp = classp->next_same_value)
            for (classp = classp->first_same_value;
                 classp != 0;
                 classp = classp->next_same_value)
-             if (GET_CODE (classp->exp) == REG
+             if (REG_P (classp->exp)
                  && GET_MODE (classp->exp) == GET_MODE (x))
                {
                  make_regs_eqv (regno, REGNO (classp->exp));
                  && GET_MODE (classp->exp) == GET_MODE (x))
                {
                  make_regs_eqv (regno, REGNO (classp->exp));
@@ -1313,7 +1223,7 @@ insert_regs (rtx x, struct table_elt *classp, int modified)
      not be accessible because its hash code will have changed.  So assign
      a quantity number now.  */
 
      not be accessible because its hash code will have changed.  So assign
      a quantity number now.  */
 
-  else if (GET_CODE (x) == SUBREG && GET_CODE (SUBREG_REG (x)) == REG
+  else if (GET_CODE (x) == SUBREG && REG_P (SUBREG_REG (x))
           && ! REGNO_QTY_VALID_P (REGNO (SUBREG_REG (x))))
     {
       insert_regs (SUBREG_REG (x), NULL, 0);
           && ! REGNO_QTY_VALID_P (REGNO (SUBREG_REG (x))))
     {
       insert_regs (SUBREG_REG (x), NULL, 0);
@@ -1420,8 +1330,8 @@ lookup (rtx x, unsigned int hash, enum machine_mode mode)
   struct table_elt *p;
 
   for (p = table[hash]; p; p = p->next_same_hash)
   struct table_elt *p;
 
   for (p = table[hash]; p; p = p->next_same_hash)
-    if (mode == p->mode && ((x == p->exp && GET_CODE (x) == REG)
-                           || exp_equiv_p (x, p->exp, GET_CODE (x) != REG, 0)))
+    if (mode == p->mode && ((x == p->exp && REG_P (x))
+                           || exp_equiv_p (x, p->exp, !REG_P (x), false)))
       return p;
 
   return 0;
       return p;
 
   return 0;
@@ -1435,21 +1345,22 @@ lookup_for_remove (rtx x, unsigned int hash, enum machine_mode mode)
 {
   struct table_elt *p;
 
 {
   struct table_elt *p;
 
-  if (GET_CODE (x) == REG)
+  if (REG_P (x))
     {
       unsigned int regno = REGNO (x);
 
       /* Don't check the machine mode when comparing registers;
         invalidating (REG:SI 0) also invalidates (REG:DF 0).  */
       for (p = table[hash]; p; p = p->next_same_hash)
     {
       unsigned int regno = REGNO (x);
 
       /* Don't check the machine mode when comparing registers;
         invalidating (REG:SI 0) also invalidates (REG:DF 0).  */
       for (p = table[hash]; p; p = p->next_same_hash)
-       if (GET_CODE (p->exp) == REG
+       if (REG_P (p->exp)
            && REGNO (p->exp) == regno)
          return p;
     }
   else
     {
       for (p = table[hash]; p; p = p->next_same_hash)
            && REGNO (p->exp) == regno)
          return p;
     }
   else
     {
       for (p = table[hash]; p; p = p->next_same_hash)
-       if (mode == p->mode && (x == p->exp || exp_equiv_p (x, p->exp, 0, 0)))
+       if (mode == p->mode
+           && (x == p->exp || exp_equiv_p (x, p->exp, 0, false)))
          return p;
     }
 
          return p;
     }
 
@@ -1463,7 +1374,7 @@ static rtx
 lookup_as_function (rtx x, enum rtx_code code)
 {
   struct table_elt *p
 lookup_as_function (rtx x, enum rtx_code code)
 {
   struct table_elt *p
-    = lookup (x, safe_hash (x, VOIDmode) & HASH_MASK, GET_MODE (x));
+    = lookup (x, SAFE_HASH (x, VOIDmode), GET_MODE (x));
 
   /* If we are looking for a CONST_INT, the mode doesn't really matter, as
      long as we are narrowing.  So if we looked in vain for a mode narrower
 
   /* If we are looking for a CONST_INT, the mode doesn't really matter, as
      long as we are narrowing.  So if we looked in vain for a mode narrower
@@ -1473,7 +1384,7 @@ lookup_as_function (rtx x, enum rtx_code code)
     {
       x = copy_rtx (x);
       PUT_MODE (x, word_mode);
     {
       x = copy_rtx (x);
       PUT_MODE (x, word_mode);
-      p = lookup (x, safe_hash (x, VOIDmode) & HASH_MASK, word_mode);
+      p = lookup (x, SAFE_HASH (x, VOIDmode), word_mode);
     }
 
   if (p == 0)
     }
 
   if (p == 0)
@@ -1482,7 +1393,7 @@ lookup_as_function (rtx x, enum rtx_code code)
   for (p = p->first_same_value; p; p = p->next_same_value)
     if (GET_CODE (p->exp) == code
        /* Make sure this is a valid entry in the table.  */
   for (p = p->first_same_value; p; p = p->next_same_value)
     if (GET_CODE (p->exp) == code
        /* Make sure this is a valid entry in the table.  */
-       && exp_equiv_p (p->exp, p->exp, 1, 0))
+       && exp_equiv_p (p->exp, p->exp, 1, false))
       return p->exp;
 
   return 0;
       return p->exp;
 
   return 0;
@@ -1513,7 +1424,7 @@ lookup_as_function (rtx x, enum rtx_code code)
    If necessary, update table showing constant values of quantities.  */
 
 #define CHEAPER(X, Y) \
    If necessary, update table showing constant values of quantities.  */
 
 #define CHEAPER(X, Y) \
- (preferrable ((X)->cost, (X)->regcost, (Y)->cost, (Y)->regcost) < 0)
+ (preferable ((X)->cost, (X)->regcost, (Y)->cost, (Y)->regcost) < 0)
 
 static struct table_elt *
 insert (rtx x, struct table_elt *classp, unsigned int hash, enum machine_mode mode)
 
 static struct table_elt *
 insert (rtx x, struct table_elt *classp, unsigned int hash, enum machine_mode mode)
@@ -1522,11 +1433,11 @@ insert (rtx x, struct table_elt *classp, unsigned int hash, enum machine_mode mo
 
   /* If X is a register and we haven't made a quantity for it,
      something is wrong.  */
 
   /* If X is a register and we haven't made a quantity for it,
      something is wrong.  */
-  if (GET_CODE (x) == REG && ! REGNO_QTY_VALID_P (REGNO (x)))
+  if (REG_P (x) && ! REGNO_QTY_VALID_P (REGNO (x)))
     abort ();
 
   /* If X is a hard register, show it is being put in the table.  */
     abort ();
 
   /* If X is a hard register, show it is being put in the table.  */
-  if (GET_CODE (x) == REG && REGNO (x) < FIRST_PSEUDO_REGISTER)
+  if (REG_P (x) && REGNO (x) < FIRST_PSEUDO_REGISTER)
     {
       unsigned int regno = REGNO (x);
       unsigned int endregno = regno + hard_regno_nregs[regno][GET_MODE (x)];
     {
       unsigned int regno = REGNO (x);
       unsigned int endregno = regno + hard_regno_nregs[regno][GET_MODE (x)];
@@ -1558,13 +1469,7 @@ insert (rtx x, struct table_elt *classp, unsigned int hash, enum machine_mode mo
   elt->related_value = 0;
   elt->in_memory = 0;
   elt->mode = mode;
   elt->related_value = 0;
   elt->in_memory = 0;
   elt->mode = mode;
-  elt->is_const = (CONSTANT_P (x)
-                  /* GNU C++ takes advantage of this for `this'
-                     (and other const values).  */
-                  || (GET_CODE (x) == REG
-                      && RTX_UNCHANGING_P (x)
-                      && REGNO (x) >= FIRST_PSEUDO_REGISTER)
-                  || fixed_base_plus_p (x));
+  elt->is_const = (CONSTANT_P (x) || fixed_base_plus_p (x));
 
   if (table[hash])
     table[hash]->prev_same_hash = elt;
 
   if (table[hash])
     table[hash]->prev_same_hash = elt;
@@ -1622,8 +1527,8 @@ insert (rtx x, struct table_elt *classp, unsigned int hash, enum machine_mode mo
      update the qtys `const_insn' to show that `this_insn' is the latest
      insn making that quantity equivalent to the constant.  */
 
      update the qtys `const_insn' to show that `this_insn' is the latest
      insn making that quantity equivalent to the constant.  */
 
-  if (elt->is_const && classp && GET_CODE (classp->exp) == REG
-      && GET_CODE (x) != REG)
+  if (elt->is_const && classp && REG_P (classp->exp)
+      && !REG_P (x))
     {
       int exp_q = REG_QTY (REGNO (classp->exp));
       struct qty_table_elem *exp_ent = &qty_table[exp_q];
     {
       int exp_q = REG_QTY (REGNO (classp->exp));
       struct qty_table_elem *exp_ent = &qty_table[exp_q];
@@ -1632,7 +1537,7 @@ insert (rtx x, struct table_elt *classp, unsigned int hash, enum machine_mode mo
       exp_ent->const_insn = this_insn;
     }
 
       exp_ent->const_insn = this_insn;
     }
 
-  else if (GET_CODE (x) == REG
+  else if (REG_P (x)
           && classp
           && ! qty_table[REG_QTY (REGNO (x))].const_rtx
           && ! elt->is_const)
           && classp
           && ! qty_table[REG_QTY (REGNO (x))].const_rtx
           && ! elt->is_const)
@@ -1641,7 +1546,7 @@ insert (rtx x, struct table_elt *classp, unsigned int hash, enum machine_mode mo
 
       for (p = classp; p != 0; p = p->next_same_value)
        {
 
       for (p = classp; p != 0; p = p->next_same_value)
        {
-         if (p->is_const && GET_CODE (p->exp) != REG)
+         if (p->is_const && !REG_P (p->exp))
            {
              int x_q = REG_QTY (REGNO (x));
              struct qty_table_elem *x_ent = &qty_table[x_q];
            {
              int x_q = REG_QTY (REGNO (x));
              struct qty_table_elem *x_ent = &qty_table[x_q];
@@ -1654,7 +1559,7 @@ insert (rtx x, struct table_elt *classp, unsigned int hash, enum machine_mode mo
        }
     }
 
        }
     }
 
-  else if (GET_CODE (x) == REG
+  else if (REG_P (x)
           && qty_table[REG_QTY (REGNO (x))].const_rtx
           && GET_MODE (x) == qty_table[REG_QTY (REGNO (x))].mode)
     qty_table[REG_QTY (REGNO (x))].const_insn = this_insn;
           && qty_table[REG_QTY (REGNO (x))].const_rtx
           && GET_MODE (x) == qty_table[REG_QTY (REGNO (x))].mode)
     qty_table[REG_QTY (REGNO (x))].const_insn = this_insn;
@@ -1671,7 +1576,7 @@ insert (rtx x, struct table_elt *classp, unsigned int hash, enum machine_mode mo
       if (subexp != 0)
        {
          /* Get the integer-free subexpression in the hash table.  */
       if (subexp != 0)
        {
          /* Get the integer-free subexpression in the hash table.  */
-         subhash = safe_hash (subexp, mode) & HASH_MASK;
+         subhash = SAFE_HASH (subexp, mode);
          subelt = lookup (subexp, subhash, mode);
          if (subelt == 0)
            subelt = insert (subexp, NULL, subhash, mode);
          subelt = lookup (subexp, subhash, mode);
          if (subelt == 0)
            subelt = insert (subexp, NULL, subhash, mode);
@@ -1725,17 +1630,22 @@ merge_equiv_classes (struct table_elt *class1, struct table_elt *class2)
       /* Remove old entry, make a new one in CLASS1's class.
         Don't do this for invalid entries as we cannot find their
         hash code (it also isn't necessary).  */
       /* Remove old entry, make a new one in CLASS1's class.
         Don't do this for invalid entries as we cannot find their
         hash code (it also isn't necessary).  */
-      if (GET_CODE (exp) == REG || exp_equiv_p (exp, exp, 1, 0))
+      if (REG_P (exp) || exp_equiv_p (exp, exp, 1, false))
        {
        {
+         bool need_rehash = false;
+
          hash_arg_in_memory = 0;
          hash = HASH (exp, mode);
 
          hash_arg_in_memory = 0;
          hash = HASH (exp, mode);
 
-         if (GET_CODE (exp) == REG)
-           delete_reg_equiv (REGNO (exp));
+         if (REG_P (exp))
+           {
+             need_rehash = (unsigned) REG_QTY (REGNO (exp)) != REGNO (exp);
+             delete_reg_equiv (REGNO (exp));
+           }
 
          remove_from_table (elt, hash);
 
 
          remove_from_table (elt, hash);
 
-         if (insert_regs (exp, class1, 0))
+         if (insert_regs (exp, class1, 0) || need_rehash)
            {
              rehash_using_reg (exp);
              hash = HASH (exp, mode);
            {
              rehash_using_reg (exp);
              hash = HASH (exp, mode);
@@ -1759,7 +1669,7 @@ flush_hash_table (void)
       {
        /* Note that invalidate can remove elements
           after P in the current hash chain.  */
       {
        /* Note that invalidate can remove elements
           after P in the current hash chain.  */
-       if (GET_CODE (p->exp) == REG)
+       if (REG_P (p->exp))
          invalidate (p->exp, p->mode);
        else
          remove_from_table (p, i);
          invalidate (p->exp, p->mode);
        else
          remove_from_table (p, i);
@@ -1778,7 +1688,7 @@ static int
 check_dependence (rtx *x, void *data)
 {
   struct check_dependence_data *d = (struct check_dependence_data *) data;
 check_dependence (rtx *x, void *data)
 {
   struct check_dependence_data *d = (struct check_dependence_data *) data;
-  if (*x && GET_CODE (*x) == MEM)
+  if (*x && MEM_P (*x))
     return canon_true_dependence (d->exp, d->mode, d->addr, *x,
                                  cse_rtx_varies_p);
   else
     return canon_true_dependence (d->exp, d->mode, d->addr, *x,
                                  cse_rtx_varies_p);
   else
@@ -1863,7 +1773,7 @@ invalidate (rtx x, enum machine_mode full_mode)
                  {
                    next = p->next_same_hash;
 
                  {
                    next = p->next_same_hash;
 
-                   if (GET_CODE (p->exp) != REG
+                   if (!REG_P (p->exp)
                        || REGNO (p->exp) >= FIRST_PSEUDO_REGISTER)
                      continue;
 
                        || REGNO (p->exp) >= FIRST_PSEUDO_REGISTER)
                      continue;
 
@@ -1950,7 +1860,7 @@ remove_invalid_refs (unsigned int regno)
     for (p = table[i]; p; p = next)
       {
        next = p->next_same_hash;
     for (p = table[i]; p; p = next)
       {
        next = p->next_same_hash;
-       if (GET_CODE (p->exp) != REG
+       if (!REG_P (p->exp)
            && refers_to_regno_p (regno, regno + 1, p->exp, (rtx *) 0))
          remove_from_table (p, i);
       }
            && refers_to_regno_p (regno, regno + 1, p->exp, (rtx *) 0))
          remove_from_table (p, i);
       }
@@ -1972,9 +1882,9 @@ remove_invalid_subreg_refs (unsigned int regno, unsigned int offset,
        rtx exp = p->exp;
        next = p->next_same_hash;
 
        rtx exp = p->exp;
        next = p->next_same_hash;
 
-       if (GET_CODE (exp) != REG
+       if (!REG_P (exp)
            && (GET_CODE (exp) != SUBREG
            && (GET_CODE (exp) != SUBREG
-               || GET_CODE (SUBREG_REG (exp)) != REG
+               || !REG_P (SUBREG_REG (exp))
                || REGNO (SUBREG_REG (exp)) != regno
                || (((SUBREG_BYTE (exp)
                      + (GET_MODE_SIZE (GET_MODE (exp)) - 1)) >= offset)
                || REGNO (SUBREG_REG (exp)) != regno
                || (((SUBREG_BYTE (exp)
                      + (GET_MODE_SIZE (GET_MODE (exp)) - 1)) >= offset)
@@ -2002,22 +1912,21 @@ rehash_using_reg (rtx x)
   /* If X is not a register or if the register is known not to be in any
      valid entries in the table, we have no work to do.  */
 
   /* If X is not a register or if the register is known not to be in any
      valid entries in the table, we have no work to do.  */
 
-  if (GET_CODE (x) != REG
+  if (!REG_P (x)
       || REG_IN_TABLE (REGNO (x)) < 0
       || REG_IN_TABLE (REGNO (x)) != REG_TICK (REGNO (x)))
     return;
 
   /* Scan all hash chains looking for valid entries that mention X.
       || REG_IN_TABLE (REGNO (x)) < 0
       || REG_IN_TABLE (REGNO (x)) != REG_TICK (REGNO (x)))
     return;
 
   /* Scan all hash chains looking for valid entries that mention X.
-     If we find one and it is in the wrong hash chain, move it.  We can skip
-     objects that are registers, since they are handled specially.  */
+     If we find one and it is in the wrong hash chain, move it.  */
 
   for (i = 0; i < HASH_SIZE; i++)
     for (p = table[i]; p; p = next)
       {
        next = p->next_same_hash;
 
   for (i = 0; i < HASH_SIZE; i++)
     for (p = table[i]; p; p = next)
       {
        next = p->next_same_hash;
-       if (GET_CODE (p->exp) != REG && reg_mentioned_p (x, p->exp)
-           && exp_equiv_p (p->exp, p->exp, 1, 0)
-           && i != (hash = safe_hash (p->exp, p->mode) & HASH_MASK))
+       if (reg_mentioned_p (x, p->exp)
+           && exp_equiv_p (p->exp, p->exp, 1, false)
+           && i != (hash = SAFE_HASH (p->exp, p->mode)))
          {
            if (p->next_same_hash)
              p->next_same_hash->prev_same_hash = p->prev_same_hash;
          {
            if (p->next_same_hash)
              p->next_same_hash->prev_same_hash = p->prev_same_hash;
@@ -2076,7 +1985,7 @@ invalidate_for_call (void)
        {
          next = p->next_same_hash;
 
        {
          next = p->next_same_hash;
 
-         if (GET_CODE (p->exp) != REG
+         if (!REG_P (p->exp)
              || REGNO (p->exp) >= FIRST_PSEUDO_REGISTER)
            continue;
 
              || REGNO (p->exp) >= FIRST_PSEUDO_REGISTER)
            continue;
 
@@ -2116,7 +2025,7 @@ use_related_value (rtx x, struct table_elt *elt)
       rtx subexp = get_related_value (x);
       if (subexp != 0)
        relt = lookup (subexp,
       rtx subexp = get_related_value (x);
       if (subexp != 0)
        relt = lookup (subexp,
-                      safe_hash (subexp, GET_MODE (subexp)) & HASH_MASK,
+                      SAFE_HASH (subexp, GET_MODE (subexp)),
                       GET_MODE (subexp));
     }
 
                       GET_MODE (subexp));
     }
 
@@ -2142,7 +2051,7 @@ use_related_value (rtx x, struct table_elt *elt)
        q = 0;
       else
        for (q = p->first_same_value; q; q = q->next_same_value)
        q = 0;
       else
        for (q = p->first_same_value; q; q = q->next_same_value)
-         if (GET_CODE (q->exp) == REG)
+         if (REG_P (q->exp))
            break;
 
       if (q)
            break;
 
       if (q)
@@ -2167,7 +2076,7 @@ use_related_value (rtx x, struct table_elt *elt)
 \f
 /* Hash a string.  Just add its bytes up.  */
 static inline unsigned
 \f
 /* Hash a string.  Just add its bytes up.  */
 static inline unsigned
-canon_hash_string (const char *ps)
+hash_rtx_string (const char *ps)
 {
   unsigned hash = 0;
   const unsigned char *p = (const unsigned char *) ps;
 {
   unsigned hash = 0;
   const unsigned char *p = (const unsigned char *) ps;
@@ -2184,23 +2093,26 @@ canon_hash_string (const char *ps)
    MODE is used in hashing for CONST_INTs only;
    otherwise the mode of X is used.
 
    MODE is used in hashing for CONST_INTs only;
    otherwise the mode of X is used.
 
-   Store 1 in do_not_record if any subexpression is volatile.
+   Store 1 in DO_NOT_RECORD_P if any subexpression is volatile.
 
 
-   Store 1 in hash_arg_in_memory if X contains a MEM rtx
-   which does not have the RTX_UNCHANGING_P bit set.
+   If HASH_ARG_IN_MEMORY_P is not NULL, store 1 in it if X contains
+   a MEM rtx which does not have the RTX_UNCHANGING_P bit set.
 
    Note that cse_insn knows that the hash code of a MEM expression
    is just (int) MEM plus the hash code of the address.  */
 
 
    Note that cse_insn knows that the hash code of a MEM expression
    is just (int) MEM plus the hash code of the address.  */
 
-static unsigned
-canon_hash (rtx x, enum machine_mode mode)
+unsigned
+hash_rtx (rtx x, enum machine_mode mode, int *do_not_record_p,
+         int *hash_arg_in_memory_p, bool have_reg_qty)
 {
   int i, j;
   unsigned hash = 0;
   enum rtx_code code;
   const char *fmt;
 
 {
   int i, j;
   unsigned hash = 0;
   enum rtx_code code;
   const char *fmt;
 
-  /* repeat is used to turn tail-recursion into iteration.  */
+  /* Used to turn recursion into iteration.  We can't rely on GCC's
+     tail-recursion elimination since we need to keep accumulating values
+     in HASH.  */
  repeat:
   if (x == 0)
     return hash;
  repeat:
   if (x == 0)
     return hash;
@@ -2211,48 +2123,52 @@ canon_hash (rtx x, enum machine_mode mode)
     case REG:
       {
        unsigned int regno = REGNO (x);
     case REG:
       {
        unsigned int regno = REGNO (x);
-       bool record;
-
-       /* On some machines, we can't record any non-fixed hard register,
-          because extending its life will cause reload problems.  We
-          consider ap, fp, sp, gp to be fixed for this purpose.
-
-          We also consider CCmode registers to be fixed for this purpose;
-          failure to do so leads to failure to simplify 0<100 type of
-          conditionals.
 
 
-          On all machines, we can't record any global registers.
-          Nor should we record any register that is in a small
-          class, as defined by CLASS_LIKELY_SPILLED_P.  */
-
-       if (regno >= FIRST_PSEUDO_REGISTER)
-         record = true;
-       else if (x == frame_pointer_rtx
-                || x == hard_frame_pointer_rtx
-                || x == arg_pointer_rtx
-                || x == stack_pointer_rtx
-                || x == pic_offset_table_rtx)
-         record = true;
-       else if (global_regs[regno])
-         record = false;
-       else if (fixed_regs[regno])
-         record = true;
-       else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_CC)
-         record = true;
-       else if (SMALL_REGISTER_CLASSES)
-         record = false;
-       else if (CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (regno)))
-         record = false;
-       else
-         record = true;
-
-       if (!record)
+       if (!reload_completed)
          {
          {
-           do_not_record = 1;
-           return 0;
+           /* On some machines, we can't record any non-fixed hard register,
+              because extending its life will cause reload problems.  We
+              consider ap, fp, sp, gp to be fixed for this purpose.
+
+              We also consider CCmode registers to be fixed for this purpose;
+              failure to do so leads to failure to simplify 0<100 type of
+              conditionals.
+
+              On all machines, we can't record any global registers.
+              Nor should we record any register that is in a small
+              class, as defined by CLASS_LIKELY_SPILLED_P.  */
+           bool record;
+
+           if (regno >= FIRST_PSEUDO_REGISTER)
+             record = true;
+           else if (x == frame_pointer_rtx
+                    || x == hard_frame_pointer_rtx
+                    || x == arg_pointer_rtx
+                    || x == stack_pointer_rtx
+                    || x == pic_offset_table_rtx)
+             record = true;
+           else if (global_regs[regno])
+             record = false;
+           else if (fixed_regs[regno])
+             record = true;
+           else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_CC)
+             record = true;
+           else if (SMALL_REGISTER_CLASSES)
+             record = false;
+           else if (CLASS_LIKELY_SPILLED_P (REGNO_REG_CLASS (regno)))
+             record = false;
+           else
+             record = true;
+
+           if (!record)
+             {
+               *do_not_record_p = 1;
+               return 0;
+             }
          }
 
          }
 
-       hash += ((unsigned) REG << 7) + (unsigned) REG_QTY (regno);
+       hash += ((unsigned int) REG << 7);
+        hash += (have_reg_qty ? (unsigned) REG_QTY (regno) : regno);
        return hash;
       }
 
        return hash;
       }
 
@@ -2261,9 +2177,9 @@ canon_hash (rtx x, enum machine_mode mode)
        want to have to forget unrelated subregs when one subreg changes.  */
     case SUBREG:
       {
        want to have to forget unrelated subregs when one subreg changes.  */
     case SUBREG:
       {
-       if (GET_CODE (SUBREG_REG (x)) == REG)
+       if (REG_P (SUBREG_REG (x)))
          {
          {
-           hash += (((unsigned) SUBREG << 7)
+           hash += (((unsigned int) SUBREG << 7)
                     + REGNO (SUBREG_REG (x))
                     + (SUBREG_BYTE (x) / UNITS_PER_WORD));
            return hash;
                     + REGNO (SUBREG_REG (x))
                     + (SUBREG_BYTE (x) / UNITS_PER_WORD));
            return hash;
@@ -2272,21 +2188,19 @@ canon_hash (rtx x, enum machine_mode mode)
       }
 
     case CONST_INT:
       }
 
     case CONST_INT:
-      {
-       unsigned HOST_WIDE_INT tem = INTVAL (x);
-       hash += ((unsigned) CONST_INT << 7) + (unsigned) mode + tem;
-       return hash;
-      }
+      hash += (((unsigned int) CONST_INT << 7) + (unsigned int) mode
+               + (unsigned int) INTVAL (x));
+      return hash;
 
     case CONST_DOUBLE:
       /* This is like the general case, except that it only counts
         the integers representing the constant.  */
 
     case CONST_DOUBLE:
       /* This is like the general case, except that it only counts
         the integers representing the constant.  */
-      hash += (unsigned) code + (unsigned) GET_MODE (x);
+      hash += (unsigned int) code + (unsigned int) GET_MODE (x);
       if (GET_MODE (x) != VOIDmode)
        hash += real_hash (CONST_DOUBLE_REAL_VALUE (x));
       else
       if (GET_MODE (x) != VOIDmode)
        hash += real_hash (CONST_DOUBLE_REAL_VALUE (x));
       else
-       hash += ((unsigned) CONST_DOUBLE_LOW (x)
-                + (unsigned) CONST_DOUBLE_HIGH (x));
+       hash += ((unsigned int) CONST_DOUBLE_LOW (x)
+                + (unsigned int) CONST_DOUBLE_HIGH (x));
       return hash;
 
     case CONST_VECTOR:
       return hash;
 
     case CONST_VECTOR:
@@ -2299,7 +2213,8 @@ canon_hash (rtx x, enum machine_mode mode)
        for (i = 0; i < units; ++i)
          {
            elt = CONST_VECTOR_ELT (x, i);
        for (i = 0; i < units; ++i)
          {
            elt = CONST_VECTOR_ELT (x, i);
-           hash += canon_hash (elt, GET_MODE (elt));
+           hash += hash_rtx (elt, GET_MODE (elt), do_not_record_p,
+                             hash_arg_in_memory_p, have_reg_qty);
          }
 
        return hash;
          }
 
        return hash;
@@ -2307,23 +2222,39 @@ canon_hash (rtx x, enum machine_mode mode)
 
       /* Assume there is only one rtx object for any given label.  */
     case LABEL_REF:
 
       /* Assume there is only one rtx object for any given label.  */
     case LABEL_REF:
-      hash += ((unsigned) LABEL_REF << 7) + (unsigned long) XEXP (x, 0);
+      /* We don't hash on the address of the CODE_LABEL to avoid bootstrap
+        differences and differences between each stage's debugging dumps.  */
+        hash += (((unsigned int) LABEL_REF << 7)
+                 + CODE_LABEL_NUMBER (XEXP (x, 0)));
       return hash;
 
     case SYMBOL_REF:
       return hash;
 
     case SYMBOL_REF:
-      hash += ((unsigned) SYMBOL_REF << 7) + (unsigned long) XSTR (x, 0);
-      return hash;
+      {
+       /* Don't hash on the symbol's address to avoid bootstrap differences.
+          Different hash values may cause expressions to be recorded in
+          different orders and thus different registers to be used in the
+          final assembler.  This also avoids differences in the dump files
+          between various stages.  */
+       unsigned int h = 0;
+       const unsigned char *p = (const unsigned char *) XSTR (x, 0);
+
+       while (*p)
+         h += (h << 7) + *p++; /* ??? revisit */
+
+       hash += ((unsigned int) SYMBOL_REF << 7) + h;
+       return hash;
+      }
 
     case MEM:
       /* We don't record if marked volatile or if BLKmode since we don't
         know the size of the move.  */
       if (MEM_VOLATILE_P (x) || GET_MODE (x) == BLKmode)
        {
 
     case MEM:
       /* We don't record if marked volatile or if BLKmode since we don't
         know the size of the move.  */
       if (MEM_VOLATILE_P (x) || GET_MODE (x) == BLKmode)
        {
-         do_not_record = 1;
+         *do_not_record_p = 1;
          return 0;
        }
          return 0;
        }
-      if (! RTX_UNCHANGING_P (x) || fixed_base_plus_p (XEXP (x, 0)))
-       hash_arg_in_memory = 1;
+      if (hash_arg_in_memory_p && !MEM_READONLY_P (x))
+       *hash_arg_in_memory_p = 1;
 
       /* Now that we have already found this special case,
         might as well speed it up as much as possible.  */
 
       /* Now that we have already found this special case,
         might as well speed it up as much as possible.  */
@@ -2335,15 +2266,16 @@ canon_hash (rtx x, enum machine_mode mode)
       /* A USE that mentions non-volatile memory needs special
         handling since the MEM may be BLKmode which normally
         prevents an entry from being made.  Pure calls are
       /* A USE that mentions non-volatile memory needs special
         handling since the MEM may be BLKmode which normally
         prevents an entry from being made.  Pure calls are
-        marked by a USE which mentions BLKmode memory.  */
-      if (GET_CODE (XEXP (x, 0)) == MEM
+        marked by a USE which mentions BLKmode memory.
+        See calls.c:emit_call_1.  */
+      if (MEM_P (XEXP (x, 0))
          && ! MEM_VOLATILE_P (XEXP (x, 0)))
        {
          hash += (unsigned) USE;
          x = XEXP (x, 0);
 
          && ! MEM_VOLATILE_P (XEXP (x, 0)))
        {
          hash += (unsigned) USE;
          x = XEXP (x, 0);
 
-         if (! RTX_UNCHANGING_P (x) || fixed_base_plus_p (XEXP (x, 0)))
-           hash_arg_in_memory = 1;
+         if (hash_arg_in_memory_p && !MEM_READONLY_P (x))
+           *hash_arg_in_memory_p = 1;
 
          /* Now that we have already found this special case,
             might as well speed it up as much as possible.  */
 
          /* Now that we have already found this special case,
             might as well speed it up as much as possible.  */
@@ -2363,34 +2295,36 @@ canon_hash (rtx x, enum machine_mode mode)
     case CC0:
     case CALL:
     case UNSPEC_VOLATILE:
     case CC0:
     case CALL:
     case UNSPEC_VOLATILE:
-      do_not_record = 1;
+      *do_not_record_p = 1;
       return 0;
 
     case ASM_OPERANDS:
       if (MEM_VOLATILE_P (x))
        {
       return 0;
 
     case ASM_OPERANDS:
       if (MEM_VOLATILE_P (x))
        {
-         do_not_record = 1;
+         *do_not_record_p = 1;
          return 0;
        }
       else
        {
          /* We don't want to take the filename and line into account.  */
          hash += (unsigned) code + (unsigned) GET_MODE (x)
          return 0;
        }
       else
        {
          /* We don't want to take the filename and line into account.  */
          hash += (unsigned) code + (unsigned) GET_MODE (x)
-           + canon_hash_string (ASM_OPERANDS_TEMPLATE (x))
-           + canon_hash_string (ASM_OPERANDS_OUTPUT_CONSTRAINT (x))
+           + hash_rtx_string (ASM_OPERANDS_TEMPLATE (x))
+           + hash_rtx_string (ASM_OPERANDS_OUTPUT_CONSTRAINT (x))
            + (unsigned) ASM_OPERANDS_OUTPUT_IDX (x);
 
          if (ASM_OPERANDS_INPUT_LENGTH (x))
            {
              for (i = 1; i < ASM_OPERANDS_INPUT_LENGTH (x); i++)
                {
            + (unsigned) ASM_OPERANDS_OUTPUT_IDX (x);
 
          if (ASM_OPERANDS_INPUT_LENGTH (x))
            {
              for (i = 1; i < ASM_OPERANDS_INPUT_LENGTH (x); i++)
                {
-                 hash += (canon_hash (ASM_OPERANDS_INPUT (x, i),
-                                      GET_MODE (ASM_OPERANDS_INPUT (x, i)))
-                          + canon_hash_string (ASM_OPERANDS_INPUT_CONSTRAINT
-                                               (x, i)));
+                 hash += (hash_rtx (ASM_OPERANDS_INPUT (x, i),
+                                    GET_MODE (ASM_OPERANDS_INPUT (x, i)),
+                                    do_not_record_p, hash_arg_in_memory_p,
+                                    have_reg_qty)
+                          + hash_rtx_string
+                               (ASM_OPERANDS_INPUT_CONSTRAINT (x, i)));
                }
 
                }
 
-             hash += canon_hash_string (ASM_OPERANDS_INPUT_CONSTRAINT (x, 0));
+             hash += hash_rtx_string (ASM_OPERANDS_INPUT_CONSTRAINT (x, 0));
              x = ASM_OPERANDS_INPUT (x, 0);
              mode = GET_MODE (x);
              goto repeat;
              x = ASM_OPERANDS_INPUT (x, 0);
              mode = GET_MODE (x);
              goto repeat;
@@ -2411,48 +2345,59 @@ canon_hash (rtx x, enum machine_mode mode)
     {
       if (fmt[i] == 'e')
        {
     {
       if (fmt[i] == 'e')
        {
-         rtx tem = XEXP (x, i);
-
          /* If we are about to do the last recursive call
             needed at this level, change it into iteration.
             This function  is called enough to be worth it.  */
          if (i == 0)
            {
          /* If we are about to do the last recursive call
             needed at this level, change it into iteration.
             This function  is called enough to be worth it.  */
          if (i == 0)
            {
-             x = tem;
+             x = XEXP (x, i);
              goto repeat;
            }
              goto repeat;
            }
-         hash += canon_hash (tem, 0);
+
+         hash += hash_rtx (XEXP (x, i), 0, do_not_record_p,
+                           hash_arg_in_memory_p, have_reg_qty);
        }
        }
+
       else if (fmt[i] == 'E')
        for (j = 0; j < XVECLEN (x, i); j++)
       else if (fmt[i] == 'E')
        for (j = 0; j < XVECLEN (x, i); j++)
-         hash += canon_hash (XVECEXP (x, i, j), 0);
+         {
+           hash += hash_rtx (XVECEXP (x, i, j), 0, do_not_record_p,
+                             hash_arg_in_memory_p, have_reg_qty);
+         }
+
       else if (fmt[i] == 's')
       else if (fmt[i] == 's')
-       hash += canon_hash_string (XSTR (x, i));
+       hash += hash_rtx_string (XSTR (x, i));
       else if (fmt[i] == 'i')
       else if (fmt[i] == 'i')
-       {
-         unsigned tem = XINT (x, i);
-         hash += tem;
-       }
+       hash += (unsigned int) XINT (x, i);
       else if (fmt[i] == '0' || fmt[i] == 't')
        /* Unused.  */
        ;
       else
        abort ();
     }
       else if (fmt[i] == '0' || fmt[i] == 't')
        /* Unused.  */
        ;
       else
        abort ();
     }
+
   return hash;
 }
 
   return hash;
 }
 
-/* Like canon_hash but with no side effects.  */
+/* Hash an rtx X for cse via hash_rtx.
+   Stores 1 in do_not_record if any subexpression is volatile.
+   Stores 1 in hash_arg_in_memory if X contains a mem rtx which
+   does not have the RTX_UNCHANGING_P bit set.  */
+
+static inline unsigned
+canon_hash (rtx x, enum machine_mode mode)
+{
+  return hash_rtx (x, mode, &do_not_record, &hash_arg_in_memory, true);
+}
 
 
-static unsigned
+/* Like canon_hash but with no side effects, i.e. do_not_record
+   and hash_arg_in_memory are not changed.  */
+
+static inline unsigned
 safe_hash (rtx x, enum machine_mode mode)
 {
 safe_hash (rtx x, enum machine_mode mode)
 {
-  int save_do_not_record = do_not_record;
-  int save_hash_arg_in_memory = hash_arg_in_memory;
-  unsigned hash = canon_hash (x, mode);
-  hash_arg_in_memory = save_hash_arg_in_memory;
-  do_not_record = save_do_not_record;
-  return hash;
+  int dummy_do_not_record;
+  return hash_rtx (x, mode, &dummy_do_not_record, NULL, true);
 }
 \f
 /* Return 1 iff X and Y would canonicalize into the same thing,
 }
 \f
 /* Return 1 iff X and Y would canonicalize into the same thing,
@@ -2462,16 +2407,10 @@ safe_hash (rtx x, enum machine_mode mode)
    and Y was found in the hash table.  We check register refs
    in Y for being marked as valid.
 
    and Y was found in the hash table.  We check register refs
    in Y for being marked as valid.
 
-   If EQUAL_VALUES is nonzero, we allow a register to match a constant value
-   that is known to be in the register.  Ordinarily, we don't allow them
-   to match, because letting them match would cause unpredictable results
-   in all the places that search a hash table chain for an equivalent
-   for a given value.  A possible equivalent that has different structure
-   has its hash code computed from different data.  Whether the hash code
-   is the same as that of the given value is pure luck.  */
+   If FOR_GCSE is true, we compare X and Y for equivalence for GCSE.  */
 
 
-static int
-exp_equiv_p (rtx x, rtx y, int validate, int equal_values)
+int
+exp_equiv_p (rtx x, rtx y, int validate, bool for_gcse)
 {
   int i, j;
   enum rtx_code code;
 {
   int i, j;
   enum rtx_code code;
@@ -2481,42 +2420,13 @@ exp_equiv_p (rtx x, rtx y, int validate, int equal_values)
      if VALIDATE is nonzero.  */
   if (x == y && !validate)
     return 1;
      if VALIDATE is nonzero.  */
   if (x == y && !validate)
     return 1;
+
   if (x == 0 || y == 0)
     return x == y;
 
   code = GET_CODE (x);
   if (code != GET_CODE (y))
   if (x == 0 || y == 0)
     return x == y;
 
   code = GET_CODE (x);
   if (code != GET_CODE (y))
-    {
-      if (!equal_values)
-       return 0;
-
-      /* If X is a constant and Y is a register or vice versa, they may be
-        equivalent.  We only have to validate if Y is a register.  */
-      if (CONSTANT_P (x) && GET_CODE (y) == REG
-         && REGNO_QTY_VALID_P (REGNO (y)))
-       {
-         int y_q = REG_QTY (REGNO (y));
-         struct qty_table_elem *y_ent = &qty_table[y_q];
-
-         if (GET_MODE (y) == y_ent->mode
-             && rtx_equal_p (x, y_ent->const_rtx)
-             && (! validate || REG_IN_TABLE (REGNO (y)) == REG_TICK (REGNO (y))))
-           return 1;
-       }
-
-      if (CONSTANT_P (y) && code == REG
-         && REGNO_QTY_VALID_P (REGNO (x)))
-       {
-         int x_q = REG_QTY (REGNO (x));
-         struct qty_table_elem *x_ent = &qty_table[x_q];
-
-         if (GET_MODE (x) == x_ent->mode
-             && rtx_equal_p (y, x_ent->const_rtx))
-           return 1;
-       }
-
-      return 0;
-    }
+    return 0;
 
   /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.  */
   if (GET_MODE (x) != GET_MODE (y))
 
   /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.  */
   if (GET_MODE (x) != GET_MODE (y))
@@ -2536,29 +2446,48 @@ exp_equiv_p (rtx x, rtx y, int validate, int equal_values)
       return XSTR (x, 0) == XSTR (y, 0);
 
     case REG:
       return XSTR (x, 0) == XSTR (y, 0);
 
     case REG:
-      {
-       unsigned int regno = REGNO (y);
-       unsigned int endregno
-         = regno + (regno >= FIRST_PSEUDO_REGISTER ? 1
-                    : hard_regno_nregs[regno][GET_MODE (y)]);
-       unsigned int i;
+      if (for_gcse)
+       return REGNO (x) == REGNO (y);
+      else
+       {
+         unsigned int regno = REGNO (y);
+         unsigned int i;
+         unsigned int endregno
+           = regno + (regno >= FIRST_PSEUDO_REGISTER ? 1
+                      : hard_regno_nregs[regno][GET_MODE (y)]);
 
 
-       /* If the quantities are not the same, the expressions are not
-          equivalent.  If there are and we are not to validate, they
-          are equivalent.  Otherwise, ensure all regs are up-to-date.  */
+         /* If the quantities are not the same, the expressions are not
+            equivalent.  If there are and we are not to validate, they
+            are equivalent.  Otherwise, ensure all regs are up-to-date.  */
 
 
-       if (REG_QTY (REGNO (x)) != REG_QTY (regno))
-         return 0;
+         if (REG_QTY (REGNO (x)) != REG_QTY (regno))
+           return 0;
+
+         if (! validate)
+           return 1;
+
+         for (i = regno; i < endregno; i++)
+           if (REG_IN_TABLE (i) != REG_TICK (i))
+             return 0;
 
 
-       if (! validate)
          return 1;
          return 1;
+       }
 
 
-       for (i = regno; i < endregno; i++)
-         if (REG_IN_TABLE (i) != REG_TICK (i))
+    case MEM:
+      if (for_gcse)
+       {
+         /* Can't merge two expressions in different alias sets, since we
+            can decide that the expression is transparent in a block when
+            it isn't, due to it being set with the different alias set.  */
+         if (MEM_ALIAS_SET (x) != MEM_ALIAS_SET (y))
            return 0;
 
            return 0;
 
-       return 1;
-      }
+         /* A volatile mem should not be considered equivalent to any
+            other.  */
+         if (MEM_VOLATILE_P (x) || MEM_VOLATILE_P (y))
+           return 0;
+       }
+      break;
 
     /*  For commutative operations, check both orders.  */
     case PLUS:
 
     /*  For commutative operations, check both orders.  */
     case PLUS:
@@ -2568,13 +2497,14 @@ exp_equiv_p (rtx x, rtx y, int validate, int equal_values)
     case XOR:
     case NE:
     case EQ:
     case XOR:
     case NE:
     case EQ:
-      return ((exp_equiv_p (XEXP (x, 0), XEXP (y, 0), validate, equal_values)
+      return ((exp_equiv_p (XEXP (x, 0), XEXP (y, 0),
+                            validate, for_gcse)
               && exp_equiv_p (XEXP (x, 1), XEXP (y, 1),
               && exp_equiv_p (XEXP (x, 1), XEXP (y, 1),
-                              validate, equal_values))
+                               validate, for_gcse))
              || (exp_equiv_p (XEXP (x, 0), XEXP (y, 1),
              || (exp_equiv_p (XEXP (x, 0), XEXP (y, 1),
-                              validate, equal_values)
+                               validate, for_gcse)
                  && exp_equiv_p (XEXP (x, 1), XEXP (y, 0),
                  && exp_equiv_p (XEXP (x, 1), XEXP (y, 0),
-                                 validate, equal_values)));
+                                  validate, for_gcse)));
 
     case ASM_OPERANDS:
       /* We don't use the generic code below because we want to
 
     case ASM_OPERANDS:
       /* We don't use the generic code below because we want to
@@ -2597,7 +2527,7 @@ exp_equiv_p (rtx x, rtx y, int validate, int equal_values)
          for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
            if (! exp_equiv_p (ASM_OPERANDS_INPUT (x, i),
                               ASM_OPERANDS_INPUT (y, i),
          for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
            if (! exp_equiv_p (ASM_OPERANDS_INPUT (x, i),
                               ASM_OPERANDS_INPUT (y, i),
-                              validate, equal_values)
+                              validate, for_gcse)
                || strcmp (ASM_OPERANDS_INPUT_CONSTRAINT (x, i),
                           ASM_OPERANDS_INPUT_CONSTRAINT (y, i)))
              return 0;
                || strcmp (ASM_OPERANDS_INPUT_CONSTRAINT (x, i),
                           ASM_OPERANDS_INPUT_CONSTRAINT (y, i)))
              return 0;
@@ -2610,7 +2540,7 @@ exp_equiv_p (rtx x, rtx y, int validate, int equal_values)
     }
 
   /* Compare the elements.  If any pair of corresponding elements
     }
 
   /* Compare the elements.  If any pair of corresponding elements
-     fail to match, return 0 for the whole things.  */
+     fail to match, return 0 for the whole thing.  */
 
   fmt = GET_RTX_FORMAT (code);
   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
 
   fmt = GET_RTX_FORMAT (code);
   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
@@ -2618,7 +2548,8 @@ exp_equiv_p (rtx x, rtx y, int validate, int equal_values)
       switch (fmt[i])
        {
        case 'e':
       switch (fmt[i])
        {
        case 'e':
-         if (! exp_equiv_p (XEXP (x, i), XEXP (y, i), validate, equal_values))
+         if (! exp_equiv_p (XEXP (x, i), XEXP (y, i),
+                             validate, for_gcse))
            return 0;
          break;
 
            return 0;
          break;
 
@@ -2627,7 +2558,7 @@ exp_equiv_p (rtx x, rtx y, int validate, int equal_values)
            return 0;
          for (j = 0; j < XVECLEN (x, i); j++)
            if (! exp_equiv_p (XVECEXP (x, i, j), XVECEXP (y, i, j),
            return 0;
          for (j = 0; j < XVECLEN (x, i); j++)
            if (! exp_equiv_p (XVECEXP (x, i, j), XVECEXP (y, i, j),
-                              validate, equal_values))
+                               validate, for_gcse))
              return 0;
          break;
 
              return 0;
          break;
 
@@ -2669,7 +2600,7 @@ cse_rtx_varies_p (rtx x, int from_alias)
      mode because if X is equivalent to a constant in some mode, it
      doesn't vary in any mode.  */
 
      mode because if X is equivalent to a constant in some mode, it
      doesn't vary in any mode.  */
 
-  if (GET_CODE (x) == REG
+  if (REG_P (x)
       && REGNO_QTY_VALID_P (REGNO (x)))
     {
       int x_q = REG_QTY (REGNO (x));
       && REGNO_QTY_VALID_P (REGNO (x)))
     {
       int x_q = REG_QTY (REGNO (x));
@@ -2682,7 +2613,7 @@ cse_rtx_varies_p (rtx x, int from_alias)
 
   if (GET_CODE (x) == PLUS
       && GET_CODE (XEXP (x, 1)) == CONST_INT
 
   if (GET_CODE (x) == PLUS
       && GET_CODE (XEXP (x, 1)) == CONST_INT
-      && GET_CODE (XEXP (x, 0)) == REG
+      && REG_P (XEXP (x, 0))
       && REGNO_QTY_VALID_P (REGNO (XEXP (x, 0))))
     {
       int x0_q = REG_QTY (REGNO (XEXP (x, 0)));
       && REGNO_QTY_VALID_P (REGNO (XEXP (x, 0))))
     {
       int x0_q = REG_QTY (REGNO (XEXP (x, 0)));
@@ -2699,8 +2630,8 @@ cse_rtx_varies_p (rtx x, int from_alias)
      load fp minus a constant into a register, then a MEM which is the
      sum of the two `constant' registers.  */
   if (GET_CODE (x) == PLUS
      load fp minus a constant into a register, then a MEM which is the
      sum of the two `constant' registers.  */
   if (GET_CODE (x) == PLUS
-      && GET_CODE (XEXP (x, 0)) == REG
-      && GET_CODE (XEXP (x, 1)) == REG
+      && REG_P (XEXP (x, 0))
+      && REG_P (XEXP (x, 1))
       && REGNO_QTY_VALID_P (REGNO (XEXP (x, 0)))
       && REGNO_QTY_VALID_P (REGNO (XEXP (x, 1))))
     {
       && REGNO_QTY_VALID_P (REGNO (XEXP (x, 0)))
       && REGNO_QTY_VALID_P (REGNO (XEXP (x, 1))))
     {
@@ -2719,6 +2650,29 @@ cse_rtx_varies_p (rtx x, int from_alias)
   return rtx_varies_p (x, from_alias);
 }
 \f
   return rtx_varies_p (x, from_alias);
 }
 \f
+/* Subroutine of canon_reg.  Pass *XLOC through canon_reg, and validate
+   the result if necessary.  INSN is as for canon_reg.  */
+
+static void
+validate_canon_reg (rtx *xloc, rtx insn)
+{
+  rtx new = canon_reg (*xloc, insn);
+  int insn_code;
+
+  /* If replacing pseudo with hard reg or vice versa, ensure the
+     insn remains valid.  Likewise if the insn has MATCH_DUPs.  */
+  if (insn != 0 && new != 0
+      && REG_P (new) && REG_P (*xloc)
+      && (((REGNO (new) < FIRST_PSEUDO_REGISTER)
+          != (REGNO (*xloc) < FIRST_PSEUDO_REGISTER))
+         || GET_MODE (new) != GET_MODE (*xloc)
+         || (insn_code = recog_memoized (insn)) < 0
+         || insn_data[insn_code].n_dups > 0))
+    validate_change (insn, xloc, new, 1);
+  else
+    *xloc = new;
+}
+
 /* Canonicalize an expression:
    replace each register reference inside it
    with the "oldest" equivalent register.
 /* Canonicalize an expression:
    replace each register reference inside it
    with the "oldest" equivalent register.
@@ -2788,25 +2742,10 @@ canon_reg (rtx x, rtx insn)
       int j;
 
       if (fmt[i] == 'e')
       int j;
 
       if (fmt[i] == 'e')
-       {
-         rtx new = canon_reg (XEXP (x, i), insn);
-         int insn_code;
-
-         /* If replacing pseudo with hard reg or vice versa, ensure the
-            insn remains valid.  Likewise if the insn has MATCH_DUPs.  */
-         if (insn != 0 && new != 0
-             && GET_CODE (new) == REG && GET_CODE (XEXP (x, i)) == REG
-             && (((REGNO (new) < FIRST_PSEUDO_REGISTER)
-                  != (REGNO (XEXP (x, i)) < FIRST_PSEUDO_REGISTER))
-                 || (insn_code = recog_memoized (insn)) < 0
-                 || insn_data[insn_code].n_dups > 0))
-           validate_change (insn, &XEXP (x, i), new, 1);
-         else
-           XEXP (x, i) = new;
-       }
+       validate_canon_reg (&XEXP (x, i), insn);
       else if (fmt[i] == 'E')
        for (j = 0; j < XVECLEN (x, i); j++)
       else if (fmt[i] == 'E')
        for (j = 0; j < XVECLEN (x, i); j++)
-         XVECEXP (x, i, j) = canon_reg (XVECEXP (x, i, j), insn);
+         validate_canon_reg (&XVECEXP (x, i, j), insn);
     }
 
   return x;
     }
 
   return x;
@@ -2850,16 +2789,15 @@ find_best_addr (rtx insn, rtx *loc, enum machine_mode mode)
      no easy way to unshare the MEM.  In addition, looking up all stack
      addresses is costly.  */
   if ((GET_CODE (addr) == PLUS
      no easy way to unshare the MEM.  In addition, looking up all stack
      addresses is costly.  */
   if ((GET_CODE (addr) == PLUS
-       && GET_CODE (XEXP (addr, 0)) == REG
+       && REG_P (XEXP (addr, 0))
        && GET_CODE (XEXP (addr, 1)) == CONST_INT
        && (regno = REGNO (XEXP (addr, 0)),
           regno == FRAME_POINTER_REGNUM || regno == HARD_FRAME_POINTER_REGNUM
           || regno == ARG_POINTER_REGNUM))
        && GET_CODE (XEXP (addr, 1)) == CONST_INT
        && (regno = REGNO (XEXP (addr, 0)),
           regno == FRAME_POINTER_REGNUM || regno == HARD_FRAME_POINTER_REGNUM
           || regno == ARG_POINTER_REGNUM))
-      || (GET_CODE (addr) == REG
+      || (REG_P (addr)
          && (regno = REGNO (addr), regno == FRAME_POINTER_REGNUM
              || regno == HARD_FRAME_POINTER_REGNUM
              || regno == ARG_POINTER_REGNUM))
          && (regno = REGNO (addr), regno == FRAME_POINTER_REGNUM
              || regno == HARD_FRAME_POINTER_REGNUM
              || regno == ARG_POINTER_REGNUM))
-      || GET_CODE (addr) == ADDRESSOF
       || CONSTANT_ADDRESS_P (addr))
     return;
 
       || CONSTANT_ADDRESS_P (addr))
     return;
 
@@ -2867,7 +2805,7 @@ find_best_addr (rtx insn, rtx *loc, enum machine_mode mode)
      sometimes simplify the expression.  Many simplifications
      will not be valid, but some, usually applying the associative rule, will
      be valid and produce better code.  */
      sometimes simplify the expression.  Many simplifications
      will not be valid, but some, usually applying the associative rule, will
      be valid and produce better code.  */
-  if (GET_CODE (addr) != REG)
+  if (!REG_P (addr))
     {
       rtx folded = fold_rtx (copy_rtx (addr), NULL_RTX);
       int addr_folded_cost = address_cost (folded, mode);
     {
       rtx folded = fold_rtx (copy_rtx (addr), NULL_RTX);
       int addr_folded_cost = address_cost (folded, mode);
@@ -2918,8 +2856,8 @@ find_best_addr (rtx insn, rtx *loc, enum machine_mode mode)
          for (p = elt->first_same_value; p; p = p->next_same_value)
            if (! p->flag)
              {
          for (p = elt->first_same_value; p; p = p->next_same_value)
            if (! p->flag)
              {
-               if ((GET_CODE (p->exp) == REG
-                    || exp_equiv_p (p->exp, p->exp, 1, 0))
+               if ((REG_P (p->exp)
+                    || exp_equiv_p (p->exp, p->exp, 1, false))
                    && ((exp_cost = address_cost (p->exp, mode)) < best_addr_cost
                        || (exp_cost == best_addr_cost
                            && ((p->cost + 1) >> 1) > best_rtx_cost)))
                    && ((exp_cost = address_cost (p->exp, mode)) < best_addr_cost
                        || (exp_cost == best_addr_cost
                            && ((p->cost + 1) >> 1) > best_rtx_cost)))
@@ -2953,9 +2891,8 @@ find_best_addr (rtx insn, rtx *loc, enum machine_mode mode)
      code on the Alpha for unaligned byte stores.  */
 
   if (flag_expensive_optimizations
      code on the Alpha for unaligned byte stores.  */
 
   if (flag_expensive_optimizations
-      && (GET_RTX_CLASS (GET_CODE (*loc)) == '2'
-         || GET_RTX_CLASS (GET_CODE (*loc)) == 'c')
-      && GET_CODE (XEXP (*loc, 0)) == REG)
+      && ARITHMETIC_P (*loc)
+      && REG_P (XEXP (*loc, 0)))
     {
       rtx op1 = XEXP (*loc, 1);
 
     {
       rtx op1 = XEXP (*loc, 1);
 
@@ -2995,8 +2932,8 @@ find_best_addr (rtx insn, rtx *loc, enum machine_mode mode)
               p && count < 32;
               p = p->next_same_value, count++)
            if (! p->flag
               p && count < 32;
               p = p->next_same_value, count++)
            if (! p->flag
-               && (GET_CODE (p->exp) == REG
-                   || exp_equiv_p (p->exp, p->exp, 1, 0)))
+               && (REG_P (p->exp)
+                   || exp_equiv_p (p->exp, p->exp, 1, false)))
              {
                rtx new = simplify_gen_binary (GET_CODE (*loc), Pmode,
                                               p->exp, op1);
              {
                rtx new = simplify_gen_binary (GET_CODE (*loc), Pmode,
                                               p->exp, op1);
@@ -3068,7 +3005,7 @@ find_comparison_args (enum rtx_code code, rtx *parg1, rtx *parg2,
       /* If ARG1 is a comparison operator and CODE is testing for
         STORE_FLAG_VALUE, get the inner arguments.  */
 
       /* If ARG1 is a comparison operator and CODE is testing for
         STORE_FLAG_VALUE, get the inner arguments.  */
 
-      else if (GET_RTX_CLASS (GET_CODE (arg1)) == '<')
+      else if (COMPARISON_P (arg1))
        {
 #ifdef FLOAT_STORE_FLAG_VALUE
          REAL_VALUE_TYPE fsfv;
        {
 #ifdef FLOAT_STORE_FLAG_VALUE
          REAL_VALUE_TYPE fsfv;
@@ -3105,8 +3042,7 @@ find_comparison_args (enum rtx_code code, rtx *parg1, rtx *parg2,
       if (x == 0)
        /* Look up ARG1 in the hash table and see if it has an equivalence
           that lets us see what is being compared.  */
       if (x == 0)
        /* Look up ARG1 in the hash table and see if it has an equivalence
           that lets us see what is being compared.  */
-       p = lookup (arg1, safe_hash (arg1, GET_MODE (arg1)) & HASH_MASK,
-                   GET_MODE (arg1));
+       p = lookup (arg1, SAFE_HASH (arg1, GET_MODE (arg1)), GET_MODE (arg1));
       if (p)
        {
          p = p->first_same_value;
       if (p)
        {
          p = p->first_same_value;
@@ -3131,7 +3067,7 @@ find_comparison_args (enum rtx_code code, rtx *parg1, rtx *parg2,
 #endif
 
          /* If the entry isn't valid, skip it.  */
 #endif
 
          /* If the entry isn't valid, skip it.  */
-         if (! exp_equiv_p (p->exp, p->exp, 1, 0))
+         if (! exp_equiv_p (p->exp, p->exp, 1, false))
            continue;
 
          if (GET_CODE (p->exp) == COMPARE
            continue;
 
          if (GET_CODE (p->exp) == COMPARE
@@ -3157,7 +3093,7 @@ find_comparison_args (enum rtx_code code, rtx *parg1, rtx *parg2,
                           REAL_VALUE_NEGATIVE (fsfv)))
 #endif
                   )
                           REAL_VALUE_NEGATIVE (fsfv)))
 #endif
                   )
-                 && GET_RTX_CLASS (GET_CODE (p->exp)) == '<'))
+                 && COMPARISON_P (p->exp)))
            {
              x = p->exp;
              break;
            {
              x = p->exp;
              break;
@@ -3177,7 +3113,7 @@ find_comparison_args (enum rtx_code code, rtx *parg1, rtx *parg2,
                            REAL_VALUE_NEGATIVE (fsfv)))
 #endif
                    )
                            REAL_VALUE_NEGATIVE (fsfv)))
 #endif
                    )
-                  && GET_RTX_CLASS (GET_CODE (p->exp)) == '<')
+                  && COMPARISON_P (p->exp))
            {
              reverse_code = 1;
              x = p->exp;
            {
              reverse_code = 1;
              x = p->exp;
@@ -3210,7 +3146,7 @@ find_comparison_args (enum rtx_code code, rtx *parg1, rtx *parg2,
          else
            code = reversed;
        }
          else
            code = reversed;
        }
-      else if (GET_RTX_CLASS (GET_CODE (x)) == '<')
+      else if (COMPARISON_P (x))
        code = GET_CODE (x);
       arg1 = XEXP (x, 0), arg2 = XEXP (x, 1);
     }
        code = GET_CODE (x);
       arg1 = XEXP (x, 0), arg2 = XEXP (x, 1);
     }
@@ -3279,10 +3215,6 @@ fold_rtx (rtx x, rtx insn)
         since they are used only for lists of args
         in a function call's REG_EQUAL note.  */
     case EXPR_LIST:
         since they are used only for lists of args
         in a function call's REG_EQUAL note.  */
     case EXPR_LIST:
-      /* Changing anything inside an ADDRESSOF is incorrect; we don't
-        want to (e.g.,) make (addressof (const_int 0)) just because
-        the location is known to be zero.  */
-    case ADDRESSOF:
       return x;
 
 #ifdef HAVE_cc0
       return x;
 
 #ifdef HAVE_cc0
@@ -3332,7 +3264,7 @@ fold_rtx (rtx x, rtx insn)
 
                if (GET_CODE (elt->exp) == SUBREG
                    && GET_MODE (SUBREG_REG (elt->exp)) == mode
 
                if (GET_CODE (elt->exp) == SUBREG
                    && GET_MODE (SUBREG_REG (elt->exp)) == mode
-                   && exp_equiv_p (elt->exp, elt->exp, 1, 0))
+                   && exp_equiv_p (elt->exp, elt->exp, 1, false))
                  return copy_rtx (SUBREG_REG (elt->exp));
              }
 
                  return copy_rtx (SUBREG_REG (elt->exp));
              }
 
@@ -3356,13 +3288,11 @@ fold_rtx (rtx x, rtx insn)
            return new;
        }
 
            return new;
        }
 
-      if (GET_CODE (folded_arg0) == REG
+      if (REG_P (folded_arg0)
          && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (folded_arg0)))
        {
          struct table_elt *elt;
 
          && GET_MODE_SIZE (mode) < GET_MODE_SIZE (GET_MODE (folded_arg0)))
        {
          struct table_elt *elt;
 
-         /* We can use HASH here since we know that canon_hash won't be
-            called.  */
          elt = lookup (folded_arg0,
                        HASH (folded_arg0, GET_MODE (folded_arg0)),
                        GET_MODE (folded_arg0));
          elt = lookup (folded_arg0,
                        HASH (folded_arg0, GET_MODE (folded_arg0)),
                        GET_MODE (folded_arg0));
@@ -3391,9 +3321,9 @@ fold_rtx (rtx x, rtx insn)
                enum rtx_code eltcode = GET_CODE (elt->exp);
 
                /* Just check for unary and binary operations.  */
                enum rtx_code eltcode = GET_CODE (elt->exp);
 
                /* Just check for unary and binary operations.  */
-               if (GET_RTX_CLASS (GET_CODE (elt->exp)) == '1'
-                   && GET_CODE (elt->exp) != SIGN_EXTEND
-                   && GET_CODE (elt->exp) != ZERO_EXTEND
+               if (UNARY_P (elt->exp)
+                   && eltcode != SIGN_EXTEND
+                   && eltcode != ZERO_EXTEND
                    && GET_CODE (XEXP (elt->exp, 0)) == SUBREG
                    && GET_MODE (SUBREG_REG (XEXP (elt->exp, 0))) == mode
                    && (GET_MODE_CLASS (mode)
                    && GET_CODE (XEXP (elt->exp, 0)) == SUBREG
                    && GET_MODE (SUBREG_REG (XEXP (elt->exp, 0))) == mode
                    && (GET_MODE_CLASS (mode)
@@ -3401,7 +3331,7 @@ fold_rtx (rtx x, rtx insn)
                  {
                    rtx op0 = SUBREG_REG (XEXP (elt->exp, 0));
 
                  {
                    rtx op0 = SUBREG_REG (XEXP (elt->exp, 0));
 
-                   if (GET_CODE (op0) != REG && ! CONSTANT_P (op0))
+                   if (!REG_P (op0) && ! CONSTANT_P (op0))
                      op0 = fold_rtx (op0, NULL_RTX);
 
                    op0 = equiv_constant (op0);
                      op0 = fold_rtx (op0, NULL_RTX);
 
                    op0 = equiv_constant (op0);
@@ -3409,8 +3339,7 @@ fold_rtx (rtx x, rtx insn)
                      new = simplify_unary_operation (GET_CODE (elt->exp), mode,
                                                      op0, mode);
                  }
                      new = simplify_unary_operation (GET_CODE (elt->exp), mode,
                                                      op0, mode);
                  }
-               else if ((GET_RTX_CLASS (GET_CODE (elt->exp)) == '2'
-                         || GET_RTX_CLASS (GET_CODE (elt->exp)) == 'c')
+               else if (ARITHMETIC_P (elt->exp)
                         && eltcode != DIV && eltcode != MOD
                         && eltcode != UDIV && eltcode != UMOD
                         && eltcode != ASHIFTRT && eltcode != LSHIFTRT
                         && eltcode != DIV && eltcode != MOD
                         && eltcode != UDIV && eltcode != UMOD
                         && eltcode != ASHIFTRT && eltcode != LSHIFTRT
@@ -3427,13 +3356,13 @@ fold_rtx (rtx x, rtx insn)
                    rtx op0 = gen_lowpart_common (mode, XEXP (elt->exp, 0));
                    rtx op1 = gen_lowpart_common (mode, XEXP (elt->exp, 1));
 
                    rtx op0 = gen_lowpart_common (mode, XEXP (elt->exp, 0));
                    rtx op1 = gen_lowpart_common (mode, XEXP (elt->exp, 1));
 
-                   if (op0 && GET_CODE (op0) != REG && ! CONSTANT_P (op0))
+                   if (op0 && !REG_P (op0) && ! CONSTANT_P (op0))
                      op0 = fold_rtx (op0, NULL_RTX);
 
                    if (op0)
                      op0 = equiv_constant (op0);
 
                      op0 = fold_rtx (op0, NULL_RTX);
 
                    if (op0)
                      op0 = equiv_constant (op0);
 
-                   if (op1 && GET_CODE (op1) != REG && ! CONSTANT_P (op1))
+                   if (op1 && !REG_P (op1) && ! CONSTANT_P (op1))
                      op1 = fold_rtx (op1, NULL_RTX);
 
                    if (op1)
                      op1 = fold_rtx (op1, NULL_RTX);
 
                    if (op1)
@@ -3468,7 +3397,7 @@ fold_rtx (rtx x, rtx insn)
                         && GET_MODE (SUBREG_REG (elt->exp)) == mode
                         && (GET_MODE_SIZE (GET_MODE (folded_arg0))
                             <= UNITS_PER_WORD)
                         && GET_MODE (SUBREG_REG (elt->exp)) == mode
                         && (GET_MODE_SIZE (GET_MODE (folded_arg0))
                             <= UNITS_PER_WORD)
-                        && exp_equiv_p (elt->exp, elt->exp, 1, 0))
+                        && exp_equiv_p (elt->exp, elt->exp, 1, false))
                  new = copy_rtx (SUBREG_REG (elt->exp));
 
                if (new)
                  new = copy_rtx (SUBREG_REG (elt->exp));
 
                if (new)
@@ -3513,7 +3442,7 @@ fold_rtx (rtx x, rtx insn)
        rtx base = 0;
        HOST_WIDE_INT offset = 0;
 
        rtx base = 0;
        HOST_WIDE_INT offset = 0;
 
-       if (GET_CODE (addr) == REG
+       if (REG_P (addr)
            && REGNO_QTY_VALID_P (REGNO (addr)))
          {
            int addr_q = REG_QTY (REGNO (addr));
            && REGNO_QTY_VALID_P (REGNO (addr)))
          {
            int addr_q = REG_QTY (REGNO (addr));
@@ -3536,8 +3465,6 @@ fold_rtx (rtx x, rtx insn)
        else if (GET_CODE (addr) == LO_SUM
                 && GET_CODE (XEXP (addr, 1)) == SYMBOL_REF)
          base = XEXP (addr, 1);
        else if (GET_CODE (addr) == LO_SUM
                 && GET_CODE (XEXP (addr, 1)) == SYMBOL_REF)
          base = XEXP (addr, 1);
-       else if (GET_CODE (addr) == ADDRESSOF)
-         return change_address (x, VOIDmode, addr);
 
        /* If this is a constant pool reference, we can fold it into its
           constant to allow better value tracking.  */
 
        /* If this is a constant pool reference, we can fold it into its
           constant to allow better value tracking.  */
@@ -3588,7 +3515,7 @@ fold_rtx (rtx x, rtx insn)
            rtx label = XEXP (base, 0);
            rtx table_insn = NEXT_INSN (label);
 
            rtx label = XEXP (base, 0);
            rtx table_insn = NEXT_INSN (label);
 
-           if (table_insn && GET_CODE (table_insn) == JUMP_INSN
+           if (table_insn && JUMP_P (table_insn)
                && GET_CODE (PATTERN (table_insn)) == ADDR_VEC)
              {
                rtx table = PATTERN (table_insn);
                && GET_CODE (PATTERN (table_insn)) == ADDR_VEC)
              {
                rtx table = PATTERN (table_insn);
@@ -3599,7 +3526,7 @@ fold_rtx (rtx x, rtx insn)
                  return XVECEXP (table, 0,
                                  offset / GET_MODE_SIZE (GET_MODE (table)));
              }
                  return XVECEXP (table, 0,
                                  offset / GET_MODE_SIZE (GET_MODE (table)));
              }
-           if (table_insn && GET_CODE (table_insn) == JUMP_INSN
+           if (table_insn && JUMP_P (table_insn)
                && GET_CODE (PATTERN (table_insn)) == ADDR_DIFF_VEC)
              {
                rtx table = PATTERN (table_insn);
                && GET_CODE (PATTERN (table_insn)) == ADDR_DIFF_VEC)
              {
                rtx table = PATTERN (table_insn);
@@ -3680,7 +3607,7 @@ fold_rtx (rtx x, rtx insn)
                struct qty_table_elem *arg_ent = &qty_table[arg_q];
 
                if (arg_ent->const_rtx != NULL_RTX
                struct qty_table_elem *arg_ent = &qty_table[arg_q];
 
                if (arg_ent->const_rtx != NULL_RTX
-                   && GET_CODE (arg_ent->const_rtx) != REG
+                   && !REG_P (arg_ent->const_rtx)
                    && GET_CODE (arg_ent->const_rtx) != PLUS)
                  const_arg
                    = gen_lowpart (GET_MODE (arg),
                    && GET_CODE (arg_ent->const_rtx) != PLUS)
                  const_arg
                    = gen_lowpart (GET_MODE (arg),
@@ -3765,12 +3692,28 @@ fold_rtx (rtx x, rtx insn)
                || (new_cost == old_cost && CONSTANT_P (XEXP (x, i))))
              break;
 
                || (new_cost == old_cost && CONSTANT_P (XEXP (x, i))))
              break;
 
+           /* It's not safe to substitute the operand of a conversion
+              operator with a constant, as the conversion's identity
+              depends upon the mode of it's operand.  This optimization
+              is handled by the call to simplify_unary_operation.  */
+           if (GET_RTX_CLASS (code) == RTX_UNARY
+               && GET_MODE (replacements[j]) != mode_arg0
+               && (code == ZERO_EXTEND
+                   || code == SIGN_EXTEND
+                   || code == TRUNCATE
+                   || code == FLOAT_TRUNCATE
+                   || code == FLOAT_EXTEND
+                   || code == FLOAT
+                   || code == FIX
+                   || code == UNSIGNED_FLOAT
+                   || code == UNSIGNED_FIX))
+             continue;
+
            if (validate_change (insn, &XEXP (x, i), replacements[j], 0))
              break;
 
            if (validate_change (insn, &XEXP (x, i), replacements[j], 0))
              break;
 
-           if (code == NE || code == EQ || GET_RTX_CLASS (code) == 'c'
-               || code == LTGT || code == UNEQ || code == ORDERED
-               || code == UNORDERED)
+           if (GET_RTX_CLASS (code) == RTX_COMM_COMPARE
+               || GET_RTX_CLASS (code) == RTX_COMM_ARITH)
              {
                validate_change (insn, &XEXP (x, i), XEXP (x, 1 - i), 1);
                validate_change (insn, &XEXP (x, 1 - i), replacements[j], 1);
              {
                validate_change (insn, &XEXP (x, i), XEXP (x, 1 - i), 1);
                validate_change (insn, &XEXP (x, 1 - i), replacements[j], 1);
@@ -3802,9 +3745,7 @@ fold_rtx (rtx x, rtx insn)
      operand unless the first operand is also a constant integer.  Otherwise,
      place any constant second unless the first operand is also a constant.  */
 
      operand unless the first operand is also a constant integer.  Otherwise,
      place any constant second unless the first operand is also a constant.  */
 
-  if (code == EQ || code == NE || GET_RTX_CLASS (code) == 'c'
-      || code == LTGT || code == UNEQ || code == ORDERED
-      || code == UNORDERED)
+  if (COMMUTATIVE_P (x))
     {
       if (must_swap
          || swap_commutative_operands_p (const_arg0 ? const_arg0
     {
       if (must_swap
          || swap_commutative_operands_p (const_arg0 ? const_arg0
@@ -3834,7 +3775,7 @@ fold_rtx (rtx x, rtx insn)
 
   switch (GET_RTX_CLASS (code))
     {
 
   switch (GET_RTX_CLASS (code))
     {
-    case '1':
+    case RTX_UNARY:
       {
        int is_const = 0;
 
       {
        int is_const = 0;
 
@@ -3857,7 +3798,8 @@ fold_rtx (rtx x, rtx insn)
       }
       break;
 
       }
       break;
 
-    case '<':
+    case RTX_COMPARE:
+    case RTX_COMM_COMPARE:
       /* See what items are actually being compared and set FOLDED_ARG[01]
         to those values and CODE to the actual comparison code.  If any are
         constant, set CONST_ARG0 and CONST_ARG1 appropriately.  We needn't
       /* See what items are actually being compared and set FOLDED_ARG[01]
         to those values and CODE to the actual comparison code.  If any are
         constant, set CONST_ARG0 and CONST_ARG1 appropriately.  We needn't
@@ -3909,16 +3851,16 @@ fold_rtx (rtx x, rtx insn)
              /* See if the two operands are the same.  */
 
              if (folded_arg0 == folded_arg1
              /* See if the two operands are the same.  */
 
              if (folded_arg0 == folded_arg1
-                 || (GET_CODE (folded_arg0) == REG
-                     && GET_CODE (folded_arg1) == REG
+                 || (REG_P (folded_arg0)
+                     && REG_P (folded_arg1)
                      && (REG_QTY (REGNO (folded_arg0))
                          == REG_QTY (REGNO (folded_arg1))))
                  || ((p0 = lookup (folded_arg0,
                      && (REG_QTY (REGNO (folded_arg0))
                          == REG_QTY (REGNO (folded_arg1))))
                  || ((p0 = lookup (folded_arg0,
-                                   (safe_hash (folded_arg0, mode_arg0)
-                                    & HASH_MASK), mode_arg0))
+                                   SAFE_HASH (folded_arg0, mode_arg0),
+                                   mode_arg0))
                      && (p1 = lookup (folded_arg1,
                      && (p1 = lookup (folded_arg1,
-                                      (safe_hash (folded_arg1, mode_arg0)
-                                       & HASH_MASK), mode_arg0))
+                                      SAFE_HASH (folded_arg1, mode_arg0),
+                                      mode_arg0))
                      && p0->first_same_value == p1->first_same_value))
                {
                  /* Sadly two equal NaNs are not equivalent.  */
                      && p0->first_same_value == p1->first_same_value))
                {
                  /* Sadly two equal NaNs are not equivalent.  */
@@ -3938,7 +3880,7 @@ fold_rtx (rtx x, rtx insn)
              /* If FOLDED_ARG0 is a register, see if the comparison we are
                 doing now is either the same as we did before or the reverse
                 (we only check the reverse if not floating-point).  */
              /* If FOLDED_ARG0 is a register, see if the comparison we are
                 doing now is either the same as we did before or the reverse
                 (we only check the reverse if not floating-point).  */
-             else if (GET_CODE (folded_arg0) == REG)
+             else if (REG_P (folded_arg0))
                {
                  int qty = REG_QTY (REGNO (folded_arg0));
 
                {
                  int qty = REG_QTY (REGNO (folded_arg0));
 
@@ -3954,7 +3896,7 @@ fold_rtx (rtx x, rtx insn)
                              || (const_arg1
                                  && rtx_equal_p (ent->comparison_const,
                                                  const_arg1))
                              || (const_arg1
                                  && rtx_equal_p (ent->comparison_const,
                                                  const_arg1))
-                             || (GET_CODE (folded_arg1) == REG
+                             || (REG_P (folded_arg1)
                                  && (REG_QTY (REGNO (folded_arg1)) == ent->comparison_qty))))
                        return (comparison_dominates_p (ent->comparison_code, code)
                                ? true_rtx : false_rtx);
                                  && (REG_QTY (REGNO (folded_arg1)) == ent->comparison_qty))))
                        return (comparison_dominates_p (ent->comparison_code, code)
                                ? true_rtx : false_rtx);
@@ -4012,35 +3954,15 @@ fold_rtx (rtx x, rtx insn)
            }
        }
 
            }
        }
 
-      new = simplify_relational_operation (code,
-                                          (mode_arg0 != VOIDmode
-                                           ? mode_arg0
-                                           : (GET_MODE (const_arg0
-                                                        ? const_arg0
-                                                        : folded_arg0)
-                                              != VOIDmode)
-                                           ? GET_MODE (const_arg0
-                                                       ? const_arg0
-                                                       : folded_arg0)
-                                           : GET_MODE (const_arg1
-                                                       ? const_arg1
-                                                       : folded_arg1)),
-                                          const_arg0 ? const_arg0 : folded_arg0,
-                                          const_arg1 ? const_arg1 : folded_arg1);
-#ifdef FLOAT_STORE_FLAG_VALUE
-      if (new != 0 && GET_MODE_CLASS (mode) == MODE_FLOAT)
-       {
-         if (new == const0_rtx)
-           new = CONST0_RTX (mode);
-         else
-           new = (CONST_DOUBLE_FROM_REAL_VALUE
-                  (FLOAT_STORE_FLAG_VALUE (mode), mode));
-       }
-#endif
+      {
+       rtx op0 = const_arg0 ? const_arg0 : folded_arg0;
+       rtx op1 = const_arg1 ? const_arg1 : folded_arg1;
+        new = simplify_relational_operation (code, mode, mode_arg0, op0, op1);
+      }
       break;
 
       break;
 
-    case '2':
-    case 'c':
+    case RTX_BIN_ARITH:
+    case RTX_COMM_ARITH:
       switch (code)
        {
        case PLUS:
       switch (code)
        {
        case PLUS:
@@ -4108,16 +4030,15 @@ fold_rtx (rtx x, rtx insn)
                 manner and hope the Sun compilers get it correct.  */
              && INTVAL (const_arg1) !=
                ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1))
                 manner and hope the Sun compilers get it correct.  */
              && INTVAL (const_arg1) !=
                ((HOST_WIDE_INT) 1 << (HOST_BITS_PER_WIDE_INT - 1))
-             && GET_CODE (folded_arg1) == REG)
+             && REG_P (folded_arg1))
            {
              rtx new_const = GEN_INT (-INTVAL (const_arg1));
              struct table_elt *p
            {
              rtx new_const = GEN_INT (-INTVAL (const_arg1));
              struct table_elt *p
-               = lookup (new_const, safe_hash (new_const, mode) & HASH_MASK,
-                         mode);
+               = lookup (new_const, SAFE_HASH (new_const, mode), mode);
 
              if (p)
                for (p = p->first_same_value; p; p = p->next_same_value)
 
              if (p)
                for (p = p->first_same_value; p; p = p->next_same_value)
-                 if (GET_CODE (p->exp) == REG)
+                 if (REG_P (p->exp))
                    return simplify_gen_binary (MINUS, mode, folded_arg0,
                                                canon_reg (p->exp, NULL_RTX));
            }
                    return simplify_gen_binary (MINUS, mode, folded_arg0,
                                                canon_reg (p->exp, NULL_RTX));
            }
@@ -4149,7 +4070,7 @@ fold_rtx (rtx x, rtx insn)
             Note that the similar optimization done by combine.c only works
             if the intermediate operation's result has only one reference.  */
 
             Note that the similar optimization done by combine.c only works
             if the intermediate operation's result has only one reference.  */
 
-         if (GET_CODE (folded_arg0) == REG
+         if (REG_P (folded_arg0)
              && const_arg1 && GET_CODE (const_arg1) == CONST_INT)
            {
              int is_shift
              && const_arg1 && GET_CODE (const_arg1) == CONST_INT)
            {
              int is_shift
@@ -4245,7 +4166,7 @@ fold_rtx (rtx x, rtx insn)
                                       const_arg1 ? const_arg1 : folded_arg1);
       break;
 
                                       const_arg1 ? const_arg1 : folded_arg1);
       break;
 
-    case 'o':
+    case RTX_OBJ:
       /* (lo_sum (high X) X) is simply X.  */
       if (code == LO_SUM && const_arg0 != 0
          && GET_CODE (const_arg0) == HIGH
       /* (lo_sum (high X) X) is simply X.  */
       if (code == LO_SUM && const_arg0 != 0
          && GET_CODE (const_arg0) == HIGH
@@ -4253,23 +4174,15 @@ fold_rtx (rtx x, rtx insn)
        return const_arg1;
       break;
 
        return const_arg1;
       break;
 
-    case '3':
-    case 'b':
+    case RTX_TERNARY:
+    case RTX_BITFIELD_OPS:
       new = simplify_ternary_operation (code, mode, mode_arg0,
                                        const_arg0 ? const_arg0 : folded_arg0,
                                        const_arg1 ? const_arg1 : folded_arg1,
                                        const_arg2 ? const_arg2 : XEXP (x, 2));
       break;
 
       new = simplify_ternary_operation (code, mode, mode_arg0,
                                        const_arg0 ? const_arg0 : folded_arg0,
                                        const_arg1 ? const_arg1 : folded_arg1,
                                        const_arg2 ? const_arg2 : XEXP (x, 2));
       break;
 
-    case 'x':
-      /* Eliminate CONSTANT_P_RTX if its constant.  */
-      if (code == CONSTANT_P_RTX)
-       {
-         if (const_arg0)
-           return const1_rtx;
-         if (optimize == 0 || !flag_gcse)
-           return const0_rtx;
-       }
+    default:
       break;
     }
 
       break;
     }
 
@@ -4282,7 +4195,7 @@ fold_rtx (rtx x, rtx insn)
 static rtx
 equiv_constant (rtx x)
 {
 static rtx
 equiv_constant (rtx x)
 {
-  if (GET_CODE (x) == REG
+  if (REG_P (x)
       && REGNO_QTY_VALID_P (REGNO (x)))
     {
       int x_q = REG_QTY (REGNO (x));
       && REGNO_QTY_VALID_P (REGNO (x)))
     {
       int x_q = REG_QTY (REGNO (x));
@@ -4300,7 +4213,7 @@ equiv_constant (rtx x)
      is a constant-pool reference.  Then try to look it up in the hash table
      in case it is something whose value we have seen before.  */
 
      is a constant-pool reference.  Then try to look it up in the hash table
      in case it is something whose value we have seen before.  */
 
-  if (GET_CODE (x) == MEM)
+  if (MEM_P (x))
     {
       struct table_elt *elt;
 
     {
       struct table_elt *elt;
 
@@ -4308,7 +4221,7 @@ equiv_constant (rtx x)
       if (CONSTANT_P (x))
        return x;
 
       if (CONSTANT_P (x))
        return x;
 
-      elt = lookup (x, safe_hash (x, GET_MODE (x)) & HASH_MASK, GET_MODE (x));
+      elt = lookup (x, SAFE_HASH (x, GET_MODE (x)), GET_MODE (x));
       if (elt == 0)
        return 0;
 
       if (elt == 0)
        return 0;
 
@@ -4336,7 +4249,7 @@ gen_lowpart_if_possible (enum machine_mode mode, rtx x)
 
   if (result)
     return result;
 
   if (result)
     return result;
-  else if (GET_CODE (x) == MEM)
+  else if (MEM_P (x))
     {
       /* This is the only other case we handle.  */
       int offset = 0;
     {
       /* This is the only other case we handle.  */
       int offset = 0;
@@ -4361,7 +4274,7 @@ gen_lowpart_if_possible (enum machine_mode mode, rtx x)
     return 0;
 }
 \f
     return 0;
 }
 \f
-/* Given INSN, a jump insn, TAKEN indicates if we are following the "taken"
+/* Given INSN, a jump insn, PATH_TAKEN indicates if we are following the "taken"
    branch.  It will be zero if not.
 
    In certain cases, this can cause us to add an equivalence.  For example,
    branch.  It will be zero if not.
 
    In certain cases, this can cause us to add an equivalence.  For example,
@@ -4538,11 +4451,11 @@ record_jump_cond (enum rtx_code code, enum machine_mode mode, rtx op0,
         register, or if OP1 is neither a register or constant, we can't
         do anything.  */
 
         register, or if OP1 is neither a register or constant, we can't
         do anything.  */
 
-      if (GET_CODE (op1) != REG)
+      if (!REG_P (op1))
        op1 = equiv_constant (op1);
 
       if ((reversed_nonequality && FLOAT_MODE_P (mode))
        op1 = equiv_constant (op1);
 
       if ((reversed_nonequality && FLOAT_MODE_P (mode))
-         || GET_CODE (op0) != REG || op1 == 0)
+         || !REG_P (op0) || op1 == 0)
        return;
 
       /* Put OP0 in the hash table if it isn't already.  This gives it a
        return;
 
       /* Put OP0 in the hash table if it isn't already.  This gives it a
@@ -4569,7 +4482,7 @@ record_jump_cond (enum rtx_code code, enum machine_mode mode, rtx op0,
       ent = &qty_table[qty];
 
       ent->comparison_code = code;
       ent = &qty_table[qty];
 
       ent->comparison_code = code;
-      if (GET_CODE (op1) == REG)
+      if (REG_P (op1))
        {
          /* Look it up again--in case op0 and op1 are the same.  */
          op1_elt = lookup (op1, op1_hash, mode);
        {
          /* Look it up again--in case op0 and op1 are the same.  */
          op1_elt = lookup (op1, op1_hash, mode);
@@ -4704,7 +4617,7 @@ cse_insn (rtx insn, rtx libcall_insn)
      Also determine whether there is a CLOBBER that invalidates
      all memory references, or all references at varying addresses.  */
 
      Also determine whether there is a CLOBBER that invalidates
      all memory references, or all references at varying addresses.  */
 
-  if (GET_CODE (insn) == CALL_INSN)
+  if (CALL_P (insn))
     {
       for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
        {
     {
       for (tem = CALL_INSN_FUNCTION_USAGE (insn); tem; tem = XEXP (tem, 1))
        {
@@ -4771,7 +4684,7 @@ cse_insn (rtx insn, rtx libcall_insn)
            {
              rtx clobbered = XEXP (y, 0);
 
            {
              rtx clobbered = XEXP (y, 0);
 
-             if (GET_CODE (clobbered) == REG
+             if (REG_P (clobbered)
                  || GET_CODE (clobbered) == SUBREG)
                invalidate (clobbered, VOIDmode);
              else if (GET_CODE (clobbered) == STRICT_LOW_PART
                  || GET_CODE (clobbered) == SUBREG)
                invalidate (clobbered, VOIDmode);
              else if (GET_CODE (clobbered) == STRICT_LOW_PART
@@ -4805,11 +4718,11 @@ cse_insn (rtx insn, rtx libcall_insn)
              /* If we clobber memory, canon the address.
                 This does nothing when a register is clobbered
                 because we have already invalidated the reg.  */
              /* If we clobber memory, canon the address.
                 This does nothing when a register is clobbered
                 because we have already invalidated the reg.  */
-             if (GET_CODE (XEXP (y, 0)) == MEM)
+             if (MEM_P (XEXP (y, 0)))
                canon_reg (XEXP (y, 0), NULL_RTX);
            }
          else if (GET_CODE (y) == USE
                canon_reg (XEXP (y, 0), NULL_RTX);
            }
          else if (GET_CODE (y) == USE
-                  && ! (GET_CODE (XEXP (y, 0)) == REG
+                  && ! (REG_P (XEXP (y, 0))
                         && REGNO (XEXP (y, 0)) < FIRST_PSEUDO_REGISTER))
            canon_reg (y, NULL_RTX);
          else if (GET_CODE (y) == CALL)
                         && REGNO (XEXP (y, 0)) < FIRST_PSEUDO_REGISTER))
            canon_reg (y, NULL_RTX);
          else if (GET_CODE (y) == CALL)
@@ -4824,13 +4737,13 @@ cse_insn (rtx insn, rtx libcall_insn)
     }
   else if (GET_CODE (x) == CLOBBER)
     {
     }
   else if (GET_CODE (x) == CLOBBER)
     {
-      if (GET_CODE (XEXP (x, 0)) == MEM)
+      if (MEM_P (XEXP (x, 0)))
        canon_reg (XEXP (x, 0), NULL_RTX);
     }
 
   /* Canonicalize a USE of a pseudo register or memory location.  */
   else if (GET_CODE (x) == USE
        canon_reg (XEXP (x, 0), NULL_RTX);
     }
 
   /* Canonicalize a USE of a pseudo register or memory location.  */
   else if (GET_CODE (x) == USE
-          && ! (GET_CODE (XEXP (x, 0)) == REG
+          && ! (REG_P (XEXP (x, 0))
                 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER))
     canon_reg (XEXP (x, 0), NULL_RTX);
   else if (GET_CODE (x) == CALL)
                 && REGNO (XEXP (x, 0)) < FIRST_PSEUDO_REGISTER))
     canon_reg (XEXP (x, 0), NULL_RTX);
   else if (GET_CODE (x) == CALL)
@@ -4872,7 +4785,7 @@ cse_insn (rtx insn, rtx libcall_insn)
       int insn_code;
 
       sets[i].orig_src = src;
       int insn_code;
 
       sets[i].orig_src = src;
-      if ((GET_CODE (new) == REG && GET_CODE (src) == REG
+      if ((REG_P (new) && REG_P (src)
           && ((REGNO (new) < FIRST_PSEUDO_REGISTER)
               != (REGNO (src) < FIRST_PSEUDO_REGISTER)))
          || (insn_code = recog_memoized (insn)) < 0
           && ((REGNO (new) < FIRST_PSEUDO_REGISTER)
               != (REGNO (src) < FIRST_PSEUDO_REGISTER)))
          || (insn_code = recog_memoized (insn)) < 0
@@ -4894,7 +4807,7 @@ cse_insn (rtx insn, rtx libcall_insn)
             || GET_CODE (dest) == SIGN_EXTRACT)
        dest = XEXP (dest, 0);
 
             || GET_CODE (dest) == SIGN_EXTRACT)
        dest = XEXP (dest, 0);
 
-      if (GET_CODE (dest) == MEM)
+      if (MEM_P (dest))
        canon_reg (dest, insn);
     }
 
        canon_reg (dest, insn);
     }
 
@@ -5021,9 +4934,9 @@ cse_insn (rtx insn, rtx libcall_insn)
         RTL would be referring to SRC, so we don't lose any optimization
         opportunities by not having SRC in the hash table.  */
 
         RTL would be referring to SRC, so we don't lose any optimization
         opportunities by not having SRC in the hash table.  */
 
-      if (GET_CODE (src) == MEM
+      if (MEM_P (src)
          && find_reg_note (insn, REG_EQUIV, NULL_RTX) != 0
          && find_reg_note (insn, REG_EQUIV, NULL_RTX) != 0
-         && GET_CODE (dest) == REG
+         && REG_P (dest)
          && REGNO (dest) >= FIRST_PSEUDO_REGISTER)
        sets[i].src_volatile = 1;
 
          && REGNO (dest) >= FIRST_PSEUDO_REGISTER)
        sets[i].src_volatile = 1;
 
@@ -5031,7 +4944,7 @@ cse_insn (rtx insn, rtx libcall_insn)
       /* It is no longer clear why we used to do this, but it doesn't
         appear to still be needed.  So let's try without it since this
         code hurts cse'ing widened ops.  */
       /* It is no longer clear why we used to do this, but it doesn't
         appear to still be needed.  So let's try without it since this
         code hurts cse'ing widened ops.  */
-      /* If source is a perverse subreg (such as QI treated as an SI),
+      /* If source is a paradoxical subreg (such as QI treated as an SI),
         treat it as volatile.  It may do the work of an SI in one context
         where the extra bits are not being used, but cannot replace an SI
         in general.  */
         treat it as volatile.  It may do the work of an SI in one context
         where the extra bits are not being used, but cannot replace an SI
         in general.  */
@@ -5174,7 +5087,7 @@ cse_insn (rtx insn, rtx libcall_insn)
 
              for (const_elt = const_elt->first_same_value;
                   const_elt; const_elt = const_elt->next_same_value)
 
              for (const_elt = const_elt->first_same_value;
                   const_elt; const_elt = const_elt->next_same_value)
-               if (GET_CODE (const_elt->exp) == REG)
+               if (REG_P (const_elt->exp))
                  {
                    src_related = gen_lowpart (mode,
                                                           const_elt->exp);
                  {
                    src_related = gen_lowpart (mode,
                                                           const_elt->exp);
@@ -5213,7 +5126,7 @@ cse_insn (rtx insn, rtx libcall_insn)
 
                  for (larger_elt = larger_elt->first_same_value;
                       larger_elt; larger_elt = larger_elt->next_same_value)
 
                  for (larger_elt = larger_elt->first_same_value;
                       larger_elt; larger_elt = larger_elt->next_same_value)
-                   if (GET_CODE (larger_elt->exp) == REG)
+                   if (REG_P (larger_elt->exp))
                      {
                        src_related
                          = gen_lowpart (mode, larger_elt->exp);
                      {
                        src_related
                          = gen_lowpart (mode, larger_elt->exp);
@@ -5230,13 +5143,13 @@ cse_insn (rtx insn, rtx libcall_insn)
       /* See if a MEM has already been loaded with a widening operation;
         if it has, we can use a subreg of that.  Many CISC machines
         also have such operations, but this is only likely to be
       /* See if a MEM has already been loaded with a widening operation;
         if it has, we can use a subreg of that.  Many CISC machines
         also have such operations, but this is only likely to be
-        beneficial these machines.  */
+        beneficial on these machines.  */
 
       if (flag_expensive_optimizations && src_related == 0
          && (GET_MODE_SIZE (mode) < UNITS_PER_WORD)
          && GET_MODE_CLASS (mode) == MODE_INT
 
       if (flag_expensive_optimizations && src_related == 0
          && (GET_MODE_SIZE (mode) < UNITS_PER_WORD)
          && GET_MODE_CLASS (mode) == MODE_INT
-         && GET_CODE (src) == MEM && ! do_not_record
-         && LOAD_EXTEND_OP (mode) != NIL)
+         && MEM_P (src) && ! do_not_record
+         && LOAD_EXTEND_OP (mode) != UNKNOWN)
        {
          enum machine_mode tmode;
 
        {
          enum machine_mode tmode;
 
@@ -5259,7 +5172,7 @@ cse_insn (rtx insn, rtx libcall_insn)
 
              for (larger_elt = larger_elt->first_same_value;
                   larger_elt; larger_elt = larger_elt->next_same_value)
 
              for (larger_elt = larger_elt->first_same_value;
                   larger_elt; larger_elt = larger_elt->next_same_value)
-               if (GET_CODE (larger_elt->exp) == REG)
+               if (REG_P (larger_elt->exp))
                  {
                    src_related = gen_lowpart (mode,
                                                           larger_elt->exp);
                  {
                    src_related = gen_lowpart (mode,
                                                           larger_elt->exp);
@@ -5295,7 +5208,7 @@ cse_insn (rtx insn, rtx libcall_insn)
          /* If the expression is not valid, ignore it.  Then we do not
             have to check for validity below.  In most cases, we can use
             `rtx_equal_p', since canonicalization has already been done.  */
          /* If the expression is not valid, ignore it.  Then we do not
             have to check for validity below.  In most cases, we can use
             `rtx_equal_p', since canonicalization has already been done.  */
-         if (code != REG && ! exp_equiv_p (p->exp, p->exp, 1, 0))
+         if (code != REG && ! exp_equiv_p (p->exp, p->exp, 1, false))
            continue;
 
          /* Also skip paradoxical subregs, unless that's what we're
            continue;
 
          /* Also skip paradoxical subregs, unless that's what we're
@@ -5391,8 +5304,8 @@ cse_insn (rtx insn, rtx libcall_insn)
          rtx trial;
 
          /* Skip invalid entries.  */
          rtx trial;
 
          /* Skip invalid entries.  */
-         while (elt && GET_CODE (elt->exp) != REG
-                && ! exp_equiv_p (elt->exp, elt->exp, 1, 0))
+         while (elt && !REG_P (elt->exp)
+                && ! exp_equiv_p (elt->exp, elt->exp, 1, false))
            elt = elt->next_same_value;
 
          /* A paradoxical subreg would be bad here: it'll be the right
            elt = elt->next_same_value;
 
          /* A paradoxical subreg would be bad here: it'll be the right
@@ -5424,14 +5337,14 @@ cse_insn (rtx insn, rtx libcall_insn)
             of equal cost, use this order:
             src_folded, src, src_eqv, src_related and hash table entry.  */
          if (src_folded
             of equal cost, use this order:
             src_folded, src, src_eqv, src_related and hash table entry.  */
          if (src_folded
-             && preferrable (src_folded_cost, src_folded_regcost,
-                             src_cost, src_regcost) <= 0
-             && preferrable (src_folded_cost, src_folded_regcost,
-                             src_eqv_cost, src_eqv_regcost) <= 0
-             && preferrable (src_folded_cost, src_folded_regcost,
-                             src_related_cost, src_related_regcost) <= 0
-             && preferrable (src_folded_cost, src_folded_regcost,
-                             src_elt_cost, src_elt_regcost) <= 0)
+             && preferable (src_folded_cost, src_folded_regcost,
+                            src_cost, src_regcost) <= 0
+             && preferable (src_folded_cost, src_folded_regcost,
+                            src_eqv_cost, src_eqv_regcost) <= 0
+             && preferable (src_folded_cost, src_folded_regcost,
+                            src_related_cost, src_related_regcost) <= 0
+             && preferable (src_folded_cost, src_folded_regcost,
+                            src_elt_cost, src_elt_regcost) <= 0)
            {
              trial = src_folded, src_folded_cost = MAX_COST;
              if (src_folded_force_flag)
            {
              trial = src_folded, src_folded_cost = MAX_COST;
              if (src_folded_force_flag)
@@ -5442,22 +5355,22 @@ cse_insn (rtx insn, rtx libcall_insn)
                }
            }
          else if (src
                }
            }
          else if (src
-                  && preferrable (src_cost, src_regcost,
-                                  src_eqv_cost, src_eqv_regcost) <= 0
-                  && preferrable (src_cost, src_regcost,
-                                  src_related_cost, src_related_regcost) <= 0
-                  && preferrable (src_cost, src_regcost,
-                                  src_elt_cost, src_elt_regcost) <= 0)
+                  && preferable (src_cost, src_regcost,
+                                 src_eqv_cost, src_eqv_regcost) <= 0
+                  && preferable (src_cost, src_regcost,
+                                 src_related_cost, src_related_regcost) <= 0
+                  && preferable (src_cost, src_regcost,
+                                 src_elt_cost, src_elt_regcost) <= 0)
            trial = src, src_cost = MAX_COST;
          else if (src_eqv_here
            trial = src, src_cost = MAX_COST;
          else if (src_eqv_here
-                  && preferrable (src_eqv_cost, src_eqv_regcost,
-                                  src_related_cost, src_related_regcost) <= 0
-                  && preferrable (src_eqv_cost, src_eqv_regcost,
-                                  src_elt_cost, src_elt_regcost) <= 0)
+                  && preferable (src_eqv_cost, src_eqv_regcost,
+                                 src_related_cost, src_related_regcost) <= 0
+                  && preferable (src_eqv_cost, src_eqv_regcost,
+                                 src_elt_cost, src_elt_regcost) <= 0)
            trial = copy_rtx (src_eqv_here), src_eqv_cost = MAX_COST;
          else if (src_related
            trial = copy_rtx (src_eqv_here), src_eqv_cost = MAX_COST;
          else if (src_related
-                  && preferrable (src_related_cost, src_related_regcost,
-                                  src_elt_cost, src_elt_regcost) <= 0)
+                  && preferable (src_related_cost, src_related_regcost,
+                                 src_elt_cost, src_elt_regcost) <= 0)
            trial = copy_rtx (src_related), src_related_cost = MAX_COST;
          else
            {
            trial = copy_rtx (src_related), src_related_cost = MAX_COST;
          else
            {
@@ -5494,11 +5407,16 @@ cse_insn (rtx insn, rtx libcall_insn)
                 need to make the same substitution in any notes attached
                 to the RETVAL insn.  */
              if (libcall_insn
                 need to make the same substitution in any notes attached
                 to the RETVAL insn.  */
              if (libcall_insn
-                 && (GET_CODE (sets[i].orig_src) == REG
+                 && (REG_P (sets[i].orig_src)
                      || GET_CODE (sets[i].orig_src) == SUBREG
                      || GET_CODE (sets[i].orig_src) == SUBREG
-                     || GET_CODE (sets[i].orig_src) == MEM))
-               simplify_replace_rtx (REG_NOTES (libcall_insn),
-                                     sets[i].orig_src, copy_rtx (new));
+                     || MEM_P (sets[i].orig_src)))
+               {
+                 rtx note = find_reg_equal_equiv_note (libcall_insn);
+                 if (note != 0)
+                   XEXP (note, 0) = simplify_replace_rtx (XEXP (note, 0),
+                                                          sets[i].orig_src,
+                                                          copy_rtx (new));
+               }
 
              /* The result of apply_change_group can be ignored; see
                 canon_reg.  */
 
              /* The result of apply_change_group can be ignored; see
                 canon_reg.  */
@@ -5526,7 +5444,7 @@ cse_insn (rtx insn, rtx libcall_insn)
                         && GET_CODE (XEXP (XEXP (trial, 0), 0)) == LABEL_REF
                         && GET_CODE (XEXP (XEXP (trial, 0), 1)) == LABEL_REF)
                   && (src_folded == 0
                         && GET_CODE (XEXP (XEXP (trial, 0), 0)) == LABEL_REF
                         && GET_CODE (XEXP (XEXP (trial, 0), 1)) == LABEL_REF)
                   && (src_folded == 0
-                      || (GET_CODE (src_folded) != MEM
+                      || (!MEM_P (src_folded)
                           && ! src_folded_force_flag))
                   && GET_MODE_CLASS (mode) != MODE_CC
                   && mode != VOIDmode)
                           && ! src_folded_force_flag))
                   && GET_MODE_CLASS (mode) != MODE_CC
                   && mode != VOIDmode)
@@ -5546,7 +5464,7 @@ cse_insn (rtx insn, rtx libcall_insn)
         with the head of the class.  If we do not do this, we will have
         both registers live over a portion of the basic block.  This way,
         their lifetimes will likely abut instead of overlapping.  */
         with the head of the class.  If we do not do this, we will have
         both registers live over a portion of the basic block.  This way,
         their lifetimes will likely abut instead of overlapping.  */
-      if (GET_CODE (dest) == REG
+      if (REG_P (dest)
          && REGNO_QTY_VALID_P (REGNO (dest)))
        {
          int dest_q = REG_QTY (REGNO (dest));
          && REGNO_QTY_VALID_P (REGNO (dest)))
        {
          int dest_q = REG_QTY (REGNO (dest));
@@ -5554,12 +5472,12 @@ cse_insn (rtx insn, rtx libcall_insn)
 
          if (dest_ent->mode == GET_MODE (dest)
              && dest_ent->first_reg != REGNO (dest)
 
          if (dest_ent->mode == GET_MODE (dest)
              && dest_ent->first_reg != REGNO (dest)
-             && GET_CODE (src) == REG && REGNO (src) == REGNO (dest)
+             && REG_P (src) && REGNO (src) == REGNO (dest)
              /* Don't do this if the original insn had a hard reg as
                 SET_SRC or SET_DEST.  */
              /* Don't do this if the original insn had a hard reg as
                 SET_SRC or SET_DEST.  */
-             && (GET_CODE (sets[i].src) != REG
+             && (!REG_P (sets[i].src)
                  || REGNO (sets[i].src) >= FIRST_PSEUDO_REGISTER)
                  || REGNO (sets[i].src) >= FIRST_PSEUDO_REGISTER)
-             && (GET_CODE (dest) != REG || REGNO (dest) >= FIRST_PSEUDO_REGISTER))
+             && (!REG_P (dest) || REGNO (dest) >= FIRST_PSEUDO_REGISTER))
            /* We can't call canon_reg here because it won't do anything if
               SRC is a hard register.  */
            {
            /* We can't call canon_reg here because it won't do anything if
               SRC is a hard register.  */
            {
@@ -5610,8 +5528,8 @@ cse_insn (rtx insn, rtx libcall_insn)
         which can be created for a reference to a compile time computable
         entry in a jump table.  */
 
         which can be created for a reference to a compile time computable
         entry in a jump table.  */
 
-      if (n_sets == 1 && src_const && GET_CODE (dest) == REG
-         && GET_CODE (src_const) != REG
+      if (n_sets == 1 && src_const && REG_P (dest)
+         && !REG_P (src_const)
          && ! (GET_CODE (src_const) == CONST
                && GET_CODE (XEXP (src_const, 0)) == MINUS
                && GET_CODE (XEXP (XEXP (src_const, 0), 0)) == LABEL_REF
          && ! (GET_CODE (src_const) == CONST
                && GET_CODE (XEXP (src_const, 0)) == MINUS
                && GET_CODE (XEXP (XEXP (src_const, 0), 0)) == LABEL_REF
@@ -5642,12 +5560,12 @@ cse_insn (rtx insn, rtx libcall_insn)
 
       sets[i].inner_dest = dest;
 
 
       sets[i].inner_dest = dest;
 
-      if (GET_CODE (dest) == MEM)
+      if (MEM_P (dest))
        {
 #ifdef PUSH_ROUNDING
          /* Stack pushes invalidate the stack pointer.  */
          rtx addr = XEXP (dest, 0);
        {
 #ifdef PUSH_ROUNDING
          /* Stack pushes invalidate the stack pointer.  */
          rtx addr = XEXP (dest, 0);
-         if (GET_RTX_CLASS (GET_CODE (addr)) == 'a'
+         if (GET_RTX_CLASS (GET_CODE (addr)) == RTX_AUTOINC
              && XEXP (addr, 0) == stack_pointer_rtx)
            invalidate (stack_pointer_rtx, Pmode);
 #endif
              && XEXP (addr, 0) == stack_pointer_rtx)
            invalidate (stack_pointer_rtx, Pmode);
 #endif
@@ -5707,7 +5625,7 @@ cse_insn (rtx insn, rtx libcall_insn)
        {
          /* Now emit a BARRIER after the unconditional jump.  */
          if (NEXT_INSN (insn) == 0
        {
          /* Now emit a BARRIER after the unconditional jump.  */
          if (NEXT_INSN (insn) == 0
-             || GET_CODE (NEXT_INSN (insn)) != BARRIER)
+             || !BARRIER_P (NEXT_INSN (insn)))
            emit_barrier_after (insn);
 
          /* We reemit the jump in as many cases as possible just in
            emit_barrier_after (insn);
 
          /* We reemit the jump in as many cases as possible just in
@@ -5719,23 +5637,31 @@ cse_insn (rtx insn, rtx libcall_insn)
             and hope for the best.  */
          if (n_sets == 1)
            {
             and hope for the best.  */
          if (n_sets == 1)
            {
-             rtx new = emit_jump_insn_after (gen_jump (XEXP (src, 0)), insn);
+             rtx new, note;
 
 
+             new = emit_jump_insn_after (gen_jump (XEXP (src, 0)), insn);
              JUMP_LABEL (new) = XEXP (src, 0);
              LABEL_NUSES (XEXP (src, 0))++;
              JUMP_LABEL (new) = XEXP (src, 0);
              LABEL_NUSES (XEXP (src, 0))++;
+
+             /* Make sure to copy over REG_NON_LOCAL_GOTO.  */
+             note = find_reg_note (insn, REG_NON_LOCAL_GOTO, 0);
+             if (note)
+               {
+                 XEXP (note, 1) = NULL_RTX;
+                 REG_NOTES (new) = note;
+               }
+
              delete_insn (insn);
              insn = new;
 
              /* Now emit a BARRIER after the unconditional jump.  */
              if (NEXT_INSN (insn) == 0
              delete_insn (insn);
              insn = new;
 
              /* Now emit a BARRIER after the unconditional jump.  */
              if (NEXT_INSN (insn) == 0
-                 || GET_CODE (NEXT_INSN (insn)) != BARRIER)
+                 || !BARRIER_P (NEXT_INSN (insn)))
                emit_barrier_after (insn);
            }
          else
            INSN_CODE (insn) = -1;
 
                emit_barrier_after (insn);
            }
          else
            INSN_CODE (insn) = -1;
 
-         never_reached_warning (insn, NULL);
-
          /* Do not bother deleting any unreachable code,
             let jump/flow do that.  */
 
          /* Do not bother deleting any unreachable code,
             let jump/flow do that.  */
 
@@ -5748,9 +5674,9 @@ cse_insn (rtx insn, rtx libcall_insn)
 
       else if (do_not_record)
        {
 
       else if (do_not_record)
        {
-         if (GET_CODE (dest) == REG || GET_CODE (dest) == SUBREG)
+         if (REG_P (dest) || GET_CODE (dest) == SUBREG)
            invalidate (dest, VOIDmode);
            invalidate (dest, VOIDmode);
-         else if (GET_CODE (dest) == MEM)
+         else if (MEM_P (dest))
            {
              /* Outgoing arguments for a libcall don't
                 affect any recorded expressions.  */
            {
              /* Outgoing arguments for a libcall don't
                 affect any recorded expressions.  */
@@ -5898,7 +5824,7 @@ cse_insn (rtx insn, rtx libcall_insn)
   /* Some registers are invalidated by subroutine calls.  Memory is
      invalidated by non-constant calls.  */
 
   /* Some registers are invalidated by subroutine calls.  Memory is
      invalidated by non-constant calls.  */
 
-  if (GET_CODE (insn) == CALL_INSN)
+  if (CALL_P (insn))
     {
       if (! CONST_OR_PURE_CALL_P (insn))
        invalidate_memory ();
     {
       if (! CONST_OR_PURE_CALL_P (insn))
        invalidate_memory ();
@@ -5921,9 +5847,9 @@ cse_insn (rtx insn, rtx libcall_insn)
           previous quantity's chain.
           Needed for memory if this is a nonvarying address, unless
           we have just done an invalidate_memory that covers even those.  */
           previous quantity's chain.
           Needed for memory if this is a nonvarying address, unless
           we have just done an invalidate_memory that covers even those.  */
-       if (GET_CODE (dest) == REG || GET_CODE (dest) == SUBREG)
+       if (REG_P (dest) || GET_CODE (dest) == SUBREG)
          invalidate (dest, VOIDmode);
          invalidate (dest, VOIDmode);
-       else if (GET_CODE (dest) == MEM)
+       else if (MEM_P (dest))
          {
            /* Outgoing arguments for a libcall don't
               affect any recorded expressions.  */
          {
            /* Outgoing arguments for a libcall don't
               affect any recorded expressions.  */
@@ -5936,7 +5862,7 @@ cse_insn (rtx insn, rtx libcall_insn)
       }
 
   /* A volatile ASM invalidates everything.  */
       }
 
   /* A volatile ASM invalidates everything.  */
-  if (GET_CODE (insn) == INSN
+  if (NONJUMP_INSN_P (insn)
       && GET_CODE (PATTERN (insn)) == ASM_OPERANDS
       && MEM_VOLATILE_P (PATTERN (insn)))
     flush_hash_table ();
       && GET_CODE (PATTERN (insn)) == ASM_OPERANDS
       && MEM_VOLATILE_P (PATTERN (insn)))
     flush_hash_table ();
@@ -5955,7 +5881,7 @@ cse_insn (rtx insn, rtx libcall_insn)
        {
          rtx x = SET_DEST (sets[i].rtl);
 
        {
          rtx x = SET_DEST (sets[i].rtl);
 
-         if (GET_CODE (x) != REG)
+         if (!REG_P (x))
            mention_regs (x);
          else
            {
            mention_regs (x);
          else
            {
@@ -6016,14 +5942,13 @@ cse_insn (rtx insn, rtx libcall_insn)
     if (sets[i].rtl)
       {
        rtx dest = SET_DEST (sets[i].rtl);
     if (sets[i].rtl)
       {
        rtx dest = SET_DEST (sets[i].rtl);
-       rtx inner_dest = sets[i].inner_dest;
        struct table_elt *elt;
 
        /* Don't record value if we are not supposed to risk allocating
           floating-point values in registers that might be wider than
           memory.  */
        if ((flag_float_store
        struct table_elt *elt;
 
        /* Don't record value if we are not supposed to risk allocating
           floating-point values in registers that might be wider than
           memory.  */
        if ((flag_float_store
-            && GET_CODE (dest) == MEM
+            && MEM_P (dest)
             && FLOAT_MODE_P (GET_MODE (dest)))
            /* Don't record BLKmode values, because we don't know the
               size of it, and can't be sure that other BLKmode values
             && FLOAT_MODE_P (GET_MODE (dest)))
            /* Don't record BLKmode values, because we don't know the
               size of it, and can't be sure that other BLKmode values
@@ -6055,7 +5980,7 @@ cse_insn (rtx insn, rtx libcall_insn)
        if (GET_CODE (dest) == STRICT_LOW_PART)
          dest = SUBREG_REG (XEXP (dest, 0));
 
        if (GET_CODE (dest) == STRICT_LOW_PART)
          dest = SUBREG_REG (XEXP (dest, 0));
 
-       if (GET_CODE (dest) == REG || GET_CODE (dest) == SUBREG)
+       if (REG_P (dest) || GET_CODE (dest) == SUBREG)
          /* Registers must also be inserted into chains for quantities.  */
          if (insert_regs (dest, sets[i].src_elt, 1))
            {
          /* Registers must also be inserted into chains for quantities.  */
          if (insert_regs (dest, sets[i].src_elt, 1))
            {
@@ -6065,22 +5990,11 @@ cse_insn (rtx insn, rtx libcall_insn)
              sets[i].dest_hash = HASH (dest, GET_MODE (dest));
            }
 
              sets[i].dest_hash = HASH (dest, GET_MODE (dest));
            }
 
-       if (GET_CODE (inner_dest) == MEM
-           && GET_CODE (XEXP (inner_dest, 0)) == ADDRESSOF)
-         /* Given (SET (MEM (ADDRESSOF (X))) Y) we don't want to say
-            that (MEM (ADDRESSOF (X))) is equivalent to Y.
-            Consider the case in which the address of the MEM is
-            passed to a function, which alters the MEM.  Then, if we
-            later use Y instead of the MEM we'll miss the update.  */
-         elt = insert (dest, 0, sets[i].dest_hash, GET_MODE (dest));
-       else
-         elt = insert (dest, sets[i].src_elt,
-                       sets[i].dest_hash, GET_MODE (dest));
+       elt = insert (dest, sets[i].src_elt,
+                     sets[i].dest_hash, GET_MODE (dest));
 
 
-       elt->in_memory = (GET_CODE (sets[i].inner_dest) == MEM
-                         && (! RTX_UNCHANGING_P (sets[i].inner_dest)
-                             || fixed_base_plus_p (XEXP (sets[i].inner_dest,
-                                                         0))));
+       elt->in_memory = (MEM_P (sets[i].inner_dest)
+                         && !MEM_READONLY_P (sets[i].inner_dest));
 
        /* If we have (set (subreg:m1 (reg:m2 foo) 0) (bar:m1)), M1 is no
           narrower than M2, and both M1 and M2 are the same number of words,
 
        /* If we have (set (subreg:m1 (reg:m2 foo) 0) (bar:m1)), M1 is no
           narrower than M2, and both M1 and M2 are the same number of words,
@@ -6117,8 +6031,8 @@ cse_insn (rtx insn, rtx libcall_insn)
                int byte = 0;
 
                /* Ignore invalid entries.  */
                int byte = 0;
 
                /* Ignore invalid entries.  */
-               if (GET_CODE (elt->exp) != REG
-                   && ! exp_equiv_p (elt->exp, elt->exp, 1, 0))
+               if (!REG_P (elt->exp)
+                   && ! exp_equiv_p (elt->exp, elt->exp, 1, false))
                  continue;
 
                /* We may have already been playing subreg games.  If the
                  continue;
 
                /* We may have already been playing subreg games.  If the
@@ -6170,8 +6084,8 @@ cse_insn (rtx insn, rtx libcall_insn)
                classp = src_elt->first_same_value;
                /* Ignore invalid entries.  */
                while (classp
                classp = src_elt->first_same_value;
                /* Ignore invalid entries.  */
                while (classp
-                      && GET_CODE (classp->exp) != REG
-                      && ! exp_equiv_p (classp->exp, classp->exp, 1, 0))
+                      && !REG_P (classp->exp)
+                      && ! exp_equiv_p (classp->exp, classp->exp, 1, false))
                  classp = classp->next_same_value;
              }
          }
                  classp = classp->next_same_value;
              }
          }
@@ -6194,9 +6108,9 @@ cse_insn (rtx insn, rtx libcall_insn)
      register to be set in the middle of a libcall, and we then get bad code
      if the libcall is deleted.  */
 
      register to be set in the middle of a libcall, and we then get bad code
      if the libcall is deleted.  */
 
-  if (n_sets == 1 && sets[0].rtl && GET_CODE (SET_DEST (sets[0].rtl)) == REG
+  if (n_sets == 1 && sets[0].rtl && REG_P (SET_DEST (sets[0].rtl))
       && NEXT_INSN (PREV_INSN (insn)) == insn
       && NEXT_INSN (PREV_INSN (insn)) == insn
-      && GET_CODE (SET_SRC (sets[0].rtl)) == REG
+      && REG_P (SET_SRC (sets[0].rtl))
       && REGNO (SET_SRC (sets[0].rtl)) >= FIRST_PSEUDO_REGISTER
       && REGNO_QTY_VALID_P (REGNO (SET_SRC (sets[0].rtl))))
     {
       && REGNO (SET_SRC (sets[0].rtl)) >= FIRST_PSEUDO_REGISTER
       && REGNO_QTY_VALID_P (REGNO (SET_SRC (sets[0].rtl))))
     {
@@ -6213,7 +6127,7 @@ cse_insn (rtx insn, rtx libcall_insn)
            {
              prev = PREV_INSN (prev);
            }
            {
              prev = PREV_INSN (prev);
            }
-         while (prev && GET_CODE (prev) == NOTE
+         while (prev && NOTE_P (prev)
                 && NOTE_LINE_NUMBER (prev) != NOTE_INSN_BASIC_BLOCK);
 
          /* Do not swap the registers around if the previous instruction
                 && NOTE_LINE_NUMBER (prev) != NOTE_INSN_BASIC_BLOCK);
 
          /* Do not swap the registers around if the previous instruction
@@ -6228,7 +6142,7 @@ cse_insn (rtx insn, rtx libcall_insn)
             note.  We cannot do that because REG_EQUIV may provide an
             uninitialized stack slot when REG_PARM_STACK_SPACE is used.  */
 
             note.  We cannot do that because REG_EQUIV may provide an
             uninitialized stack slot when REG_PARM_STACK_SPACE is used.  */
 
-         if (prev != 0 && GET_CODE (prev) == INSN
+         if (prev != 0 && NONJUMP_INSN_P (prev)
              && GET_CODE (PATTERN (prev)) == SET
              && SET_DEST (PATTERN (prev)) == SET_SRC (sets[0].rtl)
              && ! find_reg_note (prev, REG_EQUIV, NULL_RTX))
              && GET_CODE (PATTERN (prev)) == SET
              && SET_DEST (PATTERN (prev)) == SET_SRC (sets[0].rtl)
              && ! find_reg_note (prev, REG_EQUIV, NULL_RTX))
@@ -6259,7 +6173,7 @@ cse_insn (rtx insn, rtx libcall_insn)
      the condition being tested.  */
 
   last_jump_equiv_class = 0;
      the condition being tested.  */
 
   last_jump_equiv_class = 0;
-  if (GET_CODE (insn) == JUMP_INSN
+  if (JUMP_P (insn)
       && n_sets == 1 && GET_CODE (x) == SET
       && GET_CODE (SET_SRC (x)) == IF_THEN_ELSE)
     record_jump_equiv (insn, 0);
       && n_sets == 1 && GET_CODE (x) == SET
       && GET_CODE (SET_SRC (x)) == IF_THEN_ELSE)
     record_jump_equiv (insn, 0);
@@ -6268,7 +6182,7 @@ cse_insn (rtx insn, rtx libcall_insn)
   /* If the previous insn set CC0 and this insn no longer references CC0,
      delete the previous insn.  Here we use the fact that nothing expects CC0
      to be valid over an insn, which is true until the final pass.  */
   /* If the previous insn set CC0 and this insn no longer references CC0,
      delete the previous insn.  Here we use the fact that nothing expects CC0
      to be valid over an insn, which is true until the final pass.  */
-  if (prev_insn && GET_CODE (prev_insn) == INSN
+  if (prev_insn && NONJUMP_INSN_P (prev_insn)
       && (tem = single_set (prev_insn)) != 0
       && SET_DEST (tem) == cc0_rtx
       && ! reg_mentioned_p (cc0_rtx, x))
       && (tem = single_set (prev_insn)) != 0
       && SET_DEST (tem) == cc0_rtx
       && ! reg_mentioned_p (cc0_rtx, x))
@@ -6303,8 +6217,8 @@ invalidate_memory (void)
 static int
 addr_affects_sp_p (rtx addr)
 {
 static int
 addr_affects_sp_p (rtx addr)
 {
-  if (GET_RTX_CLASS (GET_CODE (addr)) == 'a'
-      && GET_CODE (XEXP (addr, 0)) == REG
+  if (GET_RTX_CLASS (GET_CODE (addr)) == RTX_AUTOINC
+      && REG_P (XEXP (addr, 0))
       && REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM)
     {
       if (REG_TICK (STACK_POINTER_REGNUM) >= 0)
       && REGNO (XEXP (addr, 0)) == STACK_POINTER_REGNUM)
     {
       if (REG_TICK (STACK_POINTER_REGNUM) >= 0)
@@ -6339,8 +6253,8 @@ invalidate_from_clobbers (rtx x)
       rtx ref = XEXP (x, 0);
       if (ref)
        {
       rtx ref = XEXP (x, 0);
       if (ref)
        {
-         if (GET_CODE (ref) == REG || GET_CODE (ref) == SUBREG
-             || GET_CODE (ref) == MEM)
+         if (REG_P (ref) || GET_CODE (ref) == SUBREG
+             || MEM_P (ref))
            invalidate (ref, VOIDmode);
          else if (GET_CODE (ref) == STRICT_LOW_PART
                   || GET_CODE (ref) == ZERO_EXTRACT)
            invalidate (ref, VOIDmode);
          else if (GET_CODE (ref) == STRICT_LOW_PART
                   || GET_CODE (ref) == ZERO_EXTRACT)
@@ -6356,8 +6270,8 @@ invalidate_from_clobbers (rtx x)
          if (GET_CODE (y) == CLOBBER)
            {
              rtx ref = XEXP (y, 0);
          if (GET_CODE (y) == CLOBBER)
            {
              rtx ref = XEXP (y, 0);
-             if (GET_CODE (ref) == REG || GET_CODE (ref) == SUBREG
-                 || GET_CODE (ref) == MEM)
+             if (REG_P (ref) || GET_CODE (ref) == SUBREG
+                 || MEM_P (ref))
                invalidate (ref, VOIDmode);
              else if (GET_CODE (ref) == STRICT_LOW_PART
                       || GET_CODE (ref) == ZERO_EXTRACT)
                invalidate (ref, VOIDmode);
              else if (GET_CODE (ref) == STRICT_LOW_PART
                       || GET_CODE (ref) == ZERO_EXTRACT)
@@ -6431,7 +6345,7 @@ cse_process_notes (rtx x, rtx object)
 
          if (ent->const_rtx != NULL_RTX
              && (CONSTANT_P (ent->const_rtx)
 
          if (ent->const_rtx != NULL_RTX
              && (CONSTANT_P (ent->const_rtx)
-                 || GET_CODE (ent->const_rtx) == REG))
+                 || REG_P (ent->const_rtx)))
            {
              rtx new = gen_lowpart (GET_MODE (x), ent->const_rtx);
              if (new)
            {
              rtx new = gen_lowpart (GET_MODE (x), ent->const_rtx);
              if (new)
@@ -6478,12 +6392,12 @@ cse_around_loop (rtx loop_start)
   /* If the jump at the end of the loop doesn't go to the start, we don't
      do anything.  */
   for (insn = PREV_INSN (loop_start);
   /* If the jump at the end of the loop doesn't go to the start, we don't
      do anything.  */
   for (insn = PREV_INSN (loop_start);
-       insn && (GET_CODE (insn) == NOTE && NOTE_LINE_NUMBER (insn) >= 0);
+       insn && (NOTE_P (insn) && NOTE_LINE_NUMBER (insn) >= 0);
        insn = PREV_INSN (insn))
     ;
 
   if (insn == 0
        insn = PREV_INSN (insn))
     ;
 
   if (insn == 0
-      || GET_CODE (insn) != NOTE
+      || !NOTE_P (insn)
       || NOTE_LINE_NUMBER (insn) != NOTE_INSN_LOOP_BEG)
     return;
 
       || NOTE_LINE_NUMBER (insn) != NOTE_INSN_LOOP_BEG)
     return;
 
@@ -6495,9 +6409,9 @@ cse_around_loop (rtx loop_start)
     for (p = last_jump_equiv_class->first_same_value; p;
         p = p->next_same_value)
       {
     for (p = last_jump_equiv_class->first_same_value; p;
         p = p->next_same_value)
       {
-       if (GET_CODE (p->exp) == MEM || GET_CODE (p->exp) == REG
+       if (MEM_P (p->exp) || REG_P (p->exp)
            || (GET_CODE (p->exp) == SUBREG
            || (GET_CODE (p->exp) == SUBREG
-               && GET_CODE (SUBREG_REG (p->exp)) == REG))
+               && REG_P (SUBREG_REG (p->exp))))
          invalidate (p->exp, VOIDmode);
        else if (GET_CODE (p->exp) == STRICT_LOW_PART
                 || GET_CODE (p->exp) == ZERO_EXTRACT)
          invalidate (p->exp, VOIDmode);
        else if (GET_CODE (p->exp) == STRICT_LOW_PART
                 || GET_CODE (p->exp) == ZERO_EXTRACT)
@@ -6517,9 +6431,9 @@ cse_around_loop (rtx loop_start)
      accesses by not processing any instructions created after cse started.  */
 
   for (insn = NEXT_INSN (loop_start);
      accesses by not processing any instructions created after cse started.  */
 
   for (insn = NEXT_INSN (loop_start);
-       GET_CODE (insn) != CALL_INSN && GET_CODE (insn) != CODE_LABEL
+       !CALL_P (insn) && !LABEL_P (insn)
        && INSN_UID (insn) < max_insn_uid
        && INSN_UID (insn) < max_insn_uid
-       && ! (GET_CODE (insn) == NOTE
+       && ! (NOTE_P (insn)
             && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END);
        insn = NEXT_INSN (insn))
     {
             && NOTE_LINE_NUMBER (insn) == NOTE_INSN_LOOP_END);
        insn = NEXT_INSN (insn))
     {
@@ -6578,13 +6492,13 @@ invalidate_skipped_block (rtx start)
 {
   rtx insn;
 
 {
   rtx insn;
 
-  for (insn = start; insn && GET_CODE (insn) != CODE_LABEL;
+  for (insn = start; insn && !LABEL_P (insn);
        insn = NEXT_INSN (insn))
     {
       if (! INSN_P (insn))
        continue;
 
        insn = NEXT_INSN (insn))
     {
       if (! INSN_P (insn))
        continue;
 
-      if (GET_CODE (insn) == CALL_INSN)
+      if (CALL_P (insn))
        {
          if (! CONST_OR_PURE_CALL_P (insn))
            invalidate_memory ();
        {
          if (! CONST_OR_PURE_CALL_P (insn))
            invalidate_memory ();
@@ -6609,7 +6523,7 @@ cse_check_loop_start (rtx x, rtx set ATTRIBUTE_UNUSED, void *data)
       || GET_CODE (x) == CC0 || GET_CODE (x) == PC)
     return;
 
       || GET_CODE (x) == CC0 || GET_CODE (x) == PC)
     return;
 
-  if ((GET_CODE (x) == MEM && GET_CODE (*cse_check_loop_start_value) == MEM)
+  if ((MEM_P (x) && MEM_P (*cse_check_loop_start_value))
       || reg_overlap_mentioned_p (x, *cse_check_loop_start_value))
     *cse_check_loop_start_value = NULL_RTX;
 }
       || reg_overlap_mentioned_p (x, *cse_check_loop_start_value))
     *cse_check_loop_start_value = NULL_RTX;
 }
@@ -6640,7 +6554,7 @@ cse_set_around_loop (rtx x, rtx insn, rtx loop_start)
      are setting PC or CC0 or whose SET_SRC is already a register.  */
   if (GET_CODE (x) == SET
       && GET_CODE (SET_DEST (x)) != PC && GET_CODE (SET_DEST (x)) != CC0
      are setting PC or CC0 or whose SET_SRC is already a register.  */
   if (GET_CODE (x) == SET
       && GET_CODE (SET_DEST (x)) != PC && GET_CODE (SET_DEST (x)) != CC0
-      && GET_CODE (SET_SRC (x)) != REG)
+      && !REG_P (SET_SRC (x)))
     {
       src_elt = lookup (SET_SRC (x),
                        HASH (SET_SRC (x), GET_MODE (SET_DEST (x))),
     {
       src_elt = lookup (SET_SRC (x),
                        HASH (SET_SRC (x), GET_MODE (SET_DEST (x))),
@@ -6649,7 +6563,7 @@ cse_set_around_loop (rtx x, rtx insn, rtx loop_start)
       if (src_elt)
        for (src_elt = src_elt->first_same_value; src_elt;
             src_elt = src_elt->next_same_value)
       if (src_elt)
        for (src_elt = src_elt->first_same_value; src_elt;
             src_elt = src_elt->next_same_value)
-         if (GET_CODE (src_elt->exp) == REG && REG_LOOP_TEST_P (src_elt->exp)
+         if (REG_P (src_elt->exp) && REG_LOOP_TEST_P (src_elt->exp)
              && COST (src_elt->exp) < COST (SET_SRC (x)))
            {
              rtx p, set;
              && COST (src_elt->exp) < COST (SET_SRC (x)))
            {
              rtx p, set;
@@ -6659,11 +6573,11 @@ cse_set_around_loop (rtx x, rtx insn, rtx loop_start)
                 a label or CALL_INSN.  */
 
              for (p = prev_nonnote_insn (loop_start);
                 a label or CALL_INSN.  */
 
              for (p = prev_nonnote_insn (loop_start);
-                  p && GET_CODE (p) != CALL_INSN
-                  && GET_CODE (p) != CODE_LABEL;
+                  p && !CALL_P (p)
+                  && !LABEL_P (p);
                   p = prev_nonnote_insn  (p))
                if ((set = single_set (p)) != 0
                   p = prev_nonnote_insn  (p))
                if ((set = single_set (p)) != 0
-                   && GET_CODE (SET_DEST (set)) == REG
+                   && REG_P (SET_DEST (set))
                    && GET_MODE (SET_DEST (set)) == src_elt->mode
                    && rtx_equal_p (SET_SRC (set), SET_SRC (x)))
                  {
                    && GET_MODE (SET_DEST (set)) == src_elt->mode
                    && rtx_equal_p (SET_SRC (set), SET_SRC (x)))
                  {
@@ -6728,8 +6642,8 @@ cse_set_around_loop (rtx x, rtx insn, rtx loop_start)
 
   /* See comment on similar code in cse_insn for explanation of these
      tests.  */
 
   /* See comment on similar code in cse_insn for explanation of these
      tests.  */
-  if (GET_CODE (SET_DEST (x)) == REG || GET_CODE (SET_DEST (x)) == SUBREG
-      || GET_CODE (SET_DEST (x)) == MEM)
+  if (REG_P (SET_DEST (x)) || GET_CODE (SET_DEST (x)) == SUBREG
+      || MEM_P (SET_DEST (x)))
     invalidate (SET_DEST (x), VOIDmode);
   else if (GET_CODE (SET_DEST (x)) == STRICT_LOW_PART
           || GET_CODE (SET_DEST (x)) == ZERO_EXTRACT)
     invalidate (SET_DEST (x), VOIDmode);
   else if (GET_CODE (SET_DEST (x)) == STRICT_LOW_PART
           || GET_CODE (SET_DEST (x)) == ZERO_EXTRACT)
@@ -6750,7 +6664,7 @@ cse_set_around_loop (rtx x, rtx insn, rtx loop_start)
    the current block.  The incoming structure's branch path, if any, is used
    to construct the output branch path.  */
 
    the current block.  The incoming structure's branch path, if any, is used
    to construct the output branch path.  */
 
-void
+static void
 cse_end_of_basic_block (rtx insn, struct cse_basic_block_data *data,
                        int follow_jumps, int after_loop, int skip_blocks)
 {
 cse_end_of_basic_block (rtx insn, struct cse_basic_block_data *data,
                        int follow_jumps, int after_loop, int skip_blocks)
 {
@@ -6763,14 +6677,15 @@ cse_end_of_basic_block (rtx insn, struct cse_basic_block_data *data,
   int i;
 
   /* Update the previous branch path, if any.  If the last branch was
   int i;
 
   /* Update the previous branch path, if any.  If the last branch was
-     previously TAKEN, mark it NOT_TAKEN.  If it was previously NOT_TAKEN,
+     previously PATH_TAKEN, mark it PATH_NOT_TAKEN.
+     If it was previously PATH_NOT_TAKEN,
      shorten the path by one and look at the previous branch.  We know that
      at least one branch must have been taken if PATH_SIZE is nonzero.  */
   while (path_size > 0)
     {
      shorten the path by one and look at the previous branch.  We know that
      at least one branch must have been taken if PATH_SIZE is nonzero.  */
   while (path_size > 0)
     {
-      if (data->path[path_size - 1].status != NOT_TAKEN)
+      if (data->path[path_size - 1].status != PATH_NOT_TAKEN)
        {
        {
-         data->path[path_size - 1].status = NOT_TAKEN;
+         data->path[path_size - 1].status = PATH_NOT_TAKEN;
          break;
        }
       else
          break;
        }
       else
@@ -6787,7 +6702,7 @@ cse_end_of_basic_block (rtx insn, struct cse_basic_block_data *data,
     follow_jumps = skip_blocks = 0;
 
   /* Scan to end of this basic block.  */
     follow_jumps = skip_blocks = 0;
 
   /* Scan to end of this basic block.  */
-  while (p && GET_CODE (p) != CODE_LABEL)
+  while (p && !LABEL_P (p))
     {
       /* Don't cse out the end of a loop.  This makes a difference
         only for the unusual loops that always execute at least once;
     {
       /* Don't cse out the end of a loop.  This makes a difference
         only for the unusual loops that always execute at least once;
@@ -6802,14 +6717,14 @@ cse_end_of_basic_block (rtx insn, struct cse_basic_block_data *data,
         If we are running after loop.c has finished, we can ignore
         the NOTE_INSN_LOOP_END.  */
 
         If we are running after loop.c has finished, we can ignore
         the NOTE_INSN_LOOP_END.  */
 
-      if (! after_loop && GET_CODE (p) == NOTE
+      if (! after_loop && NOTE_P (p)
          && NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_END)
        break;
 
       /* Don't cse over a call to setjmp; on some machines (eg VAX)
         the regs restored by the longjmp come from
         a later time than the setjmp.  */
          && NOTE_LINE_NUMBER (p) == NOTE_INSN_LOOP_END)
        break;
 
       /* Don't cse over a call to setjmp; on some machines (eg VAX)
         the regs restored by the longjmp come from
         a later time than the setjmp.  */
-      if (PREV_INSN (p) && GET_CODE (PREV_INSN (p)) == CALL_INSN
+      if (PREV_INSN (p) && CALL_P (PREV_INSN (p))
          && find_reg_note (PREV_INSN (p), REG_SETJMP, NULL))
        break;
 
          && find_reg_note (PREV_INSN (p), REG_SETJMP, NULL))
        break;
 
@@ -6817,7 +6732,7 @@ cse_end_of_basic_block (rtx insn, struct cse_basic_block_data *data,
         especially if it is really an ASM_OPERANDS.  */
       if (INSN_P (p) && GET_CODE (PATTERN (p)) == PARALLEL)
        nsets += XVECLEN (PATTERN (p), 0);
         especially if it is really an ASM_OPERANDS.  */
       if (INSN_P (p) && GET_CODE (PATTERN (p)) == PARALLEL)
        nsets += XVECLEN (PATTERN (p), 0);
-      else if (GET_CODE (p) != NOTE)
+      else if (!NOTE_P (p))
        nsets += 1;
 
       /* Ignore insns made by CSE; they cannot affect the boundaries of
        nsets += 1;
 
       /* Ignore insns made by CSE; they cannot affect the boundaries of
@@ -6832,7 +6747,7 @@ cse_end_of_basic_block (rtx insn, struct cse_basic_block_data *data,
         take it, do so.  */
       if (path_entry < path_size && data->path[path_entry].branch == p)
        {
         take it, do so.  */
       if (path_entry < path_size && data->path[path_entry].branch == p)
        {
-         if (data->path[path_entry].status != NOT_TAKEN)
+         if (data->path[path_entry].status != PATH_NOT_TAKEN)
            p = JUMP_LABEL (p);
 
          /* Point to next entry in path, if any.  */
            p = JUMP_LABEL (p);
 
          /* Point to next entry in path, if any.  */
@@ -6850,7 +6765,7 @@ cse_end_of_basic_block (rtx insn, struct cse_basic_block_data *data,
         registers set in the block when following the jump.  */
 
       else if ((follow_jumps || skip_blocks) && path_size < PARAM_VALUE (PARAM_MAX_CSE_PATH_LENGTH) - 1
         registers set in the block when following the jump.  */
 
       else if ((follow_jumps || skip_blocks) && path_size < PARAM_VALUE (PARAM_MAX_CSE_PATH_LENGTH) - 1
-              && GET_CODE (p) == JUMP_INSN
+              && JUMP_P (p)
               && GET_CODE (PATTERN (p)) == SET
               && GET_CODE (SET_SRC (PATTERN (p))) == IF_THEN_ELSE
               && JUMP_LABEL (p) != 0
               && GET_CODE (PATTERN (p)) == SET
               && GET_CODE (SET_SRC (PATTERN (p))) == IF_THEN_ELSE
               && JUMP_LABEL (p) != 0
@@ -6858,16 +6773,16 @@ cse_end_of_basic_block (rtx insn, struct cse_basic_block_data *data,
               && NEXT_INSN (JUMP_LABEL (p)) != 0)
        {
          for (q = PREV_INSN (JUMP_LABEL (p)); q; q = PREV_INSN (q))
               && NEXT_INSN (JUMP_LABEL (p)) != 0)
        {
          for (q = PREV_INSN (JUMP_LABEL (p)); q; q = PREV_INSN (q))
-           if ((GET_CODE (q) != NOTE
+           if ((!NOTE_P (q)
                 || NOTE_LINE_NUMBER (q) == NOTE_INSN_LOOP_END
                 || NOTE_LINE_NUMBER (q) == NOTE_INSN_LOOP_END
-                || (PREV_INSN (q) && GET_CODE (PREV_INSN (q)) == CALL_INSN
+                || (PREV_INSN (q) && CALL_P (PREV_INSN (q))
                     && find_reg_note (PREV_INSN (q), REG_SETJMP, NULL)))
                     && find_reg_note (PREV_INSN (q), REG_SETJMP, NULL)))
-               && (GET_CODE (q) != CODE_LABEL || LABEL_NUSES (q) != 0))
+               && (!LABEL_P (q) || LABEL_NUSES (q) != 0))
              break;
 
          /* If we ran into a BARRIER, this code is an extension of the
             basic block when the branch is taken.  */
              break;
 
          /* If we ran into a BARRIER, this code is an extension of the
             basic block when the branch is taken.  */
-         if (follow_jumps && q != 0 && GET_CODE (q) == BARRIER)
+         if (follow_jumps && q != 0 && BARRIER_P (q))
            {
              /* Don't allow ourself to keep walking around an
                 always-executed loop.  */
            {
              /* Don't allow ourself to keep walking around an
                 always-executed loop.  */
@@ -6886,7 +6801,7 @@ cse_end_of_basic_block (rtx insn, struct cse_basic_block_data *data,
                break;
 
              data->path[path_entry].branch = p;
                break;
 
              data->path[path_entry].branch = p;
-             data->path[path_entry++].status = TAKEN;
+             data->path[path_entry++].status = PATH_TAKEN;
 
              /* This branch now ends our path.  It was possible that we
                 didn't see this branch the last time around (when the
 
              /* This branch now ends our path.  It was possible that we
                 didn't see this branch the last time around (when the
@@ -6899,7 +6814,7 @@ cse_end_of_basic_block (rtx insn, struct cse_basic_block_data *data,
              PUT_MODE (NEXT_INSN (p), QImode);
            }
          /* Detect a branch around a block of code.  */
              PUT_MODE (NEXT_INSN (p), QImode);
            }
          /* Detect a branch around a block of code.  */
-         else if (skip_blocks && q != 0 && GET_CODE (q) != CODE_LABEL)
+         else if (skip_blocks && q != 0 && !LABEL_P (q))
            {
              rtx tmp;
 
            {
              rtx tmp;
 
@@ -6919,13 +6834,13 @@ cse_end_of_basic_block (rtx insn, struct cse_basic_block_data *data,
              /* This is no_labels_between_p (p, q) with an added check for
                 reaching the end of a function (in case Q precedes P).  */
              for (tmp = NEXT_INSN (p); tmp && tmp != q; tmp = NEXT_INSN (tmp))
              /* This is no_labels_between_p (p, q) with an added check for
                 reaching the end of a function (in case Q precedes P).  */
              for (tmp = NEXT_INSN (p); tmp && tmp != q; tmp = NEXT_INSN (tmp))
-               if (GET_CODE (tmp) == CODE_LABEL)
+               if (LABEL_P (tmp))
                  break;
 
              if (tmp == q)
                {
                  data->path[path_entry].branch = p;
                  break;
 
              if (tmp == q)
                {
                  data->path[path_entry].branch = p;
-                 data->path[path_entry++].status = AROUND;
+                 data->path[path_entry++].status = PATH_AROUND;
 
                  path_size = path_entry;
 
 
                  path_size = path_entry;
 
@@ -6946,7 +6861,7 @@ cse_end_of_basic_block (rtx insn, struct cse_basic_block_data *data,
   /* If all jumps in the path are not taken, set our path length to zero
      so a rescan won't be done.  */
   for (i = path_size - 1; i >= 0; i--)
   /* If all jumps in the path are not taken, set our path length to zero
      so a rescan won't be done.  */
   for (i = path_size - 1; i >= 0; i--)
-    if (data->path[i].status != NOT_TAKEN)
+    if (data->path[i].status != PATH_NOT_TAKEN)
       break;
 
   if (i == -1)
       break;
 
   if (i == -1)
@@ -6983,7 +6898,7 @@ cse_main (rtx f, int nregs, int after_loop, FILE *file)
   constant_pool_entries_cost = 0;
   constant_pool_entries_regcost = 0;
   val.path_size = 0;
   constant_pool_entries_cost = 0;
   constant_pool_entries_regcost = 0;
   val.path_size = 0;
-  gen_lowpart = gen_lowpart_if_possible;
+  rtl_hooks = cse_rtl_hooks;
 
   init_recog ();
   init_alias_analysis ();
 
   init_recog ();
   init_alias_analysis ();
@@ -7018,7 +6933,7 @@ cse_main (rtx f, int nregs, int after_loop, FILE *file)
 
   for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
     {
 
   for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
     {
-      if (GET_CODE (insn) != NOTE
+      if (!NOTE_P (insn)
          || NOTE_LINE_NUMBER (insn) < 0)
        INSN_CUID (insn) = ++i;
       else
          || NOTE_LINE_NUMBER (insn) < 0)
        INSN_CUID (insn) = ++i;
       else
@@ -7103,7 +7018,7 @@ cse_main (rtx f, int nregs, int after_loop, FILE *file)
   free (uid_cuid);
   free (reg_eqv_table);
   free (val.path);
   free (uid_cuid);
   free (reg_eqv_table);
   free (val.path);
-  gen_lowpart = gen_lowpart_general;
+  rtl_hooks = general_rtl_hooks;
 
   return cse_jumps_altered || recorded_label_ref;
 }
 
   return cse_jumps_altered || recorded_label_ref;
 }
@@ -7135,7 +7050,7 @@ cse_basic_block (rtx from, rtx to, struct branch_path *next_branch,
   new_basic_block ();
 
   /* TO might be a label.  If so, protect it from being deleted.  */
   new_basic_block ();
 
   /* TO might be a label.  If so, protect it from being deleted.  */
-  if (to != 0 && GET_CODE (to) == CODE_LABEL)
+  if (to != 0 && LABEL_P (to))
     ++LABEL_NUSES (to);
 
   for (insn = from; insn != to; insn = NEXT_INSN (insn))
     ++LABEL_NUSES (to);
 
   for (insn = from; insn != to; insn = NEXT_INSN (insn))
@@ -7162,9 +7077,9 @@ cse_basic_block (rtx from, rtx to, struct branch_path *next_branch,
       if (next_branch->branch == insn)
        {
          enum taken status = next_branch++->status;
       if (next_branch->branch == insn)
        {
          enum taken status = next_branch++->status;
-         if (status != NOT_TAKEN)
+         if (status != PATH_NOT_TAKEN)
            {
            {
-             if (status == TAKEN)
+             if (status == PATH_TAKEN)
                record_jump_equiv (insn, 1);
              else
                invalidate_skipped_block (NEXT_INSN (insn));
                record_jump_equiv (insn, 1);
              else
                invalidate_skipped_block (NEXT_INSN (insn));
@@ -7183,7 +7098,7 @@ cse_basic_block (rtx from, rtx to, struct branch_path *next_branch,
       if (GET_MODE (insn) == QImode)
        PUT_MODE (insn, VOIDmode);
 
       if (GET_MODE (insn) == QImode)
        PUT_MODE (insn, VOIDmode);
 
-      if (GET_RTX_CLASS (code) == 'i')
+      if (GET_RTX_CLASS (code) == RTX_INSN)
        {
          rtx p;
 
        {
          rtx p;
 
@@ -7226,7 +7141,7 @@ cse_basic_block (rtx from, rtx to, struct branch_path *next_branch,
            
          /* If we haven't already found an insn where we added a LABEL_REF,
             check this one.  */
            
          /* If we haven't already found an insn where we added a LABEL_REF,
             check this one.  */
-         if (GET_CODE (insn) == INSN && ! recorded_label_ref
+         if (NONJUMP_INSN_P (insn) && ! recorded_label_ref
              && for_each_rtx (&PATTERN (insn), check_for_label_ref,
                               (void *) insn))
            recorded_label_ref = 1;
              && for_each_rtx (&PATTERN (insn), check_for_label_ref,
                               (void *) insn))
            recorded_label_ref = 1;
@@ -7266,7 +7181,7 @@ cse_basic_block (rtx from, rtx to, struct branch_path *next_branch,
         want to count the use in that jump.  */
 
       if (to != 0 && NEXT_INSN (insn) == to
         want to count the use in that jump.  */
 
       if (to != 0 && NEXT_INSN (insn) == to
-         && GET_CODE (to) == CODE_LABEL && --LABEL_NUSES (to) == to_usage)
+         && LABEL_P (to) && --LABEL_NUSES (to) == to_usage)
        {
          struct cse_basic_block_data val;
          rtx prev;
        {
          struct cse_basic_block_data val;
          rtx prev;
@@ -7283,7 +7198,7 @@ cse_basic_block (rtx from, rtx to, struct branch_path *next_branch,
          /* If TO was preceded by a BARRIER we are done with this block
             because it has no continuation.  */
          prev = prev_nonnote_insn (to);
          /* If TO was preceded by a BARRIER we are done with this block
             because it has no continuation.  */
          prev = prev_nonnote_insn (to);
-         if (prev && GET_CODE (prev) == BARRIER)
+         if (prev && BARRIER_P (prev))
            {
              free (qty_table + max_reg);
              return insn;
            {
              free (qty_table + max_reg);
              return insn;
@@ -7310,7 +7225,7 @@ cse_basic_block (rtx from, rtx to, struct branch_path *next_branch,
          to = val.last;
 
          /* Prevent TO from being deleted if it is a label.  */
          to = val.last;
 
          /* Prevent TO from being deleted if it is a label.  */
-         if (to != 0 && GET_CODE (to) == CODE_LABEL)
+         if (to != 0 && LABEL_P (to))
            ++LABEL_NUSES (to);
 
          /* Back up so we process the first insn in the extension.  */
            ++LABEL_NUSES (to);
 
          /* Back up so we process the first insn in the extension.  */
@@ -7330,8 +7245,8 @@ cse_basic_block (rtx from, rtx to, struct branch_path *next_branch,
   if ((cse_jumps_altered == 0
        || (flag_cse_follow_jumps == 0 && flag_cse_skip_blocks == 0))
       && around_loop && to != 0
   if ((cse_jumps_altered == 0
        || (flag_cse_follow_jumps == 0 && flag_cse_skip_blocks == 0))
       && around_loop && to != 0
-      && GET_CODE (to) == NOTE && NOTE_LINE_NUMBER (to) == NOTE_INSN_LOOP_END
-      && GET_CODE (insn) == JUMP_INSN
+      && NOTE_P (to) && NOTE_LINE_NUMBER (to) == NOTE_INSN_LOOP_END
+      && JUMP_P (insn)
       && JUMP_LABEL (insn) != 0
       && LABEL_NUSES (JUMP_LABEL (insn)) == 1)
     cse_around_loop (JUMP_LABEL (insn));
       && JUMP_LABEL (insn) != 0
       && LABEL_NUSES (JUMP_LABEL (insn)) == 1)
     cse_around_loop (JUMP_LABEL (insn));
@@ -7394,13 +7309,13 @@ count_reg_usage (rtx x, int *counts, int incr)
     case CLOBBER:
       /* If we are clobbering a MEM, mark any registers inside the address
          as being used.  */
     case CLOBBER:
       /* If we are clobbering a MEM, mark any registers inside the address
          as being used.  */
-      if (GET_CODE (XEXP (x, 0)) == MEM)
+      if (MEM_P (XEXP (x, 0)))
        count_reg_usage (XEXP (XEXP (x, 0), 0), counts, incr);
       return;
 
     case SET:
       /* Unless we are setting a REG, count everything in SET_DEST.  */
        count_reg_usage (XEXP (XEXP (x, 0), 0), counts, incr);
       return;
 
     case SET:
       /* Unless we are setting a REG, count everything in SET_DEST.  */
-      if (GET_CODE (SET_DEST (x)) != REG)
+      if (!REG_P (SET_DEST (x)))
        count_reg_usage (SET_DEST (x), counts, incr);
       count_reg_usage (SET_SRC (x), counts, incr);
       return;
        count_reg_usage (SET_DEST (x), counts, incr);
       count_reg_usage (SET_SRC (x), counts, incr);
       return;
@@ -7490,15 +7405,10 @@ set_live_p (rtx set, rtx insn ATTRIBUTE_UNUSED, /* Only used with HAVE_cc0.  */
               || !reg_referenced_p (cc0_rtx, PATTERN (tem))))
     return false;
 #endif
               || !reg_referenced_p (cc0_rtx, PATTERN (tem))))
     return false;
 #endif
-  else if (GET_CODE (SET_DEST (set)) != REG
+  else if (!REG_P (SET_DEST (set))
           || REGNO (SET_DEST (set)) < FIRST_PSEUDO_REGISTER
           || counts[REGNO (SET_DEST (set))] != 0
           || REGNO (SET_DEST (set)) < FIRST_PSEUDO_REGISTER
           || counts[REGNO (SET_DEST (set))] != 0
-          || side_effects_p (SET_SRC (set))
-          /* An ADDRESSOF expression can turn into a use of the
-             internal arg pointer, so always consider the
-             internal arg pointer live.  If it is truly dead,
-             flow will delete the initializing insn.  */
-          || (SET_DEST (set) == current_function_internal_arg_pointer))
+          || side_effects_p (SET_SRC (set)))
     return true;
   return false;
 }
     return true;
   return false;
 }
@@ -7662,8 +7572,8 @@ delete_trivially_dead_insns (rtx insns, int nreg)
     }
   while (ndead != nlastdead);
 
     }
   while (ndead != nlastdead);
 
-  if (rtl_dump_file && ndead)
-    fprintf (rtl_dump_file, "Deleted %i trivially dead insns; %i iterations\n",
+  if (dump_file && ndead)
+    fprintf (dump_file, "Deleted %i trivially dead insns; %i iterations\n",
             ndead, niterations);
   /* Clean up.  */
   free (counts);
             ndead, niterations);
   /* Clean up.  */
   free (counts);
@@ -7682,7 +7592,7 @@ cse_change_cc_mode (rtx *loc, void *data)
   rtx newreg = (rtx) data;
 
   if (*loc
   rtx newreg = (rtx) data;
 
   if (*loc
-      && GET_CODE (*loc) == REG
+      && REG_P (*loc)
       && REGNO (*loc) == REGNO (newreg)
       && GET_MODE (*loc) != GET_MODE (newreg))
     {
       && REGNO (*loc) == REGNO (newreg)
       && GET_MODE (*loc) != GET_MODE (newreg))
     {
@@ -7694,7 +7604,7 @@ cse_change_cc_mode (rtx *loc, void *data)
 
 /* Change the mode of any reference to the register REGNO (NEWREG) to
    GET_MODE (NEWREG), starting at START.  Stop before END.  Stop at
 
 /* Change the mode of any reference to the register REGNO (NEWREG) to
    GET_MODE (NEWREG), starting at START.  Stop before END.  Stop at
-   any instruction after START which modifies NEWREG.  */
+   any instruction which modifies NEWREG.  */
 
 static void
 cse_change_cc_mode_insns (rtx start, rtx end, rtx newreg)
 
 static void
 cse_change_cc_mode_insns (rtx start, rtx end, rtx newreg)
@@ -7706,7 +7616,7 @@ cse_change_cc_mode_insns (rtx start, rtx end, rtx newreg)
       if (! INSN_P (insn))
        continue;
 
       if (! INSN_P (insn))
        continue;
 
-      if (insn != start && reg_set_p (newreg, insn))
+      if (reg_set_p (newreg, insn))
        return;
 
       for_each_rtx (&PATTERN (insn), cse_change_cc_mode, newreg);
        return;
 
       for_each_rtx (&PATTERN (insn), cse_change_cc_mode, newreg);
@@ -7778,7 +7688,7 @@ cse_cc_succs (basic_block bb, rtx cc_reg, rtx cc_src, bool can_change_mode)
          /* Check whether INSN sets CC_REG to CC_SRC.  */
          set = single_set (insn);
          if (set
          /* Check whether INSN sets CC_REG to CC_SRC.  */
          set = single_set (insn);
          if (set
-             && GET_CODE (SET_DEST (set)) == REG
+             && REG_P (SET_DEST (set))
              && REGNO (SET_DEST (set)) == REGNO (cc_reg))
            {
              bool found;
              && REGNO (SET_DEST (set)) == REGNO (cc_reg))
            {
              bool found;
@@ -7799,7 +7709,7 @@ cse_cc_succs (basic_block bb, rtx cc_reg, rtx cc_src, bool can_change_mode)
                                       XEXP (SET_SRC (set), 1)))
                           
                {
                                       XEXP (SET_SRC (set), 1)))
                           
                {
-                 comp_mode = (*targetm.cc_modes_compatible) (mode, set_mode);
+                 comp_mode = targetm.cc_modes_compatible (mode, set_mode);
                  if (comp_mode != VOIDmode
                      && (can_change_mode || comp_mode == mode))
                    found = true;
                  if (comp_mode != VOIDmode
                      && (can_change_mode || comp_mode == mode))
                    found = true;
@@ -7917,7 +7827,7 @@ cse_condition_code_reg (void)
   rtx cc_reg_2;
   basic_block bb;
 
   rtx cc_reg_2;
   basic_block bb;
 
-  if (! (*targetm.fixed_condition_code_regs) (&cc_regno_1, &cc_regno_2))
+  if (! targetm.fixed_condition_code_regs (&cc_regno_1, &cc_regno_2))
     return;
 
   cc_reg_1 = gen_rtx_REG (CCmode, cc_regno_1);
     return;
 
   cc_reg_1 = gen_rtx_REG (CCmode, cc_regno_1);
@@ -7946,7 +7856,7 @@ cse_condition_code_reg (void)
         to optimize.  */
 
       last_insn = BB_END (bb);
         to optimize.  */
 
       last_insn = BB_END (bb);
-      if (GET_CODE (last_insn) != JUMP_INSN)
+      if (!JUMP_P (last_insn))
        continue;
 
       if (reg_referenced_p (cc_reg_1, PATTERN (last_insn)))
        continue;
 
       if (reg_referenced_p (cc_reg_1, PATTERN (last_insn)))
@@ -7968,7 +7878,7 @@ cse_condition_code_reg (void)
            continue;
          set = single_set (insn);
          if (set
            continue;
          set = single_set (insn);
          if (set
-             && GET_CODE (SET_DEST (set)) == REG
+             && REG_P (SET_DEST (set))
              && REGNO (SET_DEST (set)) == REGNO (cc_reg))
            {
              cc_src_insn = insn;
              && REGNO (SET_DEST (set)) == REGNO (cc_reg))
            {
              cc_src_insn = insn;
@@ -7998,8 +7908,22 @@ cse_condition_code_reg (void)
          if (mode != GET_MODE (cc_src))
            abort ();
          if (mode != orig_mode)
          if (mode != GET_MODE (cc_src))
            abort ();
          if (mode != orig_mode)
-           cse_change_cc_mode_insns (cc_src_insn, NEXT_INSN (last_insn),
-                                     gen_rtx_REG (mode, REGNO (cc_reg)));
+           {
+             rtx newreg = gen_rtx_REG (mode, REGNO (cc_reg));
+
+             /* Change the mode of CC_REG in CC_SRC_INSN to
+                GET_MODE (NEWREG).  */
+             for_each_rtx (&PATTERN (cc_src_insn), cse_change_cc_mode,
+                           newreg);
+             for_each_rtx (&REG_NOTES (cc_src_insn), cse_change_cc_mode,
+                           newreg);
+
+             /* Do the same in the following insns that use the
+                current value of CC_REG within BB.  */
+             cse_change_cc_mode_insns (NEXT_INSN (cc_src_insn),
+                                       NEXT_INSN (last_insn),
+                                       newreg);
+           }
        }
     }
 }
        }
     }
 }