summaryrefslogtreecommitdiffstats
path: root/gcc/reload1.c
diff options
context:
space:
mode:
authorian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>1997-04-14 01:03:03 +0000
committerian <ian@138bc75d-0d04-0410-961f-82ee72b054a4>1997-04-14 01:03:03 +0000
commitea85204aa7959631b7fc61c4946b3b6f781c3d07 (patch)
tree0f33d4d89db45110779bc3f9b61a7a1c83aee384 /gcc/reload1.c
parent188c68d9c1d94d29fc5d73921b70d64a5163e247 (diff)
downloadppe42-gcc-ea85204aa7959631b7fc61c4946b3b6f781c3d07.tar.gz
ppe42-gcc-ea85204aa7959631b7fc61c4946b3b6f781c3d07.zip
When clobbering a reg, check for later words of a multi word reg value
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@13899 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/reload1.c')
-rw-r--r--gcc/reload1.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/gcc/reload1.c b/gcc/reload1.c
index 702ebd812a1..a8774507cb3 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -7551,6 +7551,12 @@ count_occurrences (x, find)
static rtx *reg_values;
+/* This is a preallocated REG rtx which we use as a temporary in
+ reload_cse_invalidate_regno, so that we don't need to allocate a
+ new one each time through a loop in that function. */
+
+static rtx invalidate_regno_rtx;
+
/* Invalidate any entries in reg_values which depend on REGNO,
including those for REGNO itself. This is called if REGNO is
changing. If CLOBBER is true, then always forget anything we
@@ -7608,6 +7614,33 @@ reload_cse_invalidate_regno (regno, mode, clobber)
}
}
}
+
+ /* We must look at earlier registers, in case REGNO is part of a
+ multi word value but is not the first register. If an earlier
+ register has a value in a mode which overlaps REGNO, then we must
+ invalidate that earlier register. Note that we do not need to
+ check REGNO or later registers (we must not check REGNO itself,
+ because we would incorrectly conclude that there was a conflict). */
+
+ for (i = 0; i < regno; i++)
+ {
+ rtx x;
+
+ for (x = reg_values[i]; x; x = XEXP (x, 1))
+ {
+ if (XEXP (x, 0) != 0)
+ {
+ PUT_MODE (invalidate_regno_rtx, GET_MODE (XEXP (x, 0)));
+ REGNO (invalidate_regno_rtx) = i;
+ if (refers_to_regno_p (regno, endregno, invalidate_regno_rtx,
+ NULL_PTR))
+ {
+ reload_cse_invalidate_regno (i, VOIDmode, 1);
+ break;
+ }
+ }
+ }
+ }
}
/* The memory at address (plus MEM_BASE MEM_OFFSET), where MEM_OFFSET
@@ -7800,6 +7833,10 @@ reload_cse_regs (first)
memory for a non-const call instruction. */
callmem = gen_rtx (MEM, BLKmode, const0_rtx);
+ /* This is used in reload_cse_invalidate_regno to avoid consing a
+ new REG in a loop in that function. */
+ invalidate_regno_rtx = gen_rtx (REG, VOIDmode, 0);
+
for (insn = first; insn; insn = NEXT_INSN (insn))
{
rtx body;
OpenPOWER on IntegriCloud