* config/arm/arm.c (thumb1_reorg): New function.
authoramker <amker@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 27 Nov 2012 09:55:33 +0000 (09:55 +0000)
committeramker <amker@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 27 Nov 2012 09:55:33 +0000 (09:55 +0000)
(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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@193841 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/arm/arm.c
gcc/config/arm/arm.md

index 4aab7fc..29efeeb 100644 (file)
@@ -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
index 50dcff5..286a6c5 100644 (file)
@@ -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;
index 3002009..ac507ef 100644 (file)
                (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