I've tried removing REG_EQUAL notes altogether unless we
know that the source of the move is function invariant, and got
identical assembler for all the EEMBC tests as without the patch.
Likewise for an entire sh4-elf multilibbed libgcc, libstdc++-v3
and newlib build. I think it is therefore reasonable to assume
that removing the notes doesn't cause any relevant performance
loss. For a 3.4 based compiler, that was just a small ifcvt.c
patch; for 4.x, I also had to reinstate function_invariant_p as
a global function.
I can't do an i686-pc-linux-gnu bootstrap at the moment because
the bootstrap fails building libjava, both with unpatched sources
from 12:00 and 16:00 UTC. I'll do a bootstrap / regression test
of the patch when we are back in bootstrap land.
FWIW, this is the failure:
./../.././gcc/gcjh -classpath '' -bootclasspath .
java/lang/AbstractMethodError
make[2]: *** [java/lang/AbstractMethodError.h] Segmentation fault
make[2]: *** Deleting file `java/lang/AbstractMethodError.h'
make[2]: Leaving directory
`/mnt/scratch/nightly/2005-05-31/i686/i686-pc-linux-gnu/libjava'
AFAICS, jcf-io.c:format_uint is miscompiled, base is not handed as
second parameter to umoddi, it uses the saved values of esi/edi
instead.
2005-05-27 J"orn Rennecke <[EMAIL PROTECTED]>
* rtl.h (function_invariant_p): Re-add declaration.
* reload1.c (function_invariant_p): No longer static.
* ifcvt.c (dead_or_predicable): Remove REG_EQUAL notes that
might have become invalid.
Index: rtl.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/rtl.h,v
retrieving revision 1.550
diff -p -r1.550 rtl.h
*** rtl.h 19 May 2005 10:38:38 -0000 1.550
--- rtl.h 31 May 2005 18:11:39 -0000
*************** extern void dbr_schedule (rtx, FILE *);
*** 2062,2067 ****
--- 2062,2070 ----
extern void dump_local_alloc (FILE *);
extern int local_alloc (void);
+ /* In reload1.c */
+ extern int function_invariant_p (rtx);
+
/* In reg-stack.c */
extern bool reg_to_stack (FILE *);
Index: reload1.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/reload1.c,v
retrieving revision 1.471
diff -p -r1.471 reload1.c
*** reload1.c 26 May 2005 05:44:38 -0000 1.471
--- reload1.c 31 May 2005 18:11:39 -0000
*************** static int reload_reg_free_for_value_p (
*** 405,411 ****
rtx, rtx, int, int);
static int free_for_value_p (int, enum machine_mode, int, enum reload_type,
rtx, rtx, int, int);
- static int function_invariant_p (rtx);
static int reload_reg_reaches_end_p (unsigned int, int, enum reload_type);
static int allocate_reload_reg (struct insn_chain *, int, int);
static int conflicts_with_override (rtx);
--- 405,410 ----
*************** free_for_value_p (int regno, enum machin
*** 4984,4990 ****
pic_offset_table_rtx is not, and we must not spill these things to
memory. */
! static int
function_invariant_p (rtx x)
{
if (CONSTANT_P (x))
--- 4983,4989 ----
pic_offset_table_rtx is not, and we must not spill these things to
memory. */
! int
function_invariant_p (rtx x)
{
if (CONSTANT_P (x))
Index: ifcvt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/ifcvt.c,v
retrieving revision 1.189
diff -p -r1.189 ifcvt.c
*** ifcvt.c 29 May 2005 18:56:42 -0000 1.189
--- ifcvt.c 31 May 2005 18:11:40 -0000
*************** dead_or_predicable (basic_block test_bb,
*** 3430,3441 ****
--- 3430,3460 ----
/* Move the insns out of MERGE_BB to before the branch. */
if (head != NULL)
{
+ rtx insn;
+
if (end == BB_END (merge_bb))
BB_END (merge_bb) = PREV_INSN (head);
if (squeeze_notes (&head, &end))
return TRUE;
+ /* PR 21767: When moving insns above a conditional branch, REG_EQUAL
+ notes might become invalid. */
+ insn = head;
+ do
+ {
+ rtx note, set;
+
+ if (! INSN_P (insn))
+ continue;
+ note = find_reg_note (insn, REG_EQUAL, NULL_RTX);
+ if (! note)
+ continue;
+ set = single_set (insn);
+ if (!set || !function_invariant_p (SET_SRC (set)))
+ remove_note (insn, note);
+ } while (insn != end && (insn = NEXT_INSN (insn)));
+
reorder_insns (head, end, PREV_INSN (earliest));
}