From: Nick Clifton Date: Fri, 5 Nov 1999 10:11:40 +0000 (+0000) Subject: If purge_addressof_1 fails to remove addressofs in notes, remove the notes X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=8c36698e5207d286292375e844faf9c95c35ce42;p=gcc.git If purge_addressof_1 fails to remove addressofs in notes, remove the notes instead. From-SVN: r30414 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 59145c0cbdd..8be07eae1d4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +Fri Nov 5 10:07:25 1999 Nick Clifton + + * 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 * genoutput.c (null_operand =): Initialize all fields. diff --git a/gcc/function.c b/gcc/function.c index 07dd0b103d0..c9b4e20de86 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -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 (®_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 (®_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. */