/* 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.
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
;
#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
init_reg_sets_1 ();
init_reg_modes ();
+
+ init_reg_autoinc ();
}
/* Initialize some fake stack-frame MEM references for use in
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);
}
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;
}
}
#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
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;
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);
|| (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 ... */