aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1995-08-13 18:45:42 -0400
committerRichard Kenner <kenner@gcc.gnu.org>1995-08-13 18:45:42 -0400
commit9c6b0bae3c840478cf7bd5e2963177bc812ea4df (patch)
tree243eaf7eea0c8240bd5c8b21b7d2a3b282928e93 /gcc
parent91503d95ef8a0d0a8063291ed77b8973eed74a69 (diff)
downloadgcc-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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cse.c50
1 files changed, 50 insertions, 0 deletions
diff --git a/gcc/cse.c b/gcc/cse.c
index 3c5ba6f..5f7e01d 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -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);
}