This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] nonzero bits as result of PROMOTE_FUNCTION_RETURN
- To: gcc-patches at gcc dot gnu dot org
- Subject: [PATCH] nonzero bits as result of PROMOTE_FUNCTION_RETURN
- From: Jakub Jelinek <jakub at redhat dot com>
- Date: Tue, 30 Nov 1999 14:13:25 +0100
Hi!
If PROMOTE_FUNCTION_RETURN is defined, then we very often can say
what bits are for sure zero, but combine does not take this into account.
This patch solves this.
As the information is not stored in the call rtl anywhere, I track this from
the SUBREG_PROMOTED_VAR_P bit of some SUBREG later on which directly or
indirectly uses the return value. This has the disadvantage that if e.g. all
subroutines in some function return say "unsigned int", then
reg_nonzero_bits will not be set eventhough the return value hard register
has those bits always zero, but at least sets the reg_last_set_* bits, so
things can be optimized out within each basic block.
Sample routine which this patch speeds up can be e.g.:
unsigned foo(void);
unsigned bar(void)
{
return foo()|1;
}
1999-11-30 Jakub Jelinek <jakub@redhat.com>
* combine.c (check_promoted_subreg, record_promoted_value): New
functions.
(combine_instructions): Use it.
--- gcc/combine.c.jj Fri Nov 26 16:09:55 1999
+++ gcc/combine.c Tue Nov 30 13:25:53 1999
@@ -403,6 +403,9 @@ static enum rtx_code simplify_comparison
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
+ instructions based on 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))
@@ -11051,6 +11060,88 @@ 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 combiner 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
Cheers,
Jakub
___________________________________________________________________
Jakub Jelinek | jakub@redhat.com | http://sunsite.mff.cuni.cz/~jj
Linux version 2.3.18 on a sparc64 machine (1343.49 BogoMips)
___________________________________________________________________