aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>2004-11-02 17:59:46 +0000
committersteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>2004-11-02 17:59:46 +0000
commitea92ba8003d183cd5defac7bd67254e8ce04f18e (patch)
treece74266679e739b6b67a76a1605aab9369fb1ee5
parent8a7535caa354b48ba63ee772d6bc72505663b76c (diff)
* 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
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/cfgloop.h2
-rw-r--r--gcc/cse.c6
-rw-r--r--gcc/expr.h16
-rw-r--r--gcc/loop.c315
-rw-r--r--gcc/rtl.h11
-rw-r--r--gcc/rtlanal.c312
-rw-r--r--gcc/sched-deps.c8
8 files changed, 350 insertions, 336 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 00dc1027ea9..f6c687404fe 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,19 @@
+2004-11-02 Steven Bosscher <stevenb@suse.de>
+
+ * 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.
+
2004-11-02 Andrew Pinski <pinskia@physics.uc.edu>
PR tree-opt/16808
diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
index 61af71738a1..3261adb8e2d 100644
--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -144,7 +144,7 @@ struct loop
void *aux;
/* The following are currently used by loop.c but they are likely to
- disappear as loop.c is converted to use the CFG. */
+ disappear when loop.c is replaced and removed. */
/* The NOTE_INSN_LOOP_BEG. */
rtx start;
diff --git a/gcc/cse.c b/gcc/cse.c
index 2b21852544b..19e7f7145cf 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -6775,11 +6775,7 @@ cse_main (rtx f, int nregs, FILE *file)
/* Process a single basic block. FROM and TO and the limits of the basic
block. NEXT_BRANCH points to the branch path when following jumps or
- a null path when not following jumps.
-
- AROUND_LOOP is nonzero if we are to try to cse around to the start of a
- loop. This is true when we are being called for the last time on a
- block and this CSE pass is before loop.c. */
+ a null path when not following jumps. */
static rtx
cse_basic_block (rtx from, rtx to, struct branch_path *next_branch)
diff --git a/gcc/expr.h b/gcc/expr.h
index 54b04c2eb60..b5ec33f02bf 100644
--- a/gcc/expr.h
+++ b/gcc/expr.h
@@ -298,6 +298,9 @@ extern void emit_cmp_and_jump_insns (rtx, rtx, enum rtx_code, rtx,
/* Generate code to indirectly jump to a location given in the rtx LOC. */
extern void emit_indirect_jump (rtx);
+/* Generate a conditional trap instruction. */
+extern rtx gen_cond_trap (enum rtx_code, rtx, rtx, rtx);
+
#include "insn-config.h"
#ifdef HAVE_conditional_move
@@ -329,19 +332,6 @@ extern rtx emit_store_flag (rtx, enum rtx_code, rtx, rtx, enum machine_mode,
/* Like emit_store_flag, but always succeeds. */
extern rtx emit_store_flag_force (rtx, enum rtx_code, rtx, rtx,
enum machine_mode, int, int);
-
-/* Functions from loop.c: */
-
-/* Given an insn and condition, return a canonical description of
- the test being made. */
-extern rtx canonicalize_condition (rtx, rtx, int, rtx *, rtx, int, int);
-
-/* Given a JUMP_INSN, return a canonical description of the test
- being made. */
-extern rtx get_condition (rtx, rtx *, int, int);
-
-/* Generate a conditional trap instruction. */
-extern rtx gen_cond_trap (enum rtx_code, rtx, rtx, rtx);
/* Functions from builtins.c: */
extern rtx expand_builtin (tree, rtx, rtx, enum machine_mode, int);
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)
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 9b9bfcce6b7..67eea8b04b9 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -1657,6 +1657,15 @@ extern bool keep_with_call_p (rtx);
extern bool label_is_jump_target_p (rtx, rtx);
extern int insn_rtx_cost (rtx);
+/* Given an insn and condition, return a canonical description of
+ the test being made. */
+extern rtx canonicalize_condition (rtx, rtx, int, rtx *, rtx, int, int);
+
+/* Given a JUMP_INSN, return a canonical description of the test
+ being made. */
+extern rtx get_condition (rtx, rtx *, int, int);
+
+
/* flow.c */
extern rtx find_use_as_address (rtx, rtx, HOST_WIDE_INT);
@@ -2017,6 +2026,8 @@ extern void print_inline_rtx (FILE *, rtx, int);
/* In loop.c */
extern void init_loop (void);
extern void loop_optimize (rtx, FILE *, int);
+
+/* In bt-load.c */
extern void branch_target_load_optimize (bool);
/* In function.c */
diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c
index d61df8902bf..8ada3974c1b 100644
--- a/gcc/rtlanal.c
+++ b/gcc/rtlanal.c
@@ -4333,3 +4333,315 @@ insn_rtx_cost (rtx pat)
cost = rtx_cost (SET_SRC (set), SET);
return cost > 0 ? cost : COSTS_N_INSNS (1);
}
+
+/* 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);
+}
+
diff --git a/gcc/sched-deps.c b/gcc/sched-deps.c
index 1df1b47facb..ef53ea602aa 100644
--- a/gcc/sched-deps.c
+++ b/gcc/sched-deps.c
@@ -101,7 +101,7 @@ static void sched_analyze_1 (struct deps *, rtx, rtx);
static void sched_analyze_2 (struct deps *, rtx, rtx);
static void sched_analyze_insn (struct deps *, rtx, rtx, rtx);
-static rtx get_condition (rtx);
+static rtx sched_get_condition (rtx);
static int conditions_mutex_p (rtx, rtx);
/* Return nonzero if a load of the memory reference MEM can cause a trap. */
@@ -138,7 +138,7 @@ find_insn_list (rtx insn, rtx list)
/* Find the condition under which INSN is executed. */
static rtx
-get_condition (rtx insn)
+sched_get_condition (rtx insn)
{
rtx pat = PATTERN (insn);
rtx src;
@@ -218,8 +218,8 @@ add_dependence (rtx insn, rtx elem, enum reg_note dep_type)
be dependent. */
if (!CALL_P (insn) && !CALL_P (elem))
{
- cond1 = get_condition (insn);
- cond2 = get_condition (elem);
+ cond1 = sched_get_condition (insn);
+ cond2 = sched_get_condition (elem);
if (cond1 && cond2
&& conditions_mutex_p (cond1, cond2)
/* Make sure first instruction doesn't affect condition of second