From 3f1b9b1b90632ed16bcc15a27547482be6020dfb Mon Sep 17 00:00:00 2001 From: Jeffrey A Law Date: Sat, 10 Apr 1999 02:55:36 +0000 Subject: [PATCH] rtl.h (local_alloc): Returns an integer now. * 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 --- gcc/ChangeLog | 11 +++++++++++ gcc/local-alloc.c | 23 ++++++++++++++++++++++- gcc/rtl.h | 2 +- gcc/toplev.c | 20 ++++++++++++++++++-- 4 files changed, 52 insertions(+), 4 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index ba0072c9ac8..8637a8cf6dd 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +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. diff --git a/gcc/local-alloc.c b/gcc/local-alloc.c index 598d405198f..d1df595c4c1 100644 --- a/gcc/local-alloc.c +++ b/gcc/local-alloc.c @@ -237,6 +237,9 @@ static rtx *reg_equiv_replacement; /* 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)); @@ -292,12 +295,16 @@ alloc_qty (regno, mode, size, birth) /* 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. */ @@ -410,6 +417,7 @@ local_alloc () free (reg_qty); free (reg_offset); free (reg_next_in_qty); + return recorded_label_ref; } /* Depth of loops we are in while in update_equiv_regs. */ @@ -842,6 +850,19 @@ 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. */ diff --git a/gcc/rtl.h b/gcc/rtl.h index 2661934dd18..eee7473cd33 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -1539,7 +1539,7 @@ extern void init_optabs PROTO ((void)); #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 */ diff --git a/gcc/toplev.c b/gcc/toplev.c index 728c53ada31..3847c5dcd7b 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -3526,6 +3526,7 @@ rest_of_compilation (decl) /* 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. */ @@ -4063,15 +4064,20 @@ rest_of_compilation (decl) } /* 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. */ @@ -4106,6 +4112,16 @@ rest_of_compilation (decl) 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); -- 2.30.2