OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / regclass.c
index 689f91e..f31ccd1 100644 (file)
@@ -1,6 +1,6 @@
 /* Compute register class preferences for pseudo-registers.
    Copyright (C) 1987, 1988, 1991, 1992, 1993, 1994, 1995, 1996
-   1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
+   1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -81,7 +81,7 @@ HARD_REG_SET fixed_reg_set;
 
 /* Data for initializing the above.  */
 
-static char initial_fixed_regs[] = FIXED_REGISTERS;
+static const char initial_fixed_regs[] = FIXED_REGISTERS;
 
 /* Indexed by hard register number, contains 1 for registers
    that are fixed use or are clobbered by function calls.
@@ -100,7 +100,7 @@ HARD_REG_SET losing_caller_save_reg_set;
 
 /* Data for initializing the above.  */
 
-static char initial_call_used_regs[] = CALL_USED_REGISTERS;
+static const char initial_call_used_regs[] = CALL_USED_REGISTERS;
 
 /* This is much like call_used_regs, except it doesn't have to
    be a superset of FIXED_REGISTERS. This vector indicates
@@ -108,8 +108,7 @@ static char initial_call_used_regs[] = CALL_USED_REGISTERS;
    regs_invalidated_by_call.  */
 
 #ifdef CALL_REALLY_USED_REGISTERS
-static char initial_call_really_used_regs[] = CALL_REALLY_USED_REGISTERS;
-char call_really_used_regs[FIRST_PSEUDO_REGISTER];
+char call_really_used_regs[] = CALL_REALLY_USED_REGISTERS;
 #endif
 
 #ifdef CALL_REALLY_USED_REGISTERS
@@ -146,6 +145,16 @@ char global_regs[FIRST_PSEUDO_REGISTER];
 
 HARD_REG_SET regs_invalidated_by_call;
 
+/* Same information as REGS_INVALIDATED_BY_CALL but in regset form to be used
+   in dataflow more conveniently.  */
+
+regset regs_invalidated_by_call_regset;
+
+/* The bitmap_obstack is used to hold some static variables that
+   should not be reset after each function is compiled.  */
+
+static bitmap_obstack persistent_obstack;
+
 /* Table of register numbers in the order in which to try to use them.  */
 #ifdef REG_ALLOC_ORDER
 int reg_alloc_order[FIRST_PSEUDO_REGISTER] = REG_ALLOC_ORDER;
@@ -179,7 +188,7 @@ static enum reg_class reg_class_superclasses[N_REG_CLASSES][N_REG_CLASSES];
 
 /* For each reg class, table listing all the classes contained in it.  */
 
-static enum reg_class reg_class_subclasses[N_REG_CLASSES][N_REG_CLASSES];
+enum reg_class reg_class_subclasses[N_REG_CLASSES][N_REG_CLASSES];
 
 /* For each pair of reg classes,
    a largest reg class contained in their union.  */
@@ -193,11 +202,7 @@ enum reg_class reg_class_superunion[N_REG_CLASSES][N_REG_CLASSES];
 
 /* Array containing all of the register names.  */
 
-const char * reg_names[FIRST_PSEUDO_REGISTER];
-
-/* Data for initializing the above.  */
-
-const char * initial_reg_names[] = REGISTER_NAMES;
+const char * reg_names[] = REGISTER_NAMES;
 
 /* Array containing all of the register class names.  */
 
@@ -216,24 +221,22 @@ bool have_regs_of_mode [MAX_MACHINE_MODE];
 
 /* 1 if class does contain register of given mode.  */
 
-static char contains_reg_of_mode [N_REG_CLASSES] [MAX_MACHINE_MODE];
-
-typedef unsigned short move_table[N_REG_CLASSES];
+char contains_reg_of_mode [N_REG_CLASSES] [MAX_MACHINE_MODE];
 
 /* Maximum cost of moving from a register in one class to a register in
    another class.  Based on REGISTER_MOVE_COST.  */
 
-static move_table *move_cost[MAX_MACHINE_MODE];
+move_table *move_cost[MAX_MACHINE_MODE];
 
 /* Similar, but here we don't have to move if the first index is a subset
    of the second so in that case the cost is zero.  */
 
-static move_table *may_move_in_cost[MAX_MACHINE_MODE];
+move_table *may_move_in_cost[MAX_MACHINE_MODE];
 
 /* Similar, but here we don't have to move if the first index is a superset
    of the second so in that case the cost is zero.  */
 
-static move_table *may_move_out_cost[MAX_MACHINE_MODE];
+move_table *may_move_out_cost[MAX_MACHINE_MODE];
 
 /* Keep track of the last mode we initialized move costs for.  */
 static int last_mode_for_init_move_cost;
@@ -306,17 +309,19 @@ init_reg_sets (void)
          SET_HARD_REG_BIT (reg_class_contents[i], j);
     }
 
