From 99788e063016c4f8d87dae3de71c646effac654f Mon Sep 17 00:00:00 2001 From: Alan Hayward Date: Mon, 6 Aug 2018 09:54:28 +0000 Subject: 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 --- gcc/cselib.c | 42 ++++++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 10 deletions(-) (limited to 'gcc/cselib.c') 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)) { -- cgit v1.2.1