If purge_addressof_1 fails to remove addressofs in notes, remove the notes

instead.

From-SVN: r30414
This commit is contained in:
Nick Clifton 1999-11-05 10:11:40 +00:00 committed by Nick Clifton
parent ce82ff5c17
commit 8c36698e52
2 changed files with 75 additions and 23 deletions

View File

@ -1,3 +1,13 @@
Fri Nov 5 10:07:25 1999 Nick Clifton <nickc@cygnus.com>
* function.c (is_addressof): New function. Returns true if
the given piece of RTL is an ADDRESSOF.
(purge_addressof_1): Make boolean. Return false if the
ADDRESSOFs could not be purged.
(purge_addressof): If ADDRESSOFs could not be purged from the
notes attached to an insn, remove the offending note(s),
unless they are attached to a libcall.
1999-11-05 Andreas Jaeger <aj@suse.de>
* genoutput.c (null_operand =): Initialize all fields.

View File

@ -268,8 +268,9 @@ static int all_blocks PROTO((tree, tree *));
static int *record_insns PROTO((rtx)) ATTRIBUTE_UNUSED;
static int contains PROTO((rtx, int *));
static void put_addressof_into_stack PROTO((rtx, struct hash_table *));
static void purge_addressof_1 PROTO((rtx *, rtx, int, int,
static boolean purge_addressof_1 PROTO((rtx *, rtx, int, int,
struct hash_table *));
static int is_addressof PROTO ((rtx *, void *));
static struct hash_entry *insns_for_mem_newfunc PROTO((struct hash_entry *,
struct hash_table *,
hash_table_key));
@ -2765,9 +2766,10 @@ 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. */
the stack. If the function returns FALSE then the replacement could not
be made. */
static void
static boolean
purge_addressof_1 (loc, insn, force, store, ht)
rtx *loc;
rtx insn;
@ -2778,13 +2780,14 @@ purge_addressof_1 (loc, insn, force, store, ht)
RTX_CODE code;
int i, j;
const char *fmt;
boolean result = true;
/* Re-start here to avoid recursion in common cases. */
restart:
x = *loc;
if (x == 0)
return;
return true;
code = GET_CODE (x);
@ -2793,9 +2796,9 @@ purge_addressof_1 (loc, insn, force, store, ht)
memory. */
if (code == SET)
{
purge_addressof_1 (&SET_DEST (x), insn, force, 1, ht);
purge_addressof_1 (&SET_SRC (x), insn, force, 0, ht);
return;
result = purge_addressof_1 (&SET_DEST (x), insn, force, 1, ht);
result &= purge_addressof_1 (&SET_SRC (x), insn, force, 0, ht);
return result;
}
else if (code == ADDRESSOF && GET_CODE (XEXP (x, 0)) == MEM)
@ -2807,7 +2810,7 @@ purge_addressof_1 (loc, insn, force, store, ht)
if (validate_change (insn, loc, sub, 0)
|| validate_replace_rtx (x, sub, insn))
return;
return true;
start_sequence ();
sub = force_operand (sub, NULL_RTX);
@ -2818,7 +2821,7 @@ purge_addressof_1 (loc, insn, force, store, ht)
insns = gen_sequence ();
end_sequence ();
emit_insn_before (insns, insn);
return;
return true;
}
else if (code == MEM && GET_CODE (XEXP (x, 0)) == ADDRESSOF && ! force)
@ -2853,7 +2856,7 @@ purge_addressof_1 (loc, insn, force, store, ht)
if (rtx_equal_p (x, XEXP (tem, 0)))
{
*loc = XEXP (XEXP (tem, 1), 0);
return;
return true;
}
/* See comment for purge_addressof_replacements. */
@ -2896,8 +2899,14 @@ purge_addressof_1 (loc, insn, force, store, ht)
return;
}
/* There should always be such a replacement. */
abort ();
/* Sometimes we may not be able to find the replacement. For
example when the original insn was a MEM in a wider mode,
and the note is part of a sign extension of a narrowed
version of that MEM. Gcc testcase compile/990829-1.c can
generate an example of this siutation. Rather than complain
we return false, which will prompt our caller to remove the
offending note. */
return false;
}
size_x = GET_MODE_BITSIZE (GET_MODE (x));
@ -2989,7 +2998,7 @@ purge_addressof_1 (loc, insn, force, store, ht)
purge_bitfield_addressof_replacements));
/* We replaced with a reg -- all done. */
return;
return true;
}
}
@ -3007,13 +3016,13 @@ purge_addressof_1 (loc, insn, force, store, ht)
if (rtx_equal_p (XEXP (x, 0), XEXP (tem, 0)))
{
XEXP (XEXP (tem, 1), 0) = sub;
return;
return true;
}
purge_addressof_replacements
= gen_rtx (EXPR_LIST, VOIDmode, XEXP (x, 0),
gen_rtx_EXPR_LIST (VOIDmode, sub,
purge_addressof_replacements));
return;
return true;
}
goto restart;
}
@ -3028,9 +3037,9 @@ purge_addressof_1 (loc, insn, force, store, ht)
}
else if (code == SET)
{
purge_addressof_1 (&SET_DEST (x), insn, force, 1, ht);
purge_addressof_1 (&SET_SRC (x), insn, force, 0, ht);
return;
result = purge_addressof_1 (&SET_DEST (x), insn, force, 1, ht);
result &= purge_addressof_1 (&SET_SRC (x), insn, force, 0, ht);
return result;
}
/* Scan all subexpressions. */
@ -3038,11 +3047,13 @@ purge_addressof_1 (loc, insn, force, store, ht)
for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
{
if (*fmt == 'e')
purge_addressof_1 (&XEXP (x, i), insn, force, 0, ht);
result &= purge_addressof_1 (&XEXP (x, i), insn, force, 0, ht);
else if (*fmt == 'E')
for (j = 0; j < XVECLEN (x, i); j++)
purge_addressof_1 (&XVECEXP (x, i, j), insn, force, 0, ht);
result &= purge_addressof_1 (&XVECEXP (x, i, j), insn, force, 0, ht);
}
return result;
}
/* Return a new hash table entry in HT. */
@ -3162,6 +3173,16 @@ compute_insns_for_mem (insns, last_insn, ht)
}
}
/* Helper function for purge_addressof called through for_each_rtx.
Returns true iff the rtl is an ADDRESSOF. */
static int
is_addressof (rtl, data)
rtx * rtl;
void * data ATTRIBUTE_UNUSED;
{
return GET_CODE (* rtl) == ADDRESSOF;
}
/* Eliminate all occurrences of ADDRESSOF from INSNS. Elide any remaining
(MEM (ADDRESSOF)) patterns, and force any needed registers into the
stack. */
@ -3190,9 +3211,30 @@ purge_addressof (insns)
if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
|| GET_CODE (insn) == CALL_INSN)
{
purge_addressof_1 (&PATTERN (insn), insn,
asm_noperands (PATTERN (insn)) > 0, 0, &ht);
purge_addressof_1 (&REG_NOTES (insn), NULL_RTX, 0, 0, &ht);
if (! purge_addressof_1 (&PATTERN (insn), insn,
asm_noperands (PATTERN (insn)) > 0, 0, &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 we could not replace the ADDRESSOFs in the insn's notes,
we can just remove the offending notes instead. */
rtx note;
for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
{
/* If we find a REG_RETVAL note then the insn is a libcall.
Such insns must have REG_EQUAL notes as well, in order
for later passes of the compiler to work. So it is not
safe to delete the notes here, and instead we abort. */
if (REG_NOTE_KIND (note) == REG_RETVAL)
abort ();
if (for_each_rtx (& note, is_addressof, NULL))
remove_note (insn, note);
}
}
}
/* Clean up. */