This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

jump after register allocation & reload



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



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]