This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
RE: [PATCH, combine] Try REG_EQUAL for nonzero_bits
- From: "Thomas Preud'homme" <thomas dot preudhomme at arm dot com>
- To: "'Eric Botcazou'" <ebotcazou at adacore dot com>
- Cc: <gcc-patches at gcc dot gnu dot org>
- Date: Tue, 10 Feb 2015 10:00:15 +0800
- Subject: RE: [PATCH, combine] Try REG_EQUAL for nonzero_bits
- Authentication-results: sourceware.org; auth=none
- References: <000001d00546$33445430$99ccfc90$ at arm dot com> <1667449 dot SiF8mNp2oU at polaris> <000601d015e4$3915ef50$ab41cdf0$ at arm dot com> <2389505 dot JqqgOpb7ZL at polaris>
And this is part 2.
> From: gcc-patches-owner@gcc.gnu.org [mailto:gcc-patches-
> owner@gcc.gnu.org] On Behalf Of Eric Botcazou
>
> Once this is done, the same thing needs to be applied to XEXP
> (reg_equal, 0)
> before it is sent to nonzero_bits.
>
>
> > - /* Don't call nonzero_bits if it cannot change anything. */
> > - if (rsp->nonzero_bits != ~(unsigned HOST_WIDE_INT) 0)
> > - rsp->nonzero_bits |= nonzero_bits (src, nonzero_bits_mode);
> > num = num_sign_bit_copies (SET_SRC (set), GET_MODE (x));
> > if (rsp->sign_bit_copies == 0
> >
> > || rsp->sign_bit_copies > num)
> >
> > rsp->sign_bit_copies = num;
> > +
> > + /* Don't call nonzero_bits if it cannot change anything. */
> > + if (rsp->nonzero_bits != ~(unsigned HOST_WIDE_INT) 0)
> > + update_rsp_from_reg_equal (rsp, insn, src, x);
>
> Can't we improve on this? rsp->sign_bit_copies is modified both here
> and in
> update_rsp_from_reg_equal, but rsp->nonzero_bits is modified only in
> the
> latter function. There is no reason for this discrepancy, so they ought to
> be
> handled the same way, either entirely here or entirely in the function.
So I moved all the handling inside the new function and also added a check
before calling num_sign_bit_copies about whether it would give any more
information to be consistent with what is done for nonzero_bits.
ChangeLog entry is as follows:
2015-02-09 Thomas Preud'homme <thomas.preudhomme@arm.com>
* combine.c i(set_nonzero_bits_and_sign_copies): Split code updating
rsp->sign_bit_copies and rsp->nonzero_bits into ...
(update_rsp_from_reg_equal): This. Also use REG_EQUAL note on src if
present to get more accurate information about the number of sign bit
copies and non zero bits.
diff --git a/gcc/combine.c b/gcc/combine.c
index f2b26c2..622279e 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -1660,6 +1660,51 @@ sign_extend_short_imm (rtx src, machine_mode mode, unsigned int prec)
}
#endif
+/* Update RSP for pseudo-register X from INSN's REG_EQUAL note (if one exists)
+ and SET. */
+
+static void
+update_rsp_from_reg_equal (reg_stat_type *rsp, rtx_insn *insn, const_rtx set,
+ rtx x)
+{
+ rtx reg_equal_note = insn ? find_reg_equal_equiv_note (insn) : NULL_RTX;
+ unsigned HOST_WIDE_INT bits = 0;
+ rtx reg_equal = NULL, src = SET_SRC (set);
+ unsigned int num = 0;
+
+ if (reg_equal_note)
+ reg_equal = XEXP (reg_equal_note, 0);
+
+#ifdef SHORT_IMMEDIATES_SIGN_EXTEND
+ src = sign_extend_short_imm (src, GET_MODE (x), BITS_PER_WORD);
+ if (reg_equal)
+ reg_equal = sign_extend_short_imm (reg_equal, GET_MODE (x), BITS_PER_WORD);
+#endif
+
+ /* Don't call nonzero_bits if it cannot change anything. */
+ if (rsp->nonzero_bits != ~(unsigned HOST_WIDE_INT) 0)
+ {
+ bits = nonzero_bits (src, nonzero_bits_mode);
+ if (reg_equal && bits)
+ bits &= nonzero_bits (reg_equal, nonzero_bits_mode);
+ rsp->nonzero_bits |= bits;
+ }
+
+ /* Don't call num_sign_bit_copies if it cannot change anything. */
+ if (rsp->sign_bit_copies != 1)
+ {
+ num = num_sign_bit_copies (SET_SRC (set), GET_MODE (x));
+ if (reg_equal && num != GET_MODE_PRECISION (GET_MODE (x)))
+ {
+ unsigned int numeq = num_sign_bit_copies (reg_equal, GET_MODE (x));
+ if (num == 0 || numeq > num)
+ num = numeq;
+ }
+ if (rsp->sign_bit_copies == 0 || num < rsp->sign_bit_copies)
+ rsp->sign_bit_copies = num;
+ }
+}
+
/* Called via note_stores. If X is a pseudo that is narrower than
HOST_BITS_PER_WIDE_INT and is being set, record what bits are known zero.
@@ -1675,7 +1720,6 @@ static void
set_nonzero_bits_and_sign_copies (rtx x, const_rtx set, void *data)
{
rtx_insn *insn = (rtx_insn *) data;
- unsigned int num;
if (REG_P (x)
&& REGNO (x) >= FIRST_PSEUDO_REGISTER
@@ -1735,21 +1779,7 @@ set_nonzero_bits_and_sign_copies (rtx x, const_rtx set, void *data)
if (SET_DEST (set) == x
|| (paradoxical_subreg_p (SET_DEST (set))
&& SUBREG_REG (SET_DEST (set)) == x))
- {
- rtx src = SET_SRC (set);
-
-#ifdef SHORT_IMMEDIATES_SIGN_EXTEND
- src = sign_extend_short_imm (src, GET_MODE (x), BITS_PER_WORD);
-#endif
-
- /* Don't call nonzero_bits if it cannot change anything. */
- if (rsp->nonzero_bits != ~(unsigned HOST_WIDE_INT) 0)
- rsp->nonzero_bits |= nonzero_bits (src, nonzero_bits_mode);
- num = num_sign_bit_copies (SET_SRC (set), GET_MODE (x));
- if (rsp->sign_bit_copies == 0
- || rsp->sign_bit_copies > num)
- rsp->sign_bit_copies = num;
- }
+ update_rsp_from_reg_equal (rsp, insn, set, x);
else
{
rsp->nonzero_bits = GET_MODE_MASK (GET_MODE (x));
Is this ok for stage 1?
Best regards,
Thomas