OSDN Git Service

* regclass.c (init_reg_autoinc): New function.
[pf3gnuchains/gcc-fork.git] / gcc / regclass.c
index 6b6a6dd..ea6c86b 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 Free Software Foundation, Inc.
+   1997, 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
 
 This file is part of GCC.
 
@@ -50,6 +50,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 
 static void init_reg_sets_1    PARAMS ((void));
 static void init_reg_modes     PARAMS ((void));
+static void init_reg_autoinc   PARAMS ((void));
 
 /* If we have auto-increment or auto-decrement and we can have secondary
    reloads, we are not allowed to use classes requiring secondary
@@ -459,7 +460,7 @@ init_reg_sets_1 ()
        ;
 #endif
 #ifndef PIC_OFFSET_TABLE_REG_CALL_CLOBBERED
-      else if (i == PIC_OFFSET_TABLE_REGNUM && fixed_regs[i])
+      else if (i == (unsigned) PIC_OFFSET_TABLE_REGNUM && fixed_regs[i])
        ;
 #endif
       else if (0
@@ -578,6 +579,8 @@ init_regs ()
   init_reg_sets_1 ();
 
   init_reg_modes ();
+
+  init_reg_autoinc ();
 }
 
 /* Initialize some fake stack-frame MEM references for use in
@@ -977,7 +980,7 @@ record_operand_costs (insn, op_costs, reg_pref)
        record_address_regs (XEXP (recog_data.operand[i], 0),
                             MODE_BASE_REG_CLASS (modes[i]), frequency * 2);
       else if (constraints[i][0] == 'p'
-              || EXTRA_ADDRESS_CONSTRAINT (constraints[i][0]))
+              || EXTRA_ADDRESS_CONSTRAINT (constraints[i][0], constraints[i]))
        record_address_regs (recog_data.operand[i],
                             MODE_BASE_REG_CLASS (modes[i]), frequency * 2);
     }
@@ -1143,37 +1146,18 @@ scan_one_insn (insn, pass)
   return insn;
 }
 
-/* This is a pass of the compiler that scans all instructions
-   and calculates the preferred class for each pseudo-register.
-   This information can be accessed later by calling `reg_preferred_class'.
-   This pass comes just before local register allocation.  */
+/* Initialize information about which register classes can be used for
+   pseudos that are auto-incremented or auto-decremented.  */
 
-void
-regclass (f, nregs, dump)
-     rtx f;
-     int nregs;
-     FILE *dump;
+static void
+init_reg_autoinc ()
 {
-  rtx insn;
-  int i;
-  int pass;
-
-  init_recog ();
-
-  costs = (struct costs *) xmalloc (nregs * sizeof (struct costs));
-
 #ifdef FORBIDDEN_INC_DEC_CLASSES
-
-  in_inc_dec = (char *) xmalloc (nregs);
-
-  /* Initialize information about which register classes can be used for
-     pseudos that are auto-incremented or auto-decremented.  It would
-     seem better to put this in init_reg_sets, but we need to be able
-     to allocate rtx, which we can't do that early.  */
+  int i;
 
   for (i = 0; i < N_REG_CLASSES; i++)
     {
-      rtx r = gen_rtx_REG (VOIDmode, 0);
+      rtx r = gen_rtx_raw_REG (VOIDmode, 0);
       enum machine_mode m;
       int j;
 
@@ -1214,6 +1198,32 @@ regclass (f, nregs, dump)
          }
     }
 #endif /* FORBIDDEN_INC_DEC_CLASSES */
