diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 425e6ce2c78..d99ef4affcb 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +Wed Apr 4 00:45:38 EDT 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. + 2001-04-04 Alan Modra * dwarf2out.c (dwarf2out_frame_debug_expr): Support adjusting diff --git a/gcc/cse.c b/gcc/cse.c index 2b487510eae..6913aef32b5 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -7612,14 +7612,7 @@ delete_trivially_dead_insns (insns, nreg) 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)))) + if (set_noop_p (PATTERN (insn))) ; #ifdef HAVE_cc0 @@ -7649,9 +7642,7 @@ delete_trivially_dead_insns (insns, nreg) 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))) + if (set_noop_p (elt)) ; #ifdef HAVE_cc0 diff --git a/gcc/flow.c b/gcc/flow.c index 388bd2a9d8a..607ecb6a115 100644 --- a/gcc/flow.c +++ b/gcc/flow.c @@ -386,7 +386,6 @@ static void tidy_fallthru_edges PARAMS ((void)); 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 *)); @@ -3077,27 +3076,6 @@ free_basic_block_vars (keep_head_end_p) } } -/* 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_BYTE (src) != SUBREG_BYTE (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 value to itself. */ diff --git a/gcc/gcse.c b/gcc/gcse.c index cac80f9d4b9..9eda522e859 100644 --- a/gcc/gcse.c +++ b/gcc/gcse.c @@ -1964,7 +1964,7 @@ hash_scan_set (pat, insn, set_p) /* Is SET_SRC something we want to gcse? */ && want_to_gcse_p (src) /* Don't CSE a nop. */ - && src != dest) + && ! set_noop_p (pat)) { /* An expression is not anticipatable if its operands are modified before this insn or if this is not the only SET in diff --git a/gcc/jump.c b/gcc/jump.c index 5c5807394dc..6bd6edd9c48 100644 --- a/gcc/jump.c +++ b/gcc/jump.c @@ -956,15 +956,7 @@ delete_noop_moves (f) /* 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)))) + if (GET_CODE (body) == SET && set_noop_p (body)) delete_computation (insn); /* Detect and ignore no-op move instructions @@ -1073,16 +1065,6 @@ delete_noop_moves (f) 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; } diff --git a/gcc/recog.c b/gcc/recog.c index e278f985529..bc7c712de24 100644 --- a/gcc/recog.c +++ b/gcc/recog.c @@ -2882,7 +2882,7 @@ split_all_insns (upd_life) 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))) + && set_noop_p (set)) { /* Nops get in the way while scheduling, so delete them now if register allocation has already been done. It diff --git a/gcc/rtl.h b/gcc/rtl.h index 667a304aec3..02f37b75018 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -1401,6 +1401,7 @@ extern int insn_dependent_p PARAMS ((rtx, rtx)); 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 *)); diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 36c3c9ff42f..3dd7c138b0d 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -980,6 +980,42 @@ multiple_sets (insn) 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 (src) || side_effects_p (dst)) + 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_BYTE (src) != SUBREG_BYTE (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