This is the mail archive of the gcc@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]

Re: "generic" vectorization?


Geert Bosch <bosch@gnat.com> writes:

> Even for systems with vector instructions it will be useful.  For
> example logical operations will usually be done fastest using
> regular registers. In essence optimized memmove implementations use
> such "generic" vectorization.

Right. So a heuristic for the vectorizer could probably be "vectorize
even without target-specific instructions for logical ops and add/sub
with at least 4 elements". 

I've quickly hacked the improved open-coding for vector adds, but I
don't have time right now to follow this further, maybe somebody else
has... it improves addv8qi on Alpha from 54 to 12 insns (6 of which
are constant generation which could be moved out of loops).

Index: optabs.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/optabs.c,v
retrieving revision 1.137.2.27
diff -u -p -r1.137.2.27 optabs.c
--- optabs.c	25 Nov 2003 02:09:50 -0000	1.137.2.27
+++ optabs.c	3 Jan 2004 22:09:47 -0000
@@ -1931,6 +1931,43 @@ expand_vector_binop (enum machine_mode m
       if (!target)
 	target = gen_reg_rtx (mode);
 
+      if (binoptab->code == PLUS && elts >= 4
+	  && int_mode_for_mode (mode) != BLKmode)
+	{
+	  /* Do full word add and fix up spilling overflows.  */
+	  rtx signmask, inv_signmask, signs;
+	  HOST_WIDE_INT m = 0;
+
+	  tmode = int_mode_for_mode (mode);
+
+	  /* Build mask for all sign bits except highest one.  */
+	  for (i = 0; i < elts - 1; ++i)
+	    {
+	      m <<= subbitsize;
+	      m |= 1 << (subbitsize - 1);
+	    }
+	  signmask = GEN_INT(m);
+	  inv_signmask = GEN_INT(~m);
+
+	  t = simplify_gen_subreg (tmode, target, mode, 0);
+	  a = simplify_gen_subreg (tmode, op0, mode, 0);
+	  b = simplify_gen_subreg (tmode, op1, mode, 0);
+
+	  signs = expand_binop (tmode, xor_optab, a, b, NULL_RTX,
+				true, methods);
+	  signs = expand_binop (tmode, and_optab, signs, signmask, NULL_RTX,
+				true, methods);
+	  a = expand_binop (tmode, and_optab, a, inv_signmask, NULL_RTX,
+			    true, methods);
+	  b = expand_binop (tmode, and_optab, b, inv_signmask, NULL_RTX,
+			    true, methods);
+	  a = expand_binop (tmode, add_optab, a, b, NULL_RTX,
+			    true, methods);	  
+	  res = expand_binop (tmode, xor_optab, a, signs, t,
+			      true, methods);
+	  emit_move_insn (t, res);
+	}
+      else
       for (i = 0; i < elts; ++i)
 	{
 	  /* If this is part of a register, and not the first item in the


-- 
	Falk


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