mirror of
https://gcc.gnu.org/git/gcc.git
synced 2024-11-24 11:24:05 +08:00
Separate target-specific initialization from general back-end initialization.
2007-08-27 Sandra Loosemore <sandra@codesourcery.com> David Ung <davidu@mips.com> Nigel Stephens <nigel@mips.com> gcc/ Separate target-specific initialization from general back-end initialization. * toplev.c (init_alignments): New, split out from... (process_options): ...here. (backend_init_target): New, split out from... (backend_init): ...here. (lang_dependent_init_target): New, split out from... (lang_dependent_init): ...here. (target_reinit): New. * toplev.h (target_reinit): Declare. * expr.c (init_expr_target): Renamed from init_expr_once, since it now can be called more than once. Update comments. * expr.h (init_expr_target): Likewise. * alias.c (init_alias_target): Renamed from init_alias_once, since it now can be called more than once. Explicitly zero static_reg_base_value. * emit-rtl.c (init_emit_regs): New, split out from... (init_emit_once): Here. * regclass.c (initial_fixed_regs, initial_call_used_regs): Make non-const, so that changes from command-line arguments can overwrite values provided by the static initializers. (initial_call_really_used_regs): New, used similarly to the above. (initial_reg_names): Likewise. (last_mode_for_init_move_cost): Promoted function-local static to file-scope static to make it accessible outside init_move_cost. (init_reg_sets): Do not initialize fixed_regs and call_used_regs yet. Do not initialize inv_reg_alloc_order yet, either. Do initialize reg_names since it is needed for parsing command-line options. (init_move_cost): Use last_mode_for_init_move_cost instead of function-local static. (init_reg_sets_1): Initialize fixed_regs, call_used_regs, and call_really_used_regs now. Reinitialize reg_names. Also initialize inv_reg_alloc_order. Zero reg_class_subunion and reg_class_superunion. Clear losing_caller_save_reg_set. Preserve global registers if called more than once. Reset move cost, may_move_in_cost, may_move_out_cost, and last_mode_for_init_move_cost. (init_reg_modes_target): Renamed from init_reg_modes_once, since it can now be invoked more than once. Update comments. (init_regs): Update comments. (fix_register): Update initial_fixed_regs, initial_call_used_regs, and initial_call_really_used_regs, instead of the non-initial variables. This allows us to save the command-line register settings after target reinitialization. (init_reg_autoinc): Zero forbidden_inc_dec_classes. * rtl.h (init_emit_regs): Declare. (init_reg_modes_target, init_alias_target): Renamed as described above. * reload1.c (init_reload): Update comments. * optabs.c (init_optabs): Likewise. * cfgloopanal.c (init_set_costs): Explicitly zero target_avail_regs. Co-Authored-By: David Ung <davidu@mips.com> Co-Authored-By: Nigel Stephens <nigel@mips.com> From-SVN: r127832
This commit is contained in:
parent
107d76762a
commit
b5deb7b691
@ -1,3 +1,60 @@
|
||||
2007-08-27 Sandra Loosemore <sandra@codesourcery.com>
|
||||
David Ung <davidu@mips.com>
|
||||
Nigel Stephens <nigel@mips.com>
|
||||
|
||||
Separate target-specific initialization from general
|
||||
back-end initialization.
|
||||
|
||||
* toplev.c (init_alignments): New, split out from...
|
||||
(process_options): ...here.
|
||||
(backend_init_target): New, split out from...
|
||||
(backend_init): ...here.
|
||||
(lang_dependent_init_target): New, split out from...
|
||||
(lang_dependent_init): ...here.
|
||||
(target_reinit): New.
|
||||
* toplev.h (target_reinit): Declare.
|
||||
* expr.c (init_expr_target): Renamed from init_expr_once, since it
|
||||
now can be called more than once. Update comments.
|
||||
* expr.h (init_expr_target): Likewise.
|
||||
* alias.c (init_alias_target): Renamed from init_alias_once, since it
|
||||
now can be called more than once. Explicitly zero
|
||||
static_reg_base_value.
|
||||
* emit-rtl.c (init_emit_regs): New, split out from...
|
||||
(init_emit_once): Here.
|
||||
* regclass.c (initial_fixed_regs, initial_call_used_regs): Make
|
||||
non-const, so that changes from command-line arguments can overwrite
|
||||
values provided by the static initializers.
|
||||
(initial_call_really_used_regs): New, used similarly to the above.
|
||||
(initial_reg_names): Likewise.
|
||||
(last_mode_for_init_move_cost): Promoted function-local static to
|
||||
file-scope static to make it accessible outside init_move_cost.
|
||||
(init_reg_sets): Do not initialize fixed_regs and call_used_regs yet.
|
||||
Do not initialize inv_reg_alloc_order yet, either. Do initialize
|
||||
reg_names since it is needed for parsing command-line options.
|
||||
(init_move_cost): Use last_mode_for_init_move_cost instead of
|
||||
function-local static.
|
||||
(init_reg_sets_1): Initialize fixed_regs, call_used_regs, and
|
||||
call_really_used_regs now. Reinitialize reg_names. Also
|
||||
initialize inv_reg_alloc_order. Zero reg_class_subunion and
|
||||
reg_class_superunion. Clear losing_caller_save_reg_set.
|
||||
Preserve global registers if called more than once. Reset
|
||||
move cost, may_move_in_cost, may_move_out_cost, and
|
||||
last_mode_for_init_move_cost.
|
||||
(init_reg_modes_target): Renamed from init_reg_modes_once, since it
|
||||
can now be invoked more than once. Update comments.
|
||||
(init_regs): Update comments.
|
||||
(fix_register): Update initial_fixed_regs, initial_call_used_regs,
|
||||
and initial_call_really_used_regs, instead of the non-initial
|
||||
variables. This allows us to save the command-line register settings
|
||||
after target reinitialization.
|
||||
(init_reg_autoinc): Zero forbidden_inc_dec_classes.
|
||||
* rtl.h (init_emit_regs): Declare.
|
||||
(init_reg_modes_target, init_alias_target): Renamed as described
|
||||
above.
|
||||
* reload1.c (init_reload): Update comments.
|
||||
* optabs.c (init_optabs): Likewise.
|
||||
* cfgloopanal.c (init_set_costs): Explicitly zero target_avail_regs.
|
||||
|
||||
2007-08-26 Chao-ying Fu <fu@mips.com>
|
||||
|
||||
* rtl.h (XCNMPFV): Preserve const-ness of parameters through use of
|
||||
|
@ -2325,10 +2325,12 @@ output_dependence (const_rtx mem, const_rtx x)
|
||||
|
||||
|
||||
void
|
||||
init_alias_once (void)
|
||||
init_alias_target (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
memset (static_reg_base_value, 0, sizeof static_reg_base_value);
|
||||
|
||||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
||||
/* Check whether this register can hold an incoming pointer
|
||||
argument. FUNCTION_ARG_REGNO_P tests outgoing register
|
||||
|
@ -334,6 +334,7 @@ init_set_costs (void)
|
||||
rtx mem = validize_mem (gen_rtx_MEM (SImode, addr));
|
||||
unsigned i;
|
||||
|
||||
target_avail_regs = 0;
|
||||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
||||
if (TEST_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], i)
|
||||
&& !fixed_regs[i])
|
||||
|
129
gcc/emit-rtl.c
129
gcc/emit-rtl.c
@ -5260,6 +5260,74 @@ gen_rtx_CONST_VECTOR (enum machine_mode mode, rtvec v)
|
||||
return gen_rtx_raw_CONST_VECTOR (mode, v);
|
||||
}
|
||||
|
||||
/* Initialise global register information required by all functions. */
|
||||
|
||||
void
|
||||
init_emit_regs (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Reset register attributes */
|
||||
htab_empty (reg_attrs_htab);
|
||||
|
||||
/* We need reg_raw_mode, so initialize the modes now. */
|
||||
init_reg_modes_target ();
|
||||
|
||||
/* Assign register numbers to the globally defined register rtx. */
|
||||
pc_rtx = gen_rtx_PC (VOIDmode);
|
||||
cc0_rtx = gen_rtx_CC0 (VOIDmode);
|
||||
stack_pointer_rtx = gen_raw_REG (Pmode, STACK_POINTER_REGNUM);
|
||||
frame_pointer_rtx = gen_raw_REG (Pmode, FRAME_POINTER_REGNUM);
|
||||
hard_frame_pointer_rtx = gen_raw_REG (Pmode, HARD_FRAME_POINTER_REGNUM);
|
||||
arg_pointer_rtx = gen_raw_REG (Pmode, ARG_POINTER_REGNUM);
|
||||
virtual_incoming_args_rtx =
|
||||
gen_raw_REG (Pmode, VIRTUAL_INCOMING_ARGS_REGNUM);
|
||||
virtual_stack_vars_rtx =
|
||||
gen_raw_REG (Pmode, VIRTUAL_STACK_VARS_REGNUM);
|
||||
virtual_stack_dynamic_rtx =
|
||||
gen_raw_REG (Pmode, VIRTUAL_STACK_DYNAMIC_REGNUM);
|
||||
virtual_outgoing_args_rtx =
|
||||
gen_raw_REG (Pmode, VIRTUAL_OUTGOING_ARGS_REGNUM);
|
||||
virtual_cfa_rtx = gen_raw_REG (Pmode, VIRTUAL_CFA_REGNUM);
|
||||
|
||||
/* Initialize RTL for commonly used hard registers. These are
|
||||
copied into regno_reg_rtx as we begin to compile each function. */
|
||||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
||||
static_regno_reg_rtx[i] = gen_raw_REG (reg_raw_mode[i], i);
|
||||
|
||||
#ifdef RETURN_ADDRESS_POINTER_REGNUM
|
||||
return_address_pointer_rtx
|
||||
= gen_raw_REG (Pmode, RETURN_ADDRESS_POINTER_REGNUM);
|
||||
#endif
|
||||
|
||||
#ifdef STATIC_CHAIN_REGNUM
|
||||
static_chain_rtx = gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM);
|
||||
|
||||
#ifdef STATIC_CHAIN_INCOMING_REGNUM
|
||||
if (STATIC_CHAIN_INCOMING_REGNUM != STATIC_CHAIN_REGNUM)
|
||||
static_chain_incoming_rtx
|
||||
= gen_rtx_REG (Pmode, STATIC_CHAIN_INCOMING_REGNUM);
|
||||
else
|
||||
#endif
|
||||
static_chain_incoming_rtx = static_chain_rtx;
|
||||
#endif
|
||||
|
||||
#ifdef STATIC_CHAIN
|
||||
static_chain_rtx = STATIC_CHAIN;
|
||||
|
||||
#ifdef STATIC_CHAIN_INCOMING
|
||||
static_chain_incoming_rtx = STATIC_CHAIN_INCOMING;
|
||||
#else
|
||||
static_chain_incoming_rtx = static_chain_rtx;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
|
||||
pic_offset_table_rtx = gen_raw_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
|
||||
else
|
||||
pic_offset_table_rtx = NULL_RTX;
|
||||
}
|
||||
|
||||
/* Create some permanent unique rtl objects shared between all functions.
|
||||
LINE_NUMBERS is nonzero if line numbers are to be generated. */
|
||||
|
||||
@ -5270,9 +5338,6 @@ init_emit_once (int line_numbers)
|
||||
enum machine_mode mode;
|
||||
enum machine_mode double_mode;
|
||||
|
||||
/* We need reg_raw_mode, so initialize the modes now. */
|
||||
init_reg_modes_once ();
|
||||
|
||||
/* Initialize the CONST_INT, CONST_DOUBLE, CONST_FIXED, and memory attribute
|
||||
hash tables. */
|
||||
const_int_htab = htab_create_ggc (37, const_int_htab_hash,
|
||||
@ -5321,34 +5386,6 @@ init_emit_once (int line_numbers)
|
||||
|
||||
ptr_mode = mode_for_size (POINTER_SIZE, GET_MODE_CLASS (Pmode), 0);
|
||||
|
||||
/* Assign register numbers to the globally defined register rtx.
|
||||
This must be done at runtime because the register number field
|
||||
is in a union and some compilers can't initialize unions. */
|
||||
|
||||
pc_rtx = gen_rtx_PC (VOIDmode);
|
||||
cc0_rtx = gen_rtx_CC0 (VOIDmode);
|
||||
stack_pointer_rtx = gen_raw_REG (Pmode, STACK_POINTER_REGNUM);
|
||||
frame_pointer_rtx = gen_raw_REG (Pmode, FRAME_POINTER_REGNUM);
|
||||
if (hard_frame_pointer_rtx == 0)
|
||||
hard_frame_pointer_rtx = gen_raw_REG (Pmode,
|
||||
HARD_FRAME_POINTER_REGNUM);
|
||||
if (arg_pointer_rtx == 0)
|
||||
arg_pointer_rtx = gen_raw_REG (Pmode, ARG_POINTER_REGNUM);
|
||||
virtual_incoming_args_rtx =
|
||||
gen_raw_REG (Pmode, VIRTUAL_INCOMING_ARGS_REGNUM);
|
||||
virtual_stack_vars_rtx =
|
||||
gen_raw_REG (Pmode, VIRTUAL_STACK_VARS_REGNUM);
|
||||
virtual_stack_dynamic_rtx =
|
||||
gen_raw_REG (Pmode, VIRTUAL_STACK_DYNAMIC_REGNUM);
|
||||
virtual_outgoing_args_rtx =
|
||||
gen_raw_REG (Pmode, VIRTUAL_OUTGOING_ARGS_REGNUM);
|
||||
virtual_cfa_rtx = gen_raw_REG (Pmode, VIRTUAL_CFA_REGNUM);
|
||||
|
||||
/* Initialize RTL for commonly used hard registers. These are
|
||||
copied into regno_reg_rtx as we begin to compile each function. */
|
||||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
||||
static_regno_reg_rtx[i] = gen_raw_REG (reg_raw_mode[i], i);
|
||||
|
||||
#ifdef INIT_EXPANDERS
|
||||
/* This is to initialize {init|mark|free}_machine_status before the first
|
||||
call to push_function_context_to. This is needed by the Chill front
|
||||
@ -5558,36 +5595,6 @@ init_emit_once (int line_numbers)
|
||||
const_tiny_rtx[0][(int) BImode] = const0_rtx;
|
||||
if (STORE_FLAG_VALUE == 1)
|
||||
const_tiny_rtx[1][(int) BImode] = const1_rtx;
|
||||
|
||||
#ifdef RETURN_ADDRESS_POINTER_REGNUM
|
||||
return_address_pointer_rtx
|
||||
= gen_raw_REG (Pmode, RETURN_ADDRESS_POINTER_REGNUM);
|
||||
#endif
|
||||
|
||||
#ifdef STATIC_CHAIN_REGNUM
|
||||
static_chain_rtx = gen_rtx_REG (Pmode, STATIC_CHAIN_REGNUM);
|
||||
|
||||
#ifdef STATIC_CHAIN_INCOMING_REGNUM
|
||||
if (STATIC_CHAIN_INCOMING_REGNUM != STATIC_CHAIN_REGNUM)
|
||||
static_chain_incoming_rtx
|
||||
= gen_rtx_REG (Pmode, STATIC_CHAIN_INCOMING_REGNUM);
|
||||
else
|
||||
#endif
|
||||
static_chain_incoming_rtx = static_chain_rtx;
|
||||
#endif
|
||||
|
||||
#ifdef STATIC_CHAIN
|
||||
static_chain_rtx = STATIC_CHAIN;
|
||||
|
||||
#ifdef STATIC_CHAIN_INCOMING
|
||||
static_chain_incoming_rtx = STATIC_CHAIN_INCOMING;
|
||||
#else
|
||||
static_chain_incoming_rtx = static_chain_rtx;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
|
||||
pic_offset_table_rtx = gen_raw_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
|
||||
}
|
||||
|
||||
/* Produce exact duplicate of insn INSN after AFTER.
|
||||
|
@ -243,11 +243,12 @@ enum insn_code sync_lock_release[NUM_MACHINE_MODES];
|
||||
#define SLOW_UNALIGNED_ACCESS(MODE, ALIGN) STRICT_ALIGNMENT
|
||||
#endif
|
||||
|
||||
/* This is run once per compilation to set up which modes can be used
|
||||
directly in memory and to initialize the block move optab. */
|
||||
/* This is run to set up which modes can be used
|
||||
directly in memory and to initialize the block move optab. It is run
|
||||
at the beginning of compilation and when the target is reinitialized. */
|
||||
|
||||
void
|
||||
init_expr_once (void)
|
||||
init_expr_target (void)
|
||||
{
|
||||
rtx insn, pat;
|
||||
enum machine_mode mode;
|
||||
|
@ -352,9 +352,9 @@ extern rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, enum machine_mode);
|
||||
|
||||
/* Functions from expr.c: */
|
||||
|
||||
/* This is run once per compilation to set up which modes can be used
|
||||
directly in memory and to initialize the block move optab. */
|
||||
extern void init_expr_once (void);
|
||||
/* This is run during target initialization to set up which modes can be
|
||||
used directly in memory and to initialize the block move optab. */
|
||||
extern void init_expr_target (void);
|
||||
|
||||
/* This is run at the start of compiling a function. */
|
||||
extern void init_expr (void);
|
||||
|
@ -5563,7 +5563,7 @@ set_conv_libfunc (convert_optab optable, enum machine_mode tmode,
|
||||
convert_optab_handler (optable, tmode, fmode)->libfunc = 0;
|
||||
}
|
||||
|
||||
/* Call this once to initialize the contents of the optabs
|
||||
/* Call this to initialize the contents of the optabs
|
||||
appropriately for the current target machine. */
|
||||
|
||||
void
|
||||
|
121
gcc/regclass.c
121
gcc/regclass.c
@ -81,7 +81,7 @@ HARD_REG_SET fixed_reg_set;
|
||||
|
||||
/* Data for initializing the above. */
|
||||
|
||||
static const char initial_fixed_regs[] = FIXED_REGISTERS;
|
||||
static 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 const char initial_call_used_regs[] = CALL_USED_REGISTERS;
|
||||
static 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,7 +108,8 @@ static const char initial_call_used_regs[] = CALL_USED_REGISTERS;
|
||||
regs_invalidated_by_call. */
|
||||
|
||||
#ifdef CALL_REALLY_USED_REGISTERS
|
||||
char call_really_used_regs[] = CALL_REALLY_USED_REGISTERS;
|
||||
static char initial_call_really_used_regs[] = CALL_REALLY_USED_REGISTERS;
|
||||
char call_really_used_regs[FIRST_PSEUDO_REGISTER];
|
||||
#endif
|
||||
|
||||
#ifdef CALL_REALLY_USED_REGISTERS
|
||||
@ -192,7 +193,11 @@ enum reg_class reg_class_superunion[N_REG_CLASSES][N_REG_CLASSES];
|
||||
|
||||
/* Array containing all of the register names. */
|
||||
|
||||
const char * reg_names[] = REGISTER_NAMES;
|
||||
const char * reg_names[FIRST_PSEUDO_REGISTER];
|
||||
|
||||
/* Data for initializing the above. */
|
||||
|
||||
const char * initial_reg_names[] = REGISTER_NAMES;
|
||||
|
||||
/* Array containing all of the register class names. */
|
||||
|
||||
@ -230,6 +235,9 @@ static move_table *may_move_in_cost[MAX_MACHINE_MODE];
|
||||
|
||||
static 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;
|
||||
|
||||
#ifdef FORBIDDEN_INC_DEC_CLASSES
|
||||
|
||||
/* These are the classes that regs which are auto-incremented or decremented
|
||||
@ -298,19 +306,12 @@ init_reg_sets (void)
|
||||
SET_HARD_REG_BIT (reg_class_contents[i], j);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
memset (global_regs, 0, sizeof global_regs);
|
||||
|
||||
#ifdef REG_ALLOC_ORDER
|
||||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
||||
inv_reg_alloc_order[reg_alloc_order[i]] = i;
|
||||
#endif
|
||||
/* 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);
|
||||
}
|
||||
|
||||
/* Initialize may_move_cost and friends for mode M. */
|
||||
@ -319,7 +320,6 @@ static void
|
||||
init_move_cost (enum machine_mode m)
|
||||
{
|
||||
static unsigned short last_move_cost[N_REG_CLASSES][N_REG_CLASSES];
|
||||
static int last_mode = -1;
|
||||
bool all_match = true;
|
||||
unsigned int i, j;
|
||||
|
||||
@ -339,14 +339,14 @@ init_move_cost (enum machine_mode m)
|
||||
all_match &= (last_move_cost[i][j] == cost);
|
||||
last_move_cost[i][j] = cost;
|
||||
}
|
||||
if (all_match && last_mode != -1)
|
||||
if (all_match && last_mode_for_init_move_cost != -1)
|
||||
{
|
||||
move_cost[m] = move_cost[last_mode];
|
||||
may_move_in_cost[m] = may_move_in_cost[last_mode];
|
||||
may_move_out_cost[m] = may_move_out_cost[last_mode];
|
||||
move_cost[m] = move_cost[last_mode_for_init_move_cost];
|
||||
may_move_in_cost[m] = may_move_in_cost[last_mode_for_init_move_cost];
|
||||
may_move_out_cost[m] = may_move_out_cost[last_mode_for_init_move_cost];
|
||||
return;
|
||||
}
|
||||
last_mode = m;
|
||||
last_mode_for_init_move_cost = m;
|
||||
move_cost[m] = (move_table *)xmalloc (sizeof (move_table)
|
||||
* N_REG_CLASSES);
|
||||
may_move_in_cost[m] = (move_table *)xmalloc (sizeof (move_table)
|
||||
@ -412,6 +412,31 @@ init_reg_sets_1 (void)
|
||||
unsigned int i, j;
|
||||
unsigned int /* enum machine_mode */ m;
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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 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);
|
||||
|
||||
#ifdef REG_ALLOC_ORDER
|
||||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
||||
inv_reg_alloc_order[reg_alloc_order[i]] = i;
|
||||
#endif
|
||||
|
||||
/* This macro allows the fixed or call-used registers
|
||||
and the register classes to depend on target flags. */
|
||||
|
||||
@ -431,6 +456,7 @@ init_reg_sets_1 (void)
|
||||
reg_class_subunion[I][J] gets the largest-numbered reg-class
|
||||
that is contained in the union of classes I and J. */
|
||||
|
||||
memset (reg_class_subunion, 0, sizeof reg_class_subunion);
|
||||
for (i = 0; i < N_REG_CLASSES; i++)
|
||||
{
|
||||
for (j = 0; j < N_REG_CLASSES; j++)
|
||||
@ -453,6 +479,7 @@ init_reg_sets_1 (void)
|
||||
reg_class_superunion[I][J] gets the smallest-numbered reg-class
|
||||
containing the union of classes I and J. */
|
||||
|
||||
memset (reg_class_superunion, 0, sizeof reg_class_superunion);
|
||||
for (i = 0; i < N_REG_CLASSES; i++)
|
||||
{
|
||||
for (j = 0; j < N_REG_CLASSES; j++)
|
||||
@ -511,6 +538,7 @@ init_reg_sets_1 (void)
|
||||
CLEAR_HARD_REG_SET (call_used_reg_set);
|
||||
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);
|
||||
|
||||
memcpy (call_fixed_regs, fixed_regs, sizeof call_fixed_regs);
|
||||
|
||||
@ -564,6 +592,18 @@ init_reg_sets_1 (void)
|
||||
SET_HARD_REG_BIT (regs_invalidated_by_call, i);
|
||||
}
|
||||
|
||||
/* Preserve global registers if called more than once. */
|
||||
for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
|
||||
{
|
||||
if (global_regs[i])
|
||||
{
|
||||
fixed_regs[i] = call_used_regs[i] = call_fixed_regs[i] = 1;
|
||||
SET_HARD_REG_BIT (fixed_reg_set, i);
|
||||
SET_HARD_REG_BIT (call_used_reg_set, i);
|
||||
SET_HARD_REG_BIT (call_fixed_reg_set, i);
|
||||
}
|
||||
}
|
||||
|
||||
memset (have_regs_of_mode, 0, sizeof (have_regs_of_mode));
|
||||
memset (contains_reg_of_mode, 0, sizeof (contains_reg_of_mode));
|
||||
for (m = 0; m < (unsigned int) MAX_MACHINE_MODE; m++)
|
||||
@ -582,14 +622,36 @@ init_reg_sets_1 (void)
|
||||
have_regs_of_mode [m] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Reset move_cost and friends, making sure we only free shared
|
||||
table entries once. */
|
||||
for (i = 0; i < MAX_MACHINE_MODE; i++)
|
||||
if (move_cost[i])
|
||||
{
|
||||
for (j = 0; j < i && move_cost[i] != move_cost[j]; j++)
|
||||
;
|
||||
if (i == j)
|
||||
{
|
||||
free (move_cost[i]);
|
||||
free (may_move_in_cost[i]);
|
||||
free (may_move_out_cost[i]);
|
||||
}
|
||||
}
|
||||
memset (move_cost, 0, sizeof move_cost);
|
||||
memset (may_move_in_cost, 0, sizeof may_move_in_cost);
|
||||
memset (may_move_out_cost, 0, sizeof may_move_out_cost);
|
||||
last_mode_for_init_move_cost = -1;
|
||||
}
|
||||
|
||||
/* Compute the table of register modes.
|
||||
These values are used to record death information for individual registers
|
||||
(as opposed to a multi-register mode). */
|
||||
(as opposed to a multi-register mode).
|
||||
This function might be invoked more than once, if the target has support
|
||||
for changing register usage conventions on a per-function basis.
|
||||
*/
|
||||
|
||||
void
|
||||
init_reg_modes_once (void)
|
||||
init_reg_modes_target (void)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
@ -611,8 +673,10 @@ init_reg_modes_once (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Finish initializing the register sets and
|
||||
initialize the register modes. */
|
||||
/* Finish initializing the register sets and initialize the register modes.
|
||||
This function might be invoked more than once, if the target has support
|
||||
for changing register usage conventions on a per-function basis.
|
||||
*/
|
||||
|
||||
void
|
||||
init_regs (void)
|
||||
@ -782,11 +846,11 @@ fix_register (const char *name, int fixed, int call_used)
|
||||
}
|
||||
else
|
||||
{
|
||||
fixed_regs[i] = fixed;
|
||||
call_used_regs[i] = call_used;
|
||||
initial_fixed_regs[i] = fixed;
|
||||
initial_call_used_regs[i] = call_used;
|
||||
#ifdef CALL_REALLY_USED_REGISTERS
|
||||
if (fixed == 0)
|
||||
call_really_used_regs[i] = call_used;
|
||||
initial_call_really_used_regs[i] = call_used;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -1157,6 +1221,7 @@ init_reg_autoinc (void)
|
||||
#ifdef FORBIDDEN_INC_DEC_CLASSES
|
||||
int i;
|
||||
|
||||
memset (forbidden_inc_dec_class, 0, sizeof forbidden_inc_dec_classes);
|
||||
for (i = 0; i < N_REG_CLASSES; i++)
|
||||
{
|
||||
rtx r = gen_rtx_raw_REG (VOIDmode, 0);
|
||||
|
@ -448,7 +448,8 @@ static int reloads_conflict (int, int);
|
||||
static rtx gen_reload (rtx, rtx, int, enum reload_type);
|
||||
static rtx emit_insn_if_valid_for_reload (rtx);
|
||||
|
||||
/* Initialize the reload pass once per compilation. */
|
||||
/* Initialize the reload pass. This is called at the beginning of compilation
|
||||
and may be called again if the target is reinitialized. */
|
||||
|
||||
void
|
||||
init_reload (void)
|
||||
|
@ -2077,6 +2077,7 @@ extern int get_max_uid (void);
|
||||
extern int in_sequence_p (void);
|
||||
extern void force_next_line_note (void);
|
||||
extern void init_emit (void);
|
||||
extern void init_emit_regs (void);
|
||||
extern void init_emit_once (int);
|
||||
extern void push_topmost_sequence (void);
|
||||
extern void pop_topmost_sequence (void);
|
||||
@ -2186,7 +2187,7 @@ extern void build_insn_chain (rtx);
|
||||
extern int reg_classes_intersect_p (enum reg_class, enum reg_class);
|
||||
extern int reg_class_subset_p (enum reg_class, enum reg_class);
|
||||
extern void globalize_reg (int);
|
||||
extern void init_reg_modes_once (void);
|
||||
extern void init_reg_modes_target (void);
|
||||
extern void init_regs (void);
|
||||
extern void init_fake_stack_mems (void);
|
||||
extern void init_reg_sets (void);
|
||||
@ -2254,7 +2255,7 @@ extern int canon_true_dependence (const_rtx, enum machine_mode, rtx, const_rtx,
|
||||
extern int read_dependence (const_rtx, const_rtx);
|
||||
extern int anti_dependence (const_rtx, const_rtx);
|
||||
extern int output_dependence (const_rtx, const_rtx);
|
||||
extern void init_alias_once (void);
|
||||
extern void init_alias_target (void);
|
||||
extern void init_alias_analysis (void);
|
||||
extern void end_alias_analysis (void);
|
||||
extern bool memory_modified_in_insn_p (const_rtx, const_rtx);
|
||||
|
144
gcc/toplev.c
144
gcc/toplev.c
@ -1685,6 +1685,31 @@ target_supports_section_anchors_p (void)
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Default the align_* variables to 1 if they're still unset, and
|
||||
set up the align_*_log variables. */
|
||||
static void
|
||||
init_alignments (void)
|
||||
{
|
||||
if (align_loops <= 0)
|
||||
align_loops = 1;
|
||||
if (align_loops_max_skip > align_loops)
|
||||
align_loops_max_skip = align_loops - 1;
|
||||
align_loops_log = floor_log2 (align_loops * 2 - 1);
|
||||
if (align_jumps <= 0)
|
||||
align_jumps = 1;
|
||||
if (align_jumps_max_skip > align_jumps)
|
||||
align_jumps_max_skip = align_jumps - 1;
|
||||
align_jumps_log = floor_log2 (align_jumps * 2 - 1);
|
||||
if (align_labels <= 0)
|
||||
align_labels = 1;
|
||||
align_labels_log = floor_log2 (align_labels * 2 - 1);
|
||||
if (align_labels_max_skip > align_labels)
|
||||
align_labels_max_skip = align_labels - 1;
|
||||
if (align_functions <= 0)
|
||||
align_functions = 1;
|
||||
align_functions_log = floor_log2 (align_functions * 2 - 1);
|
||||
}
|
||||
|
||||
/* Process the options that have been parsed. */
|
||||
static void
|
||||
process_options (void)
|
||||
@ -1730,23 +1755,6 @@ process_options (void)
|
||||
else
|
||||
aux_base_name = "gccaux";
|
||||
|
||||
/* Set up the align_*_log variables, defaulting them to 1 if they
|
||||
were still unset. */
|
||||
if (align_loops <= 0) align_loops = 1;
|
||||
if (align_loops_max_skip > align_loops || !align_loops)
|
||||
align_loops_max_skip = align_loops - 1;
|
||||
align_loops_log = floor_log2 (align_loops * 2 - 1);
|
||||
if (align_jumps <= 0) align_jumps = 1;
|
||||
if (align_jumps_max_skip > align_jumps || !align_jumps)
|
||||
align_jumps_max_skip = align_jumps - 1;
|
||||
align_jumps_log = floor_log2 (align_jumps * 2 - 1);
|
||||
if (align_labels <= 0) align_labels = 1;
|
||||
align_labels_log = floor_log2 (align_labels * 2 - 1);
|
||||
if (align_labels_max_skip > align_labels || !align_labels)
|
||||
align_labels_max_skip = align_labels - 1;
|
||||
if (align_functions <= 0) align_functions = 1;
|
||||
align_functions_log = floor_log2 (align_functions * 2 - 1);
|
||||
|
||||
/* Unrolling all loops implies that standard loop unrolling must also
|
||||
be done. */
|
||||
if (flag_unroll_all_loops)
|
||||
@ -1998,7 +2006,50 @@ process_options (void)
|
||||
}
|
||||
}
|
||||
|
||||
/* Initialize the compiler back end. */
|
||||
/* This function can be called multiple times to reinitialize the compiler
|
||||
back end when register classes or instruction sets have changed,
|
||||
before each function. */
|
||||
static void
|
||||
backend_init_target (void)
|
||||
{
|
||||
/* Initialize alignment variables. */
|
||||
init_alignments ();
|
||||
|
||||
/* This reinitializes hard_frame_pointer, and calls init_reg_modes_target()
|
||||
to initialize reg_raw_mode[]. */
|
||||
init_emit_regs ();
|
||||
|
||||
/* This invokes target hooks to set fixed_reg[] etc, which is
|
||||
mode-dependent. */
|
||||
init_regs ();
|
||||
|
||||
/* This depends on stack_pointer_rtx. */
|
||||
init_fake_stack_mems ();
|
||||
|
||||
/* Sets static_base_value[HARD_FRAME_POINTER_REGNUM], which is
|
||||
mode-dependent. */
|
||||
init_alias_target ();
|
||||
|
||||
/* Depends on HARD_FRAME_POINTER_REGNUM. */
|
||||
init_reload ();
|
||||
|
||||
/* The following initialization functions need to generate rtl, so
|
||||
provide a dummy function context for them. */
|
||||
init_dummy_function_start ();
|
||||
|
||||
/* rtx_cost is mode-dependent, so cached values need to be recomputed
|
||||
on a mode change. */
|
||||
init_expmed ();
|
||||
|
||||
/* We may need to recompute regno_save_code[] and regno_restore_code[]
|
||||
after a mode change as well. */
|
||||
if (flag_caller_saves)
|
||||
init_caller_save ();
|
||||
expand_dummy_function_end ();
|
||||
}
|
||||
|
||||
/* Initialize the compiler back end. This function is called only once,
|
||||
when starting the compiler. */
|
||||
static void
|
||||
backend_init (void)
|
||||
{
|
||||
@ -2011,19 +2062,34 @@ backend_init (void)
|
||||
|| flag_test_coverage);
|
||||
|
||||
init_rtlanal ();
|
||||
init_regs ();
|
||||
init_fake_stack_mems ();
|
||||
init_alias_once ();
|
||||
init_inline_once ();
|
||||
init_reload ();
|
||||
init_varasm_once ();
|
||||
|
||||
/* Initialize the target-specific back end pieces. */
|
||||
backend_init_target ();
|
||||
}
|
||||
|
||||
/* Initialize things that are both lang-dependent and target-dependent.
|
||||
This function can be called more than once if target parameters change. */
|
||||
static void
|
||||
lang_dependent_init_target (void)
|
||||
{
|
||||
/* This creates various _DECL nodes, so needs to be called after the
|
||||
front end is initialized. It also depends on the HAVE_xxx macros
|
||||
generated from the target machine description. */
|
||||
init_optabs ();
|
||||
|
||||
/* The following initialization functions need to generate rtl, so
|
||||
provide a dummy function context for them. */
|
||||
init_dummy_function_start ();
|
||||
init_expmed ();
|
||||
if (flag_caller_saves)
|
||||
init_caller_save ();
|
||||
|
||||
/* Do the target-specific parts of expr initialization. */
|
||||
init_expr_target ();
|
||||
|
||||
/* Although the actions of init_set_costs are language-independent,
|
||||
it uses optabs, so we cannot call it from backend_init. */
|
||||
init_set_costs ();
|
||||
|
||||
expand_dummy_function_end ();
|
||||
}
|
||||
|
||||
@ -2048,21 +2114,12 @@ lang_dependent_init (const char *name)
|
||||
|
||||
init_asm_output (name);
|
||||
|
||||
/* These create various _DECL nodes, so need to be called after the
|
||||
/* This creates various _DECL nodes, so needs to be called after the
|
||||
front end is initialized. */
|
||||
init_eh ();
|
||||
init_optabs ();
|
||||
|
||||
/* The following initialization functions need to generate rtl, so
|
||||
provide a dummy function context for them. */
|
||||
init_dummy_function_start ();
|
||||
init_expr_once ();
|
||||
|
||||
/* Although the actions of init_set_costs are language-independent,
|
||||
it uses optabs, so we cannot call it from backend_init. */
|
||||
init_set_costs ();
|
||||
|
||||
expand_dummy_function_end ();
|
||||
/* Do the target-specific parts of the initialization. */
|
||||
lang_dependent_init_target ();
|
||||
|
||||
/* If dbx symbol table desired, initialize writing it and output the
|
||||
predefined types. */
|
||||
@ -2082,6 +2139,19 @@ lang_dependent_init (const char *name)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/* Reinitialize everything when target parameters, such as register usage,
|
||||
have changed. */
|
||||
void
|
||||
target_reinit (void)
|
||||
{
|
||||
/* Reinitialise RTL backend. */
|
||||
backend_init_target ();
|
||||
|
||||
/* Reinitialize lang-dependent parts. */
|
||||
lang_dependent_init_target ();
|
||||
}
|
||||
|
||||
void
|
||||
dump_memory_report (bool final)
|
||||
{
|
||||
|
@ -101,6 +101,8 @@ extern void write_global_declarations (void);
|
||||
|
||||
extern void dump_memory_report (bool);
|
||||
|
||||
extern void target_reinit (void);
|
||||
|
||||
/* A unique local time stamp, might be zero if none is available. */
|
||||
extern unsigned local_tick;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user