This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
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. */