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
This commit is contained in:
parent
77d19c725f
commit
e2b5ad1ea6
3 changed files with 73 additions and 38 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Add table
Reference in a new issue