diff options
author | Richard Kenner <kenner@gcc.gnu.org> | 1995-08-13 18:45:42 -0400 |
---|---|---|
committer | Richard Kenner <kenner@gcc.gnu.org> | 1995-08-13 18:45:42 -0400 |
commit | 9c6b0bae3c840478cf7bd5e2963177bc812ea4df (patch) | |
tree | 243eaf7eea0c8240bd5c8b21b7d2a3b282928e93 | |
parent | 91503d95ef8a0d0a8063291ed77b8973eed74a69 (diff) | |
download | gcc-9c6b0bae3c840478cf7bd5e2963177bc812ea4df.zip gcc-9c6b0bae3c840478cf7bd5e2963177bc812ea4df.tar.gz gcc-9c6b0bae3c840478cf7bd5e2963177bc812ea4df.tar.bz2 |
(set_nonvarying_address_components): Handle addresses which are the sum of two constant pseudo regs.
(set_nonvarying_address_components): Handle addresses which are the sum of
two constant pseudo regs.
(cse_rtx_addr_varies_p): Likewise.
From-SVN: r10220
-rw-r--r-- | gcc/cse.c | 50 |
1 files changed, 50 insertions, 0 deletions
@@ -2269,6 +2269,37 @@ set_nonvarying_address_components (addr, size, pbase, pstart, pend) start = INTVAL (XEXP (base, 1)); base = qty_const[reg_qty[REGNO (XEXP (base, 0))]]; } + /* This can happen as the result of virtual register instantiation, + if the inital offset is too large to be a valid address. */ + else if (GET_CODE (base) == PLUS + && GET_CODE (XEXP (base, 0)) == REG + && GET_CODE (XEXP (base, 1)) == 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))]] + && REGNO_QTY_VALID_P (REGNO (XEXP (base, 1))) + && (qty_mode[reg_qty[REGNO (XEXP (base, 1))]] + == GET_MODE (XEXP (base, 1))) + && qty_const[reg_qty[REGNO (XEXP (base, 1))]]) + { + rtx tem = qty_const[reg_qty[REGNO (XEXP (base, 1))]]; + base = qty_const[reg_qty[REGNO (XEXP (base, 0))]]; + + /* One of the two values must be a constant. */ + if (GET_CODE (base) != CONST_INT) + { + if (GET_CODE (tem) != CONST_INT) + abort (); + start = INTVAL (tem); + } + else + { + start = INTVAL (base); + base = tem; + } + } /* Handle everything that we can find inside an address that has been viewed as constant. */ @@ -2439,6 +2470,25 @@ cse_rtx_addr_varies_p (x) && qty_const[reg_qty[REGNO (XEXP (XEXP (x, 0), 0))]]) return 0; + /* This can happen as the result of virtual register instantiation, if + the initial constant is too large to be a valid address. This gives + us a three instruction sequence, load large offset into a register, + load fp minus a constant into a register, then a MEM which is the + sum of the two `constant' registers. */ + if (GET_CODE (x) == MEM + && GET_CODE (XEXP (x, 0)) == PLUS + && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG + && GET_CODE (XEXP (XEXP (x, 0), 1)) == REG + && REGNO_QTY_VALID_P (REGNO (XEXP (XEXP (x, 0), 0))) + && (GET_MODE (XEXP (XEXP (x, 0), 0)) + == qty_mode[reg_qty[REGNO (XEXP (XEXP (x, 0), 0))]]) + && qty_const[reg_qty[REGNO (XEXP (XEXP (x, 0), 0))]] + && REGNO_QTY_VALID_P (REGNO (XEXP (XEXP (x, 0), 1))) + && (GET_MODE (XEXP (XEXP (x, 0), 1)) + == qty_mode[reg_qty[REGNO (XEXP (XEXP (x, 0), 1))]]) + && qty_const[reg_qty[REGNO (XEXP (XEXP (x, 0), 1))]]) + return 0; + return rtx_addr_varies_p (x); } |