Commit ca9fef16 by Jan Hubicka Committed by Jan Hubicka

flow.c (try_simplify_condjump): Avoid duplicated edges.

	* flow.c (try_simplify_condjump): Avoid duplicated edges.
	(verify_flow_info): Check for duplicated edges; clarify
	error reporting.

	* flow.c (block_label): Update basic_block_for_insn.
	(commit_edge_insertions): Call compute_bb_for_insn.

	* flow.c (purge_dead_edges): Handle conditional jumps and conditional
	returns too.

	* flow.c (redirect_edge_and_branch,
	try_optimize_cfg): Use redirect_edge_succ_nodup
	(redirect_edge_succ_nodup): New.
	* basic_block.h (redirect_edge_succ_nodup): Declare.

	* toplev.c (rest_of_compilation): Rebuild CFG before cfg_cleanup
	after gcse.

From-SVN: r44320
parent 40fc4e6a
Wed Jul 25 01:41:27 CEST 2001 Jan Hubicka <jh@suse.cz>
* flow.c (try_simplify_condjump): Avoid duplicated edges.
(verify_flow_info): Check for duplicated edges; clarify
error reporting.
* flow.c (block_label): Update basic_block_for_insn.
(commit_edge_insertions): Call compute_bb_for_insn.
* flow.c (purge_dead_edges): Handle conditional jumps and conditional
returns too.
* flow.c (redirect_edge_and_branch,
try_optimize_cfg): Use redirect_edge_succ_nodup
(redirect_edge_succ_nodup): New.
* basic_block.h (redirect_edge_succ_nodup): Declare.
* toplev.c (rest_of_compilation): Rebuild CFG before cfg_cleanup
after gcse.
Wed Jul 25 00:32:49 CEST 2001 Jan Hubicka <jh@suse.cz> Wed Jul 25 00:32:49 CEST 2001 Jan Hubicka <jh@suse.cz>
* flow.c (try_forward_edges): Accept fallthru edge; Update comment. * flow.c (try_forward_edges): Accept fallthru edge; Update comment.
......
...@@ -296,6 +296,7 @@ extern void make_edge PARAMS ((sbitmap *, basic_block, ...@@ -296,6 +296,7 @@ extern void make_edge PARAMS ((sbitmap *, basic_block,
basic_block, int)); basic_block, int));
extern void remove_edge PARAMS ((edge)); extern void remove_edge PARAMS ((edge));
extern void redirect_edge_succ PARAMS ((edge, basic_block)); extern void redirect_edge_succ PARAMS ((edge, basic_block));
extern void redirect_edge_succ_nodup PARAMS ((edge, basic_block));
extern void redirect_edge_pred PARAMS ((edge, basic_block)); extern void redirect_edge_pred PARAMS ((edge, basic_block));
extern void create_basic_block PARAMS ((int, rtx, rtx, rtx)); extern void create_basic_block PARAMS ((int, rtx, rtx, rtx));
extern int flow_delete_block PARAMS ((basic_block)); extern int flow_delete_block PARAMS ((basic_block));
......
...@@ -1592,7 +1592,11 @@ block_label (block) ...@@ -1592,7 +1592,11 @@ block_label (block)
if (block == EXIT_BLOCK_PTR) if (block == EXIT_BLOCK_PTR)
return NULL_RTX; return NULL_RTX;
if (GET_CODE (block->head) != CODE_LABEL) if (GET_CODE (block->head) != CODE_LABEL)
block->head = emit_label_before (gen_label_rtx (), block->head); {
block->head = emit_label_before (gen_label_rtx (), block->head);
if (basic_block_for_insn)
set_block_for_insn (block->head, block);
}
return block->head; return block->head;
} }
...@@ -1834,22 +1838,7 @@ redirect_edge_and_branch (e, target) ...@@ -1834,22 +1838,7 @@ redirect_edge_and_branch (e, target)
fprintf (rtl_dump_file, "Edge %i->%i redirected to %i\n", fprintf (rtl_dump_file, "Edge %i->%i redirected to %i\n",
e->src->index, e->dest->index, target->index); e->src->index, e->dest->index, target->index);
if (e->dest != target) if (e->dest != target)
{ redirect_edge_succ_nodup (e, target);
edge s;
/* Check whether the edge is already present. */
for (s = src->succ; s; s=s->succ_next)
if (s->dest == target)
break;
if (s)
{
s->flags |= e->flags;
s->probability += e->probability;
s->count += e->count;
remove_edge (e);
}
else
redirect_edge_succ (e, target);
}
return true; return true;
} }
...@@ -2293,6 +2282,7 @@ commit_edge_insertions () ...@@ -2293,6 +2282,7 @@ commit_edge_insertions ()
{ {
int i; int i;
basic_block bb; basic_block bb;
compute_bb_for_insn (get_max_uid ());
#ifdef ENABLE_CHECKING #ifdef ENABLE_CHECKING
verify_flow_info (); verify_flow_info ();
...@@ -3076,8 +3066,8 @@ try_simplify_condjump (cbranch_block) ...@@ -3076,8 +3066,8 @@ try_simplify_condjump (cbranch_block)
/* Success. Update the CFG to match. Note that after this point /* Success. Update the CFG to match. Note that after this point
the edge variable names appear backwards; the redirection is done the edge variable names appear backwards; the redirection is done
this way to preserve edge profile data. */ this way to preserve edge profile data. */
redirect_edge_succ (cbranch_jump_edge, cbranch_dest_block); redirect_edge_succ_nodup (cbranch_jump_edge, cbranch_dest_block);
redirect_edge_succ (cbranch_fallthru_edge, jump_dest_block); redirect_edge_succ_nodup (cbranch_fallthru_edge, jump_dest_block);
cbranch_jump_edge->flags |= EDGE_FALLTHRU; cbranch_jump_edge->flags |= EDGE_FALLTHRU;
cbranch_fallthru_edge->flags &= ~EDGE_FALLTHRU; cbranch_fallthru_edge->flags &= ~EDGE_FALLTHRU;
...@@ -3820,7 +3810,7 @@ try_optimize_cfg (mode) ...@@ -3820,7 +3810,7 @@ try_optimize_cfg (mode)
fprintf (rtl_dump_file, "Deleting fallthru block %i.\n", fprintf (rtl_dump_file, "Deleting fallthru block %i.\n",
b->index); b->index);
c = BASIC_BLOCK (b->index ? b->index - 1 : 1); c = BASIC_BLOCK (b->index ? b->index - 1 : 1);
redirect_edge_succ (b->pred, b->succ->dest); redirect_edge_succ_nodup (b->pred, b->succ->dest);
flow_delete_block (b); flow_delete_block (b);
changed = true; changed = true;
b = c; b = c;
...@@ -7979,11 +7969,13 @@ verify_flow_info () ...@@ -7979,11 +7969,13 @@ verify_flow_info ()
const int max_uid = get_max_uid (); const int max_uid = get_max_uid ();
const rtx rtx_first = get_insns (); const rtx rtx_first = get_insns ();
rtx last_head = get_last_insn (); rtx last_head = get_last_insn ();
basic_block *bb_info; basic_block *bb_info, *last_visited;
rtx x; rtx x;
int i, last_bb_num_seen, num_bb_notes, err = 0; int i, last_bb_num_seen, num_bb_notes, err = 0;
bb_info = (basic_block *) xcalloc (max_uid, sizeof (basic_block)); bb_info = (basic_block *) xcalloc (max_uid, sizeof (basic_block));
last_visited = (basic_block *) xcalloc (n_basic_blocks + 2,
sizeof (basic_block));
for (i = n_basic_blocks - 1; i >= 0; i--) for (i = n_basic_blocks - 1; i >= 0; i--)
{ {
...@@ -8040,6 +8032,14 @@ verify_flow_info () ...@@ -8040,6 +8032,14 @@ verify_flow_info ()
e = bb->succ; e = bb->succ;
while (e) while (e)
{ {
if (last_visited [e->dest->index + 2] == bb)
{
error ("verify_flow_info: Duplicate edge %i->%i",
e->src->index, e->dest->index);
err = 1;
}
last_visited [e->dest->index + 2] = bb;
if ((e->flags & EDGE_FALLTHRU) if ((e->flags & EDGE_FALLTHRU)
&& e->src != ENTRY_BLOCK_PTR && e->src != ENTRY_BLOCK_PTR
&& e->dest != EXIT_BLOCK_PTR && e->dest != EXIT_BLOCK_PTR
...@@ -8166,8 +8166,7 @@ verify_flow_info () ...@@ -8166,8 +8166,7 @@ verify_flow_info ()
basic_block bb = NOTE_BASIC_BLOCK (x); basic_block bb = NOTE_BASIC_BLOCK (x);
num_bb_notes++; num_bb_notes++;
if (bb->index != last_bb_num_seen + 1) if (bb->index != last_bb_num_seen + 1)
/* Basic blocks not numbered consecutively. */ internal_error ("Basic blocks not numbered consecutively.");
abort ();
last_bb_num_seen = bb->index; last_bb_num_seen = bb->index;
} }
...@@ -8213,10 +8212,11 @@ verify_flow_info () ...@@ -8213,10 +8212,11 @@ verify_flow_info ()
num_bb_notes, n_basic_blocks); num_bb_notes, n_basic_blocks);
if (err) if (err)
abort (); internal_error ("verify_flow_info failed.");
/* Clean up. */ /* Clean up. */
free (bb_info); free (bb_info);
free (last_visited);
} }
/* Functions to access an edge list with a vector representation. /* Functions to access an edge list with a vector representation.
...@@ -8629,6 +8629,29 @@ redirect_edge_succ (e, new_succ) ...@@ -8629,6 +8629,29 @@ redirect_edge_succ (e, new_succ)
e->dest = new_succ; e->dest = new_succ;
} }
/* Like previous but avoid possible dupplicate edge. */
void
redirect_edge_succ_nodup (e, new_succ)
edge e;
basic_block new_succ;
{
edge s;
/* Check whether the edge is already present. */
for (s = e->src->succ; s; s = s->succ_next)
if (s->dest == new_succ && s != e)
break;
if (s)
{
s->flags |= e->flags;
s->probability += e->probability;
s->count += e->count;
remove_edge (e);
}
else
redirect_edge_succ (e, new_succ);
}
/* Redirect an edge's predecessor from one block to another. */ /* Redirect an edge's predecessor from one block to another. */
void void
...@@ -9794,21 +9817,56 @@ purge_dead_edges (bb) ...@@ -9794,21 +9817,56 @@ purge_dead_edges (bb)
return; return;
if (GET_CODE (insn) == JUMP_INSN) if (GET_CODE (insn) == JUMP_INSN)
{ {
int removed = 0;
rtx note;
edge b,f;
/* We do care only about conditional jumps and simplejumps. */
if (!any_condjump_p (insn)
&& !returnjump_p (insn)
&& !simplejump_p (insn))
return;
for (e = bb->succ; e; e = next) for (e = bb->succ; e; e = next)
{ {
next = e->succ_next; next = e->succ_next;
if (e->dest == EXIT_BLOCK_PTR || e->dest->head != JUMP_LABEL (insn))
remove_edge (e); /* Check purposes we can have edge. */
if ((e->flags & EDGE_FALLTHRU)
&& any_condjump_p (insn))
continue;
if (e->dest != EXIT_BLOCK_PTR
&& e->dest->head == JUMP_LABEL (insn))
continue;
if (e->dest == EXIT_BLOCK_PTR
&& returnjump_p (insn))
continue;
removed = 1;
remove_edge (e);
} }
if (bb->succ && bb->succ->succ_next) if (!bb->succ || !removed)
abort ();
if (!bb->succ)
return; return;
bb->succ->probability = REG_BR_PROB_BASE;
bb->succ->count = bb->count;
if (rtl_dump_file) if (rtl_dump_file)
fprintf (rtl_dump_file, "Purged edges from bb %i\n", bb->index); fprintf (rtl_dump_file, "Purged edges from bb %i\n", bb->index);
if (!optimize)
return;
/* Redistribute probabilities. */
if (!bb->succ->succ_next)
{
bb->succ->probability = REG_BR_PROB_BASE;
bb->succ->count = bb->count;
}
else
{
note = find_reg_note (insn, REG_BR_PROB, NULL);
if (!note)
return;
b = BRANCH_EDGE (bb);
f = FALLTHRU_EDGE (bb);
b->probability = INTVAL (XEXP (note, 0));
f->probability = REG_BR_PROB_BASE - b->probability;
b->count = bb->count * b->probability / REG_BR_PROB_BASE;
f->count = bb->count * f->probability / REG_BR_PROB_BASE;
}
return; return;
} }
/* If we don't see a jump insn, we don't know exactly why the block would /* If we don't see a jump insn, we don't know exactly why the block would
......
...@@ -3060,6 +3060,8 @@ rest_of_compilation (decl) ...@@ -3060,6 +3060,8 @@ rest_of_compilation (decl)
tem = tem2 = 0; tem = tem2 = 0;
timevar_push (TV_JUMP); timevar_push (TV_JUMP);
rebuild_jump_labels (insns); rebuild_jump_labels (insns);
delete_trivially_dead_insns (insns, max_reg_num (), 0);
find_basic_blocks (insns, max_reg_num (), rtl_dump_file);
cleanup_cfg (CLEANUP_EXPENSIVE); cleanup_cfg (CLEANUP_EXPENSIVE);
timevar_pop (TV_JUMP); timevar_pop (TV_JUMP);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment