aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2002-01-10 21:37:43 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2002-01-10 20:37:43 +0000
commitb446e5a266b232e701fd4a9a7bd48f0aab8fc2c5 (patch)
tree19471938dee687744538e8ca3cc2eb35fdb507c2 /gcc
parenta01da83b2291abdccd8abe66eff604c50e3c71f0 (diff)
downloadgcc-b446e5a266b232e701fd4a9a7bd48f0aab8fc2c5.zip
gcc-b446e5a266b232e701fd4a9a7bd48f0aab8fc2c5.tar.gz
gcc-b446e5a266b232e701fd4a9a7bd48f0aab8fc2c5.tar.bz2
basic-block.h (update_br_prob_note): Declare.
* 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. From-SVN: r48750
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog18
-rw-r--r--gcc/basic-block.h1
-rw-r--r--gcc/cfgcleanup.c68
-rw-r--r--gcc/cfglayout.c2
-rw-r--r--gcc/cfgrtl.c13
-rw-r--r--gcc/config/i386/i386.c20
-rw-r--r--gcc/gcse.c7
-rw-r--r--gcc/ifcvt.c1
8 files changed, 89 insertions, 41 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 8935aff..ee9b1d2 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,21 @@
+Thu Jan 10 22:35:54 CET 2002 Jan Hubicka <jh@suse.cz>
+
+ * 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.
+
2002-01-10 Kazu Hirata <kazu@hxi.com>
* toplev.c: Fix formatting.
diff --git a/gcc/basic-block.h b/gcc/basic-block.h
index 338763f..29df84a 100644
--- a/gcc/basic-block.h
+++ b/gcc/basic-block.h
@@ -687,6 +687,7 @@ extern conflict_graph conflict_graph_compute
PARAMS ((regset,
partition));
extern bool mark_dfs_back_edges PARAMS ((void));
+extern void update_br_prob_note PARAMS ((basic_block));
/* In dominance.c */
diff --git a/gcc/cfgcleanup.c b/gcc/cfgcleanup.c
index 0af87b4..5015c81 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. */
diff --git a/gcc/cfglayout.c b/gcc/cfglayout.c
index ef5206b..329e9f8 100644
--- a/gcc/cfglayout.c
+++ b/gcc/cfglayout.c
@@ -412,6 +412,7 @@ fixup_reorder_chain ()
{
e_fall->flags &= ~EDGE_FALLTHRU;
e_taken->flags |= EDGE_FALLTHRU;
+ update_br_prob_note (bb);
e = e_fall, e_fall = e_taken, e_taken = e;
}
}
@@ -423,6 +424,7 @@ fixup_reorder_chain ()
{
e_fall->flags &= ~EDGE_FALLTHRU;
e_taken->flags |= EDGE_FALLTHRU;
+ update_br_prob_note (bb);
continue;
}
}
diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c
index 56b3bf2..a4f25f8 100644
--- a/gcc/cfgrtl.c
+++ b/gcc/cfgrtl.c
@@ -1510,6 +1510,19 @@ print_rtl_with_bb (outf, rtx_first)
}
}
+void
+update_br_prob_note (bb)
+ basic_block bb;
+{
+ rtx note;
+ if (GET_CODE (bb->end) != JUMP_INSN)
+ return;
+ note = find_reg_note (bb->end, REG_BR_PROB, NULL_RTX);
+ if (!note || INTVAL (XEXP (note, 0)) == BRANCH_EDGE (bb)->probability)
+ return;
+ XEXP (note, 0) = GEN_INT (BRANCH_EDGE (bb)->probability);
+}
+
/* Verify the CFG consistency. This function check some CFG invariants and
aborts when something is wrong. Hope that this function will help to
convert many optimization passes to preserve CFG consistent.
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 91ccb8c..4d04780 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -4349,8 +4349,10 @@ ix86_expand_epilogue (style)
}
/* Extract the parts of an RTL expression that is a valid memory address
- for an instruction. Return false if the structure of the address is
- grossly off. */
+ for an instruction. Return 0 if the structure of the address is
+ grossly off. Return -1 if the address contains ASHIFT, so it is not
+ strictly valid, but still used for computing length of lea instruction.
+ */
static int
ix86_decompose_address (addr, out)
@@ -4362,6 +4364,7 @@ ix86_decompose_address (addr, out)
rtx disp = NULL_RTX;
HOST_WIDE_INT scale = 1;
rtx scale_rtx = NULL_RTX;
+ int retval = 1;
if (GET_CODE (addr) == REG || GET_CODE (addr) == SUBREG)
base = addr;
@@ -4402,7 +4405,7 @@ ix86_decompose_address (addr, out)
disp = op1;
}
else
- return FALSE;
+ return 0;
}
else if (GET_CODE (addr) == MULT)
{
@@ -4417,11 +4420,12 @@ ix86_decompose_address (addr, out)
index = XEXP (addr, 0);
tmp = XEXP (addr, 1);
if (GET_CODE (tmp) != CONST_INT)
- return FALSE;
+ return 0;
scale = INTVAL (tmp);
if ((unsigned HOST_WIDE_INT) scale > 3)
- return FALSE;
+ return 0;
scale = 1 << scale;
+ retval = -1;
}
else
disp = addr; /* displacement */
@@ -4430,7 +4434,7 @@ ix86_decompose_address (addr, out)
if (scale_rtx)
{
if (GET_CODE (scale_rtx) != CONST_INT)
- return FALSE;
+ return 0;
scale = INTVAL (scale_rtx);
}
@@ -4471,7 +4475,7 @@ ix86_decompose_address (addr, out)
out->disp = disp;
out->scale = scale;
- return TRUE;
+ return retval;
}
/* Return cost of the memory address x.
@@ -4684,7 +4688,7 @@ legitimate_address_p (mode, addr, strict)
debug_rtx (addr);
}
- if (! ix86_decompose_address (addr, &parts))
+ if (ix86_decompose_address (addr, &parts) <= 0)
{
reason = "decomposition failed";
goto report_error;
diff --git a/gcc/gcse.c b/gcc/gcse.c
index e8361fc..af3b29e 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -2204,9 +2204,7 @@ hash_scan_set (pat, insn, set_p)
&& REGNO (src) >= FIRST_PSEUDO_REGISTER
&& can_copy_p [GET_MODE (dest)]
&& REGNO (src) != regno)
- || GET_CODE (src) == CONST_INT
- || GET_CODE (src) == SYMBOL_REF
- || GET_CODE (src) == CONST_DOUBLE)
+ || CONSTANT_P (src))
/* A copy is not available if its src or dest is subsequently
modified. Here we want to search from INSN+1 on, but
oprs_available_p searches from INSN on. */
@@ -4155,8 +4153,7 @@ cprop_insn (bb, insn, alter_jumps)
src = SET_SRC (pat);
/* Constant propagation. */
- if (GET_CODE (src) == CONST_INT || GET_CODE (src) == CONST_DOUBLE
- || GET_CODE (src) == SYMBOL_REF)
+ if (CONSTANT_P (src))
{
/* Handle normal insns first. */
if (GET_CODE (insn) == INSN
diff --git a/gcc/ifcvt.c b/gcc/ifcvt.c
index f6a07e9..2939de4 100644
--- a/gcc/ifcvt.c
+++ b/gcc/ifcvt.c
@@ -2657,6 +2657,7 @@ dead_or_predicable (test_bb, merge_bb, other_bb, new_dest, reversep)
probability = BRANCH_EDGE (test_bb)->probability;
BRANCH_EDGE (test_bb)->probability = FALLTHRU_EDGE (test_bb)->probability;
FALLTHRU_EDGE (test_bb)->probability = probability;
+ update_br_prob_note (test_bb);
}
/* Move the insns out of MERGE_BB to before the branch. */