diff options
author | Richard Henderson <rth@redhat.com> | 2003-03-21 15:57:00 -0800 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2003-03-21 15:57:00 -0800 |
commit | b8f7beaa0cdeab1ba675073813568376a7674686 (patch) | |
tree | 77f3bd7bbe5199a2dbca3654e66afac867081aac /gcc/bb-reorder.c | |
parent | dbb358e090fae72287c37e89f20efef0612302fd (diff) | |
download | gcc-b8f7beaa0cdeab1ba675073813568376a7674686.tar.gz |
re PR rtl-optimization/2001 (Inordinately long compile times in reload CSE regs)
PR opt/2001
* 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.
From-SVN: r64689
Diffstat (limited to 'gcc/bb-reorder.c')
-rw-r--r-- | gcc/bb-reorder.c | 45 |
1 files changed, 45 insertions, 0 deletions
diff --git a/gcc/bb-reorder.c b/gcc/bb-reorder.c index 24c41e51ced..857e0fbc6ec 100644 --- a/gcc/bb-reorder.c +++ b/gcc/bb-reorder.c @@ -89,11 +89,13 @@ #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. */ @@ -130,6 +132,45 @@ make_reorder_chain () 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. @@ -206,6 +247,10 @@ make_reorder_chain_1 (bb, prev) 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 there had been a fallthru edge, that will be the one. */ |