aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorAndy Hutchinson <hutchinsonandy@gcc.gnu.org>2009-12-13 21:03:41 +0000
committerAndy Hutchinson <hutchinsonandy@gcc.gnu.org>2009-12-13 21:03:41 +0000
commit83613dbea0846612b0ed3c4305aa541cca499b1d (patch)
tree1dc22f3c9c93e19fbf1fe7e45ac7d179e8c144e5 /gcc
parent1bea309889ac0d3f7cab5d51e2105cda6fc7f59b (diff)
downloadgcc-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/ChangeLog13
-rw-r--r--gcc/config/avr/avr.md144
-rwxr-xr-xgcc/config/avr/predicates.md5
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)")))