aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDale Johannesen <dalej@apple.com>2003-12-22 18:25:35 +0000
committerDale Johannesen <dalej@gcc.gnu.org>2003-12-22 18:25:35 +0000
commite3e9336fc6b86be87305ae5c8ccf1f4d8a98039b (patch)
tree327de0674aeed7ccab094bea1d154d6e220af7a7
parentaaf3ce3e553c3bb85fe447691c9309f9522facb5 (diff)
downloadgcc-e3e9336fc6b86be87305ae5c8ccf1f4d8a98039b.zip
gcc-e3e9336fc6b86be87305ae5c8ccf1f4d8a98039b.tar.gz
gcc-e3e9336fc6b86be87305ae5c8ccf1f4d8a98039b.tar.bz2
reload1.c: Add reg_reloaded_call_part_clobbered.
2003-12-22 Dale Johannesen <dalej@apple.com> * reload1.c: Add reg_reloaded_call_part_clobbered. (reload_as_needed): Use it. (forget_old_reloads_1): Ditto. (emit_reload_insns): Ditto. From-SVN: r74936
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/reload1.c32
2 files changed, 35 insertions, 4 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 6d07741..a5636de 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,12 @@
2003-12-22 Dale Johannesen <dalej@apple.com>
+ * reload1.c: Add reg_reloaded_call_part_clobbered.
+ (reload_as_needed): Use it.
+ (forget_old_reloads_1): Ditto.
+ (emit_reload_insns): Ditto.
+
+2003-12-22 Dale Johannesen <dalej@apple.com>
+
PR optimization/12828
* loop.c: Add find_regs_nested to look inside CLOBBER(MEM).
(scan_loop): Call it.
diff --git a/gcc/reload1.c b/gcc/reload1.c
index a739da3..9a0ad89 100644
--- a/gcc/reload1.c
+++ b/gcc/reload1.c
@@ -138,6 +138,11 @@ static HARD_REG_SET reg_reloaded_valid;
This is only valid if reg_reloaded_contents is set and valid. */
static HARD_REG_SET reg_reloaded_dead;
+/* Indicate whether the register's current value is one that is not
+ safe to retain across a call, even for registers that are normally
+ call-saved. */
+static HARD_REG_SET reg_reloaded_call_part_clobbered;
+
/* Number of spill-regs so far; number of valid elements of spill_regs. */
static int n_spills;
@@ -3757,6 +3762,7 @@ reload_as_needed (int live_known)
reg_last_reload_reg = xcalloc (max_regno, sizeof (rtx));
reg_has_output_reload = xmalloc (max_regno);
CLEAR_HARD_REG_SET (reg_reloaded_valid);
+ CLEAR_HARD_REG_SET (reg_reloaded_call_part_clobbered);
set_initial_elim_offsets ();
@@ -4004,9 +4010,13 @@ reload_as_needed (int live_known)
CLEAR_HARD_REG_SET (reg_reloaded_valid);
/* Don't assume a reload reg is still good after a call insn
- if it is a call-used reg. */
+ if it is a call-used reg, or if it contains a value that will
+ be partially clobbered by the call. */
else if (GET_CODE (insn) == CALL_INSN)
+ {
AND_COMPL_HARD_REG_SET (reg_reloaded_valid, call_used_reg_set);
+ AND_COMPL_HARD_REG_SET (reg_reloaded_valid, reg_reloaded_call_part_clobbered);
+ }
}
/* Clean up. */
@@ -4061,6 +4071,7 @@ forget_old_reloads_1 (rtx x, rtx ignored ATTRIBUTE_UNUSED,
|| ! TEST_HARD_REG_BIT (reg_is_output_reload, regno + i))
{
CLEAR_HARD_REG_BIT (reg_reloaded_valid, regno + i);
+ CLEAR_HARD_REG_BIT (reg_reloaded_call_part_clobbered, regno + i);
spill_reg_store[regno + i] = 0;
}
}
@@ -7043,7 +7054,10 @@ emit_reload_insns (struct insn_chain *chain)
If consecutive registers are used, clear them all. */
for (k = 0; k < nr; k++)
+ {
CLEAR_HARD_REG_BIT (reg_reloaded_valid, i + k);
+ CLEAR_HARD_REG_BIT (reg_reloaded_call_part_clobbered, i + k);
+ }
/* Maybe the spill reg contains a copy of reload_out. */
if (rld[r].out != 0
@@ -7090,6 +7104,8 @@ emit_reload_insns (struct insn_chain *chain)
: nregno + k);
reg_reloaded_insn[i + k] = insn;
SET_HARD_REG_BIT (reg_reloaded_valid, i + k);
+ if (HARD_REGNO_CALL_PART_CLOBBERED (i + k, GET_MODE (out)))
+ SET_HARD_REG_BIT (reg_reloaded_call_part_clobbered, i + k);
}
}
@@ -7107,14 +7123,16 @@ emit_reload_insns (struct insn_chain *chain)
{
int nregno;
int nnr;
+ rtx in;
if (GET_CODE (rld[r].in) == REG
&& REGNO (rld[r].in) >= FIRST_PSEUDO_REGISTER)
- nregno = REGNO (rld[r].in);
+ in = rld[r].in;
else if (GET_CODE (rld[r].in_reg) == REG)
- nregno = REGNO (rld[r].in_reg);
+ in = rld[r].in_reg;
else
- nregno = REGNO (XEXP (rld[r].in_reg, 0));
+ in = XEXP (rld[r].in_reg, 0);
+ nregno = REGNO (in);
nnr = (nregno >= FIRST_PSEUDO_REGISTER ? 1
: HARD_REGNO_NREGS (nregno,
@@ -7146,6 +7164,8 @@ emit_reload_insns (struct insn_chain *chain)
: nregno + k);
reg_reloaded_insn[i + k] = insn;
SET_HARD_REG_BIT (reg_reloaded_valid, i + k);
+ if (HARD_REGNO_CALL_PART_CLOBBERED (i + k, GET_MODE (in)))
+ SET_HARD_REG_BIT (reg_reloaded_call_part_clobbered, i + k);
}
}
}
@@ -7232,6 +7252,10 @@ emit_reload_insns (struct insn_chain *chain)
reg_reloaded_insn[src_regno + nr] = store_insn;
CLEAR_HARD_REG_BIT (reg_reloaded_dead, src_regno + nr);
SET_HARD_REG_BIT (reg_reloaded_valid, src_regno + nr);
+ if (HARD_REGNO_CALL_PART_CLOBBERED (src_regno + nr,
+ GET_MODE (src_reg)))
+ SET_HARD_REG_BIT (reg_reloaded_call_part_clobbered,
+ src_regno + nr);
SET_HARD_REG_BIT (reg_is_output_reload, src_regno + nr);
if (note)
SET_HARD_REG_BIT (reg_reloaded_died, src_regno);