diff options
author | Kugan Vivekanandarajah <kuganv@linaro.org> | 2015-07-12 11:16:30 +0000 |
---|---|---|
committer | Kugan Vivekanandarajah <kugan@gcc.gnu.org> | 2015-07-12 11:16:30 +0000 |
commit | 7f7379f6f4f28376ac4fa9a807217f1fec2488fc (patch) | |
tree | 6635ab0b12302db27b1fd7effdbb88af0fd00813 /gcc | |
parent | 01169386a0f51405866e190bc836d6a1883a684f (diff) | |
download | gcc-7f7379f6f4f28376ac4fa9a807217f1fec2488fc.zip gcc-7f7379f6f4f28376ac4fa9a807217f1fec2488fc.tar.gz gcc-7f7379f6f4f28376ac4fa9a807217f1fec2488fc.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/cse.c | 49 | ||||
-rw-r--r-- | gcc/emit-rtl.c | 3 |
3 files changed, 50 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dd6155e..c435e30 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 @@ -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 diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index 93dd459..ed2b30b 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -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. */ |