From f451db89907a1b16fbaa6330b09d76bd00a0cce6 Mon Sep 17 00:00:00 2001 From: Jeff Law Date: Thu, 11 Mar 1993 05:46:36 -0700 Subject: [PATCH] cse.c (set_nonvarying_address_components): New function. * cse.c (set_nonvarying_address_components): New function. (invalidate): Use set_nonvarying_address_components instead of computing them. (refers_to_mem_p): Likewise. Simplify checks for conflicting memory accesses. Make static. From-SVN: r3703 --- gcc/cse.c | 198 ++++++++++++++++++++++++------------------------------ 1 file changed, 88 insertions(+), 110 deletions(-) diff --git a/gcc/cse.c b/gcc/cse.c index e2bb7ae1456..979df3fa2f6 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -603,8 +603,10 @@ static rtx use_related_value PROTO((rtx, struct table_elt *)); static int canon_hash PROTO((rtx, enum machine_mode)); static int safe_hash PROTO((rtx, enum machine_mode)); static int exp_equiv_p PROTO((rtx, rtx, int, int)); +static void set_nonvarying_address_components PROTO((rtx, int, rtx *, + int *, int *)); static int refers_to_p PROTO((rtx, rtx)); -int refers_to_mem_p PROTO((rtx, rtx, HOST_WIDE_INT, +static int refers_to_mem_p PROTO((rtx, rtx, HOST_WIDE_INT, HOST_WIDE_INT)); static int cse_rtx_addr_varies_p PROTO((rtx)); static rtx canon_reg PROTO((rtx, rtx)); @@ -1451,8 +1453,8 @@ invalidate (x) { register int i; register struct table_elt *p; - register rtx base; - register HOST_WIDE_INT start, end; + rtx base; + HOST_WIDE_INT start, end; /* If X is a register, dependencies on its contents are recorded through the qty number mechanism. @@ -1531,38 +1533,10 @@ invalidate (x) if (GET_CODE (x) != MEM) abort (); - base = XEXP (x, 0); - start = 0; - /* Registers with nonvarying addresses usually have constant equivalents; - but the frame pointer register is also possible. */ - if (GET_CODE (base) == REG - && REGNO_QTY_VALID_P (REGNO (base)) - && qty_mode[reg_qty[REGNO (base)]] == GET_MODE (base) - && qty_const[reg_qty[REGNO (base)]] != 0) - base = qty_const[reg_qty[REGNO (base)]]; - else if (GET_CODE (base) == PLUS - && GET_CODE (XEXP (base, 1)) == CONST_INT - && GET_CODE (XEXP (base, 0)) == REG - && REGNO_QTY_VALID_P (REGNO (XEXP (base, 0))) - && (qty_mode[reg_qty[REGNO (XEXP (base, 0))]] - == GET_MODE (XEXP (base, 0))) - && qty_const[reg_qty[REGNO (XEXP (base, 0))]]) - { - start = INTVAL (XEXP (base, 1)); - base = qty_const[reg_qty[REGNO (XEXP (base, 0))]]; - } - - if (GET_CODE (base) == CONST) - base = XEXP (base, 0); - if (GET_CODE (base) == PLUS - && GET_CODE (XEXP (base, 1)) == CONST_INT) - { - start += INTVAL (XEXP (base, 1)); - base = XEXP (base, 0); - } + set_nonvarying_address_components (XEXP (x, 0), GET_MODE_SIZE (GET_MODE (x)), + &base, &start, &end); - end = start + GET_MODE_SIZE (GET_MODE (x)); for (i = 0; i < NBUCKETS; i++) { register struct table_elt *next; @@ -2212,20 +2186,87 @@ refers_to_p (x, y) return 0; } +/* Given ADDR and SIZE (a memory address, and the size of the memory reference), + set PBASE, PSTART, and PEND which correspond to the base of the address, + the starting offset, and ending offset respectively. + + ADDR is known to be a nonvarying address. + + cse_address_varies_p returns zero for nonvarying addresses. */ + +static void +set_nonvarying_address_components (addr, size, pbase, pstart, pend) + rtx addr; + int size; + rtx *pbase; + int *pstart, *pend; +{ + rtx base; + int start, end; + + base = addr; + start = 0; + end = 0; + + /* Registers with nonvarying addresses usually have constant equivalents; + but the frame pointer register is also possible. */ + if (GET_CODE (base) == REG + && qty_const != 0 + && REGNO_QTY_VALID_P (REGNO (base)) + && qty_mode[reg_qty[REGNO (base)]] == GET_MODE (base) + && qty_const[reg_qty[REGNO (base)]] != 0) + base = qty_const[reg_qty[REGNO (base)]]; + else if (GET_CODE (base) == PLUS + && GET_CODE (XEXP (base, 1)) == CONST_INT + && GET_CODE (XEXP (base, 0)) == REG + && qty_const != 0 + && REGNO_QTY_VALID_P (REGNO (XEXP (base, 0))) + && (qty_mode[reg_qty[REGNO (XEXP (base, 0))]] + == GET_MODE (XEXP (base, 0))) + && qty_const[reg_qty[REGNO (XEXP (base, 0))]]) + { + start = INTVAL (XEXP (base, 1)); + base = qty_const[reg_qty[REGNO (XEXP (base, 0))]]; + } + + /* By definition, operand1 of a LO_SUM is the associated constant + address. Use the associated constant address as the base instead. */ + if (GET_CODE (base) == LO_SUM) + base = XEXP (base, 1); + + /* Strip off CONST. */ + if (GET_CODE (base) == CONST) + base = XEXP (base, 0); + + if (GET_CODE (base) == PLUS + && GET_CODE (XEXP (base, 1)) == CONST_INT) + { + start += INTVAL (XEXP (base, 1)); + base = XEXP (base, 0); + } + + end = start + size; + + /* Set the return values. */ + *pbase = base; + *pstart = start; + *pend = end; +} + /* Return 1 iff any subexpression of X refers to memory at an address of BASE plus some offset such that any of the bytes' offsets fall between START (inclusive) and END (exclusive). - The value is undefined if X is a varying address. - This function is not used in such cases. + The value is undefined if X is a varying address (as determined by + cse_rtx_addr_varies_p). This function is not used in such cases. When used in the cse pass, `qty_const' is nonzero, and it is used to treat an address that is a register with a known constant value as if it were that constant value. In the loop pass, `qty_const' is zero, so this is not done. */ -int +static int refers_to_mem_p (x, base, start, end) rtx x, base; HOST_WIDE_INT start, end; @@ -2249,83 +2290,20 @@ refers_to_mem_p (x, base, start, end) if (code == MEM) { register rtx addr = XEXP (x, 0); /* Get the address. */ - int myend; - - i = 0; - if (GET_CODE (addr) == REG - /* qty_const is 0 when outside the cse pass; - at such times, this info is not available. */ - && qty_const != 0 - && REGNO_QTY_VALID_P (REGNO (addr)) - && GET_MODE (addr) == qty_mode[reg_qty[REGNO (addr)]] - && qty_const[reg_qty[REGNO (addr)]] != 0) - addr = qty_const[reg_qty[REGNO (addr)]]; - else if (GET_CODE (addr) == PLUS - && GET_CODE (XEXP (addr, 1)) == CONST_INT - && GET_CODE (XEXP (addr, 0)) == REG - && qty_const != 0 - && REGNO_QTY_VALID_P (REGNO (XEXP (addr, 0))) - && (GET_MODE (XEXP (addr, 0)) - == qty_mode[reg_qty[REGNO (XEXP (addr, 0))]]) - && qty_const[reg_qty[REGNO (XEXP (addr, 0))]]) - { - i = INTVAL (XEXP (addr, 1)); - addr = qty_const[reg_qty[REGNO (XEXP (addr, 0))]]; - } + rtx mybase; + int mystart, myend; - check_addr: - if (GET_CODE (addr) == CONST) - addr = XEXP (addr, 0); - - /* If ADDR is BASE, or BASE plus an integer, put - the integer in I. */ - if (GET_CODE (addr) == PLUS - && XEXP (addr, 0) == base - && GET_CODE (XEXP (addr, 1)) == CONST_INT) - i += INTVAL (XEXP (addr, 1)); - else if (GET_CODE (addr) == LO_SUM) - { - if (GET_CODE (base) != LO_SUM) - return 1; - /* The REG component of the LO_SUM is known by the - const value in the XEXP part. */ - addr = XEXP (addr, 1); - base = XEXP (base, 1); - i = 0; - if (GET_CODE (base) == CONST) - base = XEXP (base, 0); - if (GET_CODE (base) == PLUS - && GET_CODE (XEXP (base, 1)) == CONST_INT) - { - HOST_WIDE_INT tem = INTVAL (XEXP (base, 1)); - start += tem; - end += tem; - base = XEXP (base, 0); - } - goto check_addr; - } - else if (GET_CODE (base) == LO_SUM) - { - base = XEXP (base, 1); - if (GET_CODE (base) == CONST) - base = XEXP (base, 0); - if (GET_CODE (base) == PLUS - && GET_CODE (XEXP (base, 1)) == CONST_INT) - { - HOST_WIDE_INT tem = INTVAL (XEXP (base, 1)); - start += tem; - end += tem; - base = XEXP (base, 0); - } - goto check_addr; - } - else if (GET_CODE (addr) == CONST_INT && base == const0_rtx) - i = INTVAL (addr); - else if (addr != base) + set_nonvarying_address_components (addr, GET_MODE_SIZE (GET_MODE (x)), + &mybase, &mystart, &myend); + + + /* refers_to_mem_p is never called with varying addresses. + If the base addresses are not equal, there is no chance + of the memory addresses conflicting. */ + if (mybase != base) return 0; - myend = i + GET_MODE_SIZE (GET_MODE (x)); - return myend > start && i < end; + return myend > start && mystart < end; } /* X does not match, so try its subexpressions. */ -- 2.30.2