This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RE: [PATCH, combine] Try REG_EQUAL for nonzero_bits


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 





Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]