diff options
author | Georg-Johann Lay <avr@gjlay.de> | 2011-08-10 08:58:03 +0000 |
---|---|---|
committer | Georg-Johann Lay <gjl@gcc.gnu.org> | 2011-08-10 08:58:03 +0000 |
commit | 4ada410ba1cf7440e3cc4b57a55c53da63ae341c (patch) | |
tree | 8455f2447914d9dcc0fa653e32875377b768e3ed /gcc | |
parent | d1f4e15f16e037c3f57aa0636d0cc7eddcaff10e (diff) | |
download | gcc-4ada410ba1cf7440e3cc4b57a55c53da63ae341c.zip gcc-4ada410ba1cf7440e3cc4b57a55c53da63ae341c.tar.gz gcc-4ada410ba1cf7440e3cc4b57a55c53da63ae341c.tar.bz2 |
re PR target/29560 ([avr] Poor optimization for byte shifts)
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/config/avr/avr.md | 82 |
2 files changed, 91 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 2c50a1d..9fd1ab7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index b5aa73c..8293ba7 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -2263,6 +2263,88 @@ [(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") |