OSDN Git Service

2010-06-18 Jerry DeLisle <jvdelisle@gcc.gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / postreload.c
index 16dec22..c165b52 100644 (file)
@@ -1,13 +1,13 @@
 /* Perform simple optimizations to clean up the result of reload.
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
 /* Perform simple optimizations to clean up the result of reload.
    Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997,
-   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
-   Free Software Foundation, Inc.
+   1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
+   2010 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
-Software Foundation; either version 2, or (at your option) any later
+Software Foundation; either version 3, or (at your option) any later
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
 version.
 
 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -16,9 +16,8 @@ FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 for more details.
 
 You should have received a copy of the GNU General Public License
 for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to the Free
-Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
-02110-1301, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 #include "config.h"
 #include "system.h"
 
 #include "config.h"
 #include "system.h"
@@ -41,7 +40,6 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "recog.h"
 #include "output.h"
 #include "cselib.h"
 #include "recog.h"
 #include "output.h"
 #include "cselib.h"
-#include "real.h"
 #include "toplev.h"
 #include "except.h"
 #include "tree.h"
 #include "toplev.h"
 #include "except.h"
 #include "tree.h"
@@ -58,10 +56,10 @@ static int reload_cse_simplify_operands (rtx, rtx);
 
 static void reload_combine (void);
 static void reload_combine_note_use (rtx *, rtx);
 
 static void reload_combine (void);
 static void reload_combine_note_use (rtx *, rtx);
-static void reload_combine_note_store (rtx, rtx, void *);
+static void reload_combine_note_store (rtx, const_rtx, void *);
 
 static void reload_cse_move2add (rtx);
 
 static void reload_cse_move2add (rtx);
-static void move2add_note_store (rtx, rtx, void *);
+static void move2add_note_store (rtx, const_rtx, void *);
 
 /* Call cse / combine like post-reload optimization phases.
    FIRST is the first instruction.  */
 
 /* Call cse / combine like post-reload optimization phases.
    FIRST is the first instruction.  */
@@ -199,7 +197,7 @@ reload_cse_regs_1 (rtx first)
   rtx insn;
   rtx testreg = gen_rtx_REG (VOIDmode, -1);
 
   rtx insn;
   rtx testreg = gen_rtx_REG (VOIDmode, -1);
 
-  cselib_init (true);
+  cselib_init (CSELIB_RECORD_MEMORY);
   init_alias_analysis ();
 
   for (insn = first; insn; insn = NEXT_INSN (insn))
   init_alias_analysis ();
 
   for (insn = first; insn; insn = NEXT_INSN (insn))
@@ -234,6 +232,7 @@ reload_cse_simplify_set (rtx set, rtx insn)
 #ifdef LOAD_EXTEND_OP
   enum rtx_code extend_op = UNKNOWN;
 #endif
 #ifdef LOAD_EXTEND_OP
   enum rtx_code extend_op = UNKNOWN;
 #endif
+  bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
 
   dreg = true_regnum (SET_DEST (set));
   if (dreg < 0)
 
   dreg = true_regnum (SET_DEST (set));
   if (dreg < 0)
@@ -263,12 +262,12 @@ reload_cse_simplify_set (rtx set, rtx insn)
 
   /* If memory loads are cheaper than register copies, don't change them.  */
   if (MEM_P (src))
 
   /* If memory loads are cheaper than register copies, don't change them.  */
   if (MEM_P (src))
-    old_cost = MEMORY_MOVE_COST (GET_MODE (src), dclass, 1);
+    old_cost = memory_move_cost (GET_MODE (src), dclass, true);
   else if (REG_P (src))
     old_cost = REGISTER_MOVE_COST (GET_MODE (src),
                                   REGNO_REG_CLASS (REGNO (src)), dclass);
   else
   else if (REG_P (src))
     old_cost = REGISTER_MOVE_COST (GET_MODE (src),
                                   REGNO_REG_CLASS (REGNO (src)), dclass);
   else
