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:
Sandra Loosemore 2007-08-27 09:34:14 -04:00 committed by Sandra Loosemore
parent 107d76762a
commit b5deb7b691
12 changed files with 344 additions and 137 deletions

View File

@ -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

View File

@ -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

View File

@ -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])

View File

@ -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.

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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)

View File

@ -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);

View File

@ -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)
{

View File

@ -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;