This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
avoid cfg rebuild after combine
- To: gcc-patches at gcc dot gnu dot org, rth at cygnus dot com, patches at x86-64 dot org
- Subject: avoid cfg rebuild after combine
- From: Jan Hubicka <jh at suse dot cz>
- Date: Sun, 15 Jul 2001 22:05:48 +0200
Bootstrapped/regtested i686 together with other today patches
Ne čec 15 21:45:03 CEST 2001 Jan Hubicka <jh@suse.cz>
* basic-block.h (purge_all_dead_edges, purge_dead_edges): New functions.
* toplev.c (rest_of_compilation): Conditionally call purge_all_dead_edges
after combine.
* gcse.c (cprop_cc0_jump, cprop_insn): New argument "basic_block".
(cprop_jump): Likewise; call purge_dead_edges if substitution suceeded.
*** /p1/jumpr2/jumpr/egcs/gcc/basic-block.h Sat Jul 14 14:57:44 2001
--- basic-block.h Sun Jul 15 21:30:26 2001
*************** extern void dump_regset PARAMS ((regse
*** 597,602 ****
--- 599,606 ----
extern void debug_regset PARAMS ((regset));
extern void allocate_reg_life_data PARAMS ((void));
extern void find_unreachable_blocks PARAMS ((void));
+ extern void purge_all_dead_edges PARAMS ((void));
+ extern void purge_dead_edges PARAMS ((basic_block));
/* This function is always defined so it can be called from the
debugger, and it is declared extern so we don't get warnings about
*** /p1/jumpr2/jumpr/egcs/gcc/flow.c Sat Jul 14 22:05:38 2001
--- flow.c Sun Jul 15 21:05:09 2001
*************** init_flow ()
*** 9832,9835 ****
--- 9857,9919 ----
obstack_free (&flow_obstack, flow_firstobj);
flow_firstobj = (char *) obstack_alloc (&flow_obstack, 0);
}
+ }
+
+ /* Assume that the preceeding pass has possibly eliminated jump instructions
+ or converted the unconditional jumps. Eliminate the edges from CFG. */
+
+ void
+ purge_dead_edges (bb)
+ basic_block bb;
+ {
+ edge e, next;
+ rtx insn = bb->end;
+ if (GET_CODE (insn) == JUMP_INSN && !simplejump_p (insn))
+ return;
+ if (GET_CODE (insn) == JUMP_INSN)
+ {
+ for (e = bb->succ; e; e = next)
+ {
+ next = e->succ_next;
+ if (e->dest == EXIT_BLOCK_PTR || e->dest->head != JUMP_LABEL (insn))
+ remove_edge (e);
+ }
+ if (bb->succ->succ_next)
+ abort ();
+ bb->succ->probability = REG_BR_PROB_BASE;
+ bb->succ->count = bb->count;
+
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, "Purged edges from bb %i\n", bb->index);
+ return;
+ }
+ /* In case we see other insn, we are not sure if the edges are not just
+ edges created by the insn we see. See whether we do have normal edges
+ created by jump insn. */
+ for (e = bb->succ; e && (e->flags & (EDGE_COMPLEX | EDGE_FALLTHRU));
+ e = e->succ_next);
+ if (!e)
+ return;
+ for (e = bb->succ; e; e = next)
+ if (!(e->flags & EDGE_FALLTHRU))
+ remove_edge (e);
+ if (!bb->succ || bb->succ->succ_next)
+ abort ();
+ bb->succ->probability = REG_BR_PROB_BASE;
+ bb->succ->count = bb->count;
+
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file, "Purged non-fallthru edges from bb %i\n",
+ bb->index);
+ return;
+ }
+
+ /* Search all basic blocks for potentionally dead edges and purge them. */
+
+ void
+ purge_all_dead_edges ()
+ {
+ int i;
+ for (i = 0; i < n_basic_blocks; i++)
+ purge_dead_edges (BASIC_BLOCK (i));
}
*** /p1/jumpr2/jumpr/egcs/gcc/gcse.c Thu Jul 12 18:03:39 2001
--- gcse.c Sun Jul 15 20:56:41 2001
*************** static void compute_cprop_data PARAMS ((
*** 616,629 ****
static void find_used_regs PARAMS ((rtx *, void *));
static int try_replace_reg PARAMS ((rtx, rtx, rtx));
static struct expr *find_avail_set PARAMS ((int, rtx));
! static int cprop_jump PARAMS ((rtx, rtx, rtx));
#ifdef HAVE_cc0
! static int cprop_cc0_jump PARAMS ((rtx, struct reg_use *, rtx));
#endif
static void mems_conflict_for_gcse_p PARAMS ((rtx, rtx, void *));
static int load_killed_in_block_p PARAMS ((basic_block, int, rtx, int));
static void canon_list_insert PARAMS ((rtx, rtx, void *));
! static int cprop_insn PARAMS ((rtx, int));
static int cprop PARAMS ((int));
static int one_cprop_pass PARAMS ((int, int));
static void alloc_pre_mem PARAMS ((int, int));
--- 616,629 ----
static void find_used_regs PARAMS ((rtx *, void *));
static int try_replace_reg PARAMS ((rtx, rtx, rtx));
static struct expr *find_avail_set PARAMS ((int, rtx));
! static int cprop_jump PARAMS ((basic_block, rtx, rtx, rtx));
#ifdef HAVE_cc0
! static int cprop_cc0_jump PARAMS ((basic_block, rtx, struct reg_use *, rtx));
#endif
static void mems_conflict_for_gcse_p PARAMS ((rtx, rtx, void *));
static int load_killed_in_block_p PARAMS ((basic_block, int, rtx, int));
static void canon_list_insert PARAMS ((rtx, rtx, void *));
! static int cprop_insn PARAMS ((basic_block, rtx, int));
static int cprop PARAMS ((int));
static int one_cprop_pass PARAMS ((int, int));
static void alloc_pre_mem PARAMS ((int, int));
*************** hash_scan_set (pat, insn, set_p)
*** 2205,2211 ****
/* Is SET_SRC something we want to gcse? */
&& want_to_gcse_p (src)
/* Don't CSE a nop. */
! && ! set_noop_p (pat)
/* Don't GCSE if it has attached REG_EQUIV note.
At this point this only function parameters should have
REG_EQUIV notes and if the argument slot is used somewhere
--- 2205,2211 ----
/* Is SET_SRC something we want to gcse? */
&& want_to_gcse_p (src)
/* Don't CSE a nop. */
! && ! set_noop_p (pat, insn)
/* Don't GCSE if it has attached REG_EQUIV note.
At this point this only function parameters should have
REG_EQUIV notes and if the argument slot is used somewhere
*************** find_avail_set (regno, insn)
*** 4107,4116 ****
nonzero if a change was made. We know INSN has just a SET. */
static int
! cprop_jump (insn, from, src)
rtx insn;
rtx from;
rtx src;
{
rtx set = PATTERN (insn);
rtx new = simplify_replace_rtx (SET_SRC (set), from, src);
--- 4107,4117 ----
nonzero if a change was made. We know INSN has just a SET. */
static int
! cprop_jump (bb, insn, from, src)
rtx insn;
rtx from;
rtx src;
+ basic_block bb;
{
rtx set = PATTERN (insn);
rtx new = simplify_replace_rtx (SET_SRC (set), from, src);
*************** cprop_jump (insn, from, src)
*** 4151,4156 ****
--- 4152,4158 ----
print_rtl (gcse_file, src);
fprintf (gcse_file, "\n");
}
+ purge_dead_edges (bb);
return 1;
}
*************** cprop_jump (insn, from, src)
*** 4164,4170 ****
Returns nonzero if a change was made. */
static int
! cprop_cc0_jump (insn, reg_used, src)
rtx insn;
struct reg_use *reg_used;
rtx src;
--- 4166,4173 ----
Returns nonzero if a change was made. */
static int
! cprop_cc0_jump (bb, insn, reg_used, src)
! basic_block bb;
rtx insn;
struct reg_use *reg_used;
rtx src;
*************** cprop_cc0_jump (insn, reg_used, src)
*** 4175,4181 ****
rtx new_src = simplify_replace_rtx (SET_SRC (PATTERN (insn)),
reg_used->reg_rtx, src);
! if (! cprop_jump (jump, cc0_rtx, new_src))
return 0;
/* If we succeeded, delete the cc0 setter. */
--- 4178,4184 ----
rtx new_src = simplify_replace_rtx (SET_SRC (PATTERN (insn)),
reg_used->reg_rtx, src);
! if (! cprop_jump (bb, jump, cc0_rtx, new_src))
return 0;
/* If we succeeded, delete the cc0 setter. */
*************** cprop_cc0_jump (insn, reg_used, src)
*** 4191,4197 ****
The result is non-zero if a change was made. */
static int
! cprop_insn (insn, alter_jumps)
rtx insn;
int alter_jumps;
{
--- 4194,4201 ----
The result is non-zero if a change was made. */
static int
! cprop_insn (bb, insn, alter_jumps)
! basic_block bb;
rtx insn;
int alter_jumps;
{
*************** cprop_insn (insn, alter_jumps)
*** 4275,4281 ****
&& GET_CODE (insn) == JUMP_INSN
&& condjump_p (insn)
&& ! simplejump_p (insn))
! changed |= cprop_jump (insn, reg_used->reg_rtx, src);
#ifdef HAVE_cc0
/* Similar code for machines that use a pair of CC0 setter and
--- 4279,4285 ----
&& GET_CODE (insn) == JUMP_INSN
&& condjump_p (insn)
&& ! simplejump_p (insn))
! changed |= cprop_jump (bb, insn, reg_used->reg_rtx, src);
#ifdef HAVE_cc0
/* Similar code for machines that use a pair of CC0 setter and
*************** cprop (alter_jumps)
*** 4344,4350 ****
insn = NEXT_INSN (insn))
if (INSN_P (insn))
{
! changed |= cprop_insn (insn, alter_jumps);
/* Keep track of everything modified by this insn. */
/* ??? Need to be careful w.r.t. mods done to INSN. Don't
--- 4348,4354 ----
insn = NEXT_INSN (insn))
if (INSN_P (insn))
{
! changed |= cprop_insn (bb, insn, alter_jumps);
/* Keep track of everything modified by this insn. */
/* ??? Need to be careful w.r.t. mods done to INSN. Don't
*** /p1/jumpr2/jumpr/egcs/gcc/toplev.c Sat Jul 14 14:57:44 2001
--- toplev.c Sun Jul 15 21:29:05 2001
*************** rest_of_compilation (decl)
*** 3349,3355 ****
timevar_pop (TV_JUMP);
timevar_push (TV_FLOW);
! find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
cleanup_cfg (CLEANUP_EXPENSIVE);
/* Blimey. We've got to have the CFG up to date for the call to
--- 3358,3364 ----
timevar_pop (TV_JUMP);
timevar_push (TV_FLOW);
! purge_all_dead_edges ();
cleanup_cfg (CLEANUP_EXPENSIVE);
/* Blimey. We've got to have the CFG up to date for the call to