This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] AVR: Solve missed optimization problem due to "double-set" problem for divmod4 patterns.


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")

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]