summaryrefslogtreecommitdiff
path: root/gcc/cselib.c
diff options
context:
space:
mode:
authorAlan Hayward <alan.hayward@arm.com>2018-08-06 09:54:28 +0000
committerAlan Hayward <alahay01@gcc.gnu.org>2018-08-06 09:54:28 +0000
commit99788e063016c4f8d87dae3de71c646effac654f (patch)
tree073666483b43c7890a2cd761d82b0a76d323033a /gcc/cselib.c
parent30dc1902a777966dc1d1dad0fb5f19b7a960e5ca (diff)
downloadgcc-99788e063016c4f8d87dae3de71c646effac654f.tar.gz
cse support for clobber_high
gcc/ * cse.c (invalidate_reg): New function extracted from... (invalidate): ...here. (canonicalize_insn): Check for clobber high. (invalidate_from_clobbers): invalidate clobber highs. (invalidate_from_sets_and_clobbers): Likewise. (count_reg_usage): Check for clobber high. (insn_live_p): Likewise. * cselib.c (cselib_expand_value_rtx_1):Likewise. (cselib_invalidate_regno): Check for clobber in setter. (cselib_invalidate_rtx): Pass through setter. (cselib_invalidate_rtx_note_stores): (cselib_process_insn): Check for clobber high. * cselib.h (cselib_invalidate_rtx): Add operand. From-SVN: r263330
Diffstat (limited to 'gcc/cselib.c')
-rw-r--r--gcc/cselib.c42
1 files changed, 32 insertions, 10 deletions
diff --git a/gcc/cselib.c b/gcc/cselib.c
index 5a978c1f4b8..6d3a4078c68 100644
--- a/gcc/cselib.c
+++ b/gcc/cselib.c
@@ -54,7 +54,8 @@ static unsigned int cselib_hash_rtx (rtx, int, machine_mode);
static cselib_val *new_cselib_val (unsigned int, machine_mode, rtx);
static void add_mem_for_addr (cselib_val *, cselib_val *, rtx);
static cselib_val *cselib_lookup_mem (rtx, int);
-static void cselib_invalidate_regno (unsigned int, machine_mode);
+static void cselib_invalidate_regno (unsigned int, machine_mode,
+ const_rtx = NULL);
static void cselib_invalidate_mem (rtx);
static void cselib_record_set (rtx, cselib_val *, cselib_val *);
static void cselib_record_sets (rtx_insn *);
@@ -1661,6 +1662,7 @@ cselib_expand_value_rtx_1 (rtx orig, struct expand_value_data *evd,
/* SCRATCH must be shared because they represent distinct values. */
return orig;
case CLOBBER:
+ case CLOBBER_HIGH:
if (REG_P (XEXP (orig, 0)) && HARD_REGISTER_NUM_P (REGNO (XEXP (orig, 0))))
return orig;
break;
@@ -2163,7 +2165,8 @@ cselib_lookup (rtx x, machine_mode mode,
invalidating call clobbered registers across a call. */
static void
-cselib_invalidate_regno (unsigned int regno, machine_mode mode)
+cselib_invalidate_regno (unsigned int regno, machine_mode mode,
+ const_rtx setter)
{
unsigned int endregno;
unsigned int i;
@@ -2186,6 +2189,9 @@ cselib_invalidate_regno (unsigned int regno, machine_mode mode)
i = regno - max_value_regs;
endregno = end_hard_regno (mode, regno);
+
+ if (setter && GET_CODE (setter) == CLOBBER_HIGH)
+ gcc_assert (endregno == regno + 1);
}
else
{
@@ -2218,6 +2224,19 @@ cselib_invalidate_regno (unsigned int regno, machine_mode mode)
continue;
}
+ /* Ignore if clobber high and the register isn't clobbered. */
+ if (setter && GET_CODE (setter) == CLOBBER_HIGH)
+ {
+ gcc_assert (endregno == regno + 1);
+ const_rtx x = XEXP (setter, 0);
+ if (!reg_is_clobbered_by_clobber_high (i, GET_MODE (v->val_rtx),
+ x))
+ {
+ l = &(*l)->next;
+ continue;
+ }
+ }
+
/* We have an overlap. */
if (*l == REG_VALUES (i))
{
@@ -2352,10 +2371,10 @@ cselib_invalidate_mem (rtx mem_rtx)
*vp = &dummy_val;
}
-/* Invalidate DEST, which is being assigned to or clobbered. */
+/* Invalidate DEST, which is being assigned to or clobbered by SETTER. */
void
-cselib_invalidate_rtx (rtx dest)
+cselib_invalidate_rtx (rtx dest, const_rtx setter)
{
while (GET_CODE (dest) == SUBREG
|| GET_CODE (dest) == ZERO_EXTRACT
@@ -2363,7 +2382,7 @@ cselib_invalidate_rtx (rtx dest)
dest = XEXP (dest, 0);
if (REG_P (dest))
- cselib_invalidate_regno (REGNO (dest), GET_MODE (dest));
+ cselib_invalidate_regno (REGNO (dest), GET_MODE (dest), setter);
else if (MEM_P (dest))
cselib_invalidate_mem (dest);
}
@@ -2371,10 +2390,10 @@ cselib_invalidate_rtx (rtx dest)
/* A wrapper for cselib_invalidate_rtx to be called via note_stores. */
static void
-cselib_invalidate_rtx_note_stores (rtx dest, const_rtx ignore ATTRIBUTE_UNUSED,
+cselib_invalidate_rtx_note_stores (rtx dest, const_rtx setter,
void *data ATTRIBUTE_UNUSED)
{
- cselib_invalidate_rtx (dest);
+ cselib_invalidate_rtx (dest, setter);
}
/* Record the result of a SET instruction. DEST is being set; the source
@@ -2775,9 +2794,12 @@ cselib_process_insn (rtx_insn *insn)
if (CALL_P (insn))
{
for (x = CALL_INSN_FUNCTION_USAGE (insn); x; x = XEXP (x, 1))
- if (GET_CODE (XEXP (x, 0)) == CLOBBER)
- cselib_invalidate_rtx (XEXP (XEXP (x, 0), 0));
- /* Flush evertything on setjmp. */
+ {
+ gcc_assert (GET_CODE (XEXP (x, 0)) != CLOBBER_HIGH);
+ if (GET_CODE (XEXP (x, 0)) == CLOBBER)
+ cselib_invalidate_rtx (XEXP (XEXP (x, 0), 0));
+ }
+ /* Flush everything on setjmp. */
if (cselib_preserve_constants
&& find_reg_note (insn, REG_SETJMP, NULL))
{