From cedee41af78b8d6739a2eca82fa466ccebca610a Mon Sep 17 00:00:00 2001 From: bernds Date: Wed, 10 Sep 2008 13:28:34 +0000 Subject: [PATCH] * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@140230 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 10 +++++++ gcc/config/bfin/bfin.c | 78 +++++++++++++++++++++++++++++++------------------ gcc/config/bfin/bfin.md | 2 +- 3 files changed, 60 insertions(+), 30 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e6ede43f21a..4d68e2248de 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2008-09-10 Bernd Schmidt + + * 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 * value-prof.c (gimple_ic): Fix tuplification bug. diff --git a/gcc/config/bfin/bfin.c b/gcc/config/bfin/bfin.c index 7ff1379f2c9..9af7fab73fe 100644 --- a/gcc/config/bfin/bfin.c +++ b/gcc/config/bfin/bfin.c @@ -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) diff --git a/gcc/config/bfin/bfin.md b/gcc/config/bfin/bfin.md index 1388266400b..bd2d208a334 100644 --- a/gcc/config/bfin/bfin.md +++ b/gcc/config/bfin/bfin.md @@ -2588,7 +2588,7 @@ return ""; } [(set_attr "type" "brcc") - (set_attr "length" "6")]) + (set_attr "length" "8")]) ;; setcc insns. */ (define_expand "seq" -- 2.11.4.GIT