This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: JUMP_LABEL problem and patch
- To: law at cygnus dot com
- Subject: Re: JUMP_LABEL problem and patch
- From: Anthony Green <green at cygnus dot com>
- Date: 16 Jan 2000 15:16:37 -0800
- CC: gcc-patches at gcc dot gnu dot org
- References: <19560.943773330@upchuck>
Jeffrey A Law <law@cygnus.com> writes:
> We've generally taken the approach in #1 to deal with this problem -- it's
> relatively rare and it's simpler to just pay the price to rebuild all the
> JUMP_LABEL fields for those rare cases. Examples would be CSE & register
> allocation/reload.
Please consider this patch.
2000-01-16 Anthony Green <green@cygnus.com>
* toplev.c (rest_of_compilation): Rebuild jump labels if
combine_instructions has created a new direct jump.
* combine.c (try_combine): Add new_direct_jump_p argument. Set it
when appropriate.
(combine_instructions): Call try_combine with new argument.
Return non-null value when new direct jump instruction is created.
* rtl.h: combine_instructions returns an int.
Index: gcc/toplev.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/toplev.c,v
retrieving revision 1.276
diff -u -r1.276 toplev.c
--- toplev.c 2000/01/07 00:16:51 1.276
+++ toplev.c 2000/01/16 22:53:03
@@ -3267,7 +3267,21 @@
if (optimize > 0)
{
- TIMEVAR (combine_time, combine_instructions (insns, max_reg_num ()));
+ int rebuild_jump_labels_after_combine = 0;
+
+ TIMEVAR (combine_time,
+ {
+ rebuild_jump_labels_after_combine =
+ combine_instructions (insns, max_reg_num ());
+ });
+
+ /* Combining insns may have turned an indirect jump into a
+ direct jump. Rebuid the JUMP_LABEL fields of jumping
+ instructions. */
+ if (rebuild_jump_labels_after_combine)
+ {
+ TIMEVAR (jump_time, rebuild_jump_labels (insns));
+ }
/* Dump rtl code after insn combination. */
Index: gcc/combine.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/combine.c,v
retrieving revision 1.107
diff -u -r1.107 combine.c
--- combine.c 2000/01/04 08:01:42 1.107
+++ combine.c 2000/01/16 22:53:34
@@ -359,7 +359,7 @@
static int sets_function_arg_p PROTO((rtx));
static int combinable_i3pat PROTO((rtx, rtx *, rtx, rtx, int, rtx *));
static int contains_muldiv PROTO((rtx));
-static rtx try_combine PROTO((rtx, rtx, rtx));
+static rtx try_combine PROTO((rtx, rtx, rtx, int *));
static void undo_all PROTO((void));
static void undo_commit PROTO((void));
static rtx *find_split_point PROTO((rtx *, rtx));
@@ -479,9 +479,11 @@
#define SUBST_INT(INTO, NEWVAL) do_SUBST_INT(&(INTO), (NEWVAL))
/* Main entry point for combiner. F is the first insn of the function.
- NREGS is the first unused pseudo-reg number. */
+ NREGS is the first unused pseudo-reg number.
-void
+ Return non-zero if the combiner has turned an indirect jump
+ instruction into a direct jump. */
+int
combine_instructions (f, nregs)
rtx f;
int nregs;
@@ -493,6 +495,8 @@
register int i;
register rtx links, nextlinks;
+ int new_direct_jump_p = 0;
+
combine_attempts = 0;
combine_merges = 0;
combine_extras = 0;
@@ -616,7 +620,8 @@
/* Try this insn with each insn it links back to. */
for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
- if ((next = try_combine (insn, XEXP (links, 0), NULL_RTX)) != 0)
+ if ((next = try_combine (insn, XEXP (links, 0),
+ NULL_RTX, &new_direct_jump_p)) != 0)
goto retry;
/* Try each sequence of three linked insns ending with this one. */
@@ -625,7 +630,8 @@
for (nextlinks = LOG_LINKS (XEXP (links, 0)); nextlinks;
nextlinks = XEXP (nextlinks, 1))
if ((next = try_combine (insn, XEXP (links, 0),
- XEXP (nextlinks, 0))) != 0)
+ XEXP (nextlinks, 0),
+ &new_direct_jump_p)) != 0)
goto retry;
#ifdef HAVE_cc0
@@ -641,13 +647,15 @@
&& GET_CODE (prev) == INSN
&& sets_cc0_p (PATTERN (prev)))
{
- if ((next = try_combine (insn, prev, NULL_RTX)) != 0)
+ if ((next = try_combine (insn, prev,
+ NULL_RTX, &new_direct_jump_p)) != 0)
goto retry;
for (nextlinks = LOG_LINKS (prev); nextlinks;
nextlinks = XEXP (nextlinks, 1))
if ((next = try_combine (insn, prev,
- XEXP (nextlinks, 0))) != 0)
+ XEXP (nextlinks, 0),
+ &new_direct_jump_p)) != 0)
goto retry;
}
@@ -659,13 +667,15 @@
&& GET_CODE (PATTERN (insn)) == SET
&& reg_mentioned_p (cc0_rtx, SET_SRC (PATTERN (insn))))
{
- if ((next = try_combine (insn, prev, NULL_RTX)) != 0)
+ if ((next = try_combine (insn, prev,
+ NULL_RTX, &new_direct_jump_p)) != 0)
goto retry;
for (nextlinks = LOG_LINKS (prev); nextlinks;
nextlinks = XEXP (nextlinks, 1))
if ((next = try_combine (insn, prev,
- XEXP (nextlinks, 0))) != 0)
+ XEXP (nextlinks, 0),
+ &new_direct_jump_p)) != 0)
goto retry;
}
@@ -679,7 +689,8 @@
&& (prev = prev_nonnote_insn (XEXP (links, 0))) != 0
&& GET_CODE (prev) == INSN
&& sets_cc0_p (PATTERN (prev))
- && (next = try_combine (insn, XEXP (links, 0), prev)) != 0)
+ && (next = try_combine (insn, XEXP (links, 0),
+ prev, &new_direct_jump_p)) != 0)
goto retry;
#endif
@@ -689,7 +700,8 @@
for (nextlinks = XEXP (links, 1); nextlinks;
nextlinks = XEXP (nextlinks, 1))
if ((next = try_combine (insn, XEXP (links, 0),
- XEXP (nextlinks, 0))) != 0)
+ XEXP (nextlinks, 0),
+ &new_direct_jump_p)) != 0)
goto retry;
if (GET_CODE (insn) != NOTE)
@@ -741,6 +753,8 @@
/* Make recognizer allow volatile MEMs again. */
init_recog ();
+
+ return new_direct_jump_p;
}
/* Wipe the reg_last_xxx arrays in preparation for another pass. */
@@ -1425,11 +1439,15 @@
Return 0 if the combination does not work. Then nothing is changed.
If we did the combination, return the insn at which combine should
- resume scanning. */
+ resume scanning.
+
+ Set NEW_DIRECT_JUMP_P to a non-zero value if try_combine creates a
+ new direct jump instruction. */
static rtx
-try_combine (i3, i2, i1)
+try_combine (i3, i2, i1, new_direct_jump_p)
register rtx i3, i2, i1;
+ register int *new_direct_jump_p;
{
/* New patterns for I3 and I3, respectively. */
rtx newpat, newi2pat = 0;
@@ -2670,15 +2688,22 @@
note_stores (newpat, set_nonzero_bits_and_sign_copies, NULL);
if (newi2pat)
note_stores (newi2pat, set_nonzero_bits_and_sign_copies, NULL);
+
+ /* Set new_direct_jump_p if a new return or simple jump instruction
+ has been created.
- /* If I3 is now an unconditional jump, ensure that it has a
+ If I3 is now an unconditional jump, ensure that it has a
BARRIER following it since it may have initially been a
conditional jump. It may also be the last nonnote insn. */
+
+ if (GET_CODE (newpat) == RETURN || simplejump_p (i3))
+ {
+ *new_direct_jump_p = 1;
- if ((GET_CODE (newpat) == RETURN || simplejump_p (i3))
- && ((temp = next_nonnote_insn (i3)) == NULL_RTX
- || GET_CODE (temp) != BARRIER))
- emit_barrier_after (i3);
+ if ((temp = next_nonnote_insn (i3)) == NULL_RTX
+ || GET_CODE (temp) != BARRIER)
+ emit_barrier_after (i3);
+ }
}
combine_successes++;
Index: gcc/rtl.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/rtl.h,v
retrieving revision 1.159
diff -u -r1.159 rtl.h
--- rtl.h 1999/12/26 23:06:54 1.159
+++ rtl.h 2000/01/16 22:53:39
@@ -1467,7 +1467,7 @@
extern void add_clobbers PROTO ((rtx, int));
/* In combine.c */
-extern void combine_instructions PROTO ((rtx, int));
+extern int combine_instructions PROTO ((rtx, int));
extern int extended_count PROTO ((rtx, enum machine_mode, int));
extern rtx remove_death PROTO ((int, rtx));
#ifdef BUFSIZ
I'll update the appropriate copyright dates if approved.
--
Anthony Green Red Hat
Sunnyvale, California