+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.
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);
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;
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;
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
{
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);
/* 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. */
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;
}
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)
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
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)
/ (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. */
}
\f
/* 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)
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;
disp = op1;
}
else
- return FALSE;
+ return 0;
}
else if (GET_CODE (addr) == MULT)
{
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 */
if (scale_rtx)
{
if (GET_CODE (scale_rtx) != CONST_INT)
- return FALSE;
+ return 0;
scale = INTVAL (scale_rtx);
}
out->disp = disp;
out->scale = scale;
- return TRUE;
+ return retval;
}
\f
/* Return cost of the memory address x.
debug_rtx (addr);
}
- if (! ix86_decompose_address (addr, &parts))
+ if (ix86_decompose_address (addr, &parts) <= 0)
{
reason = "decomposition failed";
goto report_error;