match.pd: Implement simple complex operations cancelling.
[gcc.git] / gcc / reload1.c
index f7acd65f87ac762bf771ac60803af8b3cb23813d..7d5bad51d88ad5b165179e56762dd7580f9cfee4 100644 (file)
@@ -30,11 +30,21 @@ along with GCC; see the file COPYING3.  If not see
 #include "insn-config.h"
 #include "ggc.h"
 #include "flags.h"
+#include "hashtab.h"
+#include "hash-set.h"
+#include "vec.h"
+#include "input.h"
 #include "function.h"
 #include "expr.h"
+#include "insn-codes.h"
 #include "optabs.h"
 #include "regs.h"
 #include "addresses.h"
+#include "predict.h"
+#include "dominance.h"
+#include "cfg.h"
+#include "cfgrtl.h"
+#include "cfgbuild.h"
 #include "basic-block.h"
 #include "df.h"
 #include "reload.h"
@@ -45,6 +55,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "target.h"
 #include "emit-rtl.h"
 #include "dumpfile.h"
+#include "rtl-iter.h"
 
 /* This file contains the reload pass of the compiler, which is
    run after register allocation has been done.  It checks that
@@ -345,7 +356,7 @@ static vec<rtx_p> substitute_stack;
 
 static int num_labels;
 \f
-static void replace_pseudos_in (rtx *, enum machine_mode, rtx);
+static void replace_pseudos_in (rtx *, machine_mode, rtx);
 static void maybe_fix_stack_asms (void);
 static void copy_reloads (struct insn_chain *);
 static void calculate_needs_all_insns (int);
@@ -360,8 +371,8 @@ static void delete_dead_insn (rtx_insn *);
 static void alter_reg (int, int, bool);
 static void set_label_offsets (rtx, rtx_insn *, int);
 static void check_eliminable_occurrences (rtx);
-static void elimination_effects (rtx, enum machine_mode);
-static rtx eliminate_regs_1 (rtx, enum machine_mode, rtx, bool, bool);
+static void elimination_effects (rtx, machine_mode);
+static rtx eliminate_regs_1 (rtx, machine_mode, rtx, bool, bool);
 static int eliminate_regs_in_insn (rtx_insn *, int);
 static void update_eliminable_offsets (void);
 static void mark_not_eliminable (rtx, const_rtx, void *);
@@ -385,13 +396,13 @@ static void forget_old_reloads_1 (rtx, const_rtx, void *);
 static void forget_marked_reloads (regset);
 static int reload_reg_class_lower (const void *, const void *);
 static void mark_reload_reg_in_use (unsigned int, int, enum reload_type,
-                                   enum machine_mode);
+                                   machine_mode);
 static void clear_reload_reg_in_use (unsigned int, int, enum reload_type,
-                                    enum machine_mode);
+                                    machine_mode);
 static int reload_reg_free_p (unsigned int, int, enum reload_type);
 static int reload_reg_free_for_value_p (int, int, int, enum reload_type,
                                        rtx, rtx, int, int);
-static int free_for_value_p (int, enum machine_mode, int, enum reload_type,
+static int free_for_value_p (int, machine_mode, int, enum reload_type,
                             rtx, rtx, int, int);
 static int allocate_reload_reg (struct insn_chain *, int, int);
 static int conflicts_with_override (rtx);
@@ -537,7 +548,7 @@ compute_use_by_pseudos (HARD_REG_SET *to, regset from)
    equivalences.  */
 
 static void
