summaryrefslogtreecommitdiff
path: root/gcc/flow.c
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2001-07-24 23:42:40 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2001-07-24 23:42:40 +0000
commit2029706725556f2b0676b40a73a36f2bcce61877 (patch)
treed1ee1391800621b2b6ec28beb4ce0ea486728f56 /gcc/flow.c
parent0d23ae5319074872ed79482237dbf64ee7275e9a (diff)
downloadgcc-2029706725556f2b0676b40a73a36f2bcce61877.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@44320 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/flow.c')
-rw-r--r--gcc/flow.c122
1 files changed, 90 insertions, 32 deletions
diff --git a/gcc/flow.c b/gcc/flow.c
index ac1ea5ccee3..733eae047bc 100644
--- a/gcc/flow.c
+++ b/gcc/flow.c
@@ -1592,7 +1592,11 @@ block_label (block)
if (block == EXIT_BLOCK_PTR)
return NULL_RTX;
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;
}
@@ -1834,22 +1838,7 @@ redirect_edge_and_branch (e, target)
fprintf (rtl_dump_file, "Edge %i->%i redirected to %i\n",
e->src->index, e->dest->index, target->index);
if (e->dest != 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);
- }
+ redirect_edge_succ_nodup (e, target);
return true;
}
@@ -2293,6 +2282,7 @@ commit_edge_insertions ()
{
int i;
basic_block bb;
+ compute_bb_for_insn (get_max_uid ());
#ifdef ENABLE_CHECKING
verify_flow_info ();
@@ -3076,8 +3066,8 @@ try_simplify_condjump (cbranch_block)
/* Success. Update the CFG to match. Note that after this point
the edge variable names appear backwards; the redirection is done
this way to preserve edge profile data. */
- redirect_edge_succ (cbranch_jump_edge, cbranch_dest_block);
- redirect_edge_succ (cbranch_fallthru_edge, jump_dest_block);
+ redirect_edge_succ_nodup (cbranch_jump_edge, cbranch_dest_block);
+ redirect_edge_succ_nodup (cbranch_fallthru_edge, jump_dest_block);
cbranch_jump_edge->flags |= EDGE_FALLTHRU;
cbranch_fallthru_edge->flags &= ~EDGE_FALLTHRU;
@@ -3820,7 +3810,7 @@ try_optimize_cfg (mode)
fprintf (rtl_dump_file, "Deleting fallthru block %i.\n",
b->index);
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);
changed = true;
b = c;
@@ -7979,11 +7969,13 @@ verify_flow_info ()
const int max_uid = get_max_uid ();
const rtx rtx_first = get_insns ();
rtx last_head = get_last_insn ();
- basic_block *bb_info;
+ basic_block *bb_info, *last_visited;
rtx x;
int i, last_bb_num_seen, num_bb_notes, err = 0;
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--)
{
@@ -8040,6 +8032,14 @@ verify_flow_info ()
e = bb->succ;
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)
&& e->src != ENTRY_BLOCK_PTR
&& e->dest != EXIT_BLOCK_PTR
@@ -8166,8 +8166,7 @@ verify_flow_info ()
basic_block bb = NOTE_BASIC_BLOCK (x);
num_bb_notes++;
if (bb->index != last_bb_num_seen + 1)
- /* Basic blocks not numbered consecutively. */
- abort ();
+ internal_error ("Basic blocks not numbered consecutively.");
last_bb_num_seen = bb->index;
}
@@ -8213,10 +8212,11 @@ verify_flow_info ()
num_bb_notes, n_basic_blocks);
if (err)
- abort ();
+ internal_error ("verify_flow_info failed.");
/* Clean up. */
free (bb_info);
+ free (last_visited);
}
/* Functions to access an edge list with a vector representation.
@@ -8629,6 +8629,29 @@ redirect_edge_succ (e, 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. */
void
@@ -9794,21 +9817,56 @@ purge_dead_edges (bb)
return;
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)
{
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)
- abort ();
- if (!bb->succ)
+ if (!bb->succ || !removed)
return;
- 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);
+ 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;
}
/* If we don't see a jump insn, we don't know exactly why the block would