/* 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.
/* 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.
/* 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
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
/* 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. */
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. */
}
}
-/* 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++)
}
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
}
}
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 */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
- 0, /* todo_flags_finish */
- 'k' /* letter */
+ 0 /* todo_flags_finish */
+ }
};
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);
}
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;
[(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;
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. */
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
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)
{
|| (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 ... */
#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 */
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 */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
- 0, /* todo_flags_finish */
- 0 /* letter */
+ 0 /* todo_flags_finish */
+ }
};