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> 2008-09-10 Jan Hubicka <jh@suse.cz>
* value-prof.c (gimple_ic): Fix tuplification bug. * value-prof.c (gimple_ic): Fix tuplification bug.
......
...@@ -4799,6 +4799,7 @@ workaround_speculation (void) ...@@ -4799,6 +4799,7 @@ workaround_speculation (void)
rtx insn, next; rtx insn, next;
rtx last_condjump = NULL_RTX; rtx last_condjump = NULL_RTX;
int cycles_since_jump = INT_MAX; int cycles_since_jump = INT_MAX;
int delay_added = 0;
if (! ENABLE_WA_SPECULATIVE_LOADS && ! ENABLE_WA_SPECULATIVE_SYNCS) if (! ENABLE_WA_SPECULATIVE_LOADS && ! ENABLE_WA_SPECULATIVE_SYNCS)
return; return;
...@@ -4808,6 +4809,7 @@ workaround_speculation (void) ...@@ -4808,6 +4809,7 @@ workaround_speculation (void)
for (insn = get_insns (); insn; insn = next) for (insn = get_insns (); insn; insn = next)
{ {
rtx pat; rtx pat;
int delay_needed = 0;
next = find_next_insn_start (insn); next = find_next_insn_start (insn);
...@@ -4826,6 +4828,7 @@ workaround_speculation (void) ...@@ -4826,6 +4828,7 @@ workaround_speculation (void)
&& ! cbranch_predicted_taken_p (insn)) && ! cbranch_predicted_taken_p (insn))
{ {
last_condjump = insn; last_condjump = insn;
delay_added = 0;
cycles_since_jump = 0; cycles_since_jump = 0;
} }
else else
...@@ -4835,49 +4838,56 @@ workaround_speculation (void) ...@@ -4835,49 +4838,56 @@ workaround_speculation (void)
{ {
rtx load_insn = find_load (insn); rtx load_insn = find_load (insn);
enum attr_type type = type_for_anomaly (insn); enum attr_type type = type_for_anomaly (insn);
int delay_needed = 0;
if (cycles_since_jump < INT_MAX) if (cycles_since_jump < INT_MAX)
cycles_since_jump++; cycles_since_jump++;
if (load_insn && ENABLE_WA_SPECULATIVE_LOADS) if (load_insn && ENABLE_WA_SPECULATIVE_LOADS)
{ {
if (trapping_loads_p (load_insn)) if (trapping_loads_p (load_insn))
delay_needed = 3; delay_needed = 4;
} }
else if (type == TYPE_SYNC && ENABLE_WA_SPECULATIVE_SYNCS) else if (type == TYPE_SYNC && ENABLE_WA_SPECULATIVE_SYNCS)
delay_needed = 4; delay_needed = 3;
}
if (delay_needed > cycles_since_jump) if (delay_needed > cycles_since_jump
{ && (delay_needed - cycles_since_jump) > delay_added)
rtx pat; {
int num_clobbers; rtx pat1;
rtx *op = recog_data.operand; int num_clobbers;
rtx *op = recog_data.operand;
delay_needed -= cycles_since_jump; delay_needed -= cycles_since_jump;
extract_insn (last_condjump); extract_insn (last_condjump);
if (optimize_size) if (optimize_size)
{ {
pat = gen_cbranch_predicted_taken (op[0], op[1], op[2], pat1 = gen_cbranch_predicted_taken (op[0], op[1], op[2],
op[3]); op[3]);
cycles_since_jump = INT_MAX; cycles_since_jump = INT_MAX;
} }
else else
/* Do not adjust cycles_since_jump in this case, so that {
we'll increase the number of NOPs for a subsequent insn /* Do not adjust cycles_since_jump in this case, so that
if necessary. */ we'll increase the number of NOPs for a subsequent insn
pat = gen_cbranch_with_nops (op[0], op[1], op[2], op[3], if necessary. */
GEN_INT (delay_needed)); pat1 = gen_cbranch_with_nops (op[0], op[1], op[2], op[3],
PATTERN (last_condjump) = pat; GEN_INT (delay_needed));
INSN_CODE (last_condjump) = recog (pat, insn, &num_clobbers); 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 /* Second pass: for predicted-true branches, see if anything at the
branch destination needs extra nops. */ branch destination needs extra nops. */
if (! ENABLE_WA_SPECULATIVE_SYNCS)
return;
for (insn = get_insns (); insn; insn = NEXT_INSN (insn)) for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
{ {
int cycles_since_jump; int cycles_since_jump;
...@@ -4888,11 +4898,15 @@ workaround_speculation (void) ...@@ -4888,11 +4898,15 @@ workaround_speculation (void)
{ {
rtx target = JUMP_LABEL (insn); rtx target = JUMP_LABEL (insn);
rtx label = target; rtx label = target;
rtx next_tgt;
cycles_since_jump = 0; 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; rtx pat;
next_tgt = find_next_insn_start (target);
if (NOTE_P (target) || BARRIER_P (target) || LABEL_P (target)) if (NOTE_P (target) || BARRIER_P (target) || LABEL_P (target))
continue; continue;
...@@ -4904,12 +4918,18 @@ workaround_speculation (void) ...@@ -4904,12 +4918,18 @@ workaround_speculation (void)
if (INSN_P (target)) if (INSN_P (target))
{ {
rtx load_insn = find_load (target);
enum attr_type type = type_for_anomaly (target); enum attr_type type = type_for_anomaly (target);
int delay_needed = 0; int delay_needed = 0;
if (cycles_since_jump < INT_MAX) if (cycles_since_jump < INT_MAX)
cycles_since_jump++; 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; delay_needed = 2;
if (delay_needed > cycles_since_jump) if (delay_needed > cycles_since_jump)
......
...@@ -2588,7 +2588,7 @@ ...@@ -2588,7 +2588,7 @@
return ""; return "";
} }
[(set_attr "type" "brcc") [(set_attr "type" "brcc")
(set_attr "length" "6")]) (set_attr "length" "8")])
;; setcc insns. */ ;; setcc insns. */
(define_expand "seq" (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