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] Peephole x86 multiplications by 3, 5 and 9


GCC decomposes integer multiplications with a constant operand into
a sequence of add and shift operations, if the constant is visible
during RTL expansion.  However, propagation of constants by the RTL
optimizers can result with explicit multiplication instructions with
immediate constant operands.

For example, on i686-pc-linux-gnu, the following source code generates
an "imul $3, 8(%ebp), %eax" instruction.

int foo(int x)
{
  int y = 3;
  return x*y;
}


On IA-32, it is preferable to use the "lea" instruction to implement
such multiplications by 3, 5 or 9, using a single faster instruction.


The patch below attempts this optimization using a set of peephole2's
in i386.md.  If the non-constant operand of the multiplication is a
register, we perform this transformation unconditionally.  Otherwise
we use a second peephole that first loads this operand into the
destination register, but only when not optimizing for size.

These are my first peephole2's, so I'm unsure if its better/easier to
use a single peephole for 3, 5 and 9, rather than the duplication below.
I'm also note sure if its possible to combine the register/non-register
forms.  However, the prototype below should start the discussion.


Ideally, the RTL optimizers should synthesize multiplications by
arbitrary constants in the middle-end.  However, much of the benefit
of such a large patch will be lost when we merge tree-ssa.  The x86
specific approach below seems like a reasonable compromise (for now).



The following patch has been tested on i686-pc-linux-gnu with a full
"make bootstrap", all languages except treelang, and regression tested
with a top-level "make -k check" with no new regressions.


2004-05-02  Roger Sayle  <roger@eyesopen.com>

	* config/i386/i386.md: New peephole2's to convert imul by 3, 5 or
	9 into the equivlaent lea instruction.


Index: i386.md
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/i386/i386.md,v
retrieving revision 1.531
diff -c -3 -p -r1.531 i386.md
*** i386.md	30 Apr 2004 06:04:57 -0000	1.531
--- i386.md	2 May 2004 20:23:11 -0000
***************
*** 23636,23638 ****
--- 23636,23708 ----
    "movddup\t{%1, %0|%0, %1}"
    [(set_attr "type" "ssecvt")
     (set_attr "mode" "DF")])
+
+ ;; Convert imul by three, five and nine into lea
+ (define_peephole2
+   [(parallel
+     [(set (match_operand:SI 0 "register_operand" "")
+ 	  (mult:SI (match_operand:SI 1 "register_operand" "")
+ 	  (const_int 3)))
+      (clobber (reg:CC 17))])]
+   "!TARGET_64BIT"
+   [(set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 2))
+ 			       (match_dup 1)))]
+   "")
+
+ (define_peephole2
+   [(parallel
+     [(set (match_operand:SI 0 "register_operand" "")
+ 	  (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
+ 	  (const_int 3)))
+      (clobber (reg:CC 17))])]
+   "!TARGET_64BIT && !optimize_size"
+   [(set (match_dup 0) (match_dup 1))
+    (set (match_dup 0) (plus:SI (mult:SI (match_dup 0) (const_int 2))
+ 			       (match_dup 0)))]
+   "")
+
+ (define_peephole2
+   [(parallel
+     [(set (match_operand:SI 0 "register_operand" "")
+ 	  (mult:SI (match_operand:SI 1 "register_operand" "")
+ 	  (const_int 5)))
+      (clobber (reg:CC 17))])]
+   "!TARGET_64BIT"
+   [(set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 4))
+ 			       (match_dup 1)))]
+   "")
+
+ (define_peephole2
+   [(parallel
+     [(set (match_operand:SI 0 "register_operand" "")
+ 	  (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
+ 	  (const_int 5)))
+      (clobber (reg:CC 17))])]
+   "!TARGET_64BIT && !optimize_size"
+   [(set (match_dup 0) (match_dup 1))
+    (set (match_dup 0) (plus:SI (mult:SI (match_dup 0) (const_int 4))
+ 			       (match_dup 0)))]
+   "")
+
+ (define_peephole2
+   [(parallel
+     [(set (match_operand:SI 0 "register_operand" "")
+ 	  (mult:SI (match_operand:SI 1 "register_operand" "")
+ 	  (const_int 9)))
+      (clobber (reg:CC 17))])]
+   "!TARGET_64BIT"
+   [(set (match_dup 0) (plus:SI (mult:SI (match_dup 1) (const_int 8))
+ 			       (match_dup 1)))]
+   "")
+
+ (define_peephole2
+   [(parallel
+     [(set (match_operand:SI 0 "register_operand" "")
+ 	  (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
+ 	  (const_int 9)))
+      (clobber (reg:CC 17))])]
+   "!TARGET_64BIT && !optimize_size"
+   [(set (match_dup 0) (match_dup 1))
+    (set (match_dup 0) (plus:SI (mult:SI (match_dup 0) (const_int 8))
+ 			       (match_dup 0)))]
+   "")


Roger
--
Roger Sayle,                         E-mail: roger@eyesopen.com
OpenEye Scientific Software,         WWW: http://www.eyesopen.com/
Suite 1107, 3600 Cerrillos Road,     Tel: (+1) 505-473-7385
Santa Fe, New Mexico, 87507.         Fax: (+1) 505-473-0833


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