cse.c (cse_insn): Calculate src_eqv for ZERO_EXTRACT.
authorKugan Vivekanandarajah <kuganv@linaro.org>
Sun, 12 Jul 2015 11:16:30 +0000 (11:16 +0000)
committerKugan Vivekanandarajah <kugan@gcc.gnu.org>
Sun, 12 Jul 2015 11:16:30 +0000 (11:16 +0000)
gcc/ChangeLog:

2015-07-12  Kugan Vivekanandarajah  <kuganv@linaro.org>

* cse.c (cse_insn): Calculate src_eqv for ZERO_EXTRACT.
* emit-rtl.c (set_for_reg_notes): Allow ZERO_EXTRACT to set
REG_EQUAL note.

From-SVN: r225721

gcc/ChangeLog
gcc/cse.c
gcc/emit-rtl.c

index dd6155e583a13c2c7ac120fe3c1291f5ce283a20..c435e30997d74715d1fc7cdb67582c2608bceb42 100644 (file)
@@ -1,3 +1,9 @@
+2015-07-12  Kugan Vivekanandarajah  <kuganv@linaro.org>
+
+       * cse.c (cse_insn): Calculate src_eqv for ZERO_EXTRACT.
+       * emit-rtl.c (set_for_reg_notes): Allow ZERO_EXTRACT to set
+       REG_EQUAL note.
+
 2015-07-11  Marek Polacek  <polacek@redhat.com>
 
        PR middle-end/66353
index 255c4dbea4cc6ed8d1b75d825c81c3e6d689e121..b06c6693d02d98cce8ef27f35630d982eb09a9d8 100644 (file)
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -4524,14 +4524,49 @@ cse_insn (rtx_insn *insn)
   canonicalize_insn (insn, &sets, n_sets);
 
   /* If this insn has a REG_EQUAL note, store the equivalent value in SRC_EQV,
-     if different, or if the DEST is a STRICT_LOW_PART.  The latter condition
-     is necessary because SRC_EQV is handled specially for this case, and if
-     it isn't set, then there will be no equivalence for the destination.  */
+     if different, or if the DEST is a STRICT_LOW_PART/ZERO_EXTRACT.  The
+     latter condition is necessary because SRC_EQV is handled specially for
+     this case, and if it isn't set, then there will be no equivalence
+     for the destination.  */
   if (n_sets == 1 && REG_NOTES (insn) != 0
-      && (tem = find_reg_note (insn, REG_EQUAL, NULL_RTX)) != 0
-      && (! rtx_equal_p (XEXP (tem, 0), SET_SRC (sets[0].rtl))
-         || GET_CODE (SET_DEST (sets[0].rtl)) == STRICT_LOW_PART))
-    src_eqv = copy_rtx (XEXP (tem, 0));
+      && (tem = find_reg_note (insn, REG_EQUAL, NULL_RTX)) != 0)
+    {
+      if ((! rtx_equal_p (XEXP (tem, 0), SET_SRC (sets[0].rtl)))
+         || GET_CODE (SET_DEST (sets[0].rtl)) == STRICT_LOW_PART)
+       src_eqv = copy_rtx (XEXP (tem, 0));
+
+      /* If DEST is of the form ZERO_EXTACT, as in:
+        (set (zero_extract:SI (reg:SI 119)
+                 (const_int 16 [0x10])
+                 (const_int 16 [0x10]))
+             (const_int 51154 [0xc7d2]))
+        REG_EQUAL note will specify the value of register (reg:SI 119) at this
+        point.  Note that this is different from SRC_EQV. We can however
+        calculate SRC_EQV with the position and width of ZERO_EXTRACT.  */
+      else if (GET_CODE (SET_DEST (sets[0].rtl)) == ZERO_EXTRACT
+              && CONST_INT_P (src_eqv)
+              && CONST_INT_P (XEXP (SET_DEST (sets[0].rtl), 1))
+              && CONST_INT_P (XEXP (SET_DEST (sets[0].rtl), 2)))
+       {
+         rtx dest_reg = XEXP (SET_DEST (sets[0].rtl), 0);
+         rtx width = XEXP (SET_DEST (sets[0].rtl), 1);
+         rtx pos = XEXP (SET_DEST (sets[0].rtl), 2);
+         HOST_WIDE_INT val = INTVAL (src_eqv);
+         HOST_WIDE_INT mask;
+         unsigned int shift;
+         if (BITS_BIG_ENDIAN)
+           shift = GET_MODE_PRECISION (GET_MODE (dest_reg))
+             - INTVAL (pos) - INTVAL (width);
+         else
+           shift = INTVAL (pos);
+         if (INTVAL (width) == HOST_BITS_PER_WIDE_INT)
+           mask = ~(HOST_WIDE_INT) 0;
+         else
+           mask = ((HOST_WIDE_INT) 1 << INTVAL (width)) - 1;
+         val = (val >> shift) & mask;
+         src_eqv = GEN_INT (val);
+       }
+    }
 
   /* Set sets[i].src_elt to the class each source belongs to.
      Detect assignments from or to volatile things
index 93dd4595ed05b26a64bd6c7fcce231a9838ba403..ed2b30b17ee1f279c9de30034ef46dd13cd88262 100644 (file)
@@ -5221,7 +5221,8 @@ set_for_reg_notes (rtx insn)
   reg = SET_DEST (pat);
 
   /* Notes apply to the contents of a STRICT_LOW_PART.  */
-  if (GET_CODE (reg) == STRICT_LOW_PART)
+  if (GET_CODE (reg) == STRICT_LOW_PART
+      || GET_CODE (reg) == ZERO_EXTRACT)
     reg = XEXP (reg, 0);
 
   /* Check that we have a register.  */