combine.c (check_promoted_subreg, [...]): New functions.

* combine.c (check_promoted_subreg, record_promoted_value): New
	functions.
	(combine_instructions): Use them to retain nonzero and sign bit
	information after SUBREGs are eliminated by optimizations in
	this pass if PROMOTE_FUNCTION_RETURN.

From-SVN: r30808
This commit is contained in:
Jakub Jelinek 1999-12-06 20:45:38 +01:00 committed by David S. Miller
parent 0974e9fec8
commit 732f2ac967
2 changed files with 99 additions and 0 deletions

View File

@ -17,6 +17,12 @@
always use move_by_pieces to avoid infinite recursion.
(restore_fixed_argument_area): Likewise.
* combine.c (check_promoted_subreg, record_promoted_value): New
functions.
(combine_instructions): Use them to retain nonzero and sign bit
information after SUBREGs are eliminated by optimizations in
this pass if PROMOTE_FUNCTION_RETURN.
Mon Dec 6 12:24:52 1999 Richard Kenner <kenner@vlsi1.ultra.nyu.edu>
* fold-const.c (optimize_bit_field_compare): Only use one mode

View File

@ -403,6 +403,9 @@ static enum rtx_code simplify_comparison PROTO((enum rtx_code, rtx *, rtx *));
static int reversible_comparison_p PROTO((rtx));
static void update_table_tick PROTO((rtx));
static void record_value_for_reg PROTO((rtx, rtx, rtx));
#ifdef PROMOTE_FUNCTION_RETURN
static void check_promoted_subreg PROTO((rtx, rtx));
#endif
static void record_dead_and_set_regs_1 PROTO((rtx, rtx, void *));
static void record_dead_and_set_regs PROTO((rtx));
static int get_last_value_validate PROTO((rtx *, rtx, int, int));
@ -608,6 +611,12 @@ combine_instructions (f, nregs)
else if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
{
#ifdef PROMOTE_FUNCTION_RETURN
/* See if we know about function return values before this
insn based upon SUBREG flags. */
check_promoted_subreg (insn, PATTERN (insn));
#endif
/* Try this insn with each insn it links back to. */
for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
@ -11048,6 +11057,90 @@ record_dead_and_set_regs (insn)
note_stores (PATTERN (insn), record_dead_and_set_regs_1, insn);
}
#ifdef PROMOTE_FUNCTION_RETURN
/* If a SUBREG has the promoted bit set, it is in fact a property of the
register present in the SUBREG, so for each such SUBREG go back and
adjust nonzero and sign bit information of the registers that are
known to have some zero/sign bits set.
This is needed because when combine blows the SUBREGs away, the
information on zero/sign bits is lost and further combines can be
missed because of that. */
static void
record_promoted_value (insn, subreg)
rtx insn;
rtx subreg;
{
rtx links, links2, set;
int regno = REGNO (SUBREG_REG (subreg));
enum machine_mode mode = GET_MODE (subreg);
if (GET_MODE_BITSIZE (mode) >= HOST_BITS_PER_WIDE_INT)
return;
for (links = LOG_LINKS (insn); links; )
{
insn = XEXP (links, 0);
set = single_set (insn);
if (! set || GET_CODE (SET_DEST (set)) != REG
|| REGNO (SET_DEST (set)) != regno
|| GET_MODE (SET_DEST (set)) != GET_MODE (SUBREG_REG (subreg)))
{
links = XEXP (links, 1);
continue;
}
if (reg_last_set [regno] == insn)
{
if (SUBREG_PROMOTED_UNSIGNED_P (subreg))
reg_last_set_nonzero_bits [regno] &= GET_MODE_MASK (mode);
}
if (GET_CODE (SET_SRC (set)) == REG)
{
regno = REGNO (SET_SRC (set));
links = LOG_LINKS (insn);
}
else
break;
}
}
/* Scan X for promoted SUBREGs. For each one found,
note what it implies to the registers used in it. */
static void
check_promoted_subreg (insn, x)
rtx insn;
rtx x;
{
if (GET_CODE (x) == SUBREG && SUBREG_PROMOTED_VAR_P (x)
&& GET_CODE (SUBREG_REG (x)) == REG)
record_promoted_value (insn, x);
else
{
const char *format = GET_RTX_FORMAT (GET_CODE (x));
int i, j;
for (i = 0; i < GET_RTX_LENGTH (GET_CODE (x)); i++)
switch (format [i])
{
case 'e':
check_promoted_subreg (insn, XEXP (x, i));
break;
case 'V':
case 'E':
if (XVEC (x, i) != 0)
for (j = 0; j < XVECLEN (x, i); j++)
check_promoted_subreg (insn, XVECEXP (x, i, j));
break;
}
}
}
#endif
/* Utility routine for the following function. Verify that all the registers
mentioned in *LOC are valid when *LOC was part of a value set when