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]
Other format: [Raw text]

Re: Can 3.4 patch for PR2001 be backported to 3.3?


On Wed, Mar 12, 2003 at 06:39:49PM -0800, Richard Henderson wrote:
> Maybe.  Certainly we can't backport the entire bb-reorder patch,
> but it may be possible to create a special pass that could 
> duplicate the one block involved as needed.

Or, perhaps even simpler than that.  Please try the following.


r~


	* bb-reorder.c (maybe_duplicate_computed_goto_succ): New.
	(make_reorder_chain_1): Call it.

        * function.h (struct function): Add computed_goto_common_label,
        computed_goto_common_reg.
        * function.c (free_after_compilation): Zap them.
        * stmt.c (expand_computed_goto): Use them to produce one
        indirect branch per function.

Index: bb-reorder.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/bb-reorder.c,v
retrieving revision 1.50
diff -c -p -d -r1.50 bb-reorder.c
*** bb-reorder.c	21 Jun 2002 19:04:59 -0000	1.50
--- bb-reorder.c	15 Mar 2003 23:37:20 -0000
***************
*** 89,99 ****
--- 89,101 ----
  #include "flags.h"
  #include "output.h"
  #include "cfglayout.h"
+ #include "function.h"
  #include "target.h"
  
  /* Local function prototypes.  */
  static void make_reorder_chain		PARAMS ((void));
  static basic_block make_reorder_chain_1	PARAMS ((basic_block, basic_block));
+ static basic_block maybe_duplicate_computed_goto_succ PARAMS ((basic_block));
  
  /* Compute an ordering for a subgraph beginning with block BB.  Record the
     ordering in RBI()->index and chained through RBI()->next.  */
*************** make_reorder_chain ()
*** 130,135 ****
--- 132,176 ----
    RBI (prev)->next = NULL;
  }
  
+ /* If the successor is our artificial computed_jump block, duplicate it.  */
+ 
+ static inline basic_block
+ maybe_duplicate_computed_goto_succ (bb)
+      basic_block bb;
+ {
+   edge e;
+   basic_block next;
+ 
+   /* Note that we can't rely on computed_goto_common_label still being in
+      the instruction stream -- cfgloop.c likes to munge things about.  But
+      we can still use it's non-null-ness to avoid a fruitless search.  */
+   if (!cfun->computed_goto_common_label)
+     return NULL;
+ 
+   /* Only want to duplicate when coming from a simple branch.  */
+   e = bb->succ;
+   if (!e || e->succ_next)
+     return NULL;
+ 
+   /* Only duplicate if we've already layed out this block once.  */
+   next = e->dest;
+   if (!RBI (next)->visited)
+     return NULL;
+ 
+   /* See if the block contains only a computed branch.  */
+   if ((next->head == next->end
+        || next_active_insn (next->head) == next->end)
+       && computed_jump_p (next->end))
+     {
+       if (rtl_dump_file)
+ 	fprintf (rtl_dump_file, "Duplicating block %d after %d\n",
+ 		 next->index, bb->index);
+       return cfg_layout_duplicate_bb (next, e);
+     }
+ 
+   return NULL;
+ }
+ 
  /* A helper function for make_reorder_chain.
  
     We do not follow EH edges, or non-fallthru edges to noreturn blocks.
*************** make_reorder_chain_1 (bb, prev)
*** 205,210 ****
--- 246,255 ----
  
        next = ((taken && e_taken) ? e_taken : e_fall)->dest;
      }
+ 
+   /* If the successor is our artificial computed_jump block, duplicate it.  */
+   else
+     next = maybe_duplicate_computed_goto_succ (bb);
  
    /* In the absence of a prediction, disturb things as little as possible
       by selecting the old "next" block from the list of successors.  If
Index: function.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/function.c,v
retrieving revision 1.389.2.3
diff -c -p -d -r1.389.2.3 function.c
*** function.c	15 Mar 2003 02:41:04 -0000	1.389.2.3
--- function.c	15 Mar 2003 23:37:21 -0000
*************** free_after_compilation (f)
*** 450,455 ****
--- 450,457 ----
    f->x_nonlocal_goto_stack_level = NULL;
    f->x_cleanup_label = NULL;
    f->x_return_label = NULL;
+   f->computed_goto_common_label = NULL;
+   f->computed_goto_common_reg = NULL;
    f->x_save_expr_regs = NULL;
    f->x_stack_slot_list = NULL;
    f->x_rtl_expr_chain = NULL;
Index: function.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/function.h,v
retrieving revision 1.89
diff -c -p -d -r1.89 function.h
*** function.h	11 Oct 2002 20:26:50 -0000	1.89
--- function.h	15 Mar 2003 23:37:22 -0000
*************** struct function GTY(())
*** 273,278 ****
--- 273,282 ----
       on machines which require execution of the epilogue on all returns.  */
    rtx x_return_label;
  
+   /* Label and register for unswitching computed gotos.  */
+   rtx computed_goto_common_label;
+   rtx computed_goto_common_reg;
+ 
    /* List (chain of EXPR_LISTs) of pseudo-regs of SAVE_EXPRs.
       So we can mark them all live at the end of the function, if nonopt.  */
    rtx x_save_expr_regs;
Index: stmt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/stmt.c,v
retrieving revision 1.276.2.4
diff -c -p -d -r1.276.2.4 stmt.c
*** stmt.c	12 Mar 2003 16:51:55 -0000	1.276.2.4
--- stmt.c	15 Mar 2003 23:37:24 -0000
*************** expand_computed_goto (exp)
*** 541,550 ****
  #endif
  
    emit_queue ();
-   do_pending_stack_adjust ();
-   emit_indirect_jump (x);
  
!   current_function_has_computed_jump = 1;
  }
  
  /* Handle goto statements and the labels that they can go to.  */
--- 541,563 ----
  #endif
  
    emit_queue ();
  
!   if (! cfun->computed_goto_common_label)
!     {
!       cfun->computed_goto_common_reg = copy_to_mode_reg (Pmode, x);
!       cfun->computed_goto_common_label = gen_label_rtx ();
!       emit_label (cfun->computed_goto_common_label);
!   
!       do_pending_stack_adjust ();
!       emit_indirect_jump (cfun->computed_goto_common_reg);
! 
!       current_function_has_computed_jump = 1;
!     }
!   else
!     {
!       emit_move_insn (cfun->computed_goto_common_reg, x);
!       emit_jump (cfun->computed_goto_common_label);
!     }
  }
  
  /* Handle goto statements and the labels that they can go to.  */


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