This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Make CSE path following use the CFG
On 12/10/06, Steven Bosscher <stevenb.gcc@gmail.com> wrote:
On 12/10/06, Richard Guenther <richard.guenther@gmail.com> wrote:
> > + /* With non-call exceptions, if this was an insn that could
> > + trap, me may have made it non-throwing now. For example
>
> s/me/we/
Yup, I spotted that after posting my previous message. It is fixed in
what I've just commited. Thanks for spotting it too :-)
Fortunately, there appears to be a more serious problem than the typo.
For CC0-targets, we clear prev_insn_cc0 too early now. I've hacked
together the attached patch, but I can't test it right now (0:00 AM,
work tomorrow, etc.). I wanted to post it anyway because maybe it
helps people forward, and maybe someone can help me by testing this on
a CC0-target;-)
Many thanks to Anatoly for spotting this.
Gr.
Steven
Index: cse.c
===================================================================
--- cse.c (revision 119706)
+++ cse.c (working copy)
@@ -276,10 +276,6 @@ struct change_cc_mode_args
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. */
@@ -898,11 +894,6 @@ new_basic_block (void)
free_element_chain = first;
}
}
-
-#ifdef HAVE_cc0
- prev_insn = 0;
- prev_insn_cc0 = 0;
-#endif
}
/* Say that register REG contains a quantity in mode MODE not in any
@@ -4019,13 +4010,6 @@ cse_insn (rtx insn, rtx libcall_insn)
int i;
rtx tem;
int n_sets = 0;
-
-#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;
struct table_elt *src_eqv_elt = 0;
int src_eqv_volatile = 0;
@@ -5120,23 +5104,6 @@ cse_insn (rtx insn, rtx libcall_insn)
if (sets[i].rtl != 0 && dest != SET_DEST (sets[i].rtl))
sets[i].dest_hash = HASH (SET_DEST (sets[i].rtl), mode);
-
-#ifdef HAVE_cc0
- /* If setting CC0, record what it was set to, or a constant, if it
- is equivalent to a constant. If it is being set to a floating-point
- value, make a COMPARE with the appropriate constant of 0. If we
- don't do this, later code can interpret this as a test against
- const0_rtx, which can cause problems if we try to put it into an
- insn as a floating-point operand. */
- if (dest == cc0_rtx)
- {
- this_insn_cc0 = src_const && mode != VOIDmode ? src_const : src;
- this_insn_cc0_mode = mode;
- if (FLOAT_MODE_P (mode))
- this_insn_cc0 = gen_rtx_COMPARE (VOIDmode, this_insn_cc0,
- CONST0_RTX (mode));
- }
-#endif
}
/* Now enter all non-volatile source expressions in the hash table
@@ -5644,20 +5611,6 @@ cse_insn (rtx insn, rtx libcall_insn)
}
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. */
@@ -6031,6 +5984,10 @@ cse_extended_basic_block (struct cse_bas
bb = ebb_data->path[path_entry].bb;
FOR_BB_INSNS (bb, insn)
{
+#ifdef HAVE_cc0
+ rtx set, prev_insn;
+#endif
+
/* If we have processed 1,000 insns, flush the hash table to
avoid extreme quadratic behavior. We must not include NOTEs
in the count since there may be more of them when generating
@@ -6047,6 +6004,36 @@ cse_extended_basic_block (struct cse_bas
num_insns = 0;
}
+#ifdef HAVE_cc0
+ /* If the previous insn sets CC0, record this. */
+ prev_insn = PREV_INSN (insn);
+ if (prev_insn && NONJUMP_INSN_P (prev_insn)
+ && (set = single_set (prev_insn)) != 0
+ && SET_DEST (set) == cc0_rtx)
+ {
+ /* If setting CC0, record what it was set to, or a constant,
+ if it is equivalent to a constant. If it is being set to
+ a floating-point value, make a compare with the appropriate
+ constant of 0. If we don't do this, later code can
+ interpret this as a test against const0_rtx, which can
+ cause problems if we try to put it into an insn as a
+ floating-point operand. */
+ rtx src = SET_SRC (set);
+ prev_insn_cc0 = SET_SRC (set);
+ prev_insn_cc0_mode = GET_MODE (src);
+ if (FLOAT_MODE_P (prev_insn_cc0_mode))
+ prev_insn_cc0 = gen_rtx_COMPARE
+ (VOIDmode, prev_insn_cc0,
+ CONST0_RTX (prev_insn_cc0_mode));
+ }
+ else
+ {
+ /* Clear the CC0-tracking related global variables. */
+ prev_insn_cc0 = 0;
+ prev_insn_cc0_mode = VOIDmode;
+ }
+#endif
+
if (INSN_P (insn))
{
/* Process notes first so we have all notes in canonical forms
@@ -6102,13 +6089,6 @@ cse_extended_basic_block (struct cse_bas
/* 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