This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Re: optimization/2001: [3.2/3.3 regression] Inordinately longcompile times in reload CSE regs
- From: Steven Bosscher <s dot bosscher at student dot tudelft dot nl>
- To: Andreas Jaeger <aj at suse dot de>
- Cc: gcc-bugs at gcc dot gnu dot org, lucier at math dot purdue dot edu, rth at redhat dot com
- Date: 16 Mar 2003 11:31:27 +0100
- Subject: Re: optimization/2001: [3.2/3.3 regression] Inordinately longcompile times in reload CSE regs
- References: <3E744BDD.1090409@student.tudelft.nl> <u8k7ezhauv.fsf@gromit.moeb>
Op zo 16-03-2003, om 11:19 schreef Andreas Jaeger:
> Steven Bosscher <s dot bosscher at student dot tudelft dot nl> writes:
>
> > http://gcc.gnu.org/cgi-bin/gnatsweb.pl?cmd=view%20audit-trail&database=gcc&pr=2001
> >
> > Richard's patch really improves things a lot for me:
> > http://gcc.gnu.org/ml/gcc-patches/2003-03/msg01478.html
> >
> > If somebody tries this: The patch doesn't apply cleanly, the
> > first hunk of bb-reorder.c needs to be applied manually.
>
> Can you send a clean patch against 3.3 to save others applying it
> manually?
I tried that, but my re-rolled patch choked on the same problem. Maybe
diff/patch have trouble with lines that only have a ^L, or my patch
program is just too old and buggy, dunno.
Anyway, try for yourself, YMMV. At least the stmt.c part now applies
without offset.
Greetz
Steven
Index: bb-reorder.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/bb-reorder.c,v
retrieving revision 1.50
diff -c -3 -p -r1.50 bb-reorder.c
*** bb-reorder.c 21 Jun 2002 19:04:59 -0000 1.50
--- bb-reorder.c 16 Mar 2003 09:36:45 -0000
***************
*** 89,99 ****
--- 89,102 ----
#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 ****
--- 133,177 ----
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 ****
--- 247,256 ----
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 -3 -p -r1.389.2.3 function.c
*** function.c 15 Mar 2003 02:41:04 -0000 1.389.2.3
--- function.c 16 Mar 2003 09:37:01 -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 -3 -p -r1.89 function.h
*** function.h 11 Oct 2002 20:26:50 -0000 1.89
--- function.h 16 Mar 2003 09:37:03 -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 -3 -p -r1.276.2.4 stmt.c
*** stmt.c 12 Mar 2003 16:51:55 -0000 1.276.2.4
--- stmt.c 16 Mar 2003 09:37:16 -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. */