c/2404: arm-linux-gcc ice
Bernd Schmidt
bernds@redhat.com
Wed Apr 4 06:26:00 GMT 2001
On 27 Mar 2001 bkohlen@intrinsyc.com wrote:
> gcc cross compiler for arm with fairly standard configure
> flags. used in combination with glibc-2.1.3 and binutils-2.10.
> I was compiling xfree86 for arm when error occured.
> >Description:
> When installing xfree86 (on my pc, so that I can package it
> for arm) it compiles shadow.c and I get the following error:
>
> shadow.c: In function `shadowImageGlyphBlt':
> shadow.c:1173: Internal compiler error in `purge_addressof_1', at function.c:3183
> Please submit a full bug report.
> See <URL: http://www.gnu.org/software/gcc/bugs.html > for instructions.
Fixed with the following patch on the 2.95 branch. See also the original
submission
http://gcc.gnu.org/ml/gcc-patches/1999-11/msg00218.html
Bernd
Index: ChangeLog
===================================================================
RCS file: /cvs/gcc/egcs/gcc/ChangeLog,v
retrieving revision 1.3667.4.352
diff -u -p -r1.3667.4.352 ChangeLog
--- ChangeLog 2001/04/03 14:46:04 1.3667.4.352
+++ ChangeLog 2001/04/04 13:04:35
@@ -1,3 +1,14 @@
+2001-04-04 Bernd Schmidt <bernds@redhat.com>
+
+ 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.
+
2001-04-03 Bernd Schmidt <bernds@redhat.com>
2001-03-16 Jakub Jelinek <jakub@redhat.com>
Index: function.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/function.c,v
retrieving revision 1.90.4.6
diff -u -p -r1.90.4.6 function.c
--- function.c 2001/01/25 14:03:15 1.90.4.6
+++ function.c 2001/04/04 13:04:36
@@ -513,8 +513,9 @@ static int *record_insns PROTO((rtx));
static int contains PROTO((rtx, int *));
#endif /* HAVE_prologue || HAVE_epilogue */
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));
@@ -3055,9 +3056,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;
@@ -3068,13 +3070,14 @@ purge_addressof_1 (loc, insn, force, sto
RTX_CODE code;
int i, j;
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);
@@ -3087,7 +3090,7 @@ purge_addressof_1 (loc, insn, force, sto
if (validate_change (insn, loc, sub, 0)
|| validate_replace_rtx (x, sub, insn))
- return;
+ return true;
start_sequence ();
sub = force_operand (sub, NULL_RTX);
@@ -3098,7 +3101,7 @@ purge_addressof_1 (loc, insn, force, sto
insns = gen_sequence ();
end_sequence ();
emit_insn_before (insns, insn);
- return;
+ return true;
}
else if (code == MEM && GET_CODE (XEXP (x, 0)) == ADDRESSOF && ! force)
{
@@ -3117,7 +3120,7 @@ purge_addressof_1 (loc, insn, force, sto
&& (MEM_VOLATILE_P (x) || GET_MODE (x) == BLKmode))
{
put_addressof_into_stack (XEXP (x, 0), ht);
- return;
+ return true;
}
else if (GET_CODE (sub) == REG && GET_MODE (x) != GET_MODE (sub))
{
@@ -3136,7 +3139,7 @@ purge_addressof_1 (loc, insn, force, sto
if (rtx_equal_p (x, XEXP (tem, 0)))
{
*loc = XEXP (XEXP (tem, 1), 0);
- return;
+ return true;
}
/* See comment for purge_addressof_replacements. */
@@ -3176,11 +3179,17 @@ purge_addressof_1 (loc, insn, force, sto
z = gen_lowpart (GET_MODE (x), z);
*loc = z;
- return;
+ return true;
}
- /* 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));
@@ -3266,7 +3275,7 @@ purge_addressof_1 (loc, insn, force, sto
purge_bitfield_addressof_replacements));
/* We replaced with a reg -- all done. */
- return;
+ return true;
}
}
else if (validate_change (insn, loc, sub, 0))
@@ -3283,13 +3292,13 @@ purge_addressof_1 (loc, insn, force, sto
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;
}
@@ -3299,13 +3308,13 @@ purge_addressof_1 (loc, insn, force, sto
else if (code == ADDRESSOF)
{
put_addressof_into_stack (x, ht);
- return;
+ return true;
}
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. */
@@ -3313,11 +3322,13 @@ purge_addressof_1 (loc, insn, force, sto
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. */
@@ -3437,6 +3448,16 @@ compute_insns_for_mem (insns, last_insn,
}
}
+/* 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. */
@@ -3465,9 +3486,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. */
More information about the Gcc-patches
mailing list