aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>2003-04-08 21:53:34 +0200
committerZdenek Dvorak <rakdver@gcc.gnu.org>2003-04-08 19:53:34 +0000
commit8a5275eb09e8d3914cb8497e3815231e60526c13 (patch)
treeba324b47e5a824b0ab6e3b63f896cb96f1908bf9
parentac55736a0a271f62a2ed018a8d34039d6f458f60 (diff)
downloadgcc-8a5275eb09e8d3914cb8497e3815231e60526c13.zip
gcc-8a5275eb09e8d3914cb8497e3815231e60526c13.tar.gz
gcc-8a5275eb09e8d3914cb8497e3815231e60526c13.tar.bz2
function.c (postponed_insns): New.
* function.c (postponed_insns): New. (purge_addressof_1): Postpone processing of insns if addressofs are not put into stack. (purge_addressof): Process postponed insns. From-SVN: r65380
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/function.c53
2 files changed, 48 insertions, 12 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9d48969..7533314 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2003-04-08 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
+
+ * function.c (postponed_insns): New.
+ (purge_addressof_1): Postpone processing of insns if addressofs
+ are not put into stack.
+ (purge_addressof): Process postponed insns.
+
2003-04-08 J"orn Rennecke <joern.rennecke@superh.com>
* sh.h (NORMAL_MODE): If interrupt handler and TARGET_FMOVD,
diff --git a/gcc/function.c b/gcc/function.c
index 0b4f93f..0b3a006 100644
--- a/gcc/function.c
+++ b/gcc/function.c
@@ -281,8 +281,7 @@ static int contains PARAMS ((rtx, varray_type));
static void emit_return_into_block PARAMS ((basic_block, rtx));
#endif
static void put_addressof_into_stack PARAMS ((rtx, htab_t));
-static bool purge_addressof_1 PARAMS ((rtx *, rtx, int, int,
- htab_t));
+static bool purge_addressof_1 PARAMS ((rtx *, rtx, int, int, int, htab_t));
static void purge_single_hard_subreg_set PARAMS ((rtx));
#if defined(HAVE_epilogue) && defined(INCOMING_RETURN_ADDR_RTX)
static rtx keep_stack_depressed PARAMS ((rtx));
@@ -300,6 +299,9 @@ static void instantiate_virtual_regs_lossage PARAMS ((rtx));
/* Pointer to chain of `struct function' for containing functions. */
static GTY(()) struct function *outer_function_chain;
+/* List of insns that were postponed by purge_addressof_1. */
+static rtx postponed_insns;
+
/* Given a function decl for a containing function,
return the `struct function' for it. */
@@ -2999,13 +3001,14 @@ static rtx purge_addressof_replacements;
/* Helper function for purge_addressof. See if the rtx expression at *LOC
in INSN needs to be changed. If FORCE, always put any ADDRESSOFs into
the stack. If the function returns FALSE then the replacement could not
- be made. */
+ be made. If MAY_POSTPONE is true and we would not put the addressof
+ to stack, postpone processing of the insn. */
static bool
-purge_addressof_1 (loc, insn, force, store, ht)
+purge_addressof_1 (loc, insn, force, store, may_postpone, ht)
rtx *loc;
rtx insn;
- int force, store;
+ int force, store, may_postpone;
htab_t ht;
{
rtx x;
@@ -3028,8 +3031,10 @@ purge_addressof_1 (loc, insn, force, store, ht)
memory. */
if (code == SET)
{
- result = purge_addressof_1 (&SET_DEST (x), insn, force, 1, ht);
- result &= purge_addressof_1 (&SET_SRC (x), insn, force, 0, ht);
+ result = purge_addressof_1 (&SET_DEST (x), insn, force, 1,
+ may_postpone, ht);
+ result &= purge_addressof_1 (&SET_SRC (x), insn, force, 0,
+ may_postpone, ht);
return result;
}
else if (code == ADDRESSOF)
@@ -3062,6 +3067,13 @@ purge_addressof_1 (loc, insn, force, store, ht)
{
rtx sub = XEXP (XEXP (x, 0), 0);
+ if (may_postpone)
+ {
+ if (!postponed_insns || XEXP (postponed_insns, 0) != insn)
+ postponed_insns = alloc_INSN_LIST (insn, postponed_insns);
+ return true;
+ }
+
if (GET_CODE (sub) == MEM)
sub = adjust_address_nv (sub, GET_MODE (x), 0);
else if (GET_CODE (sub) == REG
@@ -3260,10 +3272,12 @@ purge_addressof_1 (loc, insn, force, store, ht)
for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
{
if (*fmt == 'e')
- result &= purge_addressof_1 (&XEXP (x, i), insn, force, 0, ht);
+ result &= purge_addressof_1 (&XEXP (x, i), insn, force, 0,
+ may_postpone, ht);
else if (*fmt == 'E')
for (j = 0; j < XVECLEN (x, i); j++)
- result &= purge_addressof_1 (&XVECEXP (x, i, j), insn, force, 0, ht);
+ result &= purge_addressof_1 (&XVECEXP (x, i, j), insn, force, 0,
+ may_postpone, ht);
}
return result;
@@ -3391,7 +3405,7 @@ void
purge_addressof (insns)
rtx insns;
{
- rtx insn;
+ rtx insn, tmp;
htab_t ht;
/* When we actually purge ADDRESSOFs, we turn REGs into MEMs. That
@@ -3404,16 +3418,18 @@ purge_addressof (insns)
ht = htab_create_ggc (1000, insns_for_mem_hash, insns_for_mem_comp, NULL);
compute_insns_for_mem (insns, NULL_RTX, ht);
+ postponed_insns = NULL;
+
for (insn = insns; insn; insn = NEXT_INSN (insn))
if (INSN_P (insn))
{
if (! purge_addressof_1 (&PATTERN (insn), insn,
- asm_noperands (PATTERN (insn)) > 0, 0, ht))
+ asm_noperands (PATTERN (insn)) > 0, 0, 1, ht))
/* If we could not replace the ADDRESSOFs in the insn,
something is wrong. */
abort ();
- if (! purge_addressof_1 (&REG_NOTES (insn), NULL_RTX, 0, 0, ht))
+ if (! purge_addressof_1 (&REG_NOTES (insn), NULL_RTX, 0, 0, 0, ht))
{
/* If we could not replace the ADDRESSOFs in the insn's notes,
we can just remove the offending notes instead. */
@@ -3433,6 +3449,19 @@ purge_addressof (insns)
}
}
+ /* Process the postponed insns. */
+ while (postponed_insns)
+ {
+ insn = XEXP (postponed_insns, 0);
+ tmp = postponed_insns;
+ postponed_insns = XEXP (postponed_insns, 1);
+ free_EXPR_LIST_node (tmp);
+
+ if (! purge_addressof_1 (&PATTERN (insn), insn,
+ asm_noperands (PATTERN (insn)) > 0, 0, 0, ht))
+ abort ();
+ }
+
/* Clean up. */
purge_bitfield_addressof_replacements = 0;
purge_addressof_replacements = 0;