-  memset (global_regs, 0, sizeof global_regs);
+  /* Sanity check: make sure the target macros FIXED_REGISTERS and
+     CALL_USED_REGISTERS had the right number of initializers.  */
+  gcc_assert (sizeof fixed_regs == sizeof initial_fixed_regs);
+  gcc_assert (sizeof call_used_regs == sizeof initial_call_used_regs);
 
-  /* Processing of command-line options like -ffixed needs to know the
-     initial set of register names, so initialize that now.  */
-  gcc_assert (sizeof reg_names == sizeof initial_reg_names);
-  memcpy (reg_names, initial_reg_names, sizeof reg_names);
+  memcpy (fixed_regs, initial_fixed_regs, sizeof fixed_regs);
+  memcpy (call_used_regs, initial_call_used_regs, sizeof call_used_regs);
+  memset (global_regs, 0, sizeof global_regs);
 }
 
 /* Initialize may_move_cost and friends for mode M.  */
 
-static void
+void
 init_move_cost (enum machine_mode m)
 {
   static unsigned short last_move_cost[N_REG_CLASSES][N_REG_CLASSES];
@@ -403,34 +408,68 @@ init_move_cost (enum machine_mode m)
        }
 }
 
-/* After switches have been processed, which perhaps alter
-   `fixed_regs' and `call_used_regs', convert them to HARD_REG_SETs.  */
+/* We need to save copies of some of the register information which
+   can be munged by command-line switches so we can restore it during
+   subsequent back-end reinitialization.  */
 
