This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
jump after register allocation & reload
- To: egcs-patches at egcs dot cygnus dot com
- Subject: jump after register allocation & reload
- From: Jeffrey A Law <law at upchuck dot cygnus dot com>
- Date: Sat, 10 Apr 1999 05:03:57 -0600
- Reply-To: law at cygnus dot com
Arghhh. You can't run the jump optimizer after reload, but before threading
prologues/epilogues (the jump optimizer might try to turn jumps to the epilogue
into a return).
So this patch provides an entry point into jump.c which just rebuilds the
JUMP_LABEL/REG_LABEL stuff.
We may want to use this entry point to allow us to remove the "add_label_notes"
stuff in gcse.c and loop.c.
* rtl.h (rebuild_jump_labels): Declare.
* jump.c (jump_optimize_1): Renamed from jump_optimize. Make static.
Add new argument MARK_LABELS_ONLY. Quit after mark_all_labels if
requested.
(jump_optimize, rebuild_jump_labels): New wrapper functions for
jump_optimize_1.
* toplev.c (rest_of_compilation): Use rebuild_jump_labels instead of
running the entire jump optimizer.
Index: rtl.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/rtl.h,v
retrieving revision 1.100
diff -c -3 -p -r1.100 rtl.h
*** rtl.h 1999/04/10 02:55:33 1.100
--- rtl.h 1999/04/10 11:13:08
*************** extern int rtx_renumbered_equal_p PROTO
*** 1354,1359 ****
--- 1354,1360 ----
extern int true_regnum PROTO ((rtx));
extern int redirect_jump PROTO ((rtx, rtx));
extern void jump_optimize PROTO ((rtx, int, int, int));
+ extern void rebuild_jump_labels PROTO ((rtx));
extern void thread_jumps PROTO ((rtx, int, int));
extern int redirect_exp PROTO ((rtx *, rtx, rtx, rtx));
extern int rtx_equal_for_thread_p PROTO ((rtx, rtx, rtx));
Index: jump.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/jump.c,v
retrieving revision 1.55
diff -c -3 -p -r1.55 jump.c
*** jump.c 1999/03/10 19:45:18 1.55
--- jump.c 1999/04/10 11:13:16
*************** static void delete_from_jump_chain PROTO
*** 126,134 ****
--- 126,158 ----
static int delete_labelref_insn PROTO((rtx, rtx, int));
static void mark_modified_reg PROTO((rtx, rtx));
static void redirect_tablejump PROTO((rtx, rtx));
+ static void jump_optimize_1 PROTO ((rtx, int, int, int, int));
#ifndef HAVE_cc0
static rtx find_insert_position PROTO((rtx, rtx));
#endif
+
+ /* Main external entry point into the jump optimizer. See comments before
+ jump_optimize_1 for descriptions of the arguments. */
+ void
+ jump_optimize (f, cross_jump, noop_moves, after_regscan)
+ rtx f;
+ int cross_jump;
+ int noop_moves;
+ int after_regscan;
+ {
+ jump_optimize_1 (f, cross_jump, noop_moves, after_regscan, 0);
+ }
+
+ /* Alternate entry into the jump optimizer. This entry point only rebuilds
+ the JUMP_LABEL field in jumping insns and REG_LABEL notes in non-jumping
+ instructions. */
+ void
+ rebuild_jump_labels (f)
+ rtx f;
+ {
+ jump_optimize_1 (f, 0, 0, 0, 1);
+ }
+
/* Delete no-op jumps and optimize jumps to jumps
and jumps around jumps.
*************** static rtx find_insert_position
*** 143,148 ****
--- 167,175 ----
If AFTER_REGSCAN is nonzero, then this jump pass is being run immediately
after regscan, and it is safe to use regno_first_uid and regno_last_uid.
+ If MARK_LABELS_ONLY is nonzero, then we only rebuild the jump chain
+ and JUMP_LABEL field for jumping insns.
+
If `optimize' is zero, don't change any code,
just determine whether control drops off the end of the function.
This case occurs when we have -W and not -O.
*************** static rtx find_insert_position
*** 150,160 ****
and refrains from actually deleting when that is 0. */
void
! jump_optimize (f, cross_jump, noop_moves, after_regscan)
rtx f;
int cross_jump;
int noop_moves;
int after_regscan;
{
register rtx insn, next;
int changed;
--- 177,188 ----
and refrains from actually deleting when that is 0. */
void
! jump_optimize_1 (f, cross_jump, noop_moves, after_regscan, mark_labels_only)
rtx f;
int cross_jump;
int noop_moves;
int after_regscan;
+ int mark_labels_only;
{
register rtx insn, next;
int changed;
*************** jump_optimize (f, cross_jump, noop_moves
*** 181,186 ****
--- 209,219 ----
bzero ((char *) jump_chain, max_jump_chain * sizeof (rtx));
mark_all_labels (f, cross_jump);
+
+ /* Quit now if we just wanted to rebuild the JUMP_LABEL and REG_LABEL
+ notes. */
+ if (mark_labels_only)
+ return;
/* Keep track of labels used from static data;
they cannot ever be deleted. */
Index: toplev.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/toplev.c,v
retrieving revision 1.172
diff -c -3 -p -r1.172 toplev.c
*** toplev.c 1999/04/10 02:55:36 1.172
--- toplev.c 1999/04/10 11:13:23
*************** rest_of_compilation (decl)
*** 3526,3532 ****
/* Likewise, for DECL_ARGUMENTS. */
tree saved_arguments = 0;
int failure = 0;
! int run_jump_after_reload;
/* If we are reconsidering an inline function
at the end of compilation, skip the stuff for making it inline. */
--- 3526,3532 ----
/* Likewise, for DECL_ARGUMENTS. */
tree saved_arguments = 0;
int failure = 0;
! int rebuild_label_notes_after_reload;
/* If we are reconsidering an inline function
at the end of compilation, skip the stuff for making it inline. */
*************** rest_of_compilation (decl)
*** 4074,4083 ****
{
recompute_reg_usage (insns, ! optimize_size);
regclass (insns, max_reg_num ());
! run_jump_after_reload = local_alloc ();
});
else
! run_jump_after_reload = 0;
/* Dump rtl code after allocating regs within basic blocks. */
--- 4074,4083 ----
{
recompute_reg_usage (insns, ! optimize_size);
regclass (insns, max_reg_num ());
! rebuild_label_notes_after_reload = local_alloc ();
});
else
! rebuild_label_notes_after_reload = 0;
/* Dump rtl code after allocating regs within basic blocks. */
*************** rest_of_compilation (decl)
*** 4112,4130 ****
if (failure)
goto exit_rest_of_compilation;
- /* Register allocation and reloading may have turned an indirect jump into
- a direct jump. If so, we must rerun the jump optimizer to ensure that
- the JUMP_LABEL of any jump changed by that transformation is valid.
-
- We do this before reload_cse_regs since it may allow reload_cse to do
- a better job. */
- if (run_jump_after_reload)
- TIMEVAR (jump_time, jump_optimize (insns, !JUMP_CROSS_JUMP,
- !JUMP_NOOP_MOVES, !JUMP_AFTER_REGSCAN));
-
/* Do a very simple CSE pass over just the hard registers. */
if (optimize > 0)
reload_cse_regs (insns);
/* If optimizing and we are performing instruction scheduling after
reload, then go ahead and split insns now since we are about to
--- 4112,4126 ----
if (failure)
goto exit_rest_of_compilation;
/* Do a very simple CSE pass over just the hard registers. */
if (optimize > 0)
reload_cse_regs (insns);
+
+ /* Register allocation and reloading may have turned an indirect jump into
+ a direct jump. If so, we must rebuild the JUMP_LABEL fields of
+ jumping instructions. */
+ if (rebuild_label_notes_after_reload)
+ TIMEVAR (jump_time, rebuild_jump_labels (insns));
/* If optimizing and we are performing instruction scheduling after
reload, then go ahead and split insns now since we are about to