mirror of git://gcc.gnu.org/git/gcc.git
cse.c (cse_insn): Calculate src_eqv for ZERO_EXTRACT.
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
This commit is contained in:
parent
01169386a0
commit
7f7379f6f4
|
|
@ -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>
|
2015-07-11 Marek Polacek <polacek@redhat.com>
|
||||||
|
|
||||||
PR middle-end/66353
|
PR middle-end/66353
|
||||||
|
|
|
||||||
47
gcc/cse.c
47
gcc/cse.c
|
|
@ -4524,15 +4524,50 @@ cse_insn (rtx_insn *insn)
|
||||||
canonicalize_insn (insn, &sets, n_sets);
|
canonicalize_insn (insn, &sets, n_sets);
|
||||||
|
|
||||||
/* If this insn has a REG_EQUAL note, store the equivalent value in SRC_EQV,
|
/* 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
|
if different, or if the DEST is a STRICT_LOW_PART/ZERO_EXTRACT. The
|
||||||
is necessary because SRC_EQV is handled specially for this case, and if
|
latter condition is necessary because SRC_EQV is handled specially for
|
||||||
it isn't set, then there will be no equivalence for the destination. */
|
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
|
if (n_sets == 1 && REG_NOTES (insn) != 0
|
||||||
&& (tem = find_reg_note (insn, REG_EQUAL, NULL_RTX)) != 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))
|
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));
|
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.
|
/* Set sets[i].src_elt to the class each source belongs to.
|
||||||
Detect assignments from or to volatile things
|
Detect assignments from or to volatile things
|
||||||
and set set[i] to zero so they will be ignored
|
and set set[i] to zero so they will be ignored
|
||||||
|
|
|
||||||
|
|
@ -5221,7 +5221,8 @@ set_for_reg_notes (rtx insn)
|
||||||
reg = SET_DEST (pat);
|
reg = SET_DEST (pat);
|
||||||
|
|
||||||
/* Notes apply to the contents of a STRICT_LOW_PART. */
|
/* 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);
|
reg = XEXP (reg, 0);
|
||||||
|
|
||||||
/* Check that we have a register. */
|
/* Check that we have a register. */
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue