re PR rtl-optimization/23726 (Missed optimizations for divmod)

PR target/23726
* config/avr/predicates.md (pseudo_register_operand): New predicate for pseudos.
* config/avr/avr.md (divmodqi4): Replace with define_insn_and_split to allow div/mod optimization.
(udivmodqi4): Ditto.
(divmodhi4): Ditto.
(udivmodhi4): Ditto.
(divmodsi4): Ditto.
(udivmodsi4): Ditto.

From-SVN: r155195
This commit is contained in:
Andy Hutchinson 2009-12-13 21:03:41 +00:00
parent 1bea309889
commit 83613dbea0
3 changed files with 124 additions and 38 deletions

View File

@ -1,3 +1,16 @@
2009-12-13 Andy Hutchinson <hutchinsonandy@gcc.gnu.org>
PR target/23726
* config/avr/predicates.md (pseudo_register_operand): New predicate
for pseudos.
* config/avr/avr.md (divmodqi4): Replace with define_insn_and_split
to allow div/mod optimization.
(udivmodqi4): Ditto.
(divmodhi4): Ditto.
(udivmodhi4): Ditto.
(divmodsi4): Ditto.
(udivmodsi4): Ditto.
2009-12-13 Richard Guenther <rguenther@suse.de>
PR tree-optimization/42357

View File