+}
+
+/* This is a pass of the compiler that scans all instructions
+   and calculates the preferred class for each pseudo-register.
+   This information can be accessed later by calling `reg_preferred_class'.
+   This pass comes just before local register allocation.  */
+
+void
+regclass (f, nregs, dump)
+     rtx f;
+     int nregs;
+     FILE *dump;
+{
+  rtx insn;
+  int i;
+  int pass;
+
+  init_recog ();
+
+  costs = (struct costs *) xmalloc (nregs * sizeof (struct costs));
+
+#ifdef FORBIDDEN_INC_DEC_CLASSES
+
+  in_inc_dec = (char *) xmalloc (nregs);
+
+#endif /* FORBIDDEN_INC_DEC_CLASSES */
 
   /* Normally we scan the insns once and determine the best class to use for
      each register.  However, if -fexpensive_optimizations are on, we do so
@@ -1548,154 +1558,161 @@ record_reg_classes (n_alts, n_ops, ops, modes,
             any of the constraints.  Collect the valid register classes
             and see if this operand accepts memory.  */
 
-         while (*p && (c = *p++) != ',')
-           switch (c)
-             {
-             case '*':
-               /* Ignore the next letter for this pass.  */
-               p++;
-               break;
-
-             case '?':
-               alt_cost += 2;
-             case '!':  case '#':  case '&':
-             case '0':  case '1':  case '2':  case '3':  case '4':
-             case '5':  case '6':  case '7':  case '8':  case '9':
-               break;
+         while ((c = *p))
+           {
+             switch (c)
+               {
+               case ',':
+                 break;
+               case '*':
+                 /* Ignore the next letter for this pass.  */
+                 c = *++p;
+                 break;
 
-             case 'p':
-               allows_addr = 1;
-               win = address_operand (op, GET_MODE (op));
-               /* We know this operand is an address, so we want it to be
-                  allocated to a register that can be the base of an
-                  address, ie BASE_REG_CLASS.  */
-               classes[i]
-                 = reg_class_subunion[(int) classes[i]]
-                   [(int) MODE_BASE_REG_CLASS (VOIDmode)];
-               break;
+               case '?':
+                 alt_cost += 2;
+               case '!':  case '#':  case '&':
+               case '0':  case '1':  case '2':  case '3':  case '4':
+               case '5':  case '6':  case '7':  case '8':  case '9':
+                 break;
 
-             case 'm':  case 'o':  case 'V':
-               /* It doesn't seem worth distinguishing between offsettable
-                  and non-offsettable addresses here.  */
-               allows_mem[i] = 1;
-               if (GET_CODE (op) == MEM)
-                 win = 1;
-               break;
+               case 'p':
+                 allows_addr = 1;
+                 win = address_operand (op, GET_MODE (op));
+                 /* We know this operand is an address, so we want it to be
+                    allocated to a register that can be the base of an
+                    address, ie BASE_REG_CLASS.  */
+                 classes[i]
+                   = reg_class_subunion[(int) classes[i]]
+                     [(int) MODE_BASE_REG_CLASS (VOIDmode)];
+                 break;
 
-             case '<':
-               if (GET_CODE (op) == MEM
-                   && (GET_CODE (XEXP (op, 0)) == PRE_DEC
-                       || GET_CODE (XEXP (op, 0)) == POST_DEC))
-                 win = 1;
-               break;
+               case 'm':  case 'o':  case 'V':
+                 /* It doesn't seem worth distinguishing between offsettable
+                    and non-offsettable addresses here.  */
+                 allows_mem[i] = 1;
+                 if (GET_CODE (op) == MEM)
+                   win = 1;
+                 break;
 
-             case '>':
-               if (GET_CODE (op) == MEM
-                   && (GET_CODE (XEXP (op, 0)) == PRE_INC
-                       || GET_CODE (XEXP (op, 0)) == POST_INC))
-                 win = 1;
-               break;
+               case '<':
+                 if (GET_CODE (op) == MEM
+                     && (GET_CODE (XEXP (op, 0)) == PRE_DEC
+                         || GET_CODE (XEXP (op, 0)) == POST_DEC))
+                   win = 1;
+                 break;
 
-             case 'E':
-             case 'F':
-               if (GET_CODE (op) == CONST_DOUBLE
-                   || (GET_CODE (op) == CONST_VECTOR
-                       && (GET_MODE_CLASS (GET_MODE (op))
-                           == MODE_VECTOR_FLOAT)))
-                 win = 1;
-               break;
+               case '>':
+                 if (GET_CODE (op) == MEM
+                     && (GET_CODE (XEXP (op, 0)) == PRE_INC
+                         || GET_CODE (XEXP (op, 0)) == POST_INC))
+                   win = 1;
+                 break;
 
-             case 'G':
-             case 'H':
-               if (GET_CODE (op) == CONST_DOUBLE
-                   && CONST_DOUBLE_OK_FOR_LETTER_P (op, c))
-                 win = 1;
-               break;
+               case 'E':
+               case 'F':
+                 if (GET_CODE (op) == CONST_DOUBLE
+                     || (GET_CODE (op) == CONST_VECTOR
+                         && (GET_MODE_CLASS (GET_MODE (op))
+                             == MODE_VECTOR_FLOAT)))
+                   win = 1;
+                 break;
 
-             case 's':
-               if (GET_CODE (op) == CONST_INT
-                   || (GET_CODE (op) == CONST_DOUBLE
-                       && GET_MODE (op) == VOIDmode))
+               case 'G':
+               case 'H':
+                 if (GET_CODE (op) == CONST_DOUBLE
+                     && CONST_DOUBLE_OK_FOR_CONSTRAINT_P (op, c, p))
+                   win = 1;
                  break;
-             case 'i':
-               if (CONSTANT_P (op)
+
+               case 's':
+                 if (GET_CODE (op) == CONST_INT
+                     || (GET_CODE (op) == CONST_DOUBLE
+                         && GET_MODE (op) == VOIDmode))
+                   break;
+               case 'i':
+                 if (CONSTANT_P (op)
 #ifdef LEGITIMATE_PIC_OPERAND_P
-                   && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))
+                     && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))
 #endif
-                   )
-                 win = 1;
-               break;
+                     )
+                   win = 1;
+                 break;
 
