rtl.h (local_alloc): Returns an integer now.
authorJeffrey A Law <law@cygnus.com>
Sat, 10 Apr 1999 02:55:36 +0000 (02:55 +0000)
committerJeff Law <law@gcc.gnu.org>
Sat, 10 Apr 1999 02:55:36 +0000 (20:55 -0600)
        * 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
gcc/local-alloc.c
gcc/rtl.h
gcc/toplev.c

index ba0072c9ac82be951258640339b97b0d568e3b84..8637a8cf6dd28fd35fee34b0386ea20eb39234fa 100644 (file)
@@ -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.
index 598d405198f7e86e6c8ce99d068b8b4cacf7ba50..d1df595c4c1110d5acf444ca1448dc38a159a951 100644 (file)
@@ -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)
 \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.  */
@@ -410,6 +417,7 @@ local_alloc ()
   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.  */
@@ -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.  */
index 2661934dd18d241f2434cf9ac68c03485ba1ee3a..eee7473cd336a13594be04edcac23f1b68e5e2e8 100644 (file)
--- 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 */
index 728c53ada3108b96f367a811abcd173735cb936b..3847c5dcd7b6b9c4484867e1ff76613d28c9dcbb 100644 (file)
@@ -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);