@ -1052,17 +1052,30 @@
;; - we know exactly which registers are clobbered (for QI and HI
;; modes, some of the call-used registers are preserved)
;; - we get both the quotient and the remainder at no extra cost
(define_expand "divmodqi4"
[(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
(set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
;; - we split the patterns only after the first CSE passes because
;; CSE has problems to operate on hard regs.
;;
(define_insn_and_split "divmodqi4"
[(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
(div:QI (match_operand:QI 1 "pseudo_register_operand" "")
(match_operand:QI 2 "pseudo_register_operand" "")))
(set (match_operand:QI 3 "pseudo_register_operand" "")
(mod:QI (match_dup 1) (match_dup 2)))
(clobber (reg:QI 22))
(clobber (reg:QI 23))
(clobber (reg:QI 24))
(clobber (reg:QI 25))])]
""
"this divmodqi4 pattern should have been splitted;"
""
[(set (reg:QI 24) (match_dup 1))
(set (reg:QI 22) (match_dup 2))
(parallel [(set (reg:QI 24) (div:QI (reg:QI 24) (reg:QI 22)))
(set (reg:QI 25) (mod:QI (reg:QI 24) (reg:QI 22)))
(clobber (reg:QI 22))
(clobber (reg:QI 23))])
(set (match_operand:QI 0 "register_operand" "") (reg:QI 24))
(set (match_operand:QI 3 "register_operand" "") (reg:QI 25))]
""
(set (match_dup 0) (reg:QI 24))
(set (match_dup 3) (reg:QI 25))]
"")
(define_insn "*divmodqi4_call"
@ -1075,15 +1088,26 @@
[(set_attr "type" "xcall")
(set_attr "cc" "clobber")])
(define_expand "udivmodqi4"
[(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
(set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
(define_insn_and_split "udivmodqi4"
[(parallel [(set (match_operand:QI 0 "pseudo_register_operand" "")
(udiv:QI (match_operand:QI 1 "pseudo_register_operand" "")
(match_operand:QI 2 "pseudo_register_operand" "")))
(set (match_operand:QI 3 "pseudo_register_operand" "")
(umod:QI (match_dup 1) (match_dup 2)))
(clobber (reg:QI 22))
(clobber (reg:QI 23))
(clobber (reg:QI 24))
(clobber (reg:QI 25))])]
""
"this udivmodqi4 pattern should have been splitted;"
""
[(set (reg:QI 24) (match_dup 1))
(set (reg:QI 22) (match_dup 2))
(parallel [(set (reg:QI 24) (udiv:QI (reg:QI 24) (reg:QI 22)))
(set (reg:QI 25) (umod:QI (reg:QI 24) (reg:QI 22)))
(clobber (reg:QI 23))])
(set (match_operand:QI 0 "register_operand" "") (reg:QI 24))
(set (match_operand:QI 3 "register_operand" "") (reg:QI 25))]
""
(set (match_dup 0) (reg:QI 24))
(set (match_dup 3) (reg:QI 25))]
"")
(define_insn "*udivmodqi4_call"
@ -1095,17 +1119,28 @@
[(set_attr "type" "xcall")
(set_attr "cc" "clobber")])
(define_expand "divmodhi4"
[(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
(set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
(define_insn_and_split "divmodhi4"
[(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
(div:HI (match_operand:HI 1 "pseudo_register_operand" "")
(match_operand:HI 2 "pseudo_register_operand" "")))
(set (match_operand:HI 3 "pseudo_register_operand" "")
(mod:HI (match_dup 1) (match_dup 2)))
(clobber (reg:QI 21))
(clobber (reg:HI 22))
(clobber (reg:HI 24))
(clobber (reg:HI 26))])]
""
"this should have been splitted;"
""
[(set (reg:HI 24) (match_dup 1))
(set (reg:HI 22) (match_dup 2))
(parallel [(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
(set (reg:HI 24) (mod:HI (reg:HI 24) (reg:HI 22)))
(clobber (reg:HI 26))
(clobber (reg:QI 21))])
(set (match_operand:HI 0 "register_operand" "") (reg:HI 22))
(set (match_operand:HI 3 "register_operand" "") (reg:HI 24))]
""
"")
(set (match_dup 0) (reg:HI 22))
(set (match_dup 3) (reg:HI 24))]
"")
(define_insn "*divmodhi4_call"
[(set (reg:HI 22) (div:HI (reg:HI 24) (reg:HI 22)))
@ -1117,16 +1152,27 @@
[(set_attr "type" "xcall")
(set_attr "cc" "clobber")])
(define_expand "udivmodhi4"
[(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
(set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
(define_insn_and_split "udivmodhi4"
[(parallel [(set (match_operand:HI 0 "pseudo_register_operand" "")
(udiv:HI (match_operand:HI 1 "pseudo_register_operand" "")
(match_operand:HI 2 "pseudo_register_operand" "")))
(set (match_operand:HI 3 "pseudo_register_operand" "")
(umod:HI (match_dup 1) (match_dup 2)))
(clobber (reg:QI 21))
(clobber (reg:HI 22))
(clobber (reg:HI 24))
(clobber (reg:HI 26))])]
""
"this udivmodhi4 pattern should have been splitted.;"
""
[(set (reg:HI 24) (match_dup 1))
(set (reg:HI 22) (match_dup 2))
(parallel [(set (reg:HI 22) (udiv:HI (reg:HI 24) (reg:HI 22)))
(set (reg:HI 24) (umod:HI (reg:HI 24) (reg:HI 22)))
(clobber (reg:HI 26))
(clobber (reg:QI 21))])
(set (match_operand:HI 0 "register_operand" "") (reg:HI 22))
(set (match_operand:HI 3 "register_operand" "") (reg:HI 24))]
""
(set (match_dup 0) (reg:HI 22))
(set (match_dup 3) (reg:HI 24))]
"")
(define_insn "*udivmodhi4_call"
@ -1139,16 +1185,27 @@
[(set_attr "type" "xcall")
(set_attr "cc" "clobber")])
(define_expand "divmodsi4"
[(set (reg:SI 22) (match_operand:SI 1 "register_operand" ""))
(set (reg:SI 18) (match_operand:SI 2 "register_operand" ""))
(define_insn_and_split "divmodsi4"
[(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
(div:SI (match_operand:SI 1 "pseudo_register_operand" "")
(match_operand:SI 2 "pseudo_register_operand" "")))
(set (match_operand:SI 3 "pseudo_register_operand" "")
(mod:SI (match_dup 1) (match_dup 2)))
(clobber (reg:SI 18))
(clobber (reg:SI 22))
(clobber (reg:HI 26))
(clobber (reg:HI 30))])]
""
"this divmodsi4 pattern should have been splitted;"
""
[(set (reg:SI 22) (match_dup 1))
(set (reg:SI 18) (match_dup 2))
(parallel [(set (reg:SI 18) (div:SI (reg:SI 22) (reg:SI 18)))
(set (reg:SI 22) (mod:SI (reg:SI 22) (reg:SI 18)))
(clobber (reg:HI 26))
(clobber (reg:HI 30))])
(set (match_operand:SI 0 "register_operand" "") (reg:SI 18))
(set (match_operand:SI 3 "register_operand" "") (reg:SI 22))]
""
(set (match_dup 0) (reg:SI 18))
(set (match_dup 3) (reg:SI 22))]
"")
(define_insn "*divmodsi4_call"
@ -1161,16 +1218,27 @@
[(set_attr "type" "xcall")
(set_attr "cc" "clobber")])
(define_expand "udivmodsi4"
[(set (reg:SI 22) (match_operand:SI 1 "register_operand" ""))
(set (reg:SI 18) (match_operand:SI 2 "register_operand" ""))
(define_insn_and_split "udivmodsi4"
[(parallel [(set (match_operand:SI 0 "pseudo_register_operand" "")
(udiv:SI (match_operand:SI 1 "pseudo_register_operand" "")
(match_operand:SI 2 "pseudo_register_operand" "")))
(set (match_operand:SI 3 "pseudo_register_operand" "")
(umod:SI (match_dup 1) (match_dup 2)))
(clobber (reg:SI 18))
(clobber (reg:SI 22))
(clobber (reg:HI 26))
(clobber (reg:HI 30))])]
""
"this udivmodsi4 pattern should have been splitted;"
""
[(set (reg:SI 22) (match_dup 1))
(set (reg:SI 18) (match_dup 2))
(parallel [(set (reg:SI 18) (udiv:SI (reg:SI 22) (reg:SI 18)))
(set (reg:SI 22) (umod:SI (reg:SI 22) (reg:SI 18)))
(clobber (reg:HI 26))
(clobber (reg:HI 30))])
(set (match_operand:SI 0 "register_operand" "") (reg:SI 18))
(set (match_operand:SI 3 "register_operand" "") (reg:SI 22))]
""
(set (match_dup 0) (reg:SI 18))
(set (match_dup 3) (reg:SI 22))]
"")
(define_insn "*udivmodsi4_call"

View File

@ -110,3 +110,8 @@
(and (match_code "mem")
(ior (match_test "register_operand (XEXP (op, 0), mode)")
(match_test "CONSTANT_ADDRESS_P (XEXP (op, 0))"))))
;; True for register that is pseudo register.
(define_predicate "pseudo_register_operand"
(and (match_code "reg")
(match_test "!HARD_REGISTER_P (op)")))