Commit 8c36698e by Nick Clifton Committed by Nick Clifton

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

instead.

From-SVN: r30414
parent ce82ff5c
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> 1999-11-05 Andreas Jaeger <aj@suse.de>
* genoutput.c (null_operand =): Initialize all fields. * genoutput.c (null_operand =): Initialize all fields.
......
...@@ -268,8 +268,9 @@ static int all_blocks PROTO((tree, tree *)); ...@@ -268,8 +268,9 @@ static int all_blocks PROTO((tree, tree *));
static int *record_insns PROTO((rtx)) ATTRIBUTE_UNUSED; static int *record_insns PROTO((rtx)) ATTRIBUTE_UNUSED;
static int contains PROTO((rtx, int *)); static int contains PROTO((rtx, int *));
static void put_addressof_into_stack PROTO((rtx, struct hash_table *)); 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 *)); struct hash_table *));
static int is_addressof PROTO ((rtx *, void *));
static struct hash_entry *insns_for_mem_newfunc PROTO((struct hash_entry *, static struct hash_entry *insns_for_mem_newfunc PROTO((struct hash_entry *,
struct hash_table *, struct hash_table *,
hash_table_key)); hash_table_key));
...@@ -2765,9 +2766,10 @@ static rtx purge_addressof_replacements; ...@@ -2765,9 +2766,10 @@ static rtx purge_addressof_replacements;
/* Helper function for purge_addressof. See if the rtx expression at *LOC /* 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 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) purge_addressof_1 (loc, insn, force, store, ht)
rtx *loc; rtx *loc;
rtx insn; rtx insn;
...@@ -2778,13 +2780,14 @@ purge_addressof_1 (loc, insn, force, store, ht) ...@@ -2778,13 +2780,14 @@ purge_addressof_1 (loc, insn, force, store, ht)
RTX_CODE code; RTX_CODE code;
int i, j; int i, j;
const char *fmt; const char *fmt;
boolean result = true;
/* Re-start here to avoid recursion in common cases. */ /* Re-start here to avoid recursion in common cases. */
restart: restart:
x = *loc; x = *loc;
if (x == 0) if (x == 0)
return; return true;
code = GET_CODE (x); code = GET_CODE (x);
...@@ -2793,9 +2796,9 @@ purge_addressof_1 (loc, insn, force, store, ht) ...@@ -2793,9 +2796,9 @@ purge_addressof_1 (loc, insn, force, store, ht)
memory. */ memory. */
if (code == SET) if (code == SET)
{ {
purge_addressof_1 (&SET_DEST (x), insn, force, 1, ht); result = purge_addressof_1 (&SET_DEST (x), insn, force, 1, ht);
purge_addressof_1 (&SET_SRC (x), insn, force, 0, ht); result &= purge_addressof_1 (&SET_SRC (x), insn, force, 0, ht);
return; return result;
} }
else if (code == ADDRESSOF && GET_CODE (XEXP (x, 0)) == MEM) else if (code == ADDRESSOF && GET_CODE (XEXP (x, 0)) == MEM)
...@@ -2807,7 +2810,7 @@ purge_addressof_1 (loc, insn, force, store, ht) ...@@ -2807,7 +2810,7 @@ purge_addressof_1 (loc, insn, force, store, ht)
if (validate_change (insn, loc, sub, 0) if (validate_change (insn, loc, sub, 0)
|| validate_replace_rtx (x, sub, insn)) || validate_replace_rtx (x, sub, insn))
return; return true;
start_sequence (); start_sequence ();
sub = force_operand (sub, NULL_RTX); sub = force_operand (sub, NULL_RTX);
...@@ -2818,7 +2821,7 @@ purge_addressof_1 (loc, insn, force, store, ht) ...@@ -2818,7 +2821,7 @@ purge_addressof_1 (loc, insn, force, store, ht)
insns = gen_sequence (); insns = gen_sequence ();
end_sequence (); end_sequence ();
emit_insn_before (insns, insn); emit_insn_before (insns, insn);
return; return true;
} }
else if (code == MEM && GET_CODE (XEXP (x, 0)) == ADDRESSOF && ! force) else if (code == MEM && GET_CODE (XEXP (x, 0)) == ADDRESSOF && ! force)
...@@ -2853,7 +2856,7 @@ purge_addressof_1 (loc, insn, force, store, ht) ...@@ -2853,7 +2856,7 @@ purge_addressof_1 (loc, insn, force, store, ht)
if (rtx_equal_p (x, XEXP (tem, 0))) if (rtx_equal_p (x, XEXP (tem, 0)))
{ {
*loc = XEXP (XEXP (tem, 1), 0); *loc = XEXP (XEXP (tem, 1), 0);
return; return true;
} }
/* See comment for purge_addressof_replacements. */ /* See comment for purge_addressof_replacements. */
...@@ -2896,8 +2899,14 @@ purge_addressof_1 (loc, insn, force, store, ht) ...@@ -2896,8 +2899,14 @@ purge_addressof_1 (loc, insn, force, store, ht)
return; return;
} }
/* There should always be such a replacement. */ /* Sometimes we may not be able to find the replacement. For
abort (); 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)); size_x = GET_MODE_BITSIZE (GET_MODE (x));
...@@ -2989,7 +2998,7 @@ purge_addressof_1 (loc, insn, force, store, ht) ...@@ -2989,7 +2998,7 @@ purge_addressof_1 (loc, insn, force, store, ht)
purge_bitfield_addressof_replacements)); purge_bitfield_addressof_replacements));
/* We replaced with a reg -- all done. */ /* We replaced with a reg -- all done. */
return; return true;
} }
} }
...@@ -3007,13 +3016,13 @@ purge_addressof_1 (loc, insn, force, store, ht) ...@@ -3007,13 +3016,13 @@ purge_addressof_1 (loc, insn, force, store, ht)
if (rtx_equal_p (XEXP (x, 0), XEXP (tem, 0))) if (rtx_equal_p (XEXP (x, 0), XEXP (tem, 0)))
{ {
XEXP (XEXP (tem, 1), 0) = sub; XEXP (XEXP (tem, 1), 0) = sub;
return; return true;
} }
purge_addressof_replacements purge_addressof_replacements
= gen_rtx (EXPR_LIST, VOIDmode, XEXP (x, 0), = gen_rtx (EXPR_LIST, VOIDmode, XEXP (x, 0),
gen_rtx_EXPR_LIST (VOIDmode, sub, gen_rtx_EXPR_LIST (VOIDmode, sub,
purge_addressof_replacements)); purge_addressof_replacements));
return; return true;
} }
goto restart; goto restart;
} }
...@@ -3028,9 +3037,9 @@ purge_addressof_1 (loc, insn, force, store, ht) ...@@ -3028,9 +3037,9 @@ purge_addressof_1 (loc, insn, force, store, ht)
} }
else if (code == SET) else if (code == SET)
{ {
purge_addressof_1 (&SET_DEST (x), insn, force, 1, ht); result = purge_addressof_1 (&SET_DEST (x), insn, force, 1, ht);
purge_addressof_1 (&SET_SRC (x), insn, force, 0, ht); result &= purge_addressof_1 (&SET_SRC (x), insn, force, 0, ht);
return; return result;
} }
/* Scan all subexpressions. */ /* Scan all subexpressions. */
...@@ -3038,11 +3047,13 @@ purge_addressof_1 (loc, insn, force, store, ht) ...@@ -3038,11 +3047,13 @@ purge_addressof_1 (loc, insn, force, store, ht)
for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++) for (i = 0; i < GET_RTX_LENGTH (code); i++, fmt++)
{ {
if (*fmt == 'e') 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') else if (*fmt == 'E')
for (j = 0; j < XVECLEN (x, i); j++) 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. */ /* Return a new hash table entry in HT. */
...@@ -3162,6 +3173,16 @@ compute_insns_for_mem (insns, last_insn, 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 /* Eliminate all occurrences of ADDRESSOF from INSNS. Elide any remaining
(MEM (ADDRESSOF)) patterns, and force any needed registers into the (MEM (ADDRESSOF)) patterns, and force any needed registers into the
stack. */ stack. */
...@@ -3190,9 +3211,30 @@ purge_addressof (insns) ...@@ -3190,9 +3211,30 @@ purge_addressof (insns)
if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
|| GET_CODE (insn) == CALL_INSN) || GET_CODE (insn) == CALL_INSN)
{ {
purge_addressof_1 (&PATTERN (insn), insn, if (! purge_addressof_1 (&PATTERN (insn), insn,
asm_noperands (PATTERN (insn)) > 0, 0, &ht); asm_noperands (PATTERN (insn)) > 0, 0, &ht))
purge_addressof_1 (&REG_NOTES (insn), NULL_RTX, 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. */ /* Clean up. */
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment