* rtl.h (local_alloc): Returns an integer now.
* local-alloc.c (recorded_label_ref): New file scoped variable.
(local_alloc): Initialize recorded_label_ref to zero. Return its
value when local allocation has completed.
(update_equiv_regs); If we create an equivalence for a LABEL_REF,
set recorded_label_ref.
* toplev.c (rest_of_compilation): Run the loop optimizer after
register allocation and reloading if needed.
From-SVN: r26324
+Sat Apr 10 03:50:12 1999 Jeffrey A Law (law@cygnus.com)
+
+ * rtl.h (local_alloc): Returns an integer now.
+ * local-alloc.c (recorded_label_ref): New file scoped variable.
+ (local_alloc): Initialize recorded_label_ref to zero. Return its
+ value when local allocation has completed.
+ (update_equiv_regs); If we create an equivalence for a LABEL_REF,
+ set recorded_label_ref.
+ * toplev.c (rest_of_compilation): Run the loop optimizer after
+ register allocation and reloading if needed.
+
Fri Apr 9 21:02:57 1999 Krister Walfridsson (cato@df.lth.se)
* i386/gas.h (ASM_OUTPUT_MAX_SKIP_ALIGN): Fix typo.
/* Used for communication between update_equiv_regs and no_equiv. */
static rtx *reg_equiv_init_insns;
+/* Nonzero if we recorded an equivalence for a LABEL_REF. */
+static int recorded_label_ref;
+
static void alloc_qty PROTO((int, enum machine_mode, int, int));
static void validate_equiv_mem_from_store PROTO((rtx, rtx));
static int validate_equiv_mem PROTO((rtx, rtx, rtx));
\f
/* Main entry point of this file. */
-void
+int
local_alloc ()
{
register int b, i;
int max_qty;
+ /* We need to keep track of whether or not we recorded a LABEL_REF so
+ that we know if the jump optimizer needs to be rerun. */
+ recorded_label_ref = 0;
+
/* Leaf functions and non-leaf functions have different needs.
If defined, let the machine say what kind of ordering we
should use. */
free (reg_qty);
free (reg_offset);
free (reg_next_in_qty);
+ return recorded_label_ref;
}
\f
/* Depth of loops we are in while in update_equiv_regs. */
{
int regno = REGNO (dest);
+ /* Record whether or not we created a REG_EQUIV note for a LABEL_REF.
+ We might end up substituting the LABEL_REF for uses of the
+ pseudo here or later. That kind of transformation may turn an
+ indirect jump into a direct jump, in which case we must rerun the
+ jump optimizer to ensure that the JUMP_LABEL fields are valid. */
+ if (GET_CODE (XEXP (note, 0)) == LABEL_REF
+ || (GET_CODE (XEXP (note, 0)) == CONST
+ && GET_CODE (XEXP (XEXP (note, 0), 0)) == PLUS
+ && (GET_CODE (XEXP (XEXP (XEXP (note, 0), 0), 0))
+ == LABEL_REF)))
+ recorded_label_ref = 1;
+
+
reg_equiv_replacement[regno] = XEXP (note, 0);
/* Don't mess with things live during setjmp. */
#ifdef BUFSIZ
extern void dump_local_alloc PROTO ((FILE *));
#endif
-extern void local_alloc PROTO ((void));
+extern int local_alloc PROTO ((void));
extern int function_invariant_p PROTO ((rtx));
/* In reload1.c */
/* 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. */
}
/* Unless we did stupid register allocation,
- allocate pseudo-regs that are used only within 1 basic block. */
+ allocate pseudo-regs that are used only within 1 basic block.
+
+ RUN_JUMP_AFTER_RELOAD records whether or not we need to rerun the
+ jump optimizer after register allocation and reloading are finished. */
if (!obey_regdecls)
TIMEVAR (local_alloc_time,
{
recompute_reg_usage (insns, ! optimize_size);
regclass (insns, max_reg_num ());
- local_alloc ();
+ run_jump_after_reload = local_alloc ();
});
+ else
+ run_jump_after_reload = 0;
/* Dump rtl code after allocating regs within basic blocks. */
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);