-replace_pseudos_in (rtx *loc, enum machine_mode mem_mode, rtx usage)
+replace_pseudos_in (rtx *loc, machine_mode mem_mode, rtx usage)
 {
   rtx x = *loc;
   enum rtx_code code;
@@ -1256,7 +1267,7 @@ reload (rtx_insn *first, int global)
        if (asm_noperands (PATTERN (insn)) >= 0)
          {
            extract_insn (insn);
-           if (!constrain_operands (1))
+           if (!constrain_operands (1, get_enabled_alternatives (insn)))
              {
                error_for_asm (insn,
                               "%<asm%> operand has impossible constraints");
@@ -1355,7 +1366,7 @@ maybe_fix_stack_asms (void)
 {
 #ifdef STACK_REGS
   const char *constraints[MAX_RECOG_OPERANDS];
-  enum machine_mode operand_mode[MAX_RECOG_OPERANDS];
+  machine_mode operand_mode[MAX_RECOG_OPERANDS];
   struct insn_chain *chain;
 
   for (chain = reload_insn_chain; chain != 0; chain = chain->next)
@@ -2182,7 +2193,7 @@ alter_reg (int i, int from_reg, bool dont_share_p)
       && reg_equiv_memory_loc (i) == 0)
     {
       rtx x = NULL_RTX;
-      enum machine_mode mode = GET_MODE (regno_reg_rtx[i]);
+      machine_mode mode = GET_MODE (regno_reg_rtx[i]);
       unsigned int inherent_size = PSEUDO_REGNO_BYTES (i);
       unsigned int inherent_align = GET_MODE_ALIGNMENT (mode);
       unsigned int total_size = MAX (inherent_size, reg_max_ref_width[i]);
@@ -2311,7 +2322,7 @@ alter_reg (int i, int from_reg, bool dont_share_p)
    pseudo-reg number REGNO, accessed in MODE.  */
 
 static void
-mark_home_live_1 (int regno, enum machine_mode mode)
+mark_home_live_1 (int regno, machine_mode mode)
 {
   int i, lim;
 
@@ -2357,7 +2368,7 @@ set_label_offsets (rtx x, rtx_insn *insn, int initial_p)
       if (LABEL_REF_NONLOCAL_P (x))
        return;
 
-      x = XEXP (x, 0);
+      x = LABEL_REF_LABEL (x);
 
       /* ... fall through ...  */
 
@@ -2459,13 +2470,13 @@ set_label_offsets (rtx x, rtx_insn *insn, int initial_p)
        case IF_THEN_ELSE:
          tem = XEXP (SET_SRC (x), 1);
          if (GET_CODE (tem) == LABEL_REF)
-           set_label_offsets (XEXP (tem, 0), insn, initial_p);
+           set_label_offsets (LABEL_REF_LABEL (tem), insn, initial_p);
          else if (GET_CODE (tem) != PC && GET_CODE (tem) != RETURN)
            break;
 
          tem = XEXP (SET_SRC (x), 2);
          if (GET_CODE (tem) == LABEL_REF)
-           set_label_offsets (XEXP (tem, 0), insn, initial_p);
+           set_label_offsets (LABEL_REF_LABEL (tem), insn, initial_p);
          else if (GET_CODE (tem) != PC && GET_CODE (tem) != RETURN)
            break;
          return;
@@ -2486,34 +2497,33 @@ set_label_offsets (rtx x, rtx_insn *insn, int initial_p)
     }
 }
 \f
-/* Called through for_each_rtx, this function examines every reg that occurs
-   in PX and adjusts the costs for its elimination which are gathered by IRA.
-   DATA is the insn in which PX occurs.  We do not recurse into MEM
-   expressions.  */
+/* This function examines every reg that occurs in X and adjusts the
+   costs for its elimination which are gathered by IRA.  INSN is the
+   insn in which X occurs.  We do not recurse into MEM expressions.  */
 
-static int
-note_reg_elim_costly (rtx *px, void *data)
+static void
+note_reg_elim_costly (const_rtx x, rtx insn)
 {
-  rtx insn = (rtx)data;
-  rtx x = *px;
-
-  if (MEM_P (x))
-    return -1;
-
-  if (REG_P (x)
-      && REGNO (x) >= FIRST_PSEUDO_REGISTER
-      && reg_equiv_init (REGNO (x))
-      && reg_equiv_invariant (REGNO (x)))
-    {
-      rtx t = reg_equiv_invariant (REGNO (x));
-      rtx new_rtx = eliminate_regs_1 (t, Pmode, insn, true, true);
-      int cost = set_src_cost (new_rtx, optimize_bb_for_speed_p (elim_bb));
-      int freq = REG_FREQ_FROM_BB (elim_bb);
+  subrtx_iterator::array_type array;
+  FOR_EACH_SUBRTX (iter, array, x, NONCONST)
+    {
+      const_rtx x = *iter;
+      if (MEM_P (x))
+       iter.skip_subrtxes ();
+      else if (REG_P (x)
+              && REGNO (x) >= FIRST_PSEUDO_REGISTER
+              && reg_equiv_init (REGNO (x))
+              && reg_equiv_invariant (REGNO (x)))
+       {
+         rtx t = reg_equiv_invariant (REGNO (x));
+         rtx new_rtx = eliminate_regs_1 (t, Pmode, insn, true, true);
+         int cost = set_src_cost (new_rtx, optimize_bb_for_speed_p (elim_bb));
+         int freq = REG_FREQ_FROM_BB (elim_bb);
 
-      if (cost != 0)
-       ira_adjust_equiv_reg_cost (REGNO (x), -cost * freq);
+         if (cost != 0)
+           ira_adjust_equiv_reg_cost (REGNO (x), -cost * freq);
+       }
     }
-  return 0;
 }
 
 /* Scan X and replace any eliminable registers (such as fp) with a
@@ -2545,7 +2555,7 @@ note_reg_elim_costly (rtx *px, void *data)
    the proper thing.  */
 
 static rtx
-eliminate_regs_1 (rtx x, enum machine_mode mem_mode, rtx insn,
+eliminate_regs_1 (rtx x, machine_mode mem_mode, rtx insn,
                  bool may_use_invariant, bool for_costs)
 {
   enum rtx_code code = GET_CODE (x);
@@ -2888,7 +2898,7 @@ eliminate_regs_1 (rtx x, enum machine_mode mem_mode, rtx insn,
       if (for_costs
          && memory_address_p (GET_MODE (x), XEXP (x, 0))
          && !memory_address_p (GET_MODE (x), new_rtx))
-       for_each_rtx (&XEXP (x, 0), note_reg_elim_costly, insn);
+       note_reg_elim_costly (XEXP (x, 0), insn);
 
       return replace_equiv_address_nv (x, new_rtx);
 
@@ -2956,8 +2966,13 @@ eliminate_regs_1 (rtx x, enum machine_mode mem_mode, rtx insn,
 }
 
 rtx
-eliminate_regs (rtx x, enum machine_mode mem_mode, rtx insn)
+eliminate_regs (rtx x, machine_mode mem_mode, rtx insn)
 {
+  if (reg_eliminate == NULL)
+    {
+      gcc_assert (targetm.no_register_allocation);
+      return x;
+    }
   return eliminate_regs_1 (x, mem_mode, insn, false, false);
 }
 
@@ -2966,7 +2981,7 @@ eliminate_regs (rtx x, enum machine_mode mem_mode, rtx insn)
    the mode of an enclosing MEM rtx, or VOIDmode if not within a MEM.  */
 
 static void
-elimination_effects (rtx x, enum machine_mode mem_mode)
+elimination_effects (rtx x, machine_mode mem_mode)
 {
   enum rtx_code code = GET_CODE (x);
   struct elim_table *ep;
@@ -3732,7 +3747,7 @@ elimination_costs_in_insn (rtx_insn *insn)
          if (old_set && recog_data.operand_loc[i] == &SET_SRC (old_set))
            is_set_src = true;
          if (is_set_src && !sets_reg_p)
-           note_reg_elim_costly (&SET_SRC (old_set), insn);
+           note_reg_elim_costly (SET_SRC (old_set), insn);
          in_plus = false;
          if (plus_src && sets_reg_p
              && (recog_data.operand_loc[i] == &XEXP (plus_src, 0)
@@ -3911,13 +3926,13 @@ set_initial_label_offsets (void)
 {
   memset (offsets_known_at, 0, num_labels);
 
-  for (rtx_expr_list *x = forced_labels; x; x = x->next ())
-    if (x->element ())
-      set_label_offsets (x->element (), NULL, 1);
+  for (rtx_insn_list *x = forced_labels; x; x = x->next ())
+    if (x->insn ())
+      set_label_offsets (x->insn (), NULL, 1);
 
-  for (rtx x = nonlocal_goto_handler_labels; x; x = XEXP (x, 1))
-    if (XEXP (x, 0))
-      set_label_offsets (XEXP (x, 0), NULL, 1);
+  for (rtx_insn_list *x = nonlocal_goto_handler_labels; x; x = x->next ())
+    if (x->insn ())
+      set_label_offsets (x->insn (), NULL, 1);
 
   for_each_eh_label (set_initial_eh_label_offset);
 }
@@ -4203,7 +4218,7 @@ init_eliminable_invariants (rtx_insn *first, bool do_subregs)
                }
              else if (function_invariant_p (x))
                {
-                 enum machine_mode mode;
+                 machine_mode mode;
 
                  mode = GET_MODE (SET_DEST (set));
                  if (GET_CODE (x) == PLUS)
@@ -4573,7 +4588,6 @@ reload_as_needed (int live_known)
 #if defined (AUTO_INC_DEC)
   int i;
 #endif
-  rtx x;
   rtx_note *marker;
 
   memset (spill_reg_rtx, 0, sizeof spill_reg_rtx);
@@ -4662,7 +4676,6 @@ reload_as_needed (int live_known)
          if (n_reloads > 0)
            {
              rtx_insn *next = NEXT_INSN (insn);
-             rtx p;
 
              /* ??? PREV can get deleted by reload inheritance.
                 Work around this by emitting a marker note.  */
@@ -4693,7 +4706,7 @@ reload_as_needed (int live_known)
                fixup_eh_region_note (insn, prev, next);
 
              /* Adjust the location of REG_ARGS_SIZE.  */
-             p = find_reg_note (insn, REG_ARGS_SIZE, NULL_RTX);
+             rtx p = find_reg_note (insn, REG_ARGS_SIZE, NULL_RTX);
              if (p)
                {
                  remove_note (insn, p);
@@ -4705,11 +4718,15 @@ reload_as_needed (int live_known)
                 we have generated are valid.  If not, give an error
                 and delete them.  */
              if (asm_noperands (PATTERN (insn)) >= 0)
-               for (p = NEXT_INSN (prev); p != next; p = NEXT_INSN (p))
+               for (rtx_insn *p = NEXT_INSN (prev);
+                    p != next;
+                    p = NEXT_INSN (p))
                  if (p != insn && INSN_P (p)
                      && GET_CODE (PATTERN (p)) != USE
                      && (recog_memoized (p) < 0
-                         || (extract_insn (p), ! constrain_operands (1))))
+                         || (extract_insn (p),
+                             !(constrain_operands (1,
+                                 get_enabled_alternatives (p))))))
                    {
                      error_for_asm (insn,
                                     "%<asm%> operand requires "
@@ -4732,7 +4749,7 @@ reload_as_needed (int live_known)
 
          /* There may have been CLOBBER insns placed after INSN.  So scan
             between INSN and NEXT and use them to forget old reloads.  */
-         for (x = NEXT_INSN (insn); x != old_next; x = NEXT_INSN (x))
+         for (rtx_insn *x = NEXT_INSN (insn); x != old_next; x = NEXT_INSN (x))
            if (NONJUMP_INSN_P (x) && GET_CODE (PATTERN (x)) == CLOBBER)
              note_stores (PATTERN (x), forget_old_reloads_1, NULL);
 
@@ -4762,9 +4779,9 @@ reload_as_needed (int live_known)
 
                    {
                      rtx reload_reg = rld[i].reg_rtx;
-                     enum machine_mode mode = GET_MODE (reload_reg);
+                     machine_mode mode = GET_MODE (reload_reg);
                      int n = 0;
-                     rtx p;
+                     rtx_insn *p;
 
                      for (p = PREV_INSN (old_next); p != prev; p = PREV_INSN (p))
                        {
@@ -4792,7 +4809,8 @@ reload_as_needed (int live_known)
                              if (n)
                                {
                                  extract_insn (p);
-                                 n = constrain_operands (1);
+                                 n = constrain_operands (1,
+                                   get_enabled_alternatives (p));
                                }
 
                              /* If the constraints were not met, then
@@ -4846,7 +4864,8 @@ reload_as_needed (int live_known)
                          if (TEST_HARD_REG_BIT (reg_reloaded_valid,
                                                 in_hard_regno))
                            {
-                             for (x = old_prev ? NEXT_INSN (old_prev) : insn;
+                             for (rtx_insn *x = (old_prev ?
+                                                 NEXT_INSN (old_prev) : insn);
                                   x != old_next;
                                   x = NEXT_INSN (x))
                                if (x == reg_reloaded_insn[in_hard_regno])
@@ -4874,7 +4893,7 @@ reload_as_needed (int live_known)
          /* If a pseudo that got a hard register is auto-incremented,
             we must purge records of copying it into pseudos without
             hard registers.  */
-         for (x = REG_NOTES (insn); x; x = XEXP (x, 1))
+         for (rtx x = REG_NOTES (insn); x; x = XEXP (x, 1))
            if (REG_NOTE_KIND (x) == REG_INC)
              {
                /* See if this pseudo reg was reloaded in this insn.
@@ -5056,7 +5075,7 @@ static HARD_REG_SET reg_used_in_insn;
 
 static void
 mark_reload_reg_in_use (unsigned int regno, int opnum, enum reload_type type,
-                       enum machine_mode mode)
+                       machine_mode mode)
 {
   switch (type)
     {
@@ -5112,7 +5131,7 @@ mark_reload_reg_in_use (unsigned int regno, int opnum, enum reload_type type,
 
 static void
 clear_reload_reg_in_use (unsigned int regno, int opnum,
-                        enum reload_type type, enum machine_mode mode)
+                        enum reload_type type, machine_mode mode)
 {
   unsigned int nregs = hard_regno_nregs[regno][mode];
   unsigned int start_regno, end_regno, r;
@@ -5718,7 +5737,7 @@ gen_reload_chain_without_interm_reg_p (int r1, int r2)
          /* We want constrain operands to treat this insn strictly in
             its validity determination, i.e., the way it would after
             reload has completed.  */
-         result = constrain_operands (1);
+         result = constrain_operands (1, get_enabled_alternatives (insn));
        }
 
       delete_insns_since (last);
@@ -6078,7 +6097,7 @@ reload_reg_free_for_value_p (int start_regno, int regno, int opnum,
    register.  */
 
 static int
-free_for_value_p (int regno, enum machine_mode mode, int opnum,
+free_for_value_p (int regno, machine_mode mode, int opnum,
                  enum reload_type type, rtx value, rtx out, int reloadnum,
                  int ignore_address_reloads)
 {
@@ -6167,7 +6186,7 @@ set_reload_reg (int i, int r)
      This used to be one `if', but Sequent compiler can't handle that.  */
   if (HARD_REGNO_MODE_OK (regno, rld[r].mode))
     {
-      enum machine_mode test_mode = VOIDmode;
+      machine_mode test_mode = VOIDmode;
       if (rld[r].in)
        test_mode = GET_MODE (rld[r].in);
       /* If rld[r].in has VOIDmode, it means we will load it
@@ -6409,12 +6428,12 @@ replaced_subreg (rtx x)
    otherwise it is NULL.  */
 
 static int
-compute_reload_subreg_offset (enum machine_mode outermode,
+compute_reload_subreg_offset (machine_mode outermode,
                              rtx subreg,
-                             enum machine_mode innermode)
+                             machine_mode innermode)
 {
   int outer_offset;
-  enum machine_mode middlemode;
+  machine_mode middlemode;
 
   if (!subreg)
     return subreg_lowpart_offset (outermode, innermode);
@@ -6570,7 +6589,7 @@ choose_reload_regs (struct insn_chain *chain)
            {
              int byte = 0;
              int regno = -1;
-             enum machine_mode mode = VOIDmode;
+             machine_mode mode = VOIDmode;
              rtx subreg = NULL_RTX;
 
              if (rld[r].in == 0)
@@ -7194,7 +7213,7 @@ static HARD_REG_SET reg_reloaded_died;
 static bool
 reload_adjust_reg_for_temp (rtx *reload_reg, rtx alt_reload_reg,
                            enum reg_class new_class,
-                           enum machine_mode new_mode)
+                           machine_mode new_mode)
 
 {
   rtx reg;
@@ -7230,7 +7249,7 @@ reload_adjust_reg_for_icode (rtx *reload_reg, rtx alt_reload_reg,
 
 {
   enum reg_class new_class = scratch_reload_class (icode);
-  enum machine_mode new_mode = insn_data[(int) icode].operand[2].mode;
+  machine_mode new_mode = insn_data[(int) icode].operand[2].mode;
 
   return reload_adjust_reg_for_temp (reload_reg, alt_reload_reg,
                                     new_class, new_mode);
@@ -7248,7 +7267,7 @@ emit_input_reload_insns (struct insn_chain *chain, struct reload *rl,
   rtx oldequiv_reg = 0;
   rtx oldequiv = 0;
   int special = 0;
-  enum machine_mode mode;
+  machine_mode mode;
   rtx_insn **where;
 
   /* delete_output_reload is only invoked properly if old contains
@@ -7388,7 +7407,7 @@ emit_input_reload_insns (struct insn_chain *chain, struct reload *rl,
             autoincrement addressing mode, then the resulting insn
             is ill-formed and we must reject this optimization.  */
          extract_insn (temp);
-         if (constrain_operands (1)
+         if (constrain_operands (1, get_enabled_alternatives (temp))
 #ifdef AUTO_INC_DEC
              && ! find_reg_note (temp, REG_INC, reloadreg)
 #endif
@@ -7708,7 +7727,7 @@ emit_output_reload_insns (struct insn_chain *chain, struct reload *rl,
   rtx_insn *insn = chain->insn;
   int special = 0;
   rtx old = rl->out;
-  enum machine_mode mode;
+  machine_mode mode;
   rtx_insn *p;
   rtx rl_reg_rtx;
 
@@ -7916,7 +7935,7 @@ do_input_reload (struct insn_chain *chain, struct reload *rl, int j)
 
   if (old && reg_rtx)
     {
-      enum machine_mode mode;
+      machine_mode mode;
 
       /* Determine the mode to reload in.
         This is very tricky because we have three to choose from.
@@ -8020,7 +8039,7 @@ do_output_reload (struct insn_chain *chain, struct reload *rl, int j)
 
   if (rl->out && reg_rtx)
     {
-      enum machine_mode mode;
+      machine_mode mode;
 
       /* Determine the mode to reload in.
         See comments above (for input reloading).  */
@@ -8105,7 +8124,7 @@ do_output_reload (struct insn_chain *chain, struct reload *rl, int j)
 static bool
 inherit_piecemeal_p (int dest ATTRIBUTE_UNUSED,
                     int src ATTRIBUTE_UNUSED,
-                    enum machine_mode mode ATTRIBUTE_UNUSED)
+                    machine_mode mode ATTRIBUTE_UNUSED)
 {
 #ifdef CANNOT_CHANGE_MODE_CLASS
   return (!REG_CANNOT_CHANGE_MODE_P (dest, mode, reg_raw_mode[dest])
@@ -8289,7 +8308,7 @@ emit_reload_insns (struct insn_chain *chain)
              reg = reload_reg_rtx_for_output[r];
              if (reload_reg_rtx_reaches_end_p (reg, r))
                {
-                 enum machine_mode mode = GET_MODE (reg);
+                 machine_mode mode = GET_MODE (reg);
                  int regno = REGNO (reg);
                  int nregs = hard_regno_nregs[regno][mode];
                  rtx out = (REG_P (rld[r].out)
@@ -8359,7 +8378,7 @@ emit_reload_insns (struct insn_chain *chain)
              reg = reload_reg_rtx_for_input[r];
              if (reload_reg_rtx_reaches_end_p (reg, r))
                {
-                 enum machine_mode mode;
+                 machine_mode mode;
                  int regno;
                  int nregs;
                  int in_regno;
@@ -8442,7 +8461,7 @@ emit_reload_insns (struct insn_chain *chain)
          rtx out = ((rld[r].out && REG_P (rld[r].out))
                     ? rld[r].out : rld[r].out_reg);
          int out_regno = REGNO (out);
-         enum machine_mode mode = GET_MODE (out);
+         machine_mode mode = GET_MODE (out);
 
          /* REG_RTX is now set or clobbered by the main instruction.
             As the comment above explains, forget_old_reloads_1 only
@@ -8561,12 +8580,12 @@ emit_reload_insns (struct insn_chain *chain)
    Return the emitted insn if valid, else return NULL.  */
 
 static rtx_insn *
-emit_insn_if_valid_for_reload (rtx insn)
+emit_insn_if_valid_for_reload (rtx pat)
 {
   rtx_insn *last = get_last_insn ();
   int code;
 
-  insn = emit_insn (insn);
+  rtx_insn *insn = emit_insn (pat);
   code = recog_memoized (insn);
 
   if (code >= 0)
@@ -8575,8 +8594,8 @@ emit_insn_if_valid_for_reload (rtx insn)
       /* We want constrain operands to treat this insn strictly in its
         validity determination, i.e., the way it would after reload has
         completed.  */
-      if (constrain_operands (1))
-       return as_a <rtx_insn *> (insn);
+      if (constrain_operands (1, get_enabled_alternatives (insn)))
+       return insn;
     }
 
   delete_insns_since (last);
@@ -8593,7 +8612,7 @@ static rtx_insn *
 gen_reload (rtx out, rtx in, int opnum, enum reload_type type)
 {
   rtx_insn *last = get_last_insn ();
-  rtx tem;
+  rtx_insn *tem;
 #ifdef SECONDARY_MEMORY_NEEDED
   rtx tem1, tem2;
 #endif
@@ -8840,14 +8859,13 @@ delete_output_reload (rtx_insn *insn, int j, int last_reload_reg,
   int k;
   int n_occurrences;
   int n_inherited = 0;
-  rtx i1;
   rtx substed;
   unsigned regno;
   int nregs;
 
   /* It is possible that this reload has been only used to set another reload
      we eliminated earlier and thus deleted this instruction too.  */
-  if (INSN_DELETED_P (output_reload_insn))
+  if (output_reload_insn->deleted ())
     return;
 
   /* Get the raw pseudo-register referred to.  */
@@ -8887,7 +8905,7 @@ delete_output_reload (rtx_insn *insn, int j, int last_reload_reg,
     n_occurrences += count_occurrences (PATTERN (insn),
                                        eliminate_regs (substed, VOIDmode,
                                                        NULL_RTX), 0);
-  for (i1 = reg_equiv_alt_mem_list (REGNO (reg)); i1; i1 = XEXP (i1, 1))
+  for (rtx i1 = reg_equiv_alt_mem_list (REGNO (reg)); i1; i1 = XEXP (i1, 1))
     {
       gcc_assert (!rtx_equal_p (XEXP (i1, 0), substed));
       n_occurrences += count_occurrences (PATTERN (insn), XEXP (i1, 0), 0);
@@ -8906,7 +8924,7 @@ delete_output_reload (rtx_insn *insn, int j, int last_reload_reg,
      and we're within the same basic block, then the value can only
      pass through the reload reg and end up here.
      Otherwise, give up--return.  */
-  for (i1 = NEXT_INSN (output_reload_insn);
+  for (rtx_insn *i1 = NEXT_INSN (output_reload_insn);
        i1 != insn; i1 = NEXT_INSN (i1))
     {
       if (NOTE_INSN_BASIC_BLOCK_P (i1))
@@ -9213,7 +9231,7 @@ inc_for_reload (rtx reloadreg, rtx in, rtx value, int inc_amount)
       if (code >= 0)
        {
          extract_insn (add_insn);
-         if (constrain_operands (1))
+         if (constrain_operands (1, get_enabled_alternatives (add_insn)))
            {
              /* If this is a pre-increment and we have incremented the value
                 where it lives, copy the incremented value to RELOADREG to