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> 2009-12-13 Richard Guenther <rguenther@suse.de>
PR tree-optimization/42357 PR tree-optimization/42357

View File

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

View File

@ -110,3 +110,8 @@
(and (match_code "mem") (and (match_code "mem")
(ior (match_test "register_operand (XEXP (op, 0), mode)") (ior (match_test "register_operand (XEXP (op, 0), mode)")
(match_test "CONSTANT_ADDRESS_P (XEXP (op, 0))")))) (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)")))