Fix for deleted auto_inc instructions
Joern Rennecke
amylaar@cygnus.co.uk
Sun Nov 15 23:13:00 GMT 1998
I have gotten some failures for the SH port as some sets were deleted where
the register being set was dead, but an address used POST_INC addressing.
The problem is that flow was written with the precondition in mind that
no auto_inc expressions exist before flow is finished. Now that we
run flow another time after reload, this is no longer true.
I have appended a patch to fix this bug by making insn_dead_p return
zero if a REG_INC note is present.
If someone is more adventerous, (s)he can try to make flow replace insns
that are only needed for their addressing side effects with explicit adds.
However, I think in the short term we should first get the code working
again.
Mon Nov 16 07:04:50 1998 J"orn Rennecke <amylaar@cygnus.co.uk>
* flow.c (insn_dead_p): New argument NOTES. Changed all callers.
Index: flow.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/flow.c,v
retrieving revision 1.146
diff -p -r1.146 flow.c
*** flow.c 1998/10/28 07:17:12 1.146
--- flow.c 1998/11/16 07:03:28
*************** static int set_noop_p PROTO((rtx));
*** 266,272 ****
static int noop_move_p PROTO((rtx));
static void record_volatile_insns PROTO((rtx));
static void mark_regs_live_at_end PROTO((regset));
! static int insn_dead_p PROTO((rtx, regset, int));
static int libcall_dead_p PROTO((rtx, regset, rtx, rtx));
static void mark_set_regs PROTO((regset, regset, rtx,
rtx, regset));
--- 266,272 ----
static int noop_move_p PROTO((rtx));
static void record_volatile_insns PROTO((rtx));
static void mark_regs_live_at_end PROTO((regset));
! static int insn_dead_p PROTO((rtx, regset, int, rtx));
static int libcall_dead_p PROTO((rtx, regset, rtx, rtx));
static void mark_set_regs PROTO((regset, regset, rtx,
rtx, regset));
*************** propagate_block (old, first, last, final
*** 1750,1756 ****
register int i;
rtx note = find_reg_note (insn, REG_RETVAL, NULL_RTX);
int insn_is_dead
! = (insn_dead_p (PATTERN (insn), old, 0)
/* Don't delete something that refers to volatile storage! */
&& ! INSN_VOLATILE (insn));
int libcall_is_dead
--- 1750,1756 ----
register int i;
rtx note = find_reg_note (insn, REG_RETVAL, NULL_RTX);
int insn_is_dead
! = (insn_dead_p (PATTERN (insn), old, 0, REG_NOTES (insn))
/* Don't delete something that refers to volatile storage! */
&& ! INSN_VOLATILE (insn));
int libcall_is_dead
*************** propagate_block (old, first, last, final
*** 1939,1954 ****
(SET expressions whose destinations are registers dead after the insn).
NEEDED is the regset that says which regs are alive after the insn.
! Unless CALL_OK is non-zero, an insn is needed if it contains a CALL. */
static int
! insn_dead_p (x, needed, call_ok)
rtx x;
regset needed;
int call_ok;
{
enum rtx_code code = GET_CODE (x);
/* If setting something that's a reg or part of one,
see if that register's altered value will be live. */
--- 1939,1978 ----
(SET expressions whose destinations are registers dead after the insn).
NEEDED is the regset that says which regs are alive after the insn.
! Unless CALL_OK is non-zero, an insn is needed if it contains a CALL.
+ If X is the entire body of an insn, NOTES contains the reg notes
+ pertaining to the insn. */
+
static int
! insn_dead_p (x, needed, call_ok, notes)
rtx x;
regset needed;
int call_ok;
+ rtx notes ATTRIBUTE_UNUSED;
{
enum rtx_code code = GET_CODE (x);
+ #ifdef AUTO_INC_DEC
+ /* If flow is invoked after reload, we must take existing AUTO_INC
+ expresions into account. */
+ if (reload_completed)
+ {
+ for ( ; notes; notes = XEXP (notes, 1))
+ {
+ if (REG_NOTE_KIND (notes) == REG_INC)
+ {
+ int regno = REGNO (XEXP (notes, 0));
+
+ /* Don't delete insns to set global regs. */
+ if ((regno < FIRST_PSEUDO_REGISTER && global_regs[regno])
+ || REGNO_REG_SET_P (needed, regno))
+ return 0;
+ }
+ }
+ }
+ #endif
+
/* If setting something that's a reg or part of one,
see if that register's altered value will be live. */
*************** insn_dead_p (x, needed, call_ok)
*** 2019,2025 ****
for (i--; i >= 0; i--)
if (GET_CODE (XVECEXP (x, 0, i)) != CLOBBER
&& GET_CODE (XVECEXP (x, 0, i)) != USE
! && ! insn_dead_p (XVECEXP (x, 0, i), needed, call_ok))
return 0;
return 1;
--- 2043,2049 ----
for (i--; i >= 0; i--)
if (GET_CODE (XVECEXP (x, 0, i)) != CLOBBER
&& GET_CODE (XVECEXP (x, 0, i)) != USE
! && ! insn_dead_p (XVECEXP (x, 0, i), needed, call_ok, NULL_RTX))
return 0;
return 1;
*************** libcall_dead_p (x, needed, note, insn)
*** 2066,2071 ****
--- 2090,2096 ----
if (GET_CODE (r) == REG)
{
rtx call = XEXP (note, 0);
+ rtx call_pat;
register int i;
/* Find the call insn. */
*************** libcall_dead_p (x, needed, note, insn)
*** 2079,2090 ****
/* See if the hard reg holding the value is dead.
If this is a PARALLEL, find the call within it. */
! call = PATTERN (call);
! if (GET_CODE (call) == PARALLEL)
{
! for (i = XVECLEN (call, 0) - 1; i >= 0; i--)
! if (GET_CODE (XVECEXP (call, 0, i)) == SET
! && GET_CODE (SET_SRC (XVECEXP (call, 0, i))) == CALL)
break;
/* This may be a library call that is returning a value
--- 2104,2115 ----
/* See if the hard reg holding the value is dead.
If this is a PARALLEL, find the call within it. */
! call_pat = PATTERN (call);
! if (GET_CODE (call_pat) == PARALLEL)
{
! for (i = XVECLEN (call_pat, 0) - 1; i >= 0; i--)
! if (GET_CODE (XVECEXP (call_pat, 0, i)) == SET
! && GET_CODE (SET_SRC (XVECEXP (call_pat, 0, i))) == CALL)
break;
/* This may be a library call that is returning a value
*************** libcall_dead_p (x, needed, note, insn)
*** 2093,2102 ****
if (i < 0)
return 0;
! call = XVECEXP (call, 0, i);
}
! return insn_dead_p (call, needed, 1);
}
}
return 1;
--- 2118,2127 ----
if (i < 0)
return 0;
! call_pat = XVECEXP (call_pat, 0, i);
}
! return insn_dead_p (call_pat, needed, 1, REG_NOTES (call));
}
}
return 1;
More information about the Gcc-patches
mailing list