-    old_cost = rtx_cost (src, SET);
+    old_cost = rtx_cost (src, SET, speed);
 
   for (l = val->locs; l; l = l->next)
     {
 
   for (l = val->locs; l; l = l->next)
     {
@@ -284,7 +283,7 @@ reload_cse_simplify_set (rtx set, rtx insn)
 
              /* ??? I'm lazy and don't wish to handle CONST_DOUBLE.  Other
                 constants, such as SYMBOL_REF, cannot be extended.  */
 
              /* ??? I'm lazy and don't wish to handle CONST_DOUBLE.  Other
                 constants, such as SYMBOL_REF, cannot be extended.  */
-             if (GET_CODE (this_rtx) != CONST_INT)
+             if (!CONST_INT_P (this_rtx))
                continue;
 
              this_val = INTVAL (this_rtx);
                continue;
 
              this_val = INTVAL (this_rtx);
@@ -303,7 +302,7 @@ reload_cse_simplify_set (rtx set, rtx insn)
              this_rtx = GEN_INT (this_val);
            }
 #endif
              this_rtx = GEN_INT (this_val);
            }
 #endif
-         this_cost = rtx_cost (this_rtx, SET);
+         this_cost = rtx_cost (this_rtx, SET, speed);
        }
       else if (REG_P (this_rtx))
        {
        }
       else if (REG_P (this_rtx))
        {
@@ -311,7 +310,7 @@ reload_cse_simplify_set (rtx set, rtx insn)
          if (extend_op != UNKNOWN)
            {
              this_rtx = gen_rtx_fmt_e (extend_op, word_mode, this_rtx);
          if (extend_op != UNKNOWN)
            {
              this_rtx = gen_rtx_fmt_e (extend_op, word_mode, this_rtx);
-             this_cost = rtx_cost (this_rtx, SET);
+             this_cost = rtx_cost (this_rtx, SET, speed);
            }
          else
 #endif
            }
          else
 #endif
@@ -395,9 +394,9 @@ reload_cse_simplify_operands (rtx insn, rtx testreg)
   if (! constrain_operands (1))
     fatal_insn_not_found (insn);
 
   if (! constrain_operands (1))
     fatal_insn_not_found (insn);
 
-  alternative_reject = alloca (recog_data.n_alternatives * sizeof (int));
-  alternative_nregs = alloca (recog_data.n_alternatives * sizeof (int));
-  alternative_order = alloca (recog_data.n_alternatives * sizeof (int));
+  alternative_reject = XALLOCAVEC (int, recog_data.n_alternatives);
+  alternative_nregs = XALLOCAVEC (int, recog_data.n_alternatives);
+  alternative_order = XALLOCAVEC (int, recog_data.n_alternatives);
   memset (alternative_reject, 0, recog_data.n_alternatives * sizeof (int));
   memset (alternative_nregs, 0, recog_data.n_alternatives * sizeof (int));
 
   memset (alternative_reject, 0, recog_data.n_alternatives * sizeof (int));
   memset (alternative_nregs, 0, recog_data.n_alternatives * sizeof (int));
 
@@ -407,7 +406,6 @@ reload_cse_simplify_operands (rtx insn, rtx testreg)
       cselib_val *v;
       struct elt_loc_list *l;
       rtx op;
       cselib_val *v;
       struct elt_loc_list *l;
       rtx op;
-      enum machine_mode mode;
 
       CLEAR_HARD_REG_SET (equiv_regs[i]);
 
 
       CLEAR_HARD_REG_SET (equiv_regs[i]);
 
@@ -420,11 +418,10 @@ reload_cse_simplify_operands (rtx insn, rtx testreg)
        continue;
 
       op = recog_data.operand[i];
        continue;
 
       op = recog_data.operand[i];
-      mode = GET_MODE (op);
 #ifdef LOAD_EXTEND_OP
       if (MEM_P (op)
 #ifdef LOAD_EXTEND_OP
       if (MEM_P (op)
-         && GET_MODE_BITSIZE (mode) < BITS_PER_WORD
-         && LOAD_EXTEND_OP (mode) != UNKNOWN)
+         && GET_MODE_BITSIZE (GET_MODE (op)) < BITS_PER_WORD
+         && LOAD_EXTEND_OP (GET_MODE (op)) != UNKNOWN)
        {
          rtx set = single_set (insn);
 
        {
          rtx set = single_set (insn);
 
@@ -457,7 +454,7 @@ reload_cse_simplify_operands (rtx insn, rtx testreg)
                   && SET_DEST (set) == recog_data.operand[1-i])
            {
              validate_change (insn, recog_data.operand_loc[i],
                   && SET_DEST (set) == recog_data.operand[1-i])
            {
              validate_change (insn, recog_data.operand_loc[i],
-                              gen_rtx_fmt_e (LOAD_EXTEND_OP (mode),
+                              gen_rtx_fmt_e (LOAD_EXTEND_OP (GET_MODE (op)),
                                              word_mode, op),
                               1);
              validate_change (insn, recog_data.operand_loc[1-i],
                                              word_mode, op),
                               1);
              validate_change (insn, recog_data.operand_loc[1-i],
@@ -488,7 +485,7 @@ reload_cse_simplify_operands (rtx insn, rtx testreg)
       int regno;
       const char *p;
 
       int regno;
       const char *p;
 
-      op_alt_regno[i] = alloca (recog_data.n_alternatives * sizeof (int));
+      op_alt_regno[i] = XALLOCAVEC (int, recog_data.n_alternatives);
       for (j = 0; j < recog_data.n_alternatives; j++)
        op_alt_regno[i][j] = -1;
 
       for (j = 0; j < recog_data.n_alternatives; j++)
        op_alt_regno[i][j] = -1;
 
@@ -519,7 +516,7 @@ reload_cse_simplify_operands (rtx insn, rtx testreg)
 
       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
        {
 
       for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
        {
-         int class = (int) NO_REGS;
+         enum reg_class rclass = NO_REGS;
 
          if (! TEST_HARD_REG_BIT (equiv_regs[i], regno))
            continue;
 
          if (! TEST_HARD_REG_BIT (equiv_regs[i], regno))
            continue;
@@ -543,23 +540,23 @@ reload_cse_simplify_operands (rtx insn, rtx testreg)
                case '*':  case '%':
                case '0':  case '1':  case '2':  case '3':  case '4':
                case '5':  case '6':  case '7':  case '8':  case '9':
                case '*':  case '%':
                case '0':  case '1':  case '2':  case '3':  case '4':
                case '5':  case '6':  case '7':  case '8':  case '9':
-               case 'm':  case '<':  case '>':  case 'V':  case 'o':
+               case '<':  case '>':  case 'V':  case 'o':
                case 'E':  case 'F':  case 'G':  case 'H':
                case 's':  case 'i':  case 'n':
                case 'I':  case 'J':  case 'K':  case 'L':
                case 'M':  case 'N':  case 'O':  case 'P':
                case 'E':  case 'F':  case 'G':  case 'H':
                case 's':  case 'i':  case 'n':
                case 'I':  case 'J':  case 'K':  case 'L':
                case 'M':  case 'N':  case 'O':  case 'P':
-               case 'p': case 'X':
+               case 'p':  case 'X':  case TARGET_MEM_CONSTRAINT:
                  /* These don't say anything we care about.  */
                  break;
 
                case 'g': case 'r':
                  /* These don't say anything we care about.  */
                  break;
 
                case 'g': case 'r':
-                 class = reg_class_subunion[(int) class][(int) GENERAL_REGS];
+                 rclass = reg_class_subunion[(int) rclass][(int) GENERAL_REGS];
                  break;
 
                default:
                  break;
 
                default:
-                 class
+                 rclass
                    = (reg_class_subunion
                    = (reg_class_subunion
-                      [(int) class]
+                      [(int) rclass]
                       [(int) REG_CLASS_FROM_CONSTRAINT ((unsigned char) c, p)]);
                  break;
 
                       [(int) REG_CLASS_FROM_CONSTRAINT ((unsigned char) c, p)]);
                  break;
 
@@ -569,16 +566,18 @@ reload_cse_simplify_operands (rtx insn, rtx testreg)
                     alternative yet and the operand being replaced is not
                     a cheap CONST_INT.  */
                  if (op_alt_regno[i][j] == -1
                     alternative yet and the operand being replaced is not
                     a cheap CONST_INT.  */
                  if (op_alt_regno[i][j] == -1
-                     && reg_fits_class_p (testreg, class, 0, mode)
-                     && (GET_CODE (recog_data.operand[i]) != CONST_INT
-                         || (rtx_cost (recog_data.operand[i], SET)
-                             > rtx_cost (testreg, SET))))
+                     && reg_fits_class_p (testreg, rclass, 0, mode)
+                     && (!CONST_INT_P (recog_data.operand[i])
+                         || (rtx_cost (recog_data.operand[i], SET,
+                                       optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn)))
+                             > rtx_cost (testreg, SET,
+                                       optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn))))))
                    {
                      alternative_nregs[j]++;
                      op_alt_regno[i][j] = regno;
                    }
                  j++;
                    {
                      alternative_nregs[j]++;
                      op_alt_regno[i][j] = regno;
                    }
                  j++;
-                 class = (int) NO_REGS;
+                 rclass = NO_REGS;
                  break;
                }
              p += CONSTRAINT_LEN (c, p);
                  break;
                }
              p += CONSTRAINT_LEN (c, p);
@@ -662,7 +661,7 @@ reload_cse_simplify_operands (rtx insn, rtx testreg)
    replace them with reg+reg addressing.  */
 #define RELOAD_COMBINE_MAX_USES 6
 
    replace them with reg+reg addressing.  */
 #define RELOAD_COMBINE_MAX_USES 6
 
-/* INSN is the insn where a register has ben used, and USEP points to the
+/* INSN is the insn where a register has been used, and USEP points to the
    location of the register within the rtl.  */
 struct reg_use { rtx insn, *usep; };
 
    location of the register within the rtl.  */
 struct reg_use { rtx insn, *usep; };
 
@@ -792,7 +791,7 @@ reload_combine (void)
         ... (MEM (PLUS (REGZ) (REGY)))... .
 
         First, check that we have (set (REGX) (PLUS (REGX) (REGY)))
         ... (MEM (PLUS (REGZ) (REGY)))... .
 
         First, check that we have (set (REGX) (PLUS (REGX) (REGY)))
-        and that we know all uses of REGX before it dies.  
+        and that we know all uses of REGX before it dies.
         Also, explicitly check that REGX != REGY; our life information
         does not yet show whether REGY changes in this insn.  */
       set = single_set (insn);
         Also, explicitly check that REGX != REGY; our life information
         does not yet show whether REGY changes in this insn.  */
       set = single_set (insn);
@@ -813,22 +812,19 @@ reload_combine (void)
          rtx prev = prev_nonnote_insn (insn);
          rtx prev_set = prev ? single_set (prev) : NULL_RTX;
          unsigned int regno = REGNO (reg);
          rtx prev = prev_nonnote_insn (insn);
          rtx prev_set = prev ? single_set (prev) : NULL_RTX;
          unsigned int regno = REGNO (reg);
-         rtx const_reg = NULL_RTX;
+         rtx index_reg = NULL_RTX;
          rtx reg_sum = NULL_RTX;
 
          rtx reg_sum = NULL_RTX;
 
-         /* Now, we need an index register.
-            We'll set index_reg to this index register, const_reg to the
-            register that is to be loaded with the constant
-            (denoted as REGZ in the substitution illustration above),
-            and reg_sum to the register-register that we want to use to
-            substitute uses of REG (typically in MEMs) with.
-            First check REG and BASE for being index registers;
-            we can use them even if they are not dead.  */
+         /* Now we need to set INDEX_REG to an index register (denoted as
+            REGZ in the illustration above) and REG_SUM to the expression
+            register+register that we want to use to substitute uses of REG
+            (typically in MEMs) with.  First check REG and BASE for being
+            index registers; we can use them even if they are not dead.  */
          if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], regno)
              || TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS],
                                    REGNO (base)))
            {
          if (TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS], regno)
              || TEST_HARD_REG_BIT (reg_class_contents[INDEX_REG_CLASS],
                                    REGNO (base)))
            {
-             const_reg = reg;
+             index_reg = reg;
              reg_sum = plus;
            }
          else
              reg_sum = plus;
            }
          else