-static void
-init_reg_sets_1 (void)
-{
-  unsigned int i, j;
-  unsigned int /* enum machine_mode */ m;
+static char saved_fixed_regs[FIRST_PSEUDO_REGISTER];
+static char saved_call_used_regs[FIRST_PSEUDO_REGISTER];
+#ifdef CALL_REALLY_USED_REGISTERS
+static char saved_call_really_used_regs[FIRST_PSEUDO_REGISTER];
+#endif
+static const char *saved_reg_names[FIRST_PSEUDO_REGISTER];
+
+/* Save the register information.  */
 
+void
+save_register_info (void)
+{
   /* Sanity check:  make sure the target macros FIXED_REGISTERS and
      CALL_USED_REGISTERS had the right number of initializers.  */
-  gcc_assert (sizeof fixed_regs == sizeof initial_fixed_regs);
-  gcc_assert (sizeof call_used_regs == sizeof initial_call_used_regs);
-
-  memcpy (fixed_regs, initial_fixed_regs, sizeof fixed_regs);
-  memcpy (call_used_regs, initial_call_used_regs, sizeof call_used_regs);
+  gcc_assert (sizeof fixed_regs == sizeof saved_fixed_regs);
+  gcc_assert (sizeof call_used_regs == sizeof saved_call_used_regs);
+  memcpy (saved_fixed_regs, fixed_regs, sizeof fixed_regs);
+  memcpy (saved_call_used_regs, call_used_regs, sizeof call_used_regs);
 
   /* Likewise for call_really_used_regs.  */
 #ifdef CALL_REALLY_USED_REGISTERS
   gcc_assert (sizeof call_really_used_regs
-             == sizeof initial_call_really_used_regs);
-  memcpy (call_really_used_regs, initial_call_really_used_regs,
+             == sizeof saved_call_really_used_regs);
+  memcpy (saved_call_really_used_regs, call_really_used_regs,
          sizeof call_really_used_regs);
 #endif
 
   /* And similarly for reg_names.  */
-  gcc_assert (sizeof reg_names == sizeof initial_reg_names);
-  memcpy (reg_names, initial_reg_names, sizeof reg_names);
+  gcc_assert (sizeof reg_names == sizeof saved_reg_names);
+  memcpy (saved_reg_names, reg_names, sizeof reg_names);
+}
+
+/* Restore the register information.  */
+
+static void
+restore_register_info (void)
+{
+  memcpy (fixed_regs, saved_fixed_regs, sizeof fixed_regs);
+  memcpy (call_used_regs, saved_call_used_regs, sizeof call_used_regs);
+
+#ifdef CALL_REALLY_USED_REGISTERS
+  memcpy (call_really_used_regs, saved_call_really_used_regs,
+         sizeof call_really_used_regs);
+#endif
+
+  memcpy (reg_names, saved_reg_names, sizeof reg_names);
+}
+
+/* After switches have been processed, which perhaps alter
+   `fixed_regs' and `call_used_regs', convert them to HARD_REG_SETs.  */
+
+static void
+init_reg_sets_1 (void)
+{
+  unsigned int i, j;
+  unsigned int /* enum machine_mode */ m;
+
+  restore_register_info ();
 
 #ifdef REG_ALLOC_ORDER
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
@@ -539,6 +578,13 @@ init_reg_sets_1 (void)
   CLEAR_HARD_REG_SET (call_fixed_reg_set);
   CLEAR_HARD_REG_SET (regs_invalidated_by_call);
   CLEAR_HARD_REG_SET (losing_caller_save_reg_set);
+  if (!regs_invalidated_by_call_regset)
+    {
+      bitmap_obstack_initialize (&persistent_obstack);
+      regs_invalidated_by_call_regset = ALLOC_REG_SET (&persistent_obstack);
+    }
+  else
+    CLEAR_REG_SET (regs_invalidated_by_call_regset);
 
   memcpy (call_fixed_regs, fixed_regs, sizeof call_fixed_regs);
 
@@ -573,7 +619,10 @@ init_reg_sets_1 (void)
       if (i == STACK_POINTER_REGNUM)
        ;
       else if (global_regs[i])
-       SET_HARD_REG_BIT (regs_invalidated_by_call, i);
+        {
+         SET_HARD_REG_BIT (regs_invalidated_by_call, i);
+         SET_REGNO_REG_SET (regs_invalidated_by_call_regset, i);
+       }
       else if (i == FRAME_POINTER_REGNUM)
        ;
 #if HARD_FRAME_POINTER_REGNUM != FRAME_POINTER_REGNUM
@@ -589,7 +638,10 @@ init_reg_sets_1 (void)
        ;
 #endif
       else if (CALL_REALLY_USED_REGNO_P (i))
-       SET_HARD_REG_BIT (regs_invalidated_by_call, i);
+        {
+         SET_HARD_REG_BIT (regs_invalidated_by_call, i);
+         SET_REGNO_REG_SET (regs_invalidated_by_call_regset, i);
+        }
     }
 
   /* Preserve global registers if called more than once.  */
@@ -707,7 +759,7 @@ init_fake_stack_mems (void)
    Only needed if secondary reloads are required for memory moves.  */
 
 int
-memory_move_secondary_cost (enum machine_mode mode, enum reg_class class, int in)
+memory_move_secondary_cost (enum machine_mode mode, enum reg_class rclass, int in)
 {
   enum reg_class altclass;
   int partial_cost = 0;
@@ -716,17 +768,17 @@ memory_move_secondary_cost (enum machine_mode mode, enum reg_class class, int in
   rtx mem ATTRIBUTE_UNUSED = top_of_stack[(int) mode];
 
 
-  altclass = secondary_reload_class (in ? 1 : 0, class, mode, mem);
+  altclass = secondary_reload_class (in ? 1 : 0, rclass, mode, mem);
 
   if (altclass == NO_REGS)
     return 0;
 
   if (in)
-    partial_cost = REGISTER_MOVE_COST (mode, altclass, class);
+    partial_cost = REGISTER_MOVE_COST (mode, altclass, rclass);
   else
-    partial_cost = REGISTER_MOVE_COST (mode, class, altclass);
+    partial_cost = REGISTER_MOVE_COST (mode, rclass, altclass);
 
-  if (class == altclass)
+  if (rclass == altclass)
     /* This isn't simply a copy-to-temporary situation.  Can't guess
        what it is, so MEMORY_MOVE_COST really ought not to be calling
        here in that case.
@@ -846,11 +898,11 @@ fix_register (const char *name, int fixed, int call_used)
        }
       else
        {
-         initial_fixed_regs[i] = fixed;
-         initial_call_used_regs[i] = call_used;
+         fixed_regs[i] = fixed;
+         call_used_regs[i] = call_used;
 #ifdef CALL_REALLY_USED_REGISTERS
          if (fixed == 0)
-           initial_call_really_used_regs[i] = call_used;
+           call_really_used_regs[i] = call_used;
 #endif
        }
     }
@@ -883,7 +935,10 @@ globalize_reg (int i)
      appropriate regs_invalidated_by_call bit, even if it's already
      set in fixed_regs.  */
   if (i != STACK_POINTER_REGNUM)
-    SET_HARD_REG_BIT (regs_invalidated_by_call, i);
+    {
+      SET_HARD_REG_BIT (regs_invalidated_by_call, i);
+      SET_REGNO_REG_SET (regs_invalidated_by_call_regset, i);
+   }
 
   /* If already fixed, nothing else to do.  */
   if (fixed_regs[i])
@@ -993,6 +1048,7 @@ reg_preferred_class (int regno)
 {
   if (reg_pref == 0)
     return GENERAL_REGS;
+
   return (enum reg_class) reg_pref[regno].prefclass;
 }
 
@@ -1028,8 +1084,10 @@ regclass_init (void)
   return 1;
 }
 
-struct tree_opt_pass pass_regclass_init =
+struct rtl_opt_pass pass_regclass_init =
 {
+ {
+  RTL_PASS,
   "regclass",                           /* name */
   NULL,                                 /* gate */
   regclass_init,                        /* execute */
@@ -1041,8 +1099,8 @@ struct tree_opt_pass pass_regclass_init =
   0,                                    /* properties_provided */
   0,                                    /* properties_destroyed */
   0,                                    /* todo_flags_start */
-  0,                                    /* todo_flags_finish */
-  'k'                                   /* letter */
+  0                                     /* todo_flags_finish */
+ }
 };
 
 
@@ -1054,23 +1112,23 @@ dump_regclass (FILE *dump)
   int i;
   for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
     {
-      int /* enum reg_class */ class;
+      int /* enum reg_class */ rclass;
       if (REG_N_REFS (i))
        {
          fprintf (dump, "  Register %i costs:", i);
-         for (class = 0; class < (int) N_REG_CLASSES; class++)
-           if (contains_reg_of_mode [(enum reg_class) class][PSEUDO_REGNO_MODE (i)]
+         for (rclass = 0; rclass < (int) N_REG_CLASSES; rclass++)
+           if (contains_reg_of_mode [(enum reg_class) rclass][PSEUDO_REGNO_MODE (i)]
 #ifdef FORBIDDEN_INC_DEC_CLASSES
                && (!in_inc_dec[i]
-                   || !forbidden_inc_dec_class[(enum reg_class) class])
+                   || !forbidden_inc_dec_class[(enum reg_class) rclass])
 #endif
 #ifdef CANNOT_CHANGE_MODE_CLASS
-               && ! invalid_mode_change_p (i, (enum reg_class) class,
+               && ! invalid_mode_change_p (i, (enum reg_class) rclass,
                                            PSEUDO_REGNO_MODE (i))
 #endif
                )
-           fprintf (dump, " %s:%i", reg_class_names[class],
-                    costs[i].cost[(enum reg_class) class]);
+           fprintf (dump, " %s:%i", reg_class_names[rclass],
+                    costs[i].cost[(enum reg_class) rclass]);
          fprintf (dump, " MEM:%i\n", costs[i].mem_cost);
        }
     }
@@ -1110,8 +1168,9 @@ record_operand_costs (rtx insn, struct costs *op_costs,
        record_address_regs (GET_MODE (recog_data.operand[i]),
                             XEXP (recog_data.operand[i], 0),
                             0, MEM, SCRATCH, frequency * 2);
-      else if (constraints[i][0] == 'p'
-              || EXTRA_ADDRESS_CONSTRAINT (constraints[i][0], constraints[i]))
+      else if (recog_data.alternative_enabled_p[0]
+              && (constraints[i][0] == 'p'
+                  || EXTRA_ADDRESS_CONSTRAINT (constraints[i][0], constraints[i])))
        record_address_regs (VOIDmode, recog_data.operand[i], 0, ADDRESS,
                             SCRATCH, frequency * 2);
     }
@@ -1251,7 +1310,7 @@ init_reg_autoinc (void)
                     requires secondary reloads, disallow its class from
                     being used in such addresses.  */
 
-                 if ((secondary_reload_class (1, base_class, m, r)
+                 if ((secondary_reload_class (0, base_class, m, r)
                       || secondary_reload_class (1, base_class, m, r))
                      && ! auto_inc_dec_reg_p (r, m))
                    forbidden_inc_dec_class[i] = 1;
@@ -1276,7 +1335,7 @@ regclass (rtx f, int nregs)
 
   init_recog ();
 
-  reg_renumber = xmalloc (max_regno * sizeof (short));
+  reg_renumber = XNEWVEC (short, max_regno);
   reg_pref = XCNEWVEC (struct reg_pref, max_regno);
   memset (reg_renumber, -1, max_regno * sizeof (short));
 
@@ -1348,7 +1407,7 @@ regclass (rtx f, int nregs)
          enum reg_class best = ALL_REGS, alt = NO_REGS;
          /* This is an enum reg_class, but we call it an int
             to save lots of casts.  */
-         int class;
+         int rclass;
          struct costs *p = &costs[i];
 
          if (regno_reg_rtx[i] == NULL)
@@ -1359,27 +1418,27 @@ regclass (rtx f, int nregs)
          if (optimize && !REG_N_REFS (i) && !REG_N_SETS (i))
            continue;
 
-         for (class = (int) ALL_REGS - 1; class > 0; class--)
+         for (rclass = (int) ALL_REGS - 1; rclass > 0; rclass--)
            {
              /* Ignore classes that are too small for this operand or
                 invalid for an operand that was auto-incremented.  */
-             if (!contains_reg_of_mode [class][PSEUDO_REGNO_MODE (i)]
+             if (!contains_reg_of_mode [rclass][PSEUDO_REGNO_MODE (i)]
 #ifdef FORBIDDEN_INC_DEC_CLASSES
-                 || (in_inc_dec[i] && forbidden_inc_dec_class[class])
+                 || (in_inc_dec[i] && forbidden_inc_dec_class[rclass])
 #endif
 #ifdef CANNOT_CHANGE_MODE_CLASS
-                 || invalid_mode_change_p (i, (enum reg_class) class,
+                 || invalid_mode_change_p (i, (enum reg_class) rclass,
                                            PSEUDO_REGNO_MODE (i))
 #endif
                  )
                ;
-             else if (p->cost[class] < best_cost)
+             else if (p->cost[rclass] < best_cost)
                {
-                 best_cost = p->cost[class];
-                 best = (enum reg_class) class;
+                 best_cost = p->cost[rclass];
+                 best = (enum reg_class) rclass;
                }
-             else if (p->cost[class] == best_cost)
-               best = reg_class_subunion[(int) best][class];
+             else if (p->cost[rclass] == best_cost)
+               best = reg_class_subunion[(int) best][rclass];
            }
 
          /* If no register class is better than memory, use memory. */
@@ -1394,19 +1453,19 @@ regclass (rtx f, int nregs)
             will be doing it again later.  */
 
          if ((pass == 1  || dump_file) || ! flag_expensive_optimizations)
-           for (class = 0; class < N_REG_CLASSES; class++)
-             if (p->cost[class] < p->mem_cost
-                 && (reg_class_size[(int) reg_class_subunion[(int) alt][class]]
+           for (rclass = 0; rclass < N_REG_CLASSES; rclass++)
+             if (p->cost[rclass] < p->mem_cost
+                 && (reg_class_size[(int) reg_class_subunion[(int) alt][rclass]]
                      > reg_class_size[(int) alt])
 #ifdef FORBIDDEN_INC_DEC_CLASSES
-                 && ! (in_inc_dec[i] && forbidden_inc_dec_class[class])
+                 && ! (in_inc_dec[i] && forbidden_inc_dec_class[rclass])
 #endif
 #ifdef CANNOT_CHANGE_MODE_CLASS
-                 && ! invalid_mode_change_p (i, (enum reg_class) class,
+                 && ! invalid_mode_change_p (i, (enum reg_class) rclass,
                                              PSEUDO_REGNO_MODE (i))
 #endif
                  )
-               alt = reg_class_subunion[(int) alt][class];
+               alt = reg_class_subunion[(int) alt][rclass];
 
          /* If we don't add any classes, nothing to try.  */
          if (alt == best)
@@ -1483,7 +1542,7 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
       int alt_cost = 0;
       enum reg_class classes[MAX_RECOG_OPERANDS];
       int allows_mem[MAX_RECOG_OPERANDS];
-      int class;
+      int rclass;
 
       for (i = 0; i < n_ops; i++)
        {
@@ -1583,17 +1642,17 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
                  switch (recog_data.operand_type[i])
                    {
                    case OP_INOUT:
-                     for (class = 0; class < N_REG_CLASSES; class++)
-                       pp->cost[class] = (intable[class][op_class]
-                                          + outtable[op_class][class]);
+                     for (rclass = 0; rclass < N_REG_CLASSES; rclass++)
+                       pp->cost[rclass] = (intable[rclass][op_class]
+                                          + outtable[op_class][rclass]);
                      break;
                    case OP_IN:
-                     for (class = 0; class < N_REG_CLASSES; class++)
-                       pp->cost[class] = intable[class][op_class];
+                     for (rclass = 0; rclass < N_REG_CLASSES; rclass++)
+                       pp->cost[rclass] = intable[rclass][op_class];
                      break;
                    case OP_OUT:
-                     for (class = 0; class < N_REG_CLASSES; class++)
-                       pp->cost[class] = outtable[op_class][class];
+                     for (rclass = 0; rclass < N_REG_CLASSES; rclass++)
+                       pp->cost[rclass] = outtable[op_class][rclass];
                      break;
                    }
 
@@ -1668,7 +1727,7 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
                    [(int) base_reg_class (VOIDmode, ADDRESS, SCRATCH)];
                  break;
 
-               case 'm':  case 'o':  case 'V':
+               case TARGET_MEM_CONSTRAINT:  case 'o':  case 'V':
                  /* It doesn't seem worth distinguishing between offsettable
                     and non-offsettable addresses here.  */
                  allows_mem[i] = 1;
@@ -1827,17 +1886,17 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
                  switch (recog_data.operand_type[i])
                    {
                    case OP_INOUT:
-                     for (class = 0; class < N_REG_CLASSES; class++)
-                       pp->cost[class] = (intable[class][op_class]
-                                          + outtable[op_class][class]);
+                     for (rclass = 0; rclass < N_REG_CLASSES; rclass++)
+                       pp->cost[rclass] = (intable[rclass][op_class]
+                                          + outtable[op_class][rclass]);
                      break;
                    case OP_IN:
-                     for (class = 0; class < N_REG_CLASSES; class++)
-                       pp->cost[class] = intable[class][op_class];
+                     for (rclass = 0; rclass < N_REG_CLASSES; rclass++)
+                       pp->cost[rclass] = intable[rclass][op_class];
                      break;
                    case OP_OUT:
-                     for (class = 0; class < N_REG_CLASSES; class++)
-                       pp->cost[class] = outtable[op_class][class];
+                     for (rclass = 0; rclass < N_REG_CLASSES; rclass++)
+                       pp->cost[rclass] = outtable[op_class][rclass];
                      break;
                    }
 
@@ -1899,6 +1958,9 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
       if (alt_fail)
        continue;
 
+      if (!recog_data.alternative_enabled_p[alt])
+       continue;
+
       /* Finally, update the costs with the information we've calculated
         about this alternative.  */
 
@@ -1912,9 +1974,9 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
            pp->mem_cost = MIN (pp->mem_cost,
                                (qq->mem_cost + alt_cost) * scale);
 
-           for (class = 0; class < N_REG_CLASSES; class++)
-             pp->cost[class] = MIN (pp->cost[class],
-                                    (qq->cost[class] + alt_cost) * scale);
+           for (rclass = 0; rclass < N_REG_CLASSES; rclass++)
+             pp->cost[rclass] = MIN (pp->cost[rclass],
+                                    (qq->cost[rclass] + alt_cost) * scale);
          }
     }
 
@@ -1924,7 +1986,7 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
      we may want to adjust the cost of that register class to -1.
 
      Avoid the adjustment if the source does not die to avoid stressing of
-     register allocator by preferrencing two colliding registers into single
+     register allocator by preferencing two colliding registers into single
      class.
 
      Also avoid the adjustment if a copy between registers of the class
@@ -1941,7 +2003,7 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
        {
          unsigned int regno = REGNO (ops[!i]);
          enum machine_mode mode = GET_MODE (ops[!i]);
-         int class;
+         int rclass;
 
          if (regno >= FIRST_PSEUDO_REGISTER && reg_pref != 0
              && reg_pref[regno].prefclass != NO_REGS)
@@ -1954,15 +2016,15 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
                op_costs[i].cost[(unsigned char) pref] = -1;
            }
          else if (regno < FIRST_PSEUDO_REGISTER)
-           for (class = 0; class < N_REG_CLASSES; class++)
-             if (TEST_HARD_REG_BIT (reg_class_contents[class], regno)
-                 && reg_class_size[class] == (unsigned) CLASS_MAX_NREGS (class, mode))
+           for (rclass = 0; rclass < N_REG_CLASSES; rclass++)
+             if (TEST_HARD_REG_BIT (reg_class_contents[rclass], regno)
+                 && reg_class_size[rclass] == (unsigned) CLASS_MAX_NREGS (rclass, mode))
                {
-                 if (reg_class_size[class] == 1)
-                   op_costs[i].cost[class] = -1;
-                 else if (in_hard_reg_set_p (reg_class_contents[class],
+                 if (reg_class_size[rclass] == 1)
+                   op_costs[i].cost[rclass] = -1;
+                 else if (in_hard_reg_set_p (reg_class_contents[rclass],
                                             mode, regno))
-                   op_costs[i].cost[class] = -1;
+                   op_costs[i].cost[rclass] = -1;
                }
        }
 }
@@ -1973,7 +2035,7 @@ record_reg_classes (int n_alts, int n_ops, rtx *ops,
    X must not be a pseudo.  */
 
 static int
-copy_cost (rtx x, enum machine_mode mode, enum reg_class class, int to_p,
+copy_cost (rtx x, enum machine_mode mode, enum reg_class rclass, int to_p,
           secondary_reload_info *prev_sri)
 {
   enum reg_class secondary_class = NO_REGS;
@@ -1986,7 +2048,7 @@ copy_cost (rtx x, enum machine_mode mode, enum reg_class class, int to_p,
     return 0;
 
   /* Get the class we will actually use for a reload.  */
-  class = PREFERRED_RELOAD_CLASS (x, class);
+  rclass = PREFERRED_RELOAD_CLASS (x, rclass);
 
   /* If we need a secondary reload for an intermediate, the
      cost is that to load the input into the intermediate register, then
@@ -1994,13 +2056,13 @@ copy_cost (rtx x, enum machine_mode mode, enum reg_class class, int to_p,
 
   sri.prev_sri = prev_sri;
   sri.extra_cost = 0;
-  secondary_class = targetm.secondary_reload (to_p, x, class, mode, &sri);
+  secondary_class = targetm.secondary_reload (to_p, x, rclass, mode, &sri);
 
   if (!move_cost[mode])
     init_move_cost (mode);
 
   if (secondary_class != NO_REGS)
-    return (move_cost[mode][(int) secondary_class][(int) class]
+    return (move_cost[mode][(int) secondary_class][(int) rclass]
            + sri.extra_cost
            + copy_cost (x, mode, secondary_class, to_p, &sri));
 
@@ -2008,12 +2070,12 @@ copy_cost (rtx x, enum machine_mode mode, enum reg_class class, int to_p,
      cost to move between the register classes, and use 2 for everything
      else (constants).  */
 
-  if (MEM_P (x) || class == NO_REGS)
-    return sri.extra_cost + MEMORY_MOVE_COST (mode, class, to_p);
+  if (MEM_P (x) || rclass == NO_REGS)
+    return sri.extra_cost + MEMORY_MOVE_COST (mode, rclass, to_p);
 
   else if (REG_P (x))
     return (sri.extra_cost
-           + move_cost[mode][(int) REGNO_REG_CLASS (REGNO (x))][(int) class]);
+           + move_cost[mode][(int) REGNO_REG_CLASS (REGNO (x))][(int) rclass]);
 
   else
     /* If this is a constant, we may eventually want to call rtx_cost here.  */
@@ -2039,12 +2101,12 @@ record_address_regs (enum machine_mode mode, rtx x, int context,
                     int scale)
 {
   enum rtx_code code = GET_CODE (x);
-  enum reg_class class;
+  enum reg_class rclass;
 
   if (context == 1)
-    class = INDEX_REG_CLASS;
+    rclass = INDEX_REG_CLASS;
   else
-    class = base_reg_class (mode, outer_code, index_code);
+    rclass = base_reg_class (mode, outer_code, index_code);
 
   switch (code)
     {
@@ -2197,12 +2259,12 @@ record_address_regs (enum machine_mode mode, rtx x, int context,
        struct costs *pp = &costs[REGNO (x)];
        int i;
 
-       pp->mem_cost += (MEMORY_MOVE_COST (Pmode, class, 1) * scale) / 2;
+       pp->mem_cost += (MEMORY_MOVE_COST (Pmode, rclass, 1) * scale) / 2;
 
        if (!move_cost[Pmode])
          init_move_cost (Pmode);
        for (i = 0; i < N_REG_CLASSES; i++)
-         pp->cost[i] += (may_move_in_cost[Pmode][i][(int) class] * scale) / 2;
+         pp->cost[i] += (may_move_in_cost[Pmode][i][(int) rclass] * scale) / 2;
       }
       break;
 
@@ -2246,6 +2308,32 @@ auto_inc_dec_reg_p (rtx reg, enum machine_mode mode)
 }
 #endif
 \f
+
+/* Allocate space for reg info.  */
+void
+allocate_reg_info (void)
+{
+  int size = max_reg_num ();
+
+  gcc_assert (! reg_pref && ! reg_renumber);
+  reg_renumber = XNEWVEC (short, size);
+  reg_pref = XCNEWVEC (struct reg_pref, size);
+  memset (reg_renumber, -1, size * sizeof (short));
+}
+
+
+/* Resize reg info. The new elements will be uninitialized.  */
+void
+resize_reg_info (void)
+{
+  int size = max_reg_num ();
+
+  gcc_assert (reg_pref && reg_renumber);
+  reg_renumber = XRESIZEVEC (short, reg_renumber, size);
+  reg_pref = XRESIZEVEC (struct reg_pref, reg_pref, size);
+}
+
+
 /* Free up the space allocated by allocate_reg_info.  */
 void
 free_reg_info (void)
@@ -2263,6 +2351,21 @@ free_reg_info (void)
     }
 }
 
+
+\f
+
+/* Set up preferred and alternate classes for REGNO as PREFCLASS and
+   ALTCLASS.  */
+void
+setup_reg_classes (int regno,
+                  enum reg_class prefclass, enum reg_class altclass)
+{
+  if (reg_pref == NULL)
+    return;
+  reg_pref[regno].prefclass = prefclass;
+  reg_pref[regno].altclass = altclass;
+}
+
 \f
 /* This is the `regscan' pass of the compiler, run just before cse and
    again just before loop.  It finds the first and last use of each
@@ -2292,8 +2395,6 @@ reg_scan (rtx f, unsigned int nregs ATTRIBUTE_UNUSED)
    We should only record information for REGs with numbers
    greater than or equal to MIN_REGNO.  */
 
-extern struct tree_opt_pass *current_pass;
-
 static void
 reg_scan_mark_refs (rtx x, rtx insn)
 {
@@ -2404,10 +2505,7 @@ reg_scan_mark_refs (rtx x, rtx insn)
                 || (GET_CODE (src) == SUBREG && subreg_lowpart_p (src)))
            src = XEXP (src, 0);
 
-         if (REG_P (src))
-           REG_ATTRS (dest) = REG_ATTRS (src);
-         if (MEM_P (src))
-           set_reg_attrs_from_mem (dest, src);
+         set_reg_attrs_from_value (dest, src);
        }
 
       /* ... fall through ...  */
@@ -2468,15 +2566,18 @@ static htab_t subregs_of_mode;
 static hashval_t
 som_hash (const void *x)
 {
-  const struct subregs_of_mode_node *a = x;
+  const struct subregs_of_mode_node *const a =
+    (const struct subregs_of_mode_node *) x;
   return a->block;
 }
 
 static int
 som_eq (const void *x, const void *y)
 {
-  const struct subregs_of_mode_node *a = x;
-  const struct subregs_of_mode_node *b = y;
+  const struct subregs_of_mode_node *const a =
+    (const struct subregs_of_mode_node *) x;
+  const struct subregs_of_mode_node *const b =
+    (const struct subregs_of_mode_node *) y;
   return a->block == b->block;
 }
 
@@ -2501,7 +2602,7 @@ record_subregs_of_mode (rtx subreg)
   dummy.block = regno & -8;
   slot = htab_find_slot_with_hash (subregs_of_mode, &dummy,
                                   dummy.block, INSERT);
-  node = *slot;
+  node = (struct subregs_of_mode_node *) *slot;
   if (node == NULL)
     {
       node = XCNEW (struct subregs_of_mode_node);
@@ -2573,7 +2674,8 @@ cannot_change_mode_set_regs (HARD_REG_SET *used, enum machine_mode from,
 
   gcc_assert (subregs_of_mode);
   dummy.block = regno & -8;
-  node = htab_find_with_hash (subregs_of_mode, &dummy, dummy.block);
+  node = (struct subregs_of_mode_node *)
+    htab_find_with_hash (subregs_of_mode, &dummy, dummy.block);
   if (node == NULL)
     return;
 
@@ -2591,7 +2693,7 @@ cannot_change_mode_set_regs (HARD_REG_SET *used, enum machine_mode from,
 
 bool
 invalid_mode_change_p (unsigned int regno,
-                      enum reg_class class ATTRIBUTE_UNUSED,
+                      enum reg_class rclass ATTRIBUTE_UNUSED,
                       enum machine_mode from)
 {
   struct subregs_of_mode_node dummy, *node;
@@ -2600,14 +2702,15 @@ invalid_mode_change_p (unsigned int regno,
 
   gcc_assert (subregs_of_mode);
   dummy.block = regno & -8;
-  node = htab_find_with_hash (subregs_of_mode, &dummy, dummy.block);
+  node = (struct subregs_of_mode_node *)
+    htab_find_with_hash (subregs_of_mode, &dummy, dummy.block);
   if (node == NULL)
     return false;
 
   mask = 1 << (regno & 7);
   for (to = VOIDmode; to < NUM_MACHINE_MODES; to++)
     if (node->modes[to] & mask)
-      if (CANNOT_CHANGE_MODE_CLASS (from, to, class))
+      if (CANNOT_CHANGE_MODE_CLASS (from, to, rclass))
        return true;
 
   return false;
@@ -2644,8 +2747,10 @@ gate_subregs_of_mode_init (void)
 #endif
 }
 
-struct tree_opt_pass pass_subregs_of_mode_init =
+struct rtl_opt_pass pass_subregs_of_mode_init =
 {
+ {
+  RTL_PASS,
   "subregs_of_mode_init",               /* name */
   gate_subregs_of_mode_init,            /* gate */
   init_subregs_of_mode,                 /* execute */
@@ -2657,12 +2762,14 @@ struct tree_opt_pass pass_subregs_of_mode_init =
   0,                                    /* properties_provided */
   0,                                    /* properties_destroyed */
   0,                                    /* todo_flags_start */
-  0,                                    /* todo_flags_finish */
-  0                                     /* letter */
+  0                                     /* todo_flags_finish */
+ }
 };
 
-struct tree_opt_pass pass_subregs_of_mode_finish =
+struct rtl_opt_pass pass_subregs_of_mode_finish =
 {
+ {
+  RTL_PASS,
   "subregs_of_mode_finish",               /* name */
   gate_subregs_of_mode_init,            /* gate */
   finish_subregs_of_mode,               /* execute */
@@ -2674,8 +2781,8 @@ struct tree_opt_pass pass_subregs_of_mode_finish =
   0,                                    /* properties_provided */
   0,                                    /* properties_destroyed */
   0,                                    /* todo_flags_start */
-  0,                                    /* todo_flags_finish */
-  0                                     /* letter */
+  0                                     /* todo_flags_finish */
+ }
 };