Add support for -mreg-alloc=<xxx>

From-SVN: r8040
This commit is contained in:
Michael Meissner 1994-09-08 17:59:18 +00:00
parent 0be5d99ff2
commit f5316dfe88
2 changed files with 195 additions and 17 deletions

View File

@ -74,8 +74,120 @@ enum reg_class regclass_map[FIRST_PSEUDO_REGISTER] =
/* Test and compare insns in i386.md store the information needed to
generate branch and scc insns here. */
struct rtx_def *i386_compare_op0, *i386_compare_op1;
struct rtx_def *i386_compare_op0 = NULL_RTX;
struct rtx_def *i386_compare_op1 = NULL_RTX;
struct rtx_def *(*i386_compare_gen)(), *(*i386_compare_gen_eq)();
/* Register allocation order */
char *i386_reg_alloc_order = (char *)0;
static char regs_allocated[FIRST_PSEUDO_REGISTER];
/* Sometimes certain combinations of command options do not make
sense on a particular target machine. You can define a macro
`OVERRIDE_OPTIONS' to take account of this. This macro, if
defined, is executed once just after all the command options have
been parsed.
Don't use this macro to turn on various extra optimizations for
`-O'. That is what `OPTIMIZATION_OPTIONS' is for. */
void
override_options ()
{
int ch, i, regno;
#ifdef SUBTARGET_OVERRIDE_OPTIONS
SUBTARGET_OVERRIDE_OPTIONS;
#endif
/* Validate registers in register allocation order */
if (i386_reg_alloc_order)
{
for (i = 0; (ch = i386_reg_alloc_order[i]) != '\0'; i++)
{
switch (ch)
{
case 'a': regno = 0; break;
case 'd': regno = 1; break;
case 'c': regno = 2; break;
case 'b': regno = 3; break;
case 'S': regno = 4; break;
case 'D': regno = 5; break;
case 'B': regno = 6; break;
default: fatal ("Register '%c' is unknown", ch);
}
if (regs_allocated[regno])
fatal ("Register '%c' was already specified in the allocation order", ch);
regs_allocated[regno] = 1;
}
}
}
/* A C statement (sans semicolon) to choose the order in which to
allocate hard registers for pseudo-registers local to a basic
block.
Store the desired register order in the array `reg_alloc_order'.
Element 0 should be the register to allocate first; element 1, the
next register; and so on.
The macro body should not assume anything about the contents of
`reg_alloc_order' before execution of the macro.
On most machines, it is not necessary to define this macro. */
void
order_regs_for_local_alloc ()
{
int i, ch, order, regno;
/* User specified the register allocation order */
if (i386_reg_alloc_order)
{
for (i = order = 0; (ch = i386_reg_alloc_order[i]) != '\0'; i++)
{
switch (ch)
{
case 'a': regno = 0; break;
case 'd': regno = 1; break;
case 'c': regno = 2; break;
case 'b': regno = 3; break;
case 'S': regno = 4; break;
case 'D': regno = 5; break;
case 'B': regno = 6; break;
}
reg_alloc_order[order++] = regno;
}
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
{
if (!regs_allocated[i])
reg_alloc_order[order++] = i;
}
}
/* If users did not specify a register allocation order, favor eax
normally except if cse is following jumps, then favor edx so
that function returns are cse'ed */
else
{
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
reg_alloc_order[i] = i;
if (optimize && flag_cse_follow_jumps && !leaf_function_p ())
{
reg_alloc_order[0] = 1; /* edx */
reg_alloc_order[1] = 2; /* ecx */
reg_alloc_order[2] = 0; /* eax */
}
}
}
/* Output an insn whose source is a 386 integer register. SRC is the
rtx for the register, and TEMPLATE is the op-code template. SRC may

View File

@ -158,16 +158,34 @@ extern int target_flags;
SUBTARGET_SWITCHES \
{ "", TARGET_DEFAULT | TARGET_CPU_DEFAULT}}
/* This is meant to be redefined in the host dependent files */
/* This macro is similar to `TARGET_SWITCHES' but defines names of
command options that have values. Its definition is an
initializer with a subgrouping for each command option.
Each subgrouping contains a string constant, that defines the
fixed part of the option name, and the address of a variable. The
variable, type `char *', is set to the variable part of the given
option if the fixed part matches. The actual option name is made
by appending `-m' to the specified name. */
#define TARGET_OPTIONS \
{ { "reg-alloc=", &i386_reg_alloc_order }, \
SUBTARGET_OPTIONS }
/* Sometimes certain combinations of command options do not make
sense on a particular target machine. You can define a macro
`OVERRIDE_OPTIONS' to take account of this. This macro, if
defined, is executed once just after all the command options have
been parsed.
Don't use this macro to turn on various extra optimizations for
`-O'. That is what `OPTIMIZATION_OPTIONS' is for. */
#define OVERRIDE_OPTIONS override_options ()
/* These are meant to be redefined in the host dependent files */
#define SUBTARGET_SWITCHES
#define SUBTARGET_OPTIONS
#define OVERRIDE_OPTIONS \
{ \
SUBTARGET_OVERRIDE_OPTIONS \
}
/* This is meant to be redefined in the host dependent files */
#define SUBTARGET_OVERRIDE_OPTIONS
/* target machine storage layout */
@ -313,11 +331,24 @@ extern int target_flags;
functions, and a slightly slower compiler. Users complained about the code
generated by allocating edx first, so restore the 'natural' order of things. */
#if 0
#define REG_ALLOC_ORDER \
/*dx,cx,ax,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg*/ \
{ 1, 2, 0, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }
#endif
/*ax,dx,cx,bx,si,di,bp,sp,st,st1,st2,st3,st4,st5,st6,st7,arg*/ \
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }
/* A C statement (sans semicolon) to choose the order in which to
allocate hard registers for pseudo-registers local to a basic
block.
Store the desired register order in the array `reg_alloc_order'.
Element 0 should be the register to allocate first; element 1, the
next register; and so on.
The macro body should not assume anything about the contents of
`reg_alloc_order' before execution of the macro.
On most machines, it is not necessary to define this macro. */
#define ORDER_REGS_FOR_LOCAL_ALLOC order_regs_for_local_alloc ()
/* Macro to conditionally modify fixed_regs/call_used_regs. */
#define CONDITIONAL_REGISTER_USAGE \
@ -509,7 +540,6 @@ enum reg_class
reg number REGNO. This could be a conditional expression
or could index an array. */
extern enum reg_class regclass_map[FIRST_PSEUDO_REGISTER];
#define REGNO_REG_CLASS(REGNO) (regclass_map[REGNO])
/* When defined, the compiler allows registers explicitly used in the
@ -641,6 +671,32 @@ extern enum reg_class regclass_map[FIRST_PSEUDO_REGISTER];
#define CLASS_MAX_NREGS(CLASS, MODE) \
(FLOAT_CLASS_P (CLASS) ? 1 : \
((GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD))
/* A C expression whose value is nonzero if pseudos that have been
assigned to registers of class CLASS would likely be spilled
because registers of CLASS are needed for spill registers.
The default value of this macro returns 1 if CLASS has exactly one
register and zero otherwise. On most machines, this default
should be used. Only define this macro to some other expression
if pseudo allocated by `local-alloc.c' end up in memory because
their hard registers were needed for spill regisers. If this
macro returns nonzero for those classes, those pseudos will only
be allocated by `global.c', which knows how to reallocate the
pseudo to another register. If there would not be another
register available for reallocation, you should not change the
definition of this macro since the only effect of such a
definition would be to slow down register allocation. */
#define CLASS_LIKELY_SPILLED_P(CLASS) \
(((CLASS) == AREG) \
|| ((CLASS) == DREG) \
|| ((CLASS) == CREG) \
|| ((CLASS) == BREG) \
|| ((CLASS) == AD_REGS) \
|| ((CLASS) == SIREG) \
|| ((CLASS) == DIREG))
/* Stack layout; function entry, exit and calling. */
@ -1296,7 +1352,6 @@ while (0)
stored from the compare operation. Note that we can't use "rtx" here
since it hasn't been defined! */
extern struct rtx_def *i386_compare_op0, *i386_compare_op1;
extern struct rtx_def *(*i386_compare_gen)(), *(*i386_compare_gen_eq)();
/* Tell final.c how to eliminate redundant test instructions. */
@ -1643,6 +1698,8 @@ extern char *qi_high_reg_name[];
#define AT_SP(mode) (gen_rtx (MEM, (mode), stack_pointer_rtx))
/* Functions in i386.c */
extern void override_options ();
extern void order_regs_for_local_alloc ();
extern void output_op_from_reg ();
extern void output_to_reg ();
extern char *singlemove_string ();
@ -1676,9 +1733,18 @@ extern void restore_386_machine_status ();
extern void clear_386_stack_locals ();
extern struct rtx_def *assign_386_stack_local ();
/* Variables in i386.c */
extern char *i386_reg_alloc_order; /* register allocation order */
extern char *hi_reg_name[]; /* names for 16 bit regs */
extern char *qi_reg_name[]; /* names for 8 bit regs (low) */
extern char *qi_high_reg_name[]; /* names for 8 bit regs (high) */
extern enum reg_class regclass_map[]; /* smalled class containing REGNO */
extern struct rtx_def *i386_compare_op0; /* operand 0 for comparisons */
extern struct rtx_def *i386_compare_op1; /* operand 1 for comparisons */
/* External variables used */
extern int optimize; /* optimization level */
extern int obey_regdecls; /* TRUE if stupid register allocation */
extern int optimize; /* optimization level */
extern int obey_regdecls; /* TRUE if stupid register allocation */
/* External functions used */
extern struct rtx_def *force_operand ();