-             case 'n':
-               if (GET_CODE (op) == CONST_INT
-                   || (GET_CODE (op) == CONST_DOUBLE
-                       && GET_MODE (op) == VOIDmode))
-                 win = 1;
-               break;
+               case 'n':
+                 if (GET_CODE (op) == CONST_INT
+                     || (GET_CODE (op) == CONST_DOUBLE
+                         && GET_MODE (op) == VOIDmode))
+                   win = 1;
+                 break;
 
-             case 'I':
-             case 'J':
-             case 'K':
-             case 'L':
-             case 'M':
-             case 'N':
-             case 'O':
-             case 'P':
-               if (GET_CODE (op) == CONST_INT
-                   && CONST_OK_FOR_LETTER_P (INTVAL (op), c))
-                 win = 1;
-               break;
+               case 'I':
+               case 'J':
+               case 'K':
+               case 'L':
+               case 'M':
+               case 'N':
+               case 'O':
+               case 'P':
+                 if (GET_CODE (op) == CONST_INT
+                     && CONST_OK_FOR_CONSTRAINT_P (INTVAL (op), c, p))
+                   win = 1;
+                 break;
 
-             case 'X':
-               win = 1;
-               break;
+               case 'X':
+                 win = 1;
+                 break;
 
-             case 'g':
-               if (GET_CODE (op) == MEM
-                   || (CONSTANT_P (op)
+               case 'g':
+                 if (GET_CODE (op) == MEM
+                     || (CONSTANT_P (op)
 #ifdef LEGITIMATE_PIC_OPERAND_P
-                       && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))
+                         && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))
 #endif
-                       ))
-                 win = 1;
-               allows_mem[i] = 1;
-             case 'r':
-               classes[i]
-                 = reg_class_subunion[(int) classes[i]][(int) GENERAL_REGS];
-               break;
-
-             default:
-               if (REG_CLASS_FROM_LETTER (c) != NO_REGS)
+                         ))
+                   win = 1;
+                 allows_mem[i] = 1;
+               case 'r':
                  classes[i]
