Commit 90cbba02 by Bernd Schmidt Committed by Bernd Schmidt

bfin.c (workaround_speculation): Correct algorithm to not lose track of the number of NOPs needed.

	* config/bfin/bfin.c (workaround_speculation): Correct algorithm to
	not lose track of the number of NOPs needed.  Number of NOPs needed
	for sync vs. loads workaround was switched; corrected.  Run second
	pass for all workarounds.  No NOPs needed after call insns.  Change
	second pass to use find_next_insn_start and find_load helpers in order
	to properly detect parallel insns.
	* config/bfin/bfin.md (cbranch_with_nops): Increase length.

From-SVN: r140230
parent 06c7153f
2008-09-10 Bernd Schmidt <bernd.schmidt@analog.com>
* config/bfin/bfin.c (workaround_speculation): Correct algorithm to
not lose track of the number of NOPs needed. Number of NOPs needed
for sync vs. loads workaround was switched; corrected. Run second
pass for all workarounds. No NOPs needed after call insns. Change
second pass to use find_next_insn_start and find_load helpers in order
to properly detect parallel insns.
* config/bfin/bfin.md (cbranch_with_nops): Increase length.
2008-09-10 Jan Hubicka <jh@suse.cz>
* value-prof.c (gimple_ic): Fix tuplification bug.
......
......@@ -4799,6 +4799,7 @@ workaround_speculation (void)
rtx insn, next;
rtx last_condjump = NULL_RTX;
int cycles_since_jump = INT_MAX;
int delay_added = 0;
if (! ENABLE_WA_SPECULATIVE_LOADS && ! ENABLE_WA_SPECULATIVE_SYNCS)
return;
......@@ -4808,6 +4809,7 @@ workaround_speculation (void)
for (insn = get_insns (); insn; insn = next)
{
rtx pat;
int delay_needed = 0;
next = find_next_insn_start (insn);
......@@ -4826,6 +4828,7 @@ workaround_speculation (void)
&& ! cbranch_predicted_taken_p (insn))
{
last_condjump = insn;
delay_added = 0;
cycles_since_jump = 0;
}
else
......@@ -4835,49 +4838,56 @@ workaround_speculation (void)
{
rtx load_insn = find_load (insn);
enum attr_type type = type_for_anomaly (insn);
int delay_needed = 0;
if (cycles_since_jump < INT_MAX)
cycles_since_jump++;
if (load_insn && ENABLE_WA_SPECULATIVE_LOADS)
{
if (trapping_loads_p (load_insn))
delay_needed = 3;
delay_needed = 4;
}
else if (type == TYPE_SYNC && ENABLE_WA_SPECULATIVE_SYNCS)
delay_needed = 4;
delay_needed = 3;
}
if (delay_needed > cycles_since_jump)
{
rtx pat;
int num_clobbers;
rtx *op = recog_data.operand;
if (delay_needed > cycles_since_jump
&& (delay_needed - cycles_since_jump) > delay_added)
{
rtx pat1;
int num_clobbers;
rtx *op = recog_data.operand;
delay_needed -= cycles_since_jump;
delay_needed -= cycles_since_jump;
extract_insn (last_condjump);
if (optimize_size)
{
pat = gen_cbranch_predicted_taken (op[0], op[1], op[2],
op[3]);
cycles_since_jump = INT_MAX;
}
else
/* Do not adjust cycles_since_jump in this case, so that
we'll increase the number of NOPs for a subsequent insn
if necessary. */
pat = gen_cbranch_with_nops (op[0], op[1], op[2], op[3],
GEN_INT (delay_needed));
PATTERN (last_condjump) = pat;
INSN_CODE (last_condjump) = recog (pat, insn, &num_clobbers);
extract_insn (last_condjump);
if (optimize_size)
{
pat1 = gen_cbranch_predicted_taken (op[0], op[1], op[2],
op[3]);
cycles_since_jump = INT_MAX;
}
else
{
/* Do not adjust cycles_since_jump in this case, so that
we'll increase the number of NOPs for a subsequent insn
if necessary. */
pat1 = gen_cbranch_with_nops (op[0], op[1], op[2], op[3],
GEN_INT (delay_needed));
delay_added = delay_needed;
}
PATTERN (last_condjump) = pat1;
INSN_CODE (last_condjump) = recog (pat1, insn, &num_clobbers);
}
if (CALL_P (insn))
{
cycles_since_jump = INT_MAX;
delay_added = 0;
}
}
/* Second pass: for predicted-true branches, see if anything at the
branch destination needs extra nops. */
if (! ENABLE_WA_SPECULATIVE_SYNCS)
return;
for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
{
int cycles_since_jump;
......@@ -4888,11 +4898,15 @@ workaround_speculation (void)
{
rtx target = JUMP_LABEL (insn);
rtx label = target;
rtx next_tgt;
cycles_since_jump = 0;
for (; target && cycles_since_jump < 3; target = NEXT_INSN (target))
for (; target && cycles_since_jump < 3; target = next_tgt)
{
rtx pat;
next_tgt = find_next_insn_start (target);
if (NOTE_P (target) || BARRIER_P (target) || LABEL_P (target))
continue;
......@@ -4904,12 +4918,18 @@ workaround_speculation (void)
if (INSN_P (target))
{
rtx load_insn = find_load (target);
enum attr_type type = type_for_anomaly (target);
int delay_needed = 0;
if (cycles_since_jump < INT_MAX)
cycles_since_jump++;
if (type == TYPE_SYNC && ENABLE_WA_SPECULATIVE_SYNCS)
if (load_insn && ENABLE_WA_SPECULATIVE_LOADS)
{
if (trapping_loads_p (load_insn))
delay_needed = 2;
}
else if (type == TYPE_SYNC && ENABLE_WA_SPECULATIVE_SYNCS)
delay_needed = 2;
if (delay_needed > cycles_since_jump)
......
......@@ -2588,7 +2588,7 @@
return "";
}
[(set_attr "type" "brcc")
(set_attr "length" "6")])
(set_attr "length" "8")])
;; setcc insns. */
(define_expand "seq"
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment