This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] AVR: Solve missed optimization problem due to "double-set" problem for divmod4 patterns.
- From: Björn Haase <bjoern dot m dot haase at web dot de>
- To: Denis Chertykov <denisc at overta dot ru>,gcc-patches at gcc dot gnu dot org
- Cc: Andy Hutchinson <HutchinsonAndy at netscape dot net>,marekm at amelek dot gda dot pl,Richard Henderson <rth at redhat dot com>
- Date: Sat, 14 May 2005 10:54:52 +0200
- Subject: [PATCH] AVR: Solve missed optimization problem due to "double-set" problem for divmod4 patterns.
- References: <200504032154.35580.bjoern.m.haase@web.de> <200505102317.44777.bjoern.m.haase@web.de> <zmv1wqde.fsf@localhost.localdomain>
Hi,
when thinking about the "double-setter" problems that would show up in
cc0->CCmode conversion, I have been making an attempt to work around
the weakness of the present combiner pass. As a test case I have been
using one "double-setter" in the present machine description: "divmod4".
Presently, GCC does not identify that in a sequence like
int z,n,d,m;
void
foo (void)
{
m = z % n;
d = z / n;
}
it is not necessary to call the divmodhi4 subroutine twice. I think that
the reason is just the same "double-set" problem that one will face for
the condition code.
What I have done is adding "announce" instructions to the expand patterns
that never generate any assembly code but are used only for communicating
the mid-end that the "double-set" instruction has a possibly useful
by-product.
With the attached patch, gcc will now find out that it needs to call the
library routine only once.
I have run my simulavr-based test setup for the atmega128 and observed no
change.
Yours,
Björn
2005-05-14 Bjoern Haase <bjoern.m.haase@web.de>
config/avr/avr.md:
(divmodqi,udivmodqi):
Add "*announce_result_udivqi" and "*announce_result_umodqi" to template.
(divmodhi,udivmodhi,divmodsi,udivmodsi): Likewise.
(*announce_result_divqi,*announce_result_modqi): Add.
(*announce_result_udivqi,*announce_result_umodqi): Add.
(*announce_result_divhi,*announce_result_modhi): Add.
(*announce_result_udivhi,*announce_result_umodhi): Add.
(*announce_result_divsi,*announce_result_modsi): Add.
(*announce_result_udivsi,*announce_result_umodsi): Add.
Index: avr.md
===================================================================
RCS file: /cvsroot/gcc/gcc/gcc/config/avr/avr.md,v
retrieving revision 1.51
diff -U8 -r1.51 avr.md
--- avr.md 13 Mar 2005 10:09:53 -0000 1.51
+++ avr.md 14 May 2005 08:30:21 -0000
@@ -823,20 +823,42 @@
(define_expand "divmodqi4"
[(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
(set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
(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_operand:QI 3 "register_operand" "") (reg:QI 25))
+ (parallel[(set (match_dup 3) (mod:QI (match_dup 1) (match_dup 2)))
+ (use (match_dup 3))])
+ (parallel[(set (match_dup 0) (div:QI (match_dup 1) (match_dup 2)))
+ (use (match_dup 0))])]
""
"")
+(define_insn "*announce_result_divqi"
+ [ (parallel[(set (match_operand:QI 0 "register_operand" "")
+ (div:QI (match_operand:QI 1 "register_operand" "")
+ (match_operand:QI 2 "register_operand" "")))
+ (use (match_dup 0))])]
+ ""
+ ""
+ [(set_attr "length" "0")])
+
+(define_insn "*announce_result_modqi"
+ [ (parallel[(set (match_operand:QI 0 "register_operand" "")
+ (mod:QI (match_operand:QI 1 "register_operand" "")
+ (match_operand:QI 2 "register_operand" "")))
+ (use (match_dup 0))])]
+ ""
+ ""
+ [(set_attr "length" "0")])
+
(define_insn "*divmodqi4_call"
[(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))]
""
"%~call __divmodqi4"
[(set_attr "type" "xcall")
@@ -844,20 +866,42 @@
(define_expand "udivmodqi4"
[(set (reg:QI 24) (match_operand:QI 1 "register_operand" ""))
(set (reg:QI 22) (match_operand:QI 2 "register_operand" ""))
(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_operand:QI 3 "register_operand" "") (reg:QI 25))
+ (parallel[(set (match_dup 3) (umod:QI (match_dup 1) (match_dup 2)))
+ (use (match_dup 3))])
+ (parallel[(set (match_dup 0) (udiv:QI (match_dup 1) (match_dup 2)))
+ (use (match_dup 0))])]
""
"")
+(define_insn "*announce_result_udivqi"
+ [ (parallel[(set (match_operand:QI 0 "register_operand" "")
+ (udiv:QI (match_operand:QI 1 "register_operand" "")
+ (match_operand:QI 2 "register_operand" "")))
+ (use (match_dup 0))])]
+ ""
+ ""
+ [(set_attr "length" "0")])
+
+(define_insn "*announce_result_umodqi"
+ [ (parallel[(set (match_operand:QI 0 "register_operand" "")
+ (umod:QI (match_operand:QI 1 "register_operand" "")
+ (match_operand:QI 2 "register_operand" "")))
+ (use (match_dup 0))])]
+ ""
+ ""
+ [(set_attr "length" "0")])
+
(define_insn "*udivmodqi4_call"
[(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))]
""
"%~call __udivmodqi4"
[(set_attr "type" "xcall")
(set_attr "cc" "clobber")])
@@ -865,20 +909,42 @@
(define_expand "divmodhi4"
[(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
(set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
(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_operand:HI 3 "register_operand" "") (reg:HI 24))
+ (parallel[(set (match_dup 3) (mod:HI (match_dup 1) (match_dup 2)))
+ (use (match_dup 3))])
+ (parallel[(set (match_dup 0) (div:HI (match_dup 1) (match_dup 2)))
+ (use (match_dup 0))])]
""
"")
+(define_insn "*announce_result_divhi"
+ [ (parallel[(set (match_operand:HI 0 "register_operand" "")
+ (div:HI (match_operand:HI 1 "register_operand" "")
+ (match_operand:HI 2 "register_operand" "")))
+ (use (match_dup 0))])]
+ ""
+ ""
+ [(set_attr "length" "0")])
+
+(define_insn "*announce_result_modhi"
+ [ (parallel[(set (match_operand:HI 0 "register_operand" "")
+ (mod:HI (match_operand:HI 1 "register_operand" "")
+ (match_operand:HI 2 "register_operand" "")))
+ (use (match_dup 0))])]
+ ""
+ ""
+ [(set_attr "length" "0")])
+
(define_insn "*divmodhi4_call"
[(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))]
""
"%~call __divmodhi4"
[(set_attr "type" "xcall")
@@ -887,20 +953,42 @@
(define_expand "udivmodhi4"
[(set (reg:HI 24) (match_operand:HI 1 "register_operand" ""))
(set (reg:HI 22) (match_operand:HI 2 "register_operand" ""))
(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_operand:HI 3 "register_operand" "") (reg:HI 24))
+ (parallel[(set (match_dup 3) (umod:HI (match_dup 1) (match_dup 2)))
+ (use (match_dup 3))])
+ (parallel[(set (match_dup 0) (udiv:HI (match_dup 1) (match_dup 2)))
+ (use (match_dup 0))])]
""
"")
+(define_insn "*announce_result_udivhi"
+ [ (parallel[(set (match_operand:HI 0 "register_operand" "")
+ (udiv:HI (match_operand:HI 1 "register_operand" "")
+ (match_operand:HI 2 "register_operand" "")))
+ (use (match_dup 0))])]
+ ""
+ ""
+ [(set_attr "length" "0")])
+
+(define_insn "*announce_result_umodhi"
+ [ (parallel[(set (match_operand:HI 0 "register_operand" "")
+ (umod:HI (match_operand:HI 1 "register_operand" "")
+ (match_operand:HI 2 "register_operand" "")))
+ (use (match_dup 0))])]
+ ""
+ ""
+ [(set_attr "length" "0")])
+
(define_insn "*udivmodhi4_call"
[(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))]
""
"%~call __udivmodhi4"
[(set_attr "type" "xcall")
@@ -909,20 +997,42 @@
(define_expand "divmodsi4"
[(set (reg:SI 22) (match_operand:SI 1 "register_operand" ""))
(set (reg:SI 18) (match_operand:SI 2 "register_operand" ""))
(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_operand:SI 3 "register_operand" "") (reg:SI 22))
+ (parallel[(set (match_dup 3) (mod:SI (match_dup 1) (match_dup 2)))
+ (use (match_dup 3))])
+ (parallel[(set (match_dup 0) (div:SI (match_dup 1) (match_dup 2)))
+ (use (match_dup 0))])]
""
"")
+(define_insn "*announce_result_divsi"
+ [ (parallel[(set (match_operand:SI 0 "register_operand" "")
+ (div:SI (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "register_operand" "")))
+ (use (match_dup 0))])]
+ ""
+ ""
+ [(set_attr "length" "0")])
+
+(define_insn "*announce_result_modsi"
+ [ (parallel[(set (match_operand:SI 0 "register_operand" "")
+ (mod:SI (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "register_operand" "")))
+ (use (match_dup 0))])]
+ ""
+ ""
+ [(set_attr "length" "0")])
+
(define_insn "*divmodsi4_call"
[(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))]
""
"%~call __divmodsi4"
[(set_attr "type" "xcall")
@@ -931,20 +1041,42 @@
(define_expand "udivmodsi4"
[(set (reg:SI 22) (match_operand:SI 1 "register_operand" ""))
(set (reg:SI 18) (match_operand:SI 2 "register_operand" ""))
(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_operand:SI 3 "register_operand" "") (reg:SI 22))
+ (parallel[(set (match_dup 3) (umod:SI (match_dup 1) (match_dup 2)))
+ (use (match_dup 3))])
+ (parallel[(set (match_dup 0) (udiv:SI (match_dup 1) (match_dup 2)))
+ (use (match_dup 0))])]
""
"")
+(define_insn "*announce_result_udivsi"
+ [ (parallel[(set (match_operand:SI 0 "register_operand" "")
+ (udiv:SI (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "register_operand" "")))
+ (use (match_dup 0))])]
+ ""
+ ""
+ [(set_attr "length" "0")])
+
+(define_insn "*announce_result_umodsi"
+ [ (parallel[(set (match_operand:SI 0 "register_operand" "")
+ (umod:SI (match_operand:SI 1 "register_operand" "")
+ (match_operand:SI 2 "register_operand" "")))
+ (use (match_dup 0))])]
+ ""
+ ""
+ [(set_attr "length" "0")])
+
(define_insn "*udivmodsi4_call"
[(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))]
""
"%~call __udivmodsi4"
[(set_attr "type" "xcall")