This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] CSE path fixes for CC0-targets
- From: Steven Bosscher <stevenb dot gcc at gmail dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Sat, 16 Dec 2006 13:25:06 +0100
- Subject: [PATCH] CSE path fixes for CC0-targets
- References: <200612161309.40643.steven@gcc.gnu.org>
Hello,
This patch contains the same CC0-bits that I posted previously here:
http://gcc.gnu.org/ml/gcc-patches/2006-12/msg00800.html.
I have built a cross to AVR with this patch, and Richard Sandiford
reported that it makes things work again on m68k.
OK for trunk?
Gr.
Steven
* cse.c (this_insn_cc0, this_insn_cc0_mode): New global
variables, moved out from cse_insn.
(prev_insn): Remove this global variable).
(new_basic_block): Don't set it.
(cse_insn): Idem. Also, move code to delete unused CC0-setter
insns and code to set prev_insn_cc0 and prev_insn_cc0_mode
from here...
(cse_extended_basic_block): ...to here. Do not clear
prev_insn_cc0 until after recording equivalences from jumps.
Index: cse.c
===================================================================
*** cse.c (revision 119961)
--- cse.c (working copy)
*************** struct change_cc_mode_args
*** 269,285 ****
table since its use is guaranteed to be the insn immediately following
its definition and any other insn is presumed to invalidate it.
! Instead, we store below the value last assigned to CC0. If it should
! happen to be a constant, it is stored in preference to the actual
! assigned value. In case it is a constant, we store the mode in which
! the constant should be interpreted. */
! static rtx prev_insn_cc0;
! static enum machine_mode prev_insn_cc0_mode;
!
! /* Previous actual insn. 0 if at first insn of basic block. */
!
! static rtx prev_insn;
#endif
/* Insn being scanned. */
--- 269,281 ----
table since its use is guaranteed to be the insn immediately following
its definition and any other insn is presumed to invalidate it.
! Instead, we store below the current and last value assigned to CC0.
! If it should happen to be a constant, it is stored in preference
! to the actual assigned value. In case it is a constant, we store
! the mode in which the constant should be interpreted. */
! static rtx this_insn_cc0, prev_insn_cc0;
! static enum machine_mode this_insn_cc0_mode, prev_insn_cc0_mode;
#endif
/* Insn being scanned. */
*************** new_basic_block (void)
*** 900,906 ****
}
#ifdef HAVE_cc0
- prev_insn = 0;
prev_insn_cc0 = 0;
#endif
}
--- 896,901 ----
*************** cse_insn (rtx insn, rtx libcall_insn)
*** 4022,4029 ****
#ifdef HAVE_cc0
/* Records what this insn does to set CC0. */
! rtx this_insn_cc0 = 0;
! enum machine_mode this_insn_cc0_mode = VOIDmode;
#endif
rtx src_eqv = 0;
--- 4017,4024 ----
#ifdef HAVE_cc0
/* Records what this insn does to set CC0. */
! this_insn_cc0 = 0;
! this_insn_cc0_mode = VOIDmode;
#endif
rtx src_eqv = 0;
*************** cse_insn (rtx insn, rtx libcall_insn)
*** 5644,5663 ****
}
done:;
- #ifdef HAVE_cc0
- /* If the previous insn set CC0 and this insn no longer references CC0,
- delete the previous insn. Here we use the fact that nothing expects CC0
- to be valid over an insn, which is true until the final pass. */
- if (prev_insn && NONJUMP_INSN_P (prev_insn)
- && (tem = single_set (prev_insn)) != 0
- && SET_DEST (tem) == cc0_rtx
- && ! reg_mentioned_p (cc0_rtx, x))
- delete_insn_and_edges (prev_insn);
-
- prev_insn_cc0 = this_insn_cc0;
- prev_insn_cc0_mode = this_insn_cc0_mode;
- prev_insn = insn;
- #endif
}
/* Remove from the hash table all expressions that reference memory. */
--- 5639,5644 ----
*************** cse_extended_basic_block (struct cse_bas
*** 6096,6114 ****
&& for_each_rtx (&PATTERN (insn), check_for_label_ref,
(void *) insn))
recorded_label_ref = 1;
}
}
/* Make sure that libcalls don't span multiple basic blocks. */
gcc_assert (libcall_insn == NULL_RTX);
- #ifdef HAVE_cc0
- /* Clear the CC0-tracking related insns, they can't provide
- useful information across basic block boundaries. */
- prev_insn_cc0 = 0;
- prev_insn = 0;
- #endif
-
/* If we changed a conditional jump, we may have terminated
the path we are following. Check that by verifying that
the edge we would take still exists. If the edge does
--- 6077,6115 ----
&& for_each_rtx (&PATTERN (insn), check_for_label_ref,
(void *) insn))
recorded_label_ref = 1;
+
+ #ifdef HAVE_cc0
+ /* If the previous insn set CC0 and this insn no longer
+ references CC0, delete the previous insn. Here we use
+ fact that nothing expects CC0 to be valid over an insn,
+ which is true until the final pass. */
+ {
+ rtx prev_insn, tem;
+
+ prev_insn = PREV_INSN (insn);
+ if (prev_insn && NONJUMP_INSN_P (prev_insn)
+ && (tem = single_set (prev_insn)) != 0
+ && SET_DEST (tem) == cc0_rtx
+ && ! reg_mentioned_p (cc0_rtx, PATTERN (insn)))
+ delete_insn (prev_insn);
+ }
+
+ /* If this insn is not the last insn in the basic block,
+ it will be PREV_INSN(insn) in the next iteration. If
+ we recorded any CC0-related information for this insn,
+ remember it. */
+ if (insn != BB_END (bb))
+ {
+ prev_insn_cc0 = this_insn_cc0;
+ prev_insn_cc0_mode = this_insn_cc0_mode;
+ }
+ #endif
}
}
/* Make sure that libcalls don't span multiple basic blocks. */
gcc_assert (libcall_insn == NULL_RTX);
/* If we changed a conditional jump, we may have terminated
the path we are following. Check that by verifying that
the edge we would take still exists. If the edge does
*************** cse_extended_basic_block (struct cse_bas
*** 6133,6138 ****
--- 6134,6145 ----
bool taken = (next_bb == BRANCH_EDGE (bb)->dest);
record_jump_equiv (insn, taken);
}
+
+ #ifdef HAVE_cc0
+ /* Clear the CC0-tracking related insns, they can't provide
+ useful information across basic block boundaries. */
+ prev_insn_cc0 = 0;
+ #endif
}
gcc_assert (next_qty <= max_qty);