This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH: PR target/40835] Remove comparison with 0 after instruction movs for thumb


On Sat, 2009-10-31 at 20:56 +0800, Carrot Wei wrote:
> You are right. Use sub can remove more cmp instructions. The patch
> has been updated to reflect this.
> 
> Test:
> This patch was applied to trunk GCC and tested on the arm emulator with newlib.
> No new failure.
> 
> ChangeLog:
> 2009-10-31  Wei Guozhi  <carrot@google.com>
> 
>         PR target/40835
>         * config/arm/arm.c (emit_branch_after_movs): New function.
>         (removable_cmp_0): New function.
>         * config/arm/arm-protos.h (emit_branch_after_movs): Declare it.
>         (removable_cmp_0): Declare it.
>         * config/arm/arm.md: Add peephole rule to do the optimization.
> 		
> 2009-10-31  Wei Guozhi  <carrot@google.com>
> 
>         PR target/40835
>         * gcc.target/arm/pr40835: New testcase.
> 

This is needlessly complicated.  I've only tested the following by
examination, but it's a much more robust solution.  

Note I wouldn't normally condone adding peepholes for the second case
(where there's a natural data-flow dependency between the insns), but it
turns out that in this scenario combine is being prevented from
optimizing this case by the need to reduce register pressure and this is
common enough to warrant an exception.

R.
*** arm.md	(revision 153753)
--- arm.md	(local)
*************** (define_insn "cbranchsi4_scratch"
*** 6770,6775 ****
--- 6770,6776 ----
  		(const_int 6)
  		(const_int 8))))]
  )
+ 
  (define_insn "*movsi_cbranchsi4"
    [(set (pc)
  	(if_then_else
*************** (define_insn "*movsi_cbranchsi4"
*** 6833,6838 ****
--- 6834,6878 ----
  	   (const_int 10)))))]
  )
  
+ (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"
+   [(parallel
+     [(set (pc)
+ 	(if_then_else (match_op_dup 2 [(match_dup 1) (const_int 0)])
+ 		      (label_ref (match_dup 3))
+ 		      (pc)))
+      (set (match_dup 0) (match_dup 1))])]
+   ""
+ )
+ 
+ ;; Sigh!  This variant shouldn't be needed, but combine often fails to
+ ;; merge cases like this because the op1 is a hard register in
+ ;; 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"
+   [(parallel
+     [(set (pc)
+ 	(if_then_else (match_op_dup 2 [(match_dup 1) (const_int 0)])
+ 		      (label_ref (match_dup 3))
+ 		      (pc)))
+      (set (match_dup 0) (match_dup 1))])]
+   ""
+ )
+ 
  (define_insn "*negated_cbranchsi4"
    [(set (pc)
  	(if_then_else

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]