From 732f2ac967fede4eb604a4575a862bab1bc309e6 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Mon, 6 Dec 1999 20:45:38 +0100 Subject: [PATCH] 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 --- gcc/ChangeLog | 6 ++++ gcc/combine.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 99 insertions(+) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f2c318137c4..119a1dbabc2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 * fold-const.c (optimize_bit_field_compare): Only use one mode diff --git a/gcc/combine.c b/gcc/combine.c index f55bb669976..825d8a74616 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -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 -- 2.30.2