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
This commit is contained in:
Jan Hubicka 2002-01-10 21:37:43 +01:00 committed by Jan Hubicka
parent a01da83b22
commit b446e5a266
8 changed files with 88 additions and 40 deletions

View File

@ -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.

View File

@ -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 */

View File

@ -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;
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);
/* Fail if the difference in probabilities is
greater than 5%. */
if (abs (prob1 - prob2) > REG_BR_PROB_BASE / 20)
return false;
return false;
}
else if (note1 || note2)
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. */

View File

@ -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;
}
}

View File

@ -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.

View File

@ -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;

View File

@ -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

View File

@ -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. */