diff options
-rw-r--r-- | gcc/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/expr.h | 2 | ||||
-rw-r--r-- | gcc/loop.c | 15 | ||||
-rw-r--r-- | gcc/predict.c | 97 | ||||
-rw-r--r-- | gcc/reorg.c | 29 |
5 files changed, 75 insertions, 79 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b87c030..9fcbff8 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2000-04-17 Richard Henderson <rth@cygnus.com> + + * loop.c (canonicalize_condition): Add WANT_REG argument. + Stop the search if we match it. + * expr.h (canonicalize_condition): Update decl. + * predict.c (expected_value_to_br_prob): Use it. Track last + expected value note. + (find_expected_value): Remove. + + * reorg.c (mostly_true_jump): Always use BR_PROB if present. + 2000-04-17 Zack Weinberg <zack@wolery.cumb.org> * aclocal.m4 (AM_GNU_GETTEXT): Don't AC_REQUIRE([AC_FUNC_MMAP]). @@ -894,7 +894,7 @@ extern rtx emit_store_flag_force PARAMS ((rtx, enum rtx_code, rtx, rtx, /* Given an insn and condition, return a canonical description of the test being made. */ -extern rtx canonicalize_condition PARAMS ((rtx, rtx, int, rtx *)); +extern rtx canonicalize_condition PARAMS ((rtx, rtx, int, rtx *, rtx)); /* Given a JUMP_INSN, return a canonical description of the test being made. */ @@ -9013,14 +9013,19 @@ update_reg_last_use (x, insn) If EARLIEST is non-zero, it is a pointer to a place where the earliest insn used in locating the condition was found. If a replacement test of the condition is desired, it should be placed in front of that - insn and we will be sure that the inputs are still valid. */ + insn and we will be sure that the inputs are still valid. + + If WANT_REG is non-zero, we wish the condition to be relative to that + register, if possible. Therefore, do not canonicalize the condition + further. */ rtx -canonicalize_condition (insn, cond, reverse, earliest) +canonicalize_condition (insn, cond, reverse, earliest, want_reg) rtx insn; rtx cond; int reverse; rtx *earliest; + rtx want_reg; { enum rtx_code code; rtx prev = insn; @@ -9050,7 +9055,9 @@ canonicalize_condition (insn, cond, reverse, earliest) the same tests as a function of STORE_FLAG_VALUE as find_comparison_args in cse.c */ - while (GET_RTX_CLASS (code) == '<' && op1 == CONST0_RTX (GET_MODE (op0))) + while (GET_RTX_CLASS (code) == '<' + && op1 == CONST0_RTX (GET_MODE (op0)) + && op0 != want_reg) { /* Set non-zero when we find something of interest. */ rtx x = 0; @@ -9291,7 +9298,7 @@ get_condition (jump, earliest) = GET_CODE (XEXP (SET_SRC (PATTERN (jump)), 2)) == LABEL_REF && XEXP (XEXP (SET_SRC (PATTERN (jump)), 2), 0) == JUMP_LABEL (jump); - return canonicalize_condition (jump, cond, reverse, earliest); + return canonicalize_condition (jump, cond, reverse, earliest, NULL_RTX); } /* Similar to above routine, except that we also put an invariant last diff --git a/gcc/predict.c b/gcc/predict.c index 767afdc..958dbf9 100644 --- a/gcc/predict.c +++ b/gcc/predict.c @@ -190,29 +190,46 @@ static rtx find_expected_value PARAMS ((rtx, rtx)); void expected_value_to_br_prob () { - rtx insn, cond, earliest, ev; + rtx insn, cond, ev = NULL_RTX, ev_reg; for (insn = get_insns (); insn ; insn = NEXT_INSN (insn)) { - /* Look for simple conditional branches. */ - if (GET_CODE (insn) != JUMP_INSN) - continue; - if (! condjump_p (insn) || simplejump_p (insn)) - continue; + switch (GET_CODE (insn)) + { + case NOTE: + /* Look for expected value notes. */ + if (NOTE_LINE_NUMBER (insn) == NOTE_INSN_EXPECTED_VALUE) + { + ev = NOTE_EXPECTED_VALUE (insn); + ev_reg = XEXP (ev, 0); + } + continue; + + case CODE_LABEL: + /* Never propagate across labels. */ + ev = NULL_RTX; + continue; - /* Collect the branch condition. Some machines can branch on - user values directly, others need a compare instruction. If - the branch condition involves a MODE_INT register, try that - expression first. Otherwise use get_condition. */ + default: + /* Look for insns that clobber the EV register. */ + if (ev && reg_set_p (ev_reg, insn)) + ev = NULL_RTX; + continue; + + case JUMP_INSN: + /* Look for simple conditional branches. If we havn't got an + expected value yet, no point going further. */ + if (GET_CODE (insn) != JUMP_INSN || ev == NULL_RTX) + continue; + if (! condjump_p (insn) || simplejump_p (insn)) + continue; + break; + } + + /* Collect the branch condition, hopefully relative to EV_REG. */ cond = XEXP (SET_SRC (PATTERN (insn)), 0); - if (GET_RTX_CLASS (GET_CODE (cond)) != '<') - abort (); - if (GET_CODE (XEXP (cond, 0)) == REG - && GET_MODE_CLASS (GET_MODE (XEXP (cond, 0))) == MODE_INT - && (ev = find_expected_value (cond, insn)) != NULL_RTX) - ; - else if ((cond = get_condition (insn, &earliest)) == NULL_RTX - || (ev = find_expected_value (cond, earliest)) == NULL_RTX) + cond = canonicalize_condition (insn, cond, 0, NULL, ev_reg); + if (! cond || XEXP (cond, 0) != ev_reg) continue; /* Substitute and simplify. Given that the expression we're @@ -223,48 +240,10 @@ expected_value_to_br_prob () cond = simplify_rtx (cond); /* Turn the condition into a scaled branch probability. */ - if (cond == const0_rtx) - cond = const1_rtx; - else if (cond == const1_rtx) - cond = GEN_INT (REG_BR_PROB_BASE - 1); - else + if (cond == const1_rtx) + cond = GEN_INT (REG_BR_PROB_BASE); + else if (cond != const0_rtx) abort (); REG_NOTES (insn) = alloc_EXPR_LIST (REG_BR_PROB, cond, REG_NOTES (insn)); } } - -/* Search backwards for a NOTE_INSN_EXPECTED_VALUE note with a register - that matches the condition. */ - -static rtx -find_expected_value (cond, earliest) - rtx cond, earliest; -{ - rtx insn, reg = XEXP (cond, 0); - int timeout; - - /* The condition should be (op (reg) (const_int)), otherwise we - won't be able to intuit anything about it. */ - if (GET_CODE (reg) != REG - || GET_CODE (XEXP (cond, 1)) != CONST_INT - || GET_MODE_CLASS (GET_MODE (reg)) != MODE_INT) - return NULL_RTX; - - /* Assuming the user wrote something like `if (__builtin_expect(...))', - we shouldn't have to search too far. Also stop if we reach a code - label or if REG is modified. */ - for (insn = earliest, timeout = 10; - insn && timeout > 0; - insn = PREV_INSN (insn), --timeout) - { - if (GET_CODE (insn) == NOTE - && NOTE_LINE_NUMBER (insn) == NOTE_INSN_EXPECTED_VALUE - && XEXP (NOTE_EXPECTED_VALUE (insn), 0) == reg) - return NOTE_EXPECTED_VALUE (insn); - - if (GET_CODE (insn) == CODE_LABEL || reg_set_p (reg, insn)) - break; - } - - return NULL_RTX; -} diff --git a/gcc/reorg.c b/gcc/reorg.c index 379def7..cce40c0 100644 --- a/gcc/reorg.c +++ b/gcc/reorg.c @@ -900,30 +900,29 @@ mostly_true_jump (jump_insn, condition) rtx jump_insn, condition; { rtx target_label = JUMP_LABEL (jump_insn); - rtx insn; + rtx insn, note; int rare_dest = rare_destination (target_label); int rare_fallthrough = rare_destination (NEXT_INSN (jump_insn)); /* If branch probabilities are available, then use that number since it always gives a correct answer. */ - if (flag_branch_probabilities) + note = find_reg_note (jump_insn, REG_BR_PROB, 0); + if (note) { - rtx note = find_reg_note (jump_insn, REG_BR_PROB, 0); - if (note) - { - int prob = XINT (note, 0); + int prob = INTVAL (XEXP (note, 0)); - if (prob >= REG_BR_PROB_BASE * 9 / 10) - return 2; - else if (prob >= REG_BR_PROB_BASE / 2) - return 1; - else if (prob >= REG_BR_PROB_BASE / 10) - return 0; - else - return -1; - } + if (prob >= REG_BR_PROB_BASE * 9 / 10) + return 2; + else if (prob >= REG_BR_PROB_BASE / 2) + return 1; + else if (prob >= REG_BR_PROB_BASE / 10) + return 0; + else + return -1; } + /* ??? Ought to use estimate_probability instead. */ + /* If this is a branch outside a loop, it is highly unlikely. */ if (GET_CODE (PATTERN (jump_insn)) == SET && GET_CODE (SET_SRC (PATTERN (jump_insn))) == IF_THEN_ELSE |