@@ -845,9 +841,7 @@ reload_combine (void)
                      && reg_state[i].store_ruid <= reg_state[regno].use_ruid
                      && hard_regno_nregs[i][GET_MODE (reg)] == 1)
                    {
                      && reg_state[i].store_ruid <= reg_state[regno].use_ruid
                      && hard_regno_nregs[i][GET_MODE (reg)] == 1)
                    {
-                     rtx index_reg = gen_rtx_REG (GET_MODE (reg), i);
-
-                     const_reg = index_reg;
+                     index_reg = gen_rtx_REG (GET_MODE (reg), i);
                      reg_sum = gen_rtx_PLUS (GET_MODE (reg), index_reg, base);
                      break;
                    }
                      reg_sum = gen_rtx_PLUS (GET_MODE (reg), index_reg, base);
                      break;
                    }
@@ -857,19 +851,19 @@ reload_combine (void)
          /* Check that PREV_SET is indeed (set (REGX) (CONST_INT)) and that
             (REGY), i.e. BASE, is not clobbered before the last use we'll
             create.  */
          /* Check that PREV_SET is indeed (set (REGX) (CONST_INT)) and that
             (REGY), i.e. BASE, is not clobbered before the last use we'll
             create.  */
-         if (prev_set != 0
-             && GET_CODE (SET_SRC (prev_set)) == CONST_INT
+         if (reg_sum
+             && prev_set
+             && CONST_INT_P (SET_SRC (prev_set))
              && rtx_equal_p (SET_DEST (prev_set), reg)
              && reg_state[regno].use_index >= 0
              && (reg_state[REGNO (base)].store_ruid
              && rtx_equal_p (SET_DEST (prev_set), reg)
              && reg_state[regno].use_index >= 0
              && (reg_state[REGNO (base)].store_ruid
-                 <= reg_state[regno].use_ruid)
-             && reg_sum != 0)
+                 <= reg_state[regno].use_ruid))
            {
              int i;
 
            {
              int i;
 
-             /* Change destination register and, if necessary, the
-                constant value in PREV, the constant loading instruction.  */
-             validate_change (prev, &SET_DEST (prev_set), const_reg, 1);
+             /* Change destination register and, if necessary, the constant
+                value in PREV, the constant loading instruction.  */
+             validate_change (prev, &SET_DEST (prev_set), index_reg, 1);
              if (reg_state[regno].offset != const0_rtx)
                validate_change (prev,
                                 &SET_SRC (prev_set),
              if (reg_state[regno].offset != const0_rtx)
                validate_change (prev,
                                 &SET_SRC (prev_set),
@@ -889,6 +883,19 @@ reload_combine (void)
 
              if (apply_change_group ())
                {
 
              if (apply_change_group ())
                {
+                 /* For every new use of REG_SUM, we have to record the use
+                    of BASE therein, i.e. operand 1.  */
+                 for (i = reg_state[regno].use_index;
+                      i < RELOAD_COMBINE_MAX_USES; i++)
+                   reload_combine_note_use
+                     (&XEXP (*reg_state[regno].reg_use[i].usep, 1),
+                      reg_state[regno].reg_use[i].insn);
+
+                 if (reg_state[REGNO (base)].use_ruid
+                     > reg_state[regno].use_ruid)
+                   reg_state[REGNO (base)].use_ruid
+                     = reg_state[regno].use_ruid;
+
                  /* Delete the reg-reg addition.  */
                  delete_insn (insn);
 
                  /* Delete the reg-reg addition.  */
                  delete_insn (insn);
 
@@ -898,7 +905,7 @@ reload_combine (void)
                    remove_reg_equal_equiv_notes (prev);
 
                  reg_state[regno].use_index = RELOAD_COMBINE_MAX_USES;
                    remove_reg_equal_equiv_notes (prev);
 
                  reg_state[regno].use_index = RELOAD_COMBINE_MAX_USES;
-                 reg_state[REGNO (const_reg)].store_ruid
+                 reg_state[REGNO (index_reg)].store_ruid
                    = reload_combine_ruid;
                  continue;
                }
                    = reload_combine_ruid;
                  continue;
                }
@@ -981,7 +988,7 @@ reload_combine (void)
    accordingly.  Called via note_stores from reload_combine.  */
 
 static void
    accordingly.  Called via note_stores from reload_combine.  */
 
 static void
-reload_combine_note_store (rtx dst, rtx set, void *data ATTRIBUTE_UNUSED)
+reload_combine_note_store (rtx dst, const_rtx set, void *data ATTRIBUTE_UNUSED)
 {
   int regno = 0;
   int i;
 {
   int regno = 0;
   int i;
@@ -1072,7 +1079,7 @@ reload_combine_note_use (rtx *xp, rtx insn)
     case PLUS:
       /* We are interested in (plus (reg) (const_int)) .  */
       if (!REG_P (XEXP (x, 0))
     case PLUS:
       /* We are interested in (plus (reg) (const_int)) .  */
       if (!REG_P (XEXP (x, 0))
-         || GET_CODE (XEXP (x, 1)) != CONST_INT)
+         || !CONST_INT_P (XEXP (x, 1)))
        break;
       offset = XEXP (x, 1);
       x = XEXP (x, 0);
        break;
       offset = XEXP (x, 1);
       x = XEXP (x, 0);
@@ -1237,10 +1244,12 @@ reload_cse_move2add (rtx first)
                                  (set (STRICT_LOW_PART (REGX)) (CONST_INT B))
              */
 
                                  (set (STRICT_LOW_PART (REGX)) (CONST_INT B))
              */
 
-             if (GET_CODE (src) == CONST_INT && reg_base_reg[regno] < 0)
+             if (CONST_INT_P (src) && reg_base_reg[regno] < 0)
                {
                  rtx new_src = gen_int_mode (INTVAL (src) - reg_offset[regno],
                                              GET_MODE (reg));
                {
                  rtx new_src = gen_int_mode (INTVAL (src) - reg_offset[regno],
                                              GET_MODE (reg));
+                 bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
+
                  /* (set (reg) (plus (reg) (const_int 0))) is not canonical;
                     use (set (reg) (reg)) instead.
                     We don't delete this insn, nor do we convert it into a
                  /* (set (reg) (plus (reg) (const_int 0))) is not canonical;
                     use (set (reg) (reg)) instead.
                     We don't delete this insn, nor do we convert it into a
@@ -1256,7 +1265,7 @@ reload_cse_move2add (rtx first)
                      if (INTVAL (src) == reg_offset [regno])
                        validate_change (insn, &SET_SRC (pat), reg, 0);
                    }
                      if (INTVAL (src) == reg_offset [regno])
                        validate_change (insn, &SET_SRC (pat), reg, 0);
                    }
-                 else if (rtx_cost (new_src, PLUS) < rtx_cost (src, SET)
+                 else if (rtx_cost (new_src, PLUS, speed) < rtx_cost (src, SET, speed)
                           && have_add2_insn (reg, new_src))
                    {
                      rtx tem = gen_rtx_PLUS (GET_MODE (reg), reg, new_src);
                           && have_add2_insn (reg, new_src))
                    {
                      rtx tem = gen_rtx_PLUS (GET_MODE (reg), reg, new_src);
@@ -1321,7 +1330,7 @@ reload_cse_move2add (rtx first)
                      && SET_DEST (set) == reg
                      && GET_CODE (SET_SRC (set)) == PLUS
                      && XEXP (SET_SRC (set), 0) == reg
                      && SET_DEST (set) == reg
                      && GET_CODE (SET_SRC (set)) == PLUS
                      && XEXP (SET_SRC (set), 0) == reg
-                     && GET_CODE (XEXP (SET_SRC (set), 1)) == CONST_INT)
+                     && CONST_INT_P (XEXP (SET_SRC (set), 1)))
                    {
                      rtx src3 = XEXP (SET_SRC (set), 1);
                      HOST_WIDE_INT added_offset = INTVAL (src3);
                    {
                      rtx src3 = XEXP (SET_SRC (set), 1);
                      HOST_WIDE_INT added_offset = INTVAL (src3);
@@ -1332,14 +1341,15 @@ reload_cse_move2add (rtx first)
                                      + base_offset
                                      - regno_offset,
                                      GET_MODE (reg));
                                      + base_offset
                                      - regno_offset,
                                      GET_MODE (reg));
-                     int success = 0;
+                     bool success = false;
+                     bool speed = optimize_bb_for_speed_p (BLOCK_FOR_INSN (insn));
 
                      if (new_src == const0_rtx)
                        /* See above why we create (set (reg) (reg)) here.  */
                        success
                          = validate_change (next, &SET_SRC (set), reg, 0);
 
                      if (new_src == const0_rtx)
                        /* See above why we create (set (reg) (reg)) here.  */
                        success
                          = validate_change (next, &SET_SRC (set), reg, 0);
-                     else if ((rtx_cost (new_src, PLUS)
-                               < COSTS_N_INSNS (1) + rtx_cost (src3, SET))
+                     else if ((rtx_cost (new_src, PLUS, speed)
+                               < COSTS_N_INSNS (1) + rtx_cost (src3, SET, speed))
                               && have_add2_insn (reg, new_src))
                        {
                          rtx newpat = gen_rtx_SET (VOIDmode,
                               && have_add2_insn (reg, new_src))
                        {
                          rtx newpat = gen_rtx_SET (VOIDmode,
@@ -1393,7 +1403,7 @@ reload_cse_move2add (rtx first)
                 allocation if possible.  */
              && SCALAR_INT_MODE_P (GET_MODE (XEXP (cnd, 0)))
              && hard_regno_nregs[REGNO (XEXP (cnd, 0))][GET_MODE (XEXP (cnd, 0))] == 1
                 allocation if possible.  */
              && SCALAR_INT_MODE_P (GET_MODE (XEXP (cnd, 0)))
              && hard_regno_nregs[REGNO (XEXP (cnd, 0))][GET_MODE (XEXP (cnd, 0))] == 1
-             && GET_CODE (XEXP (cnd, 1)) == CONST_INT)
+             && CONST_INT_P (XEXP (cnd, 1)))
            {
              rtx implicit_set =
                gen_rtx_SET (VOIDmode, XEXP (cnd, 0), XEXP (cnd, 1));
            {
              rtx implicit_set =
                gen_rtx_SET (VOIDmode, XEXP (cnd, 0), XEXP (cnd, 1));
@@ -1420,7 +1430,7 @@ reload_cse_move2add (rtx first)
    Called from reload_cse_move2add via note_stores.  */
 
 static void
    Called from reload_cse_move2add via note_stores.  */
 
 static void
-move2add_note_store (rtx dst, rtx set, void *data ATTRIBUTE_UNUSED)
+move2add_note_store (rtx dst, const_rtx set, void *data ATTRIBUTE_UNUSED)
 {
   unsigned int regno = 0;
   unsigned int nregs = 0;
 {
   unsigned int regno = 0;
   unsigned int nregs = 0;
@@ -1474,7 +1484,7 @@ move2add_note_store (rtx dst, rtx set, void *data ATTRIBUTE_UNUSED)
            {
              base_reg = XEXP (src, 0);
 
            {
              base_reg = XEXP (src, 0);
 
-             if (GET_CODE (XEXP (src, 1)) == CONST_INT)
+             if (CONST_INT_P (XEXP (src, 1)))
                offset = INTVAL (XEXP (src, 1));
              else if (REG_P (XEXP (src, 1))
                       && (reg_set_luid[REGNO (XEXP (src, 1))]
                offset = INTVAL (XEXP (src, 1));
              else if (REG_P (XEXP (src, 1))
                       && (reg_set_luid[REGNO (XEXP (src, 1))]
@@ -1566,7 +1576,7 @@ move2add_note_store (rtx dst, rtx set, void *data ATTRIBUTE_UNUSED)
 static bool
 gate_handle_postreload (void)
 {
 static bool
 gate_handle_postreload (void)
 {
-  return (optimize > 0);
+  return (optimize > 0 && reload_completed);
 }
 
 
 }
 
 
@@ -1580,14 +1590,16 @@ rest_of_handle_postreload (void)
   reload_cse_regs (get_insns ());
   /* Reload_cse_regs can eliminate potentially-trapping MEMs.
      Remove any EH edges associated with them.  */
   reload_cse_regs (get_insns ());
   /* Reload_cse_regs can eliminate potentially-trapping MEMs.
      Remove any EH edges associated with them.  */
-  if (flag_non_call_exceptions)
+  if (cfun->can_throw_non_call_exceptions)
     purge_all_dead_edges ();
 
   return 0;
 }
 
     purge_all_dead_edges ();
 
   return 0;
 }
 
-struct tree_opt_pass pass_postreload_cse =
+struct rtl_opt_pass pass_postreload_cse =
 {
 {
+ {
+  RTL_PASS,
   "postreload",                         /* name */
   gate_handle_postreload,               /* gate */
   rest_of_handle_postreload,            /* execute */
   "postreload",                         /* name */
   gate_handle_postreload,               /* gate */
   rest_of_handle_postreload,            /* execute */
@@ -1599,8 +1611,7 @@ struct tree_opt_pass pass_postreload_cse =
   0,                                    /* properties_provided */
   0,                                    /* properties_destroyed */
   0,                                    /* todo_flags_start */
   0,                                    /* properties_provided */
   0,                                    /* properties_destroyed */
   0,                                    /* todo_flags_start */
-  TODO_df_finish |
-  TODO_dump_func,                       /* todo_flags_finish */
-  'o'                                   /* letter */
+  TODO_df_finish | TODO_verify_rtl_sharing |
+  TODO_dump_func                        /* todo_flags_finish */
+ }
 };
 };
-