This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
make set_noop_p handle post-reload noops
- To: gcc-patches at gcc dot gnu dot org, rth at cygnus dot com, patches at x86-64 dot org
- Subject: make set_noop_p handle post-reload noops
- From: Jan Hubicka <jh at suse dot cz>
- Date: Sun, 15 Jul 2001 22:07:12 +0200
Hi,
this patch moves the dirty hack to cleanup register allocation garbage to
set_noop_p. The goal is to make flow.c's delete_noop_moves eliminate
the jump.c's one.
Hope that this will go later, but today is too busy.
Bootstrapped/regtested i686 togerhet with other today patches.
Honza
Ne čec 15 21:52:39 CEST 2001 Jan Hubicka <jh@suse.cz>
* cse.c (delete_trivially_dead_insns): Update call of set_noop_p;
* flow.c (noop_move_p): Likewise.
* gcse.c (hash_scan_set): Likewise.
* jump.c (delete_noop_moves): Likewise.
* reorg.c (split_insn): Likewise.
* rtlanal.c (set_noop_p): Copy post-reload noop detection code from
delete_noop_moves here.
*** /p1/jumpr2/jumpr/egcs/gcc/cse.c Thu Jul 12 18:03:44 2001
--- cse.c Sun Jul 15 20:20:23 2001
*************** delete_trivially_dead_insns (insns, nreg
*** 7598,7604 ****
live_insn = ! dead_libcall;
else if (GET_CODE (PATTERN (insn)) == SET)
{
! if (set_noop_p (PATTERN (insn)))
;
#ifdef HAVE_cc0
--- 7598,7604 ----
live_insn = ! dead_libcall;
else if (GET_CODE (PATTERN (insn)) == SET)
{
! if (set_noop_p (PATTERN (insn), insn))
;
#ifdef HAVE_cc0
*************** delete_trivially_dead_insns (insns, nreg
*** 7628,7634 ****
if (GET_CODE (elt) == SET)
{
! if (set_noop_p (elt))
;
#ifdef HAVE_cc0
--- 7628,7634 ----
if (GET_CODE (elt) == SET)
{
! if (set_noop_p (elt, insn))
;
#ifdef HAVE_cc0
*** /p1/jumpr2/jumpr/egcs/gcc/flow.c Sat Jul 14 22:05:38 2001
--- flow.c Sun Jul 15 21:05:09 2001
*************** noop_move_p (insn)
*** 4348,4354 ****
if (find_reg_note (insn, REG_EQUAL, NULL_RTX))
return 0;
! if (GET_CODE (pat) == SET && set_noop_p (pat))
return 1;
if (GET_CODE (pat) == PARALLEL)
--- 4373,4379 ----
if (find_reg_note (insn, REG_EQUAL, NULL_RTX))
return 0;
! if (GET_CODE (pat) == SET && set_noop_p (pat, insn))
return 1;
if (GET_CODE (pat) == PARALLEL)
*************** noop_move_p (insn)
*** 4364,4370 ****
|| GET_CODE (tem) == CLOBBER)
continue;
! if (GET_CODE (tem) != SET || ! set_noop_p (tem))
return 0;
}
--- 4389,4395 ----
|| GET_CODE (tem) == CLOBBER)
continue;
! if (GET_CODE (tem) != SET || ! set_noop_p (tem, insn))
return 0;
}
*** /p1/jumpr2/jumpr/egcs/gcc/gcse.c Thu Jul 12 18:03:39 2001
--- gcse.c Sun Jul 15 20:56:41 2001
*************** hash_scan_set (pat, insn, set_p)
*** 2205,2211 ****
/* Is SET_SRC something we want to gcse? */
&& want_to_gcse_p (src)
/* Don't CSE a nop. */
! && ! set_noop_p (pat)
/* Don't GCSE if it has attached REG_EQUIV note.
At this point this only function parameters should have
REG_EQUIV notes and if the argument slot is used somewhere
--- 2205,2211 ----
/* Is SET_SRC something we want to gcse? */
&& want_to_gcse_p (src)
/* Don't CSE a nop. */
! && ! set_noop_p (pat, insn)
/* Don't GCSE if it has attached REG_EQUIV note.
At this point this only function parameters should have
REG_EQUIV notes and if the argument slot is used somewhere
*** /p1/jumpr2/jumpr/egcs/gcc/jump.c Sat Jul 14 20:59:50 2001
--- jump.c Sun Jul 15 21:27:45 2001
*************** delete_noop_moves (f)
*** 807,813 ****
/* Detect and delete no-op move instructions
resulting from not allocating a parameter in a register. */
! if (GET_CODE (body) == SET && set_noop_p (body))
delete_computation (insn);
/* Detect and ignore no-op move instructions
--- 346,352 ----
/* Detect and delete no-op move instructions
resulting from not allocating a parameter in a register. */
! if (GET_CODE (body) == SET && set_noop_p (body, insn))
delete_computation (insn);
/* Detect and ignore no-op move instructions
*** /p1/jumpr2/jumpr/egcs/gcc/rtl.h Sat Jul 14 21:00:04 2001
--- rtl.h Sun Jul 15 21:30:08 2001
*************** extern int insn_dependent_p PARAMS ((rt
*** 1385,1391 ****
extern int reg_set_p PARAMS ((rtx, rtx));
extern rtx single_set_2 PARAMS ((rtx, rtx));
extern int multiple_sets PARAMS ((rtx));
! extern int set_noop_p PARAMS ((rtx));
extern rtx find_last_value PARAMS ((rtx, rtx *, rtx, int));
extern int refers_to_regno_p PARAMS ((unsigned int, unsigned int,
rtx, rtx *));
--- 1385,1391 ----
extern int reg_set_p PARAMS ((rtx, rtx));
extern rtx single_set_2 PARAMS ((rtx, rtx));
extern int multiple_sets PARAMS ((rtx));
! extern int set_noop_p PARAMS ((rtx, rtx));
extern rtx find_last_value PARAMS ((rtx, rtx *, rtx, int));
extern int refers_to_regno_p PARAMS ((unsigned int, unsigned int,
rtx, rtx *));
*** /p1/jumpr2/jumpr/egcs/gcc/recog.c Thu Jul 12 19:08:30 2001
--- recog.c Sun Jul 15 22:14:01 2001
*************** split_insn (insn)
*** 2669,2682 ****
disappear later in final. Splitting such insns would
break the code that handles REG_NO_CONFLICT blocks. */
! else if ((set = single_set (insn)) != NULL && set_noop_p (set))
{
/* Nops get in the way while scheduling, so delete them
now if register allocation has already been done. It
is too risky to try to do this before register
allocation, and there are unlikely to be very many
nops then anyways. */
! if (reload_completed)
{
PUT_CODE (insn, NOTE);
NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
--- 2669,2683 ----
disappear later in final. Splitting such insns would
break the code that handles REG_NO_CONFLICT blocks. */
! else if ((set = single_set (insn)) != NULL && set_noop_p (set, 0))
{
/* Nops get in the way while scheduling, so delete them
now if register allocation has already been done. It
is too risky to try to do this before register
allocation, and there are unlikely to be very many
nops then anyways. */
! if (reload_completed
! && !find_reg_note (insn, REG_UNUSED, NULL_RTX))
{
PUT_CODE (insn, NOTE);
NOTE_LINE_NUMBER (insn) = NOTE_INSN_DELETED;
*** /p1/jumpr2/jumpr/egcs/gcc/rtlanal.c Thu Jul 12 18:03:44 2001
--- rtlanal.c Sun Jul 15 22:14:55 2001
*************** multiple_sets (insn)
*** 983,993 ****
}
/* Return nonzero if the destination of SET equals the source
! and there are no side effects. */
int
! set_noop_p (set)
! rtx set;
{
rtx src = SET_SRC (set);
rtx dst = SET_DEST (set);
--- 983,996 ----
}
/* Return nonzero if the destination of SET equals the source
! and there are no side effects.
!
! Post reload, if INSN is present, function attempts to use information
! provided by reload to kill even the non-obvious dead stores. */
int
! set_noop_p (set, insn)
! rtx set, insn;
{
rtx src = SET_SRC (set);
rtx dst = SET_DEST (set);
*************** set_noop_p (set)
*** 998,1012 ****
if (GET_CODE (dst) == MEM && GET_CODE (src) == MEM)
return rtx_equal_p (dst, src);
! if (GET_CODE (dst) == SIGN_EXTRACT
! || GET_CODE (dst) == ZERO_EXTRACT)
return rtx_equal_p (XEXP (dst, 0), src)
! && ! BYTES_BIG_ENDIAN && XEXP (dst, 2) == const0_rtx;
if (GET_CODE (dst) == STRICT_LOW_PART)
dst = XEXP (dst, 0);
! if (GET_CODE (src) == SUBREG && GET_CODE (dst) == SUBREG)
{
if (SUBREG_BYTE (src) != SUBREG_BYTE (dst))
return 0;
--- 1001,1017 ----
if (GET_CODE (dst) == MEM && GET_CODE (src) == MEM)
return rtx_equal_p (dst, src);
! if (GET_CODE (dst) == SIGN_EXTRACT || GET_CODE (dst) == ZERO_EXTRACT)
return rtx_equal_p (XEXP (dst, 0), src)
! && !BYTES_BIG_ENDIAN && XEXP (dst, 2) == const0_rtx;
if (GET_CODE (dst) == STRICT_LOW_PART)
dst = XEXP (dst, 0);
!
! /* Bypass subregs in case they do have equivalent SUBREG_BYTEs. */
! if (GET_CODE (src) == SUBREG && GET_CODE (dst) == SUBREG
! && SUBREG_BYTE (src) == SUBREG_BYTE (dst))
{
if (SUBREG_BYTE (src) != SUBREG_BYTE (dst))
return 0;
*************** set_noop_p (set)
*** 1014,1021 ****
dst = SUBREG_REG (dst);
}
! return (GET_CODE (src) == REG && GET_CODE (dst) == REG
! && REGNO (src) == REGNO (dst));
}
/* Return the last thing that X was assigned from before *PINSN. If VALID_TO
--- 1019,1104 ----
dst = SUBREG_REG (dst);
}
! /* In case we still didn't eliminated the subregs, try to get around
! the hard regs by simplify_subreg. */
! if (GET_CODE (src) == SUBREG)
! {
! rtx tem = simplify_subreg (GET_MODE (src), SUBREG_REG (src),
! GET_MODE (SUBREG_REG (src)),
! SUBREG_BYTE (src));
! if (tem)
! src = tem;
! }
! if (GET_CODE (dst) == SUBREG)
! {
! rtx tem = simplify_subreg (GET_MODE (dst), SUBREG_REG (dst),
! GET_MODE (SUBREG_REG (dst)),
! SUBREG_BYTE (dst));
! if (tem)
! dst = tem;
! }
!
! if (GET_CODE (src) == REG && GET_CODE (dst) == REG
! && REGNO (src) == REGNO (dst))
! return 1;
!
! /* After reload try even harder to cleanup register allocation loossage. */
! if (reload_completed && insn)
! {
! rtx trial;
! int sreg = true_regnum (src);
! int dreg = true_regnum (dst);
! rtx tem = find_equiv_reg (NULL_RTX, insn, 0,
! sreg, NULL, dreg,
! GET_MODE (src));
! if (tem != 0 && GET_MODE (tem) == GET_MODE (dst))
! {
! /* DREG may have been the target of a REG_DEAD note in
! the insn which makes INSN redundant. If so, reorg
! would still think it is dead. So search for such a
! note and delete it if we find it. */
! if (!find_regno_note (insn, REG_UNUSED, dreg))
! for (trial = prev_nonnote_insn (insn);
! trial && GET_CODE (trial) != CODE_LABEL;
! trial = prev_nonnote_insn (trial))
! if (find_regno_note (trial, REG_DEAD, dreg))
! {
! remove_death (dreg, trial);
! break;
! }
! return 1;
! }
! else if (dreg >= 0 && CONSTANT_P (src)
! && find_equiv_reg (src, insn, 0, dreg,
! NULL, 0, GET_MODE (dst)))
! {
! /* This handles the case where we have two consecutive
! assignments of the same constant to pseudos that didn't
! get a hard reg. Each SET from the constant will be
! converted into a SET of the spill register and an
! output reload will be made following it. This produces
! two loads of the same constant into the same spill
! register. */
!
! rtx in_insn = insn;
!
! /* Look back for a death note for the first reg.
! If there is one, it is no longer accurate. */
! while (in_insn && GET_CODE (in_insn) != CODE_LABEL)
! {
! if ((GET_CODE (in_insn) == INSN
! || GET_CODE (in_insn) == JUMP_INSN)
! && find_regno_note (in_insn, REG_DEAD, dreg))
! {
! remove_death (dreg, in_insn);
! break;
! }
! in_insn = PREV_INSN (in_insn);
! }
! return 1;
! }
! }
! return 0;
}
/* Return the last thing that X was assigned from before *PINSN. If VALID_TO