This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Repost: RFA: fix PR rtl-optimization/18992
- From: Joern RENNECKE <joern dot rennecke at st dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Mon, 18 Jul 2005 14:38:21 +0100
- Subject: Repost: RFA: fix PR rtl-optimization/18992
This patch previously posted,
http://gcc.gnu.org/ml/gcc-patches/2004-05/msg01037.html ,
no longer applies automatically because the context has changed
due to the introduction of all the foo_P macros.
I have appended the updated patch. Sucessfully bootstrapped/build
and regression tested on i686-pc-linux-gnu native and i686-pc-linux-gnu
X sh-elf
in the sh-elf-4_1-branch.
2004-05-17 J"orn Rennecke <joern.rennecke@superh.com>
PR rtl-optimization/18992
Back out this patch:
2003-10-08 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
PR optimization/12142
* cse.c (count_reg_usage): In a SET with a REG SET_DEST, count the
uses of the register in the SET_SRC. Remove unnecessary argument.
Replace it with this:
* cse.c (count_reg_usage): In INSN, JUMP_INSN and CALL_INSN cases,
if flag_non_call_exceptions is set and the insn may trap, pass
pc_rtx as dest for recursion.
In SET_SRC part of SET case, if dest is already set, pass it down
unchanged.
Index: cse.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cse.c,v
retrieving revision 1.351.2.1
diff -p -r1.351.2.1 cse.c
*** cse.c 6 Jul 2005 21:34:18 -0000 1.351.2.1
--- cse.c 18 Jul 2005 13:26:25 -0000
*************** static rtx cse_process_notes (rtx, rtx);
*** 618,624 ****
static void invalidate_skipped_set (rtx, rtx, void *);
static void invalidate_skipped_block (rtx);
static rtx cse_basic_block (rtx, rtx, struct branch_path *);
! static void count_reg_usage (rtx, int *, int);
static int check_for_label_ref (rtx *, void *);
extern void dump_class (struct table_elt*);
static void get_cse_reg_info_1 (unsigned int regno);
--- 618,624 ----
static void invalidate_skipped_set (rtx, rtx, void *);
static void invalidate_skipped_block (rtx);
static rtx cse_basic_block (rtx, rtx, struct branch_path *);
! static void count_reg_usage (rtx, int *, rtx, int);
static int check_for_label_ref (rtx *, void *);
extern void dump_class (struct table_elt*);
static void get_cse_reg_info_1 (unsigned int regno);
*************** check_for_label_ref (rtx *rtl, void *dat
*** 7079,7088 ****
/* Count the number of times registers are used (not set) in X.
COUNTS is an array in which we accumulate the count, INCR is how much
! we count each register usage. */
static void
! count_reg_usage (rtx x, int *counts, int incr)
{
enum rtx_code code;
rtx note;
--- 7079,7094 ----
/* Count the number of times registers are used (not set) in X.
COUNTS is an array in which we accumulate the count, INCR is how much
! we count each register usage.
!
! Don't count a usage of DEST, which is the SET_DEST of a SET which
! contains X in its SET_SRC. This is because such a SET does not
! modify the liveness of DEST.
! DEST is set to pc_rtx for a trapping insn, which means that we must count
! uses of a SET_DEST regardless because the insn can't be deleted here. */
static void
! count_reg_usage (rtx x, int *counts, rtx dest, int incr)
{
enum rtx_code code;
rtx note;
*************** count_reg_usage (rtx x, int *counts, int
*** 7095,7101 ****
switch (code = GET_CODE (x))
{
case REG:
! counts[REGNO (x)] += incr;
return;
case PC:
--- 7101,7108 ----
switch (code = GET_CODE (x))
{
case REG:
! if (x != dest)
! counts[REGNO (x)] += incr;
return;
case PC:
*************** count_reg_usage (rtx x, int *counts, int
*** 7112,7134 ****
/* If we are clobbering a MEM, mark any registers inside the address
as being used. */
if (MEM_P (XEXP (x, 0)))
! count_reg_usage (XEXP (XEXP (x, 0), 0), counts, incr);
return;
case SET:
/* Unless we are setting a REG, count everything in SET_DEST. */
if (!REG_P (SET_DEST (x)))
! count_reg_usage (SET_DEST (x), counts, incr);
! count_reg_usage (SET_SRC (x), counts, incr);
return;
case CALL_INSN:
- count_reg_usage (CALL_INSN_FUNCTION_USAGE (x), counts, incr);
- /* Fall through. */
-
case INSN:
case JUMP_INSN:
! count_reg_usage (PATTERN (x), counts, incr);
/* Things used in a REG_EQUAL note aren't dead since loop may try to
use them. */
--- 7119,7146 ----
/* If we are clobbering a MEM, mark any registers inside the address
as being used. */
if (MEM_P (XEXP (x, 0)))
! count_reg_usage (XEXP (XEXP (x, 0), 0), counts, NULL_RTX, incr);
return;
case SET:
/* Unless we are setting a REG, count everything in SET_DEST. */
if (!REG_P (SET_DEST (x)))
! count_reg_usage (SET_DEST (x), counts, NULL_RTX, incr);
! count_reg_usage (SET_SRC (x), counts,
! dest ? dest : SET_DEST (x),
! incr);
return;
case CALL_INSN:
case INSN:
case JUMP_INSN:
! /* We expect dest to be NULL_RTX here. If the insn may trap, mark
! this fact by setting DEST to pc_rtx. */
! if (flag_non_call_exceptions && may_trap_p (PATTERN (x)))
! dest = pc_rtx;
! if (code == CALL_INSN)
! count_reg_usage (CALL_INSN_FUNCTION_USAGE (x), counts, dest, incr);
! count_reg_usage (PATTERN (x), counts, dest, incr);
/* Things used in a REG_EQUAL note aren't dead since loop may try to
use them. */
*************** count_reg_usage (rtx x, int *counts, int
*** 7143,7154 ****
Process all the arguments. */
do
{
! count_reg_usage (XEXP (eqv, 0), counts, incr);
eqv = XEXP (eqv, 1);
}
while (eqv && GET_CODE (eqv) == EXPR_LIST);
else
! count_reg_usage (eqv, counts, incr);
}
return;
--- 7155,7166 ----
Process all the arguments. */
do
{
! count_reg_usage (XEXP (eqv, 0), counts, dest, incr);
eqv = XEXP (eqv, 1);
}
while (eqv && GET_CODE (eqv) == EXPR_LIST);
else
! count_reg_usage (eqv, counts, dest, incr);
}
return;
*************** count_reg_usage (rtx x, int *counts, int
*** 7158,7172 ****
/* FUNCTION_USAGE expression lists may include (CLOBBER (mem /u)),
involving registers in the address. */
|| GET_CODE (XEXP (x, 0)) == CLOBBER)
! count_reg_usage (XEXP (x, 0), counts, incr);
! count_reg_usage (XEXP (x, 1), counts, incr);
return;
case ASM_OPERANDS:
/* Iterate over just the inputs, not the constraints as well. */
for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
! count_reg_usage (ASM_OPERANDS_INPUT (x, i), counts, incr);
return;
case INSN_LIST:
--- 7170,7188 ----
/* FUNCTION_USAGE expression lists may include (CLOBBER (mem /u)),
involving registers in the address. */
|| GET_CODE (XEXP (x, 0)) == CLOBBER)
! count_reg_usage (XEXP (x, 0), counts, NULL_RTX, incr);
! count_reg_usage (XEXP (x, 1), counts, NULL_RTX, incr);
return;
case ASM_OPERANDS:
+ /* If the asm is volatile, then this insn cannot be deleted,
+ and so the inputs *must* be live. */
+ if (MEM_VOLATILE_P (x))
+ dest = NULL_RTX;
/* Iterate over just the inputs, not the constraints as well. */
for (i = ASM_OPERANDS_INPUT_LENGTH (x) - 1; i >= 0; i--)
! count_reg_usage (ASM_OPERANDS_INPUT (x, i), counts, dest, incr);
return;
case INSN_LIST:
*************** count_reg_usage (rtx x, int *counts, int
*** 7180,7189 ****
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{
if (fmt[i] == 'e')
! count_reg_usage (XEXP (x, i), counts, incr);
else if (fmt[i] == 'E')
for (j = XVECLEN (x, i) - 1; j >= 0; j--)
! count_reg_usage (XVECEXP (x, i, j), counts, incr);
}
}
--- 7196,7205 ----
for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
{
if (fmt[i] == 'e')
! count_reg_usage (XEXP (x, i), counts, dest, incr);
else if (fmt[i] == 'E')
for (j = XVECLEN (x, i) - 1; j >= 0; j--)
! count_reg_usage (XVECEXP (x, i, j), counts, dest, incr);
}
}
*************** dead_libcall_p (rtx insn, int *counts)
*** 7270,7280 ****
new = XEXP (note, 0);
/* While changing insn, we must update the counts accordingly. */
! count_reg_usage (insn, counts, -1);
if (validate_change (insn, &SET_SRC (set), new, 0))
{
! count_reg_usage (insn, counts, 1);
remove_note (insn, find_reg_note (insn, REG_RETVAL, NULL_RTX));
remove_note (insn, note);
return true;
--- 7286,7296 ----
new = XEXP (note, 0);
/* While changing insn, we must update the counts accordingly. */
! count_reg_usage (insn, counts, NULL_RTX, -1);
if (validate_change (insn, &SET_SRC (set), new, 0))
{
! count_reg_usage (insn, counts, NULL_RTX, 1);
remove_note (insn, find_reg_note (insn, REG_RETVAL, NULL_RTX));
remove_note (insn, note);
return true;
*************** dead_libcall_p (rtx insn, int *counts)
*** 7285,7298 ****
new = force_const_mem (GET_MODE (SET_DEST (set)), new);
if (new && validate_change (insn, &SET_SRC (set), new, 0))
{
! count_reg_usage (insn, counts, 1);
remove_note (insn, find_reg_note (insn, REG_RETVAL, NULL_RTX));
remove_note (insn, note);
return true;
}
}
! count_reg_usage (insn, counts, 1);
return false;
}
--- 7301,7314 ----
new = force_const_mem (GET_MODE (SET_DEST (set)), new);
if (new && validate_change (insn, &SET_SRC (set), new, 0))
{
! count_reg_usage (insn, counts, NULL_RTX, 1);
remove_note (insn, find_reg_note (insn, REG_RETVAL, NULL_RTX));
remove_note (insn, note);
return true;
}
}
! count_reg_usage (insn, counts, NULL_RTX, 1);
return false;
}
*************** delete_trivially_dead_insns (rtx insns,
*** 7317,7323 ****
counts = xcalloc (nreg, sizeof (int));
for (insn = insns; insn; insn = NEXT_INSN (insn))
if (INSN_P (insn))
! count_reg_usage (insn, counts, 1);
/* Go from the last insn to the first and delete insns that only set unused
registers or copy a register to itself. As we delete an insn, remove
--- 7333,7339 ----
counts = xcalloc (nreg, sizeof (int));
for (insn = insns; insn; insn = NEXT_INSN (insn))
if (INSN_P (insn))
! count_reg_usage (insn, counts, NULL_RTX, 1);
/* Go from the last insn to the first and delete insns that only set unused
registers or copy a register to itself. As we delete an insn, remove
*************** delete_trivially_dead_insns (rtx insns,
*** 7355,7361 ****
if (! live_insn)
{
! count_reg_usage (insn, counts, -1);
delete_insn_and_edges (insn);
ndead++;
}
--- 7371,7377 ----
if (! live_insn)
{
! count_reg_usage (insn, counts, NULL_RTX, -1);
delete_insn_and_edges (insn);
ndead++;
}