[avr,committed] Improve operations on non-LD_REGS when the operation follows a move from LD_REGS.

Message ID bfa51b3b-c7b9-197b-923c-aeb8eed903fe@gjlay.de
State New
Headers
Series [avr,committed] Improve operations on non-LD_REGS when the operation follows a move from LD_REGS. |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_gcc_build--master-arm fail Patch failed to apply
linaro-tcwg-bot/tcwg_gcc_build--master-aarch64 fail Patch failed to apply
linaro-tcwg-bot/tcwg_gcc_check--master-aarch64 pending Test started
linaro-tcwg-bot/tcwg_gcc_check--master-arm pending Test started

Commit Message

Georg-Johann Lay June 2, 2023, 11:38 a.m. UTC
  Applied the following patch to improve operations on no-LD_REGS
when the operation follows a move from LD_REGS.

Johann

target/110088: Improve operation of l-reg with const after move from d-reg.

After reload, there may be sequences like
    lreg = dreg
    lreg = lreg <op> const
with an LD_REGS dreg, non-LD_REGS lreg, and <op> in PLUS, IOR, AND.
If dreg dies after the first insn, it is possible to use
    dreg = dreg <op> const
    lreg = dreg
instead which is more efficient.

gcc/
	PR target/110088
	* config/avr/avr.md: Add an RTL peephole to optimize operations on
	non-LD_REGS after a move from LD_REGS.
	(piaop): New code iterator.

  (define_code_iterator eqne [eq ne])
@@ -4727,6 +4729,43 @@ (define_split
      DONE;
    })

+;; If  $0 = $0 <op> const  requires a QI scratch, and d-reg $1 dies after
+;; the first insn, then we can replace
+;;    $0 = $1
+;;    $0 = $0 <op> const
+;; by
+;;    $1 = $1 <op> const
+;;    $0 = $1
+;; This transforms constraint alternative "r,0,n,&d" of the first operation
+;; to alternative "d,0,n,X".
+;; "*addhi3_clobber"  "*addpsi3"  "*addsi3"
+;; "*addhq3"  "*adduhq3"  "*addha3"  "*adduha3"
+;; "*addsq3"  "*addusq3"  "*addsa3"  "*addusa3"
+;; "*iorhi3"  "*iorpsi3"  "*iorsi3"
+;; "*andhi3"  "*andpsi3"  "*andsi3"
+(define_peephole2
+  [(parallel [(set (match_operand:ORDERED234 0 "register_operand")
+                   (match_operand:ORDERED234 1 "d_register_operand"))
+              (clobber (reg:CC REG_CC))])
+   (parallel [(set (match_dup 0)
+                   (piaop:ORDERED234 (match_dup 0)
+                                     (match_operand:ORDERED234 2 
"const_operand")))
+              ; A d-reg as scratch tells that this insn is expensive, and
+              ; that $0 is not a d-register: l-reg or something like 
SI:14 etc.
+              (clobber (match_operand:QI 3 "d_register_operand"))
+              (clobber (reg:CC REG_CC))])]
+  "peep2_reg_dead_p (1, operands[1])"
+  [(parallel [(set (match_dup 1)
+                   (piaop:ORDERED234 (match_dup 1)
+                                     (match_dup 2)))
+              (clobber (scratch:QI))
+              (clobber (reg:CC REG_CC))])
+   ; Unfortunately, the following insn misses a REG_DEAD note for $1,
+   ; so this peep2 works only once.
+   (parallel [(set (match_dup 0)
+                   (match_dup 1))
+              (clobber (reg:CC REG_CC))])])
+

  ;; swap swap swap swap swap swap swap swap swap swap swap swap swap 
swap swap
  ;; swap
  

Patch

diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md
index 371965938a6..9f5fabc861f 100644
--- a/gcc/config/avr/avr.md
+++ b/gcc/config/avr/avr.md
@@ -279,6 +279,7 @@  (define_code_iterator any_extend2 [sign_extend 
zero_extend])
  (define_code_iterator any_extract [sign_extract zero_extract])
  (define_code_iterator any_shiftrt [lshiftrt ashiftrt])

+(define_code_iterator piaop [plus ior and])
  (define_code_iterator bitop [xor ior and])
  (define_code_iterator xior [xor ior])