diff options
author | Andy Hutchinson <hutchinsonandy@gcc.gnu.org> | 2009-12-13 21:03:41 +0000 |
---|---|---|
committer | Andy Hutchinson <hutchinsonandy@gcc.gnu.org> | 2009-12-13 21:03:41 +0000 |
commit | 83613dbea0846612b0ed3c4305aa541cca499b1d (patch) | |
tree | 1dc22f3c9c93e19fbf1fe7e45ac7d179e8c144e5 /gcc | |
parent | 1bea309889ac0d3f7cab5d51e2105cda6fc7f59b (diff) | |
download | gcc-83613dbea0846612b0ed3c4305aa541cca499b1d.zip gcc-83613dbea0846612b0ed3c4305aa541cca499b1d.tar.gz gcc-83613dbea0846612b0ed3c4305aa541cca499b1d.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 13 | ||||
-rw-r--r-- | gcc/config/avr/avr.md | 144 | ||||
-rwxr-xr-x | gcc/config/avr/predicates.md | 5 |
3 files changed, 124 insertions, 38 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c0e4634..aecafa4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -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 diff --git a/gcc/config/avr/avr.md b/gcc/config/avr/avr.md index 51fc1f9..1271fa4 100644 --- a/gcc/config/avr/avr.md +++ b/gcc/config/avr/avr.md @@ -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" diff --git a/gcc/config/avr/predicates.md b/gcc/config/avr/predicates.md index 020fb5f..2aa3e88 100755 --- a/gcc/config/avr/predicates.md +++ b/gcc/config/avr/predicates.md @@ -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)"))) |