-                   = reg_class_subunion[(int) classes[i]]
-                     [(int) REG_CLASS_FROM_LETTER (c)];
-#ifdef EXTRA_CONSTRAINT
-               else if (EXTRA_CONSTRAINT (op, c))
-                 win = 1;
+                   = reg_class_subunion[(int) classes[i]][(int) GENERAL_REGS];
+                 break;
 
-               if (EXTRA_MEMORY_CONSTRAINT (c))
-                 {
-                   /* Every MEM can be reloaded to fit.  */
-                   allows_mem[i] = 1;
-                   if (GET_CODE (op) == MEM)
-                     win = 1;
-                 }
-               if (EXTRA_ADDRESS_CONSTRAINT (op))
-                 {
-                   /* Every address can be reloaded to fit.  */
-                   allows_addr = 1;
-                   if (address_operand (op, GET_MODE (op)))
-                     win = 1;
-                   /* We know this operand is an address, so we want it to be
-                      allocated to a register that can be the base of an
-                      address, ie BASE_REG_CLASS.  */
+               default:
+                 if (REG_CLASS_FROM_CONSTRAINT (c, p) != NO_REGS)
                    classes[i]
                      = reg_class_subunion[(int) classes[i]]
-                       [(int) MODE_BASE_REG_CLASS (VOIDmode)];
-                 }
+                       [(int) REG_CLASS_FROM_CONSTRAINT (c, p)];
+#ifdef EXTRA_CONSTRAINT_STR
+                 else if (EXTRA_CONSTRAINT_STR (op, c, p))
+                   win = 1;
+
+                 if (EXTRA_MEMORY_CONSTRAINT (c, p))
+                   {
+                     /* Every MEM can be reloaded to fit.  */
+                     allows_mem[i] = 1;
+                     if (GET_CODE (op) == MEM)
+                       win = 1;
+                   }
+                 if (EXTRA_ADDRESS_CONSTRAINT (c, p))
+                   {
+                     /* Every address can be reloaded to fit.  */
+                     allows_addr = 1;
+                     if (address_operand (op, GET_MODE (op)))
+                       win = 1;
+                     /* We know this operand is an address, so we want it to
+                        be allocated to a register that can be the base of an
+                        address, ie BASE_REG_CLASS.  */
+                     classes[i]
+                       = reg_class_subunion[(int) classes[i]]
+                         [(int) MODE_BASE_REG_CLASS (VOIDmode)];
+                   }
 #endif
+                 break;
+               }
+             p += CONSTRAINT_LEN (c, p);
+             if (c == ',')
                break;
-             }
+           }
 
          constraints[i] = p;
 
@@ -2513,7 +2530,7 @@ reg_scan_mark_refs (x, insn, note_flag, min_regno)
        REG_POINTER (SET_DEST (x)) = 1;
 
       /* If this is setting a register from a register or from a simple
-        conversion of a register, propagate REG_DECL.  */
+        conversion of a register, propagate REG_EXPR.  */
       if (GET_CODE (dest) == REG)
        {
          rtx src = SET_SRC (x);
@@ -2524,10 +2541,10 @@ reg_scan_mark_refs (x, insn, note_flag, min_regno)
                 || (GET_CODE (src) == SUBREG && subreg_lowpart_p (src)))
            src = XEXP (src, 0);
 
-         if (GET_CODE (src) == REG && REGNO_DECL (REGNO (src)) == 0)
-           REGNO_DECL (REGNO (src)) = REGNO_DECL (REGNO (dest));
-         else if (GET_CODE (src) == REG && REGNO_DECL (REGNO (dest)) == 0)
-           REGNO_DECL (REGNO (dest)) = REGNO_DECL (REGNO (src));
+         if (!REG_ATTRS (dest) && REG_P (src))
+           REG_ATTRS (dest) = REG_ATTRS (src);
+         if (!REG_ATTRS (dest) && GET_CODE (src) == MEM)
+           set_reg_attrs_from_mem (dest, src);
        }
 
       /* ... fall through ...  */