diff options
author | steven <steven@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-11-02 17:59:46 +0000 |
---|---|---|
committer | steven <steven@138bc75d-0d04-0410-961f-82ee72b054a4> | 2004-11-02 17:59:46 +0000 |
commit | ea92ba8003d183cd5defac7bd67254e8ce04f18e (patch) | |
tree | ce74266679e739b6b67a76a1605aab9369fb1ee5 /gcc/loop.c | |
parent | 8a7535caa354b48ba63ee772d6bc72505663b76c (diff) | |
download | gcc-ea92ba8003d183cd5defac7bd67254e8ce04f18e.tar.gz |
* cfgloop.h (struct loop): Update comment.
* cse.c (cse_main): Remove obsolete comment.
* expr.h (gen_cond_trap): Move prototype under functions provided
by optabs.c.
(canonicalize_condition, get_condition): Move to...
* rtl.h (canonicalize_condition, get_condition): ...here.
(branch_target_load_optimize): Add comment that this function is
in bt-load.c.
* loop.c (canonicalize_condition, get_condition): Move to...
* rtlanal.c (canonicalize_condition, get_condition): ...here.
* sched-deps.c (get_condition): Rename to sched_get_condition.
(add_dependence): Update this caller.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@89995 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/loop.c')
-rw-r--r-- | gcc/loop.c | 315 |
1 files changed, 2 insertions, 313 deletions
diff --git a/gcc/loop.c b/gcc/loop.c index a573616d0e1..08b85293b8a 100644 --- a/gcc/loop.c +++ b/gcc/loop.c @@ -10438,319 +10438,8 @@ update_reg_last_use (rtx x, rtx insn) } } -/* Given an insn INSN and condition COND, return the condition in a - canonical form to simplify testing by callers. Specifically: - - (1) The code will always be a comparison operation (EQ, NE, GT, etc.). - (2) Both operands will be machine operands; (cc0) will have been replaced. - (3) If an operand is a constant, it will be the second operand. - (4) (LE x const) will be replaced with (LT x <const+1>) and similarly - for GE, GEU, and LEU. - - If the condition cannot be understood, or is an inequality floating-point - comparison which needs to be reversed, 0 will be returned. - - If REVERSE is nonzero, then reverse the condition prior to canonizing it. - - If EARLIEST is nonzero, 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. - - If WANT_REG is nonzero, we wish the condition to be relative to that - register, if possible. Therefore, do not canonicalize the condition - further. If ALLOW_CC_MODE is nonzero, allow the condition returned - to be a compare to a CC mode register. - - If VALID_AT_INSN_P, the condition must be valid at both *EARLIEST - and at INSN. */ - -rtx -canonicalize_condition (rtx insn, rtx cond, int reverse, rtx *earliest, - rtx want_reg, int allow_cc_mode, int valid_at_insn_p) -{ - enum rtx_code code; - rtx prev = insn; - rtx set; - rtx tem; - rtx op0, op1; - int reverse_code = 0; - enum machine_mode mode; - - code = GET_CODE (cond); - mode = GET_MODE (cond); - op0 = XEXP (cond, 0); - op1 = XEXP (cond, 1); - - if (reverse) - code = reversed_comparison_code (cond, insn); - if (code == UNKNOWN) - return 0; - - if (earliest) - *earliest = insn; - - /* If we are comparing a register with zero, see if the register is set - in the previous insn to a COMPARE or a comparison operation. Perform - the same tests as a function of STORE_FLAG_VALUE as find_comparison_args - in cse.c */ - - while ((GET_RTX_CLASS (code) == RTX_COMPARE - || GET_RTX_CLASS (code) == RTX_COMM_COMPARE) - && op1 == CONST0_RTX (GET_MODE (op0)) - && op0 != want_reg) - { - /* Set nonzero when we find something of interest. */ - rtx x = 0; - -#ifdef HAVE_cc0 - /* If comparison with cc0, import actual comparison from compare - insn. */ - if (op0 == cc0_rtx) - { - if ((prev = prev_nonnote_insn (prev)) == 0 - || !NONJUMP_INSN_P (prev) - || (set = single_set (prev)) == 0 - || SET_DEST (set) != cc0_rtx) - return 0; - - op0 = SET_SRC (set); - op1 = CONST0_RTX (GET_MODE (op0)); - if (earliest) - *earliest = prev; - } -#endif - - /* If this is a COMPARE, pick up the two things being compared. */ - if (GET_CODE (op0) == COMPARE) - { - op1 = XEXP (op0, 1); - op0 = XEXP (op0, 0); - continue; - } - else if (!REG_P (op0)) - break; - - /* Go back to the previous insn. Stop if it is not an INSN. We also - stop if it isn't a single set or if it has a REG_INC note because - we don't want to bother dealing with it. */ - - if ((prev = prev_nonnote_insn (prev)) == 0 - || !NONJUMP_INSN_P (prev) - || FIND_REG_INC_NOTE (prev, NULL_RTX)) - break; - - set = set_of (op0, prev); - - if (set - && (GET_CODE (set) != SET - || !rtx_equal_p (SET_DEST (set), op0))) - break; - - /* If this is setting OP0, get what it sets it to if it looks - relevant. */ - if (set) - { - enum machine_mode inner_mode = GET_MODE (SET_DEST (set)); -#ifdef FLOAT_STORE_FLAG_VALUE - REAL_VALUE_TYPE fsfv; -#endif - - /* ??? We may not combine comparisons done in a CCmode with - comparisons not done in a CCmode. This is to aid targets - like Alpha that have an IEEE compliant EQ instruction, and - a non-IEEE compliant BEQ instruction. The use of CCmode is - actually artificial, simply to prevent the combination, but - should not affect other platforms. - - However, we must allow VOIDmode comparisons to match either - CCmode or non-CCmode comparison, because some ports have - modeless comparisons inside branch patterns. - - ??? This mode check should perhaps look more like the mode check - in simplify_comparison in combine. */ - - if ((GET_CODE (SET_SRC (set)) == COMPARE - || (((code == NE - || (code == LT - && GET_MODE_CLASS (inner_mode) == MODE_INT - && (GET_MODE_BITSIZE (inner_mode) - <= HOST_BITS_PER_WIDE_INT) - && (STORE_FLAG_VALUE - & ((HOST_WIDE_INT) 1 - << (GET_MODE_BITSIZE (inner_mode) - 1)))) -#ifdef FLOAT_STORE_FLAG_VALUE - || (code == LT - && GET_MODE_CLASS (inner_mode) == MODE_FLOAT - && (fsfv = FLOAT_STORE_FLAG_VALUE (inner_mode), - REAL_VALUE_NEGATIVE (fsfv))) -#endif - )) - && COMPARISON_P (SET_SRC (set)))) - && (((GET_MODE_CLASS (mode) == MODE_CC) - == (GET_MODE_CLASS (inner_mode) == MODE_CC)) - || mode == VOIDmode || inner_mode == VOIDmode)) - x = SET_SRC (set); - else if (((code == EQ - || (code == GE - && (GET_MODE_BITSIZE (inner_mode) - <= HOST_BITS_PER_WIDE_INT) - && GET_MODE_CLASS (inner_mode) == MODE_INT - && (STORE_FLAG_VALUE - & ((HOST_WIDE_INT) 1 - << (GET_MODE_BITSIZE (inner_mode) - 1)))) -#ifdef FLOAT_STORE_FLAG_VALUE - || (code == GE - && GET_MODE_CLASS (inner_mode) == MODE_FLOAT - && (fsfv = FLOAT_STORE_FLAG_VALUE (inner_mode), - REAL_VALUE_NEGATIVE (fsfv))) -#endif - )) - && COMPARISON_P (SET_SRC (set)) - && (((GET_MODE_CLASS (mode) == MODE_CC) - == (GET_MODE_CLASS (inner_mode) == MODE_CC)) - || mode == VOIDmode || inner_mode == VOIDmode)) - - { - reverse_code = 1; - x = SET_SRC (set); - } - else - break; - } - - else if (reg_set_p (op0, prev)) - /* If this sets OP0, but not directly, we have to give up. */ - break; - - if (x) - { - /* If the caller is expecting the condition to be valid at INSN, - make sure X doesn't change before INSN. */ - if (valid_at_insn_p) - if (modified_in_p (x, prev) || modified_between_p (x, prev, insn)) - break; - if (COMPARISON_P (x)) - code = GET_CODE (x); - if (reverse_code) - { - code = reversed_comparison_code (x, prev); - if (code == UNKNOWN) - return 0; - reverse_code = 0; - } - - op0 = XEXP (x, 0), op1 = XEXP (x, 1); - if (earliest) - *earliest = prev; - } - } - - /* If constant is first, put it last. */ - if (CONSTANT_P (op0)) - code = swap_condition (code), tem = op0, op0 = op1, op1 = tem; - - /* If OP0 is the result of a comparison, we weren't able to find what - was really being compared, so fail. */ - if (!allow_cc_mode - && GET_MODE_CLASS (GET_MODE (op0)) == MODE_CC) - return 0; - - /* Canonicalize any ordered comparison with integers involving equality - if we can do computations in the relevant mode and we do not - overflow. */ - - if (GET_MODE_CLASS (GET_MODE (op0)) != MODE_CC - && GET_CODE (op1) == CONST_INT - && GET_MODE (op0) != VOIDmode - && GET_MODE_BITSIZE (GET_MODE (op0)) <= HOST_BITS_PER_WIDE_INT) - { - HOST_WIDE_INT const_val = INTVAL (op1); - unsigned HOST_WIDE_INT uconst_val = const_val; - unsigned HOST_WIDE_INT max_val - = (unsigned HOST_WIDE_INT) GET_MODE_MASK (GET_MODE (op0)); - - switch (code) - { - case LE: - if ((unsigned HOST_WIDE_INT) const_val != max_val >> 1) - code = LT, op1 = gen_int_mode (const_val + 1, GET_MODE (op0)); - break; - - /* When cross-compiling, const_val might be sign-extended from - BITS_PER_WORD to HOST_BITS_PER_WIDE_INT */ - case GE: - if ((HOST_WIDE_INT) (const_val & max_val) - != (((HOST_WIDE_INT) 1 - << (GET_MODE_BITSIZE (GET_MODE (op0)) - 1)))) - code = GT, op1 = gen_int_mode (const_val - 1, GET_MODE (op0)); - break; - - case LEU: - if (uconst_val < max_val) - code = LTU, op1 = gen_int_mode (uconst_val + 1, GET_MODE (op0)); - break; - - case GEU: - if (uconst_val != 0) - code = GTU, op1 = gen_int_mode (uconst_val - 1, GET_MODE (op0)); - break; - - default: - break; - } - } - - /* Never return CC0; return zero instead. */ - if (CC0_P (op0)) - return 0; - - return gen_rtx_fmt_ee (code, VOIDmode, op0, op1); -} - -/* Given a jump insn JUMP, return the condition that will cause it to branch - to its JUMP_LABEL. If the condition cannot be understood, or is an - inequality floating-point comparison which needs to be reversed, 0 will - be returned. - - If EARLIEST is nonzero, 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. If EARLIEST - is null, the returned condition will be valid at INSN. - - If ALLOW_CC_MODE is nonzero, allow the condition returned to be a - compare CC mode register. - - VALID_AT_INSN_P is the same as for canonicalize_condition. */ - -rtx -get_condition (rtx jump, rtx *earliest, int allow_cc_mode, int valid_at_insn_p) -{ - rtx cond; - int reverse; - rtx set; - - /* If this is not a standard conditional jump, we can't parse it. */ - if (!JUMP_P (jump) - || ! any_condjump_p (jump)) - return 0; - set = pc_set (jump); - - cond = XEXP (SET_SRC (set), 0); - - /* If this branches to JUMP_LABEL when the condition is false, reverse - the condition. */ - reverse - = GET_CODE (XEXP (SET_SRC (set), 2)) == LABEL_REF - && XEXP (XEXP (SET_SRC (set), 2), 0) == JUMP_LABEL (jump); - - return canonicalize_condition (jump, cond, reverse, earliest, NULL_RTX, - allow_cc_mode, valid_at_insn_p); -} - -/* Similar to above routine, except that we also put an invariant last - unless both operands are invariants. */ +/* Similar to rtlanal.c:get_condition, except that we also put an + invariant last unless both operands are invariants. */ static rtx get_condition_for_loop (const struct loop *loop, rtx x) |