aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBin Cheng <bin.cheng@arm.com>2012-11-27 09:55:33 +0000
committerBin Cheng <amker@gcc.gnu.org>2012-11-27 09:55:33 +0000
commite2b5ad1ea6fac601ca5c65d79f4be39c48d9dcab (patch)
tree336e22126b79e69e08fd785256740de270e592a0
parent77d19c725f827218975859ab7d3a680904075216 (diff)
downloadgcc-e2b5ad1ea6fac601ca5c65d79f4be39c48d9dcab.zip
gcc-e2b5ad1ea6fac601ca5c65d79f4be39c48d9dcab.tar.gz
gcc-e2b5ad1ea6fac601ca5c65d79f4be39c48d9dcab.tar.bz2
arm.c (thumb1_reorg): New function.
* config/arm/arm.c (thumb1_reorg): New function. (arm_reorg): Call thumb1_reorg. (thumb1_final_prescan_insn): Record src operand in thumb1_cc_op0. * config/arm/arm.md : Remove peephole2 patterns which rewrite move into subtract of ZERO. From-SVN: r193841
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/arm/arm.c66
-rw-r--r--gcc/config/arm/arm.md37
3 files changed, 73 insertions, 38 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 4aab7fc..29efeeb 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2012-11-27 Bin Cheng <bin.cheng@arm.com>
+
+ * config/arm/arm.c (thumb1_reorg): New function.
+ (arm_reorg): Call thumb1_reorg.
+ (thumb1_final_prescan_insn): Record src operand in thumb1_cc_op0.
+ * config/arm/arm.md : Remove peephole2 patterns which rewrite move
+ into subtract of ZERO.
+
2012-11-27 Richard Biener <rguenther@suse.de>
PR middle-end/55331
diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c
index 50dcff5..286a6c5 100644
--- a/gcc/config/arm/arm.c
+++ b/gcc/config/arm/arm.c
@@ -13396,6 +13396,62 @@ note_invalid_constants (rtx insn, HOST_WIDE_INT address, int do_pushes)
return;
}
+/* Rewrite move insn into subtract of 0 if the condition codes will
+ be useful in next conditional jump insn. */
+
+static void
+thumb1_reorg (void)
+{
+ basic_block bb;
+
+ FOR_EACH_BB (bb)
+ {
+ rtx set, dest, src;
+ rtx pat, op0;
+ rtx prev, insn = BB_END (bb);
+
+ while (insn != BB_HEAD (bb) && DEBUG_INSN_P (insn))
+ insn = PREV_INSN (insn);
+
+ /* Find the last cbranchsi4_insn in basic block BB. */
+ if (INSN_CODE (insn) != CODE_FOR_cbranchsi4_insn)
+ continue;
+
+ /* Find the first non-note insn before INSN in basic block BB. */
+ gcc_assert (insn != BB_HEAD (bb));
+ prev = PREV_INSN (insn);
+ while (prev != BB_HEAD (bb) && (NOTE_P (prev) || DEBUG_INSN_P (prev)))
+ prev = PREV_INSN (prev);
+
+ set = single_set (prev);
+ if (!set)
+ continue;
+
+ dest = SET_DEST (set);
+ src = SET_SRC (set);
+ if (!low_register_operand (dest, SImode)
+ || !low_register_operand (src, SImode))
+ continue;
+
+ pat = PATTERN (insn);
+ op0 = XEXP (XEXP (SET_SRC (pat), 0), 0);
+ /* Rewrite move into subtract of 0 if its operand is compared with ZERO
+ in INSN. Don't need to check dest since cprop_hardreg pass propagates
+ src into INSN. */
+ if (REGNO (op0) == REGNO (src))
+ {
+ dest = copy_rtx (dest);
+ src = copy_rtx (src);
+ src = gen_rtx_MINUS (SImode, src, const0_rtx);
+ PATTERN (prev) = gen_rtx_SET (VOIDmode, dest, src);
+ INSN_CODE (prev) = -1;
+ /* Set test register in INSN to dest. */
+ XEXP (XEXP (SET_SRC (pat), 0), 0) = copy_rtx (dest);
+ INSN_CODE (insn) = -1;
+ }
+ }
+}
+
/* Convert instructions to their cc-clobbering variant if possible, since
that allows us to use smaller encodings. */
@@ -13592,7 +13648,9 @@ arm_reorg (void)
HOST_WIDE_INT address = 0;
Mfix * fix;
- if (TARGET_THUMB2)
+ if (TARGET_THUMB1)
+ thumb1_reorg ();
+ else if (TARGET_THUMB2)
thumb2_reorg ();
/* Ensure all insns that must be split have been split at this point.
@@ -22155,6 +22213,12 @@ thumb1_final_prescan_insn (rtx insn)
if (src1 == const0_rtx)
cfun->machine->thumb1_cc_mode = CCmode;
}
+ else if (REG_P (SET_DEST (set)) && REG_P (SET_SRC (set)))
+ {
+ /* Record the src register operand instead of dest because
+ cprop_hardreg pass propagates src. */
+ cfun->machine->thumb1_cc_op0 = SET_SRC (set);
+ }
}
else if (conds != CONDS_NOCOND)
cfun->machine->thumb1_cc_insn = NULL_RTX;
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index 3002009..ac507ef 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -7166,43 +7166,6 @@
(const_int 8))))]
)
-;; Two peepholes to generate subtract of 0 instead of a move if the
-;; condition codes will be useful.
-(define_peephole2
- [(set (match_operand:SI 0 "low_register_operand" "")
- (match_operand:SI 1 "low_register_operand" ""))
- (set (pc)
- (if_then_else (match_operator 2 "arm_comparison_operator"
- [(match_dup 1) (const_int 0)])
- (label_ref (match_operand 3 "" ""))
- (pc)))]
- "TARGET_THUMB1"
- [(set (match_dup 0) (minus:SI (match_dup 1) (const_int 0)))
- (set (pc)
- (if_then_else (match_op_dup 2 [(match_dup 0) (const_int 0)])
- (label_ref (match_dup 3))
- (pc)))]
- "")
-
-;; Sigh! This variant shouldn't be needed, but combine often fails to
-;; merge cases like this because the op1 is a hard register in
-;; arm_class_likely_spilled_p.
-(define_peephole2
- [(set (match_operand:SI 0 "low_register_operand" "")
- (match_operand:SI 1 "low_register_operand" ""))
- (set (pc)
- (if_then_else (match_operator 2 "arm_comparison_operator"
- [(match_dup 0) (const_int 0)])
- (label_ref (match_operand 3 "" ""))
- (pc)))]
- "TARGET_THUMB1"
- [(set (match_dup 0) (minus:SI (match_dup 1) (const_int 0)))
- (set (pc)
- (if_then_else (match_op_dup 2 [(match_dup 0) (const_int 0)])
- (label_ref (match_dup 3))
- (pc)))]
- "")
-
(define_insn "*negated_cbranchsi4"
[(set (pc)
(if_then_else