summaryrefslogtreecommitdiff
path: root/gcc/cfgcleanup.c
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2002-01-10 20:37:43 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2002-01-10 20:37:43 +0000
commitf884e43f769f6951e24974abbd39234c6227831d (patch)
tree19471938dee687744538e8ca3cc2eb35fdb507c2 /gcc/cfgcleanup.c
parentac0c7fb1dcdaddb68f447b490882265dfd7f688c (diff)
downloadgcc-f884e43f769f6951e24974abbd39234c6227831d.tar.gz
* basic-block.h (update_br_prob_note): Declare.
* cfgcleanup.c (try_simplify_condjump): Call update_br_prob_note. (try_forward_edges): Care negative frequencies and update note. (outgoing_edges_match): Tweek conditional merging heuristics. (try_crossjump_to_edge): use update_br_prob_note. * cfglayout.c (fixup_reorder_chain): Likewise. * cfrtl.c (update_br_prob_note): New. * ifcvt.c (dead_or_predicable): Call update_br_prob_note. * i386.c (ix86_decompose_address): Return -1 if address contains shift. (legitimate_address_p): Require ix86_decompose_address to return 1. * gcse.c (hash_scan_set): Use CONSTANT_INSN_P. (cprop_insn): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@48750 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cfgcleanup.c')
-rw-r--r--gcc/cfgcleanup.c68
1 files changed, 40 insertions, 28 deletions
diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
index 0af87b4b3a4..5015c814941 100644
--- a/gcc/cfgcleanup.c
+++ b/gcc/cfgcleanup.c
@@ -177,6 +177,7 @@ try_simplify_condjump (cbranch_block)
jump_dest_block);
cbranch_jump_edge->flags |= EDGE_FALLTHRU;
cbranch_fallthru_edge->flags &= ~EDGE_FALLTHRU;
+ update_br_prob_note (cbranch_block);
/* Delete the block with the unconditional jump, and clean up the mess. */
flow_delete_block (jump_block);
@@ -521,7 +522,11 @@ try_forward_edges (mode, b)
edge t;
first->count -= edge_count;
+ if (first->count < 0)
+ first->count = 0;
first->frequency -= edge_frequency;
+ if (first->frequency < 0)
+ first->frequency = 0;
if (first->succ->succ_next)
{
edge e;
@@ -535,9 +540,11 @@ try_forward_edges (mode, b)
prob = edge_frequency * REG_BR_PROB_BASE / first->frequency;
else
prob = 0;
+ if (prob > t->probability)
+ prob = t->probability;
t->probability -= prob;
prob = REG_BR_PROB_BASE - prob;
- if (prob == 0)
+ if (prob <= 0)
{
first->succ->probability = REG_BR_PROB_BASE;
first->succ->succ_next->probability = 0;
@@ -546,6 +553,7 @@ try_forward_edges (mode, b)
for (e = first->succ; e; e = e->succ_next)
e->probability = ((e->probability * REG_BR_PROB_BASE)
/ (double) prob);
+ update_br_prob_note (first);
}
else
{
@@ -558,8 +566,10 @@ try_forward_edges (mode, b)
n++;
t = first->succ;
}
- t->count -= edge_count;
+ t->count -= edge_count;
+ if (t->count < 0)
+ t->count = 0;
first = t->dest;
}
while (first != target);
@@ -745,6 +755,7 @@ merge_blocks (e, b, c, mode)
/* If B has a fallthru edge to C, no need to move anything. */
if (e->flags & EDGE_FALLTHRU)
{
+ int b_index = b->index, c_index = c->index;
/* We need to update liveness in case C already has broken liveness
or B ends by conditional jump to next instructions that will be
removed. */
@@ -756,7 +767,7 @@ merge_blocks (e, b, c, mode)
if (rtl_dump_file)
fprintf (rtl_dump_file, "Merged %d and %d without moving.\n",
- b->index, c->index);
+ b_index, c_index);
return true;
}
@@ -1147,32 +1158,30 @@ outgoing_edges_match (mode, bb1, bb2)
we will only have one branch prediction bit to work with. Thus
we require the existing branches to have probabilities that are
roughly similar. */
- /* ??? We should use bb->frequency to allow merging in infrequently
- executed blocks, but at the moment it is not available when
- cleanup_cfg is run. */
- if (match && !optimize_size)
+ if (match
+ && !optimize_size
+ && bb1->frequency > BB_FREQ_MAX / 1000
+ && bb2->frequency > BB_FREQ_MAX / 1000)
{
- rtx note1, note2;
- int prob1, prob2;
+ int prob2;
- note1 = find_reg_note (bb1->end, REG_BR_PROB, 0);
- note2 = find_reg_note (bb2->end, REG_BR_PROB, 0);
+ if (b1->dest == b2->dest)
+ prob2 = b2->probability;
+ else
+ /* Do not use f2 probability as f2 may be forwarded. */
+ prob2 = REG_BR_PROB_BASE - b2->probability;
- if (note1 && note2)
+ /* Fail if the difference in probabilities is
+ greater than 5%. */
+ if (abs (b1->probability - prob2) > REG_BR_PROB_BASE / 20)
{
- prob1 = INTVAL (XEXP (note1, 0));
- prob2 = INTVAL (XEXP (note2, 0));
- if (reverse)
- prob2 = REG_BR_PROB_BASE - prob2;
-
- /* Fail if the difference in probabilities is
- greater than 5%. */
- if (abs (prob1 - prob2) > REG_BR_PROB_BASE / 20)
- return false;
- }
+ if (rtl_dump_file)
+ fprintf (rtl_dump_file,
+ "Outcomes of branch in bb %i and %i differs to much (%i %i)\n",
+ bb1->index, bb2->index, b1->probability, prob2);
- else if (note1 || note2)
- return false;
+ return false;
+ }
}
if (rtl_dump_file && match)
@@ -1259,7 +1268,6 @@ try_crossjump_to_edge (mode, e1, e2)
edge s;
rtx last;
rtx label;
- rtx note;
/* Search backward through forwarder blocks. We don't need to worry
about multiple entry or chained forwarders, as they will be optimized
@@ -1356,8 +1364,14 @@ try_crossjump_to_edge (mode, e1, e2)
if (FORWARDER_BLOCK_P (s2->dest))
{
s2->dest->succ->count -= s2->count;
+ if (s2->dest->succ->count < 0)
+ s2->dest->succ->count = 0;
s2->dest->count -= s2->count;
s2->dest->frequency -= EDGE_FREQUENCY (s);
+ if (s2->dest->frequency < 0)
+ s2->dest->frequency = 0;
+ if (s2->dest->count < 0)
+ s2->dest->count = 0;
}
if (!redirect_to->frequency && !src1->frequency)
@@ -1369,9 +1383,7 @@ try_crossjump_to_edge (mode, e1, e2)
/ (redirect_to->frequency + src1->frequency));
}
- note = find_reg_note (redirect_to->end, REG_BR_PROB, 0);
- if (note)
- XEXP (note, 0) = GEN_INT (BRANCH_EDGE (redirect_to)->probability);
+ update_br_prob_note (redirect_to);
/* Edit SRC1 to go to REDIRECT_TO at NEWPOS1. */