re PR target/29560 ([avr] Poor optimization for byte shifts)
authorGeorg-Johann Lay <avr@gjlay.de>
Wed, 10 Aug 2011 08:58:03 +0000 (08:58 +0000)
committerGeorg-Johann Lay <gjl@gcc.gnu.org>
Wed, 10 Aug 2011 08:58:03 +0000 (08:58 +0000)
PR target/29560
* config/avr/avr.md (*ashlhiqi3): New insn-and-split.
(*ashl<extend_prefix>qihiqi3): New insn-and-splits.
(*ashl<extend_prefix>qihiqi3.mem): New insn-and-splits.
Add peephole2 to map ashlhi3 to ashlqi3 if high part of
shift target is unused.

From-SVN: r177616

gcc/ChangeLog
gcc/config/avr/avr.md

index 2c50a1d34445ff96b404f60f2d6d0b884e1f8c8f..9fd1ab75cc46cae544e3efd5930f52b0abce8bc8 100644 (file)
@@ -1,3 +1,12 @@
+2011-08-10  Georg-Johann Lay  <avr@gjlay.de>
+       
+       PR target/29560
+       * config/avr/avr.md (*ashlhiqi3): New insn-and-split.
+       (*ashl<extend_prefix>qihiqi3): New insn-and-splits.
+       (*ashl<extend_prefix>qihiqi3.mem): New insn-and-splits.
+       Add peephole2 to map ashlhi3 to ashlqi3 if high part of
+       shift target is unused.
+
 2011-08-10  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/49937
index b5aa73c55f28e942ba703f027d6d7161f843638e..8293ba7558e75f9ffd24951f4ffef8c6d34164e4 100644 (file)
   [(set_attr "length" "6,0,2,2,4,10,10")
    (set_attr "cc" "clobber,none,set_n,clobber,set_n,clobber,clobber")])
 
+
+;; Insns like the following are generated when (implicitly) extending 8-bit shifts
+;; like char1 = char2 << char3.  Only the low-byte is needed in that situation.
+
+;; "*ashluqihiqi3"
+;; "*ashlsqihiqi3"
+(define_insn_and_split "*ashl<extend_prefix>qihiqi3"
+  [(set (match_operand:QI 0 "register_operand"                                     "=r")
+        (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "0"))
+                              (match_operand:QI 2 "register_operand"                "r"))
+                   0))]
+  ""
+  "#"
+  ""
+  [(set (match_dup 0)
+        (ashift:QI (match_dup 1)
+                   (match_dup 2)))]
+  "")
+
+;; ??? Combiner does not recognize that it could split the following insn;
+;;     presumably because he has no register handy?
+
+;; "*ashluqihiqi3.mem"
+;; "*ashlsqihiqi3.mem"
+(define_insn_and_split "*ashl<extend_prefix>qihiqi3.mem"
+  [(set (match_operand:QI 0 "memory_operand" "=m")
+        (subreg:QI (ashift:HI (any_extend:HI (match_operand:QI 1 "register_operand" "r"))
+                              (match_operand:QI 2 "register_operand" "r"))
+                   0))]
+  "!reload_completed"
+  { gcc_unreachable(); }
+  "&& 1"
+  [(set (match_dup 3)
+        (ashift:QI (match_dup 1)
+                   (match_dup 2)))
+   (set (match_dup 0)
+        (match_dup 3))]
+  {
+    operands[3] = force_reg (QImode, operands[0]);
+  })
+
+;; Similar.
+
+(define_insn_and_split "*ashlhiqi3"
+  [(set (match_operand:QI 0 "nonimmediate_operand" "=r")
+        (subreg:QI (ashift:HI (match_operand:HI 1 "register_operand" "0")
+                              (match_operand:QI 2 "register_operand" "r")) 0))]
+  "!reload_completed"
+  { gcc_unreachable(); }
+  "&& 1"
+  [(set (match_dup 4)
+        (ashift:QI (match_dup 3)
+                   (match_dup 2)))
+   (set (match_dup 0)
+        (match_dup 4))]
+  {
+    operands[3] = simplify_gen_subreg (QImode, operands[1], HImode, 0);
+    operands[4] = force_reg (QImode, operands[0]);
+  })
+
+;; High part of 16-bit shift is unused after the instruction:
+;; No need to compute it, map to 8-bit shift.
+
+(define_peephole2
+  [(set (match_operand:HI 0 "register_operand" "")
+        (ashift:HI (match_dup 0)
+                   (match_operand:QI 1 "register_operand" "")))]
+  ""
+  [(set (match_dup 2)
+        (ashift:QI (match_dup 2)
+                   (match_dup 1)))
+   (clobber (match_dup 3))]
+  {
+    operands[3] = simplify_gen_subreg (QImode, operands[0], HImode, 1);
+
+    if (!peep2_reg_dead_p (1, operands[3]))
+      FAIL;
+
+    operands[2] = simplify_gen_subreg (QImode, operands[0], HImode, 0);
+  })
+
+
 (define_insn "ashlsi3"
   [(set (match_operand:SI 0 "register_operand"           "=r,r,r,r,r,r,r")
        (ashift:SI (match_operand:SI 1 "register_operand" "0,0,0,r,0,0,0")