This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Patch to cleanup noop move handling (version 2)
- To: gcc-patches at gcc dot gnu dot org
- Subject: Patch to cleanup noop move handling (version 2)
- From: John Wehle <john at feith dot com>
- Date: Sat, 10 Mar 2001 09:29:03 -0500 (EST)
[ This version cleans up a few more places. ]
This eliminates some code duplication. This patch passes make
bootstrap and check on i386-unknown-freebsd4.2. It also passes
make check for powerpc-eabisim.
ChangeLog:
Sat Mar 10 00:43:36 EST 2001 John Wehle (john@feith.com)
* rtl.h (set_noop_p): Declare.
* flow.c (set_noop_p): Move from here ...
* rtlanal.c (set_noop_p): ... to here and enhance.
* cse.c (delete_trivially_dead_insns): Use it.
* gcse.c (hash_scan_set): Likewise.
* jump.c (delete_noop_moves): Likewise.
* recog.c (split_all_insns): Likewise.
Enjoy!
-- John Wehle
------------------8<------------------------8<------------------------
*** gcc/rtl.h.ORIGINAL Sun Mar 4 14:51:02 2001
--- gcc/rtl.h Tue Mar 6 02:45:22 2001
*************** extern int insn_dependent_p PARAMS ((rt
*** 1395,1400 ****
--- 1395,1401 ----
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 *));
*** gcc/flow.c.ORIGINAL Thu Mar 1 23:57:32 2001
--- gcc/flow.c Tue Mar 6 02:45:30 2001
*************** static void tidy_fallthru_edges PARAMS
*** 387,393 ****
static int verify_wide_reg_1 PARAMS ((rtx *, void *));
static void verify_wide_reg PARAMS ((int, rtx, rtx));
static void verify_local_live_at_start PARAMS ((regset, basic_block));
- static int set_noop_p PARAMS ((rtx));
static int noop_move_p PARAMS ((rtx));
static void delete_noop_moves PARAMS ((rtx));
static void notice_stack_pointer_modification_1 PARAMS ((rtx, rtx, void *));
--- 387,392 ----
*************** free_basic_block_vars (keep_head_end_p)
*** 3300,3326 ****
EXIT_BLOCK_PTR->aux = NULL;
EXIT_BLOCK_PTR->global_live_at_start = NULL;
}
- }
-
- /* Return nonzero if the destination of SET equals the source. */
-
- static int
- set_noop_p (set)
- rtx set;
- {
- rtx src = SET_SRC (set);
- rtx dst = SET_DEST (set);
-
- if (GET_CODE (src) == SUBREG && GET_CODE (dst) == SUBREG)
- {
- if (SUBREG_WORD (src) != SUBREG_WORD (dst))
- return 0;
- src = SUBREG_REG (src);
- dst = SUBREG_REG (dst);
- }
-
- return (GET_CODE (src) == REG && GET_CODE (dst) == REG
- && REGNO (src) == REGNO (dst));
}
/* Return nonzero if an insn consists only of SETs, each of which only sets a
--- 3299,3304 ----
*** gcc/rtlanal.c.ORIGINAL Thu Mar 1 23:57:40 2001
--- gcc/rtlanal.c Tue Mar 6 03:24:00 2001
*************** multiple_sets (insn)
*** 964,969 ****
--- 964,1005 ----
return 0;
}
+ /* 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);
+
+ if (side_effects_p (set))
+ return 0;
+
+ 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_WORD (src) != SUBREG_WORD (dst))
+ return 0;
+ src = SUBREG_REG (src);
+ 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
is not NULL_RTX then verify that the object is not modified up to VALID_TO.
If the object was modified, if we hit a partial assignment to X, or hit a
*** gcc/cse.c.ORIGINAL Thu Mar 1 23:57:27 2001
--- gcc/cse.c Tue Mar 6 02:42:22 2001
*************** delete_trivially_dead_insns (insns, nreg
*** 7608,7621 ****
live_insn = ! dead_libcall;
else if (GET_CODE (PATTERN (insn)) == SET)
{
! if ((GET_CODE (SET_DEST (PATTERN (insn))) == REG
! || GET_CODE (SET_DEST (PATTERN (insn))) == SUBREG)
! && rtx_equal_p (SET_DEST (PATTERN (insn)),
! SET_SRC (PATTERN (insn))))
! ;
! else if (GET_CODE (SET_DEST (PATTERN (insn))) == STRICT_LOW_PART
! && rtx_equal_p (XEXP (SET_DEST (PATTERN (insn)), 0),
! SET_SRC (PATTERN (insn))))
;
#ifdef HAVE_cc0
--- 7608,7614 ----
live_insn = ! dead_libcall;
else if (GET_CODE (PATTERN (insn)) == SET)
{
! if (set_noop_p (PATTERN (insn)))
;
#ifdef HAVE_cc0
*************** delete_trivially_dead_insns (insns, nreg
*** 7645,7653 ****
if (GET_CODE (elt) == SET)
{
! if ((GET_CODE (SET_DEST (elt)) == REG
! || GET_CODE (SET_DEST (elt)) == SUBREG)
! && rtx_equal_p (SET_DEST (elt), SET_SRC (elt)))
;
#ifdef HAVE_cc0
--- 7638,7644 ----
if (GET_CODE (elt) == SET)
{
! if (set_noop_p (elt))
;
#ifdef HAVE_cc0
*** gcc/gcse.c.ORIGINAL Thu Mar 1 23:57:34 2001
--- gcc/gcse.c Sat Mar 10 00:34:36 2001
*************** hash_scan_set (pat, insn, set_p)
*** 1964,1970 ****
/* Is SET_SRC something we want to gcse? */
&& want_to_gcse_p (src)
/* Don't CSE a nop. */
! && src != dest)
{
/* An expression is not anticipatable if its operands are
modified before this insn. */
--- 1964,1970 ----
/* Is SET_SRC something we want to gcse? */
&& want_to_gcse_p (src)
/* Don't CSE a nop. */
! && ! set_noop_p (pat))
{
/* An expression is not anticipatable if its operands are
modified before this insn. */
*** gcc/jump.c.ORIGINAL Tue Mar 6 03:26:15 2001
--- gcc/jump.c Tue Mar 6 03:23:24 2001
*************** delete_noop_moves (f)
*** 968,982 ****
/* Detect and delete no-op move instructions
resulting from not allocating a parameter in a register. */
! if (GET_CODE (body) == SET
! && (SET_DEST (body) == SET_SRC (body)
! || (GET_CODE (SET_DEST (body)) == MEM
! && GET_CODE (SET_SRC (body)) == MEM
! && rtx_equal_p (SET_SRC (body), SET_DEST (body))))
! && ! (GET_CODE (SET_DEST (body)) == MEM
! && MEM_VOLATILE_P (SET_DEST (body)))
! && ! (GET_CODE (SET_SRC (body)) == MEM
! && MEM_VOLATILE_P (SET_SRC (body))))
delete_computation (insn);
/* Detect and ignore no-op move instructions
--- 968,974 ----
/* 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
*************** delete_noop_moves (f)
*** 1085,1100 ****
if (i < 0)
delete_insn (insn);
}
- /* Also delete insns to store bit fields if they are no-ops. */
- /* Not worth the hair to detect this in the big-endian case. */
- else if (! BYTES_BIG_ENDIAN
- && GET_CODE (body) == SET
- && GET_CODE (SET_DEST (body)) == ZERO_EXTRACT
- && XEXP (SET_DEST (body), 2) == const0_rtx
- && XEXP (SET_DEST (body), 0) == SET_SRC (body)
- && ! (GET_CODE (SET_SRC (body)) == MEM
- && MEM_VOLATILE_P (SET_SRC (body))))
- delete_insn (insn);
}
insn = next;
}
--- 1077,1082 ----
*** gcc/recog.c.ORIGINAL Thu Mar 1 23:57:40 2001
--- gcc/recog.c Sat Mar 10 00:23:28 2001
*************** split_all_insns (upd_life)
*** 2813,2819 ****
break the code that handles REG_NO_CONFLICT blocks. */
else if ((set = single_set (insn)) != NULL
! && rtx_equal_p (SET_SRC (set), SET_DEST (set)))
{
/* Nops get in the way while scheduling, so delete them
now if register allocation has already been done. It
--- 2813,2819 ----
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
-------------------------------------------------------------------------
| Feith Systems | Voice: 1-215-646-8000 | Email: john@feith.com |
| John Wehle | Fax: 1-215-540-5495 | |
-------------------------------------------------------------------------