rtl.h (initialize_uninitialized_subregs): New prototype.

2001-12-04  Andrew MacLeod  <amacleod@redhat.com>

	* rtl.h (initialize_uninitialized_subregs): New prototype.
	* toplev.c (rest_of_compilation): Call initialize_uninitialized_subregs
	when optimization is on.
	* flow.c (find_regno_partial): Find subregs within an expression.
	(initialize_uninitialized_subregs): Initialize live on entry registers
	which are used in subreg expressions.

From-SVN: r47644
This commit is contained in:
Andrew MacLeod 2001-12-05 01:39:41 +00:00 committed by Andrew Macleod
parent ee0a48c5e8
commit 0626ef8add
4 changed files with 132 additions and 3 deletions

View File

@ -1,3 +1,12 @@
2001-12-04 Andrew MacLeod <amacleod@redhat.com>
* rtl.h (initialize_uninitialized_subregs): New prototype.
* toplev.c (rest_of_compilation): Call initialize_uninitialized_subregs
when optimization is on.
* flow.c (find_regno_partial): Find subregs within an expression.
(initialize_uninitialized_subregs): Initialize live on entry registers
which are used in subreg expressions.
2001-12-04 Phil Edwards <pme@gcc.gnu.org>
* Makefile.in: Add INSTALL_SCRIPT using INSTALL definition.

View File

@ -306,6 +306,8 @@ static void mark_set_regs PARAMS ((struct propagate_block_info *,
static void mark_set_1 PARAMS ((struct propagate_block_info *,
enum rtx_code, rtx, rtx,
rtx, int));
static int find_regno_partial PARAMS ((rtx *, void *));
#ifdef HAVE_conditional_execution
static int mark_regno_cond_dead PARAMS ((struct propagate_block_info *,
int, rtx));
@ -1290,6 +1292,112 @@ calculate_global_regs_live (blocks_in, blocks_out, flags)
free (queue);
}
/* This structure is used to pass parameters to an from the
the function find_regno_partial(). It is used to pass in the
register number we are looking, as well as to return any rtx
we find. */
typedef struct {
unsigned regno_to_find;
rtx retval;
} find_regno_partial_param;
/* Find the rtx for the reg numbers specified in 'data' if it is
part of an expression which only uses part of the register. Return
it in the structure passed in. */
static int
find_regno_partial (ptr, data)
rtx *ptr;
void *data;
{
find_regno_partial_param *param = (find_regno_partial_param *)data;
unsigned reg = param->regno_to_find;
param->retval = NULL_RTX;
if (*ptr == NULL_RTX)
return 0;
switch (GET_CODE (*ptr))
{
case ZERO_EXTRACT:
case SIGN_EXTRACT:
case STRICT_LOW_PART:
if (GET_CODE (XEXP (*ptr, 0)) == REG && REGNO (XEXP (*ptr, 0)) == reg)
{
param->retval = *ptr;
return 1;
}
break;
case SUBREG:
if (GET_CODE (SUBREG_REG (*ptr)) == REG
&& REGNO (SUBREG_REG (*ptr)) == reg)
{
param->retval = *ptr;
return 1;
}
break;
}
return 0;
}
/* Process all immediate successors of the entry block looking for pseudo
registers which are live on entry. Find all of those whose first
instance is a partial register reference of some kind, and initialize
them to 0 after the entry block. This will prevent bit sets within
registers whose value is unknown, and may contain some kind of sticky
bits we don't want. */
int
initialize_uninitialized_subregs ()
{
rtx insn;
edge e;
int reg, did_something = 0;
find_regno_partial_param param;
for (e = ENTRY_BLOCK_PTR->succ; e; e = e->succ_next)
{
basic_block bb = e->dest;
regset map = bb->global_live_at_start;
EXECUTE_IF_SET_IN_REG_SET (map,
FIRST_PSEUDO_REGISTER, reg,
{
int uid = REGNO_FIRST_UID (reg);
rtx i;
/* Find an insn which mentions the register we are looking for.
Its preferable to have an instance of the register's rtl since
there may be various flags set which we need to duplicate.
If we can't find it, its probably an automatic whose initial
value doesnt matter, or hopefully something we dont care about. */
for (i = get_insns (); i && INSN_UID (i) != uid; i = NEXT_INSN (i))
;
if (i != NULL_RTX)
{
/* Found the insn, now get the REG rtx, if we can. */
param.regno_to_find = reg;
for_each_rtx (&i, find_regno_partial, &param);
if (param.retval != NULL_RTX)
{
insn = gen_move_insn (param.retval,
CONST0_RTX (GET_MODE (param.retval)));
insert_insn_on_edge (insn, e);
did_something = 1;
}
}
});
}
if (did_something)
commit_edge_insertions ();
return did_something;
}
/* Subroutines of life analysis. */

View File

@ -1903,10 +1903,11 @@ extern void move_by_pieces PARAMS ((rtx, rtx,
unsigned int));
/* In flow.c */
extern void recompute_reg_usage PARAMS ((rtx, int));
extern void recompute_reg_usage PARAMS ((rtx, int));
extern int initialize_uninitialized_subregs PARAMS ((void));
#ifdef BUFSIZ
extern void print_rtl_with_bb PARAMS ((FILE *, rtx));
extern void dump_flow_info PARAMS ((FILE *));
extern void print_rtl_with_bb PARAMS ((FILE *, rtx));
extern void dump_flow_info PARAMS ((FILE *));
#endif
/* In expmed.c */

View File

@ -3017,6 +3017,17 @@ rest_of_compilation (decl)
setjmp_args_warning ();
}
if (optimize)
{
if (initialize_uninitialized_subregs ())
{
/* Insns were inserted, so things might look a bit different. */
insns = get_insns();
life_analysis (insns, rtl_dump_file,
(PROP_LOG_LINKS | PROP_REG_INFO | PROP_DEATH_NOTES));
}
}
close_dump_file (DFI_life, print_rtl_with_bb, insns);
ggc_collect ();