OSDN Git Service

Let GET_MODE_2XWIDER_MODE find a double-width vector mode.
authorrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 10 Dec 2011 20:42:55 +0000 (20:42 +0000)
committerrth <rth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 10 Dec 2011 20:42:55 +0000 (20:42 +0000)
        * genmodes.c (struct mode_data): Remove wider_2x member.
        (blank_mode): Adjust initializer.
        (calc_wider_mode): Use XALLOCAVEC.
        (emit_move_wider): Select double-width same-element vectors for
        2xwider vectors.
        * machmode.h (GET_MODE_2XWIDER_MODE): Update documentation.
        * config/i386/i386.c (doublesize_vector_mode): Remove.
        (expand_vselect_vconcat): Use GET_MODE_2XWIDER_MODE instead.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@182191 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/config/i386/i386.c
gcc/genmodes.c
gcc/machmode.h

index 811ea31..3490874 100644 (file)
@@ -1,3 +1,14 @@
+2011-12-10  Richard Henderson  <rth@redhat.com>
+
+       * genmodes.c (struct mode_data): Remove wider_2x member.
+       (blank_mode): Adjust initializer.
+       (calc_wider_mode): Use XALLOCAVEC.
+       (emit_move_wider): Select double-width same-element vectors for
+       2xwider vectors.
+       * machmode.h (GET_MODE_2XWIDER_MODE): Update documentation.
+       * config/i386/i386.c (doublesize_vector_mode): Remove.
+       (expand_vselect_vconcat): Use GET_MODE_2XWIDER_MODE instead.
+
 2011-12-10  Joern Rennecke  <joern.rennecke@embecosm.com>
 
        * config/epiphany/epiphany.h (USE_LOAD_POST_INCREMENT): Define.
index 15c6c37..216ab0b 100644 (file)
@@ -35306,40 +35306,6 @@ ix86_builtin_vectorization_cost (enum vect_cost_for_stmt type_of_cost,
     }
 }
 
-
-/* Return a vector mode with twice as many elements as VMODE.  */
-/* ??? Consider moving this to a table generated by genmodes.c.  */
-
-static enum machine_mode
-doublesize_vector_mode (enum machine_mode vmode)
-{
-  switch (vmode)
-    {
-    case V2SFmode:     return V4SFmode;
-    case V1DImode:     return V2DImode;
-    case V2SImode:     return V4SImode;
-    case V4HImode:     return V8HImode;
-    case V8QImode:     return V16QImode;
-
-    case V2DFmode:     return V4DFmode;
-    case V4SFmode:     return V8SFmode;
-    case V2DImode:     return V4DImode;
-    case V4SImode:     return V8SImode;
-    case V8HImode:     return V16HImode;
-    case V16QImode:    return V32QImode;
-
-    case V4DFmode:     return V8DFmode;
-    case V8SFmode:     return V16SFmode;
-    case V4DImode:     return V8DImode;
-    case V8SImode:     return V16SImode;
-    case V16HImode:    return V32HImode;
-    case V32QImode:    return V64QImode;
-
-    default:
-      gcc_unreachable ();
-    }
-}
-
 /* Construct (set target (vec_select op0 (parallel perm))) and
    return true if that's a valid instruction in the active ISA.  */
 
@@ -35374,7 +35340,7 @@ expand_vselect_vconcat (rtx target, rtx op0, rtx op1,
   enum machine_mode v2mode;
   rtx x;
 
-  v2mode = doublesize_vector_mode (GET_MODE (op0));
+  v2mode = GET_MODE_2XWIDER_MODE (GET_MODE (op0));
   x = gen_rtx_VEC_CONCAT (v2mode, op0, op1);
   return expand_vselect (target, x, perm, nelt);
 }
index dae7e38..8b6f5bc 100644 (file)
@@ -63,7 +63,6 @@ struct mode_data
 
   struct mode_data *component; /* mode of components */
   struct mode_data *wider;     /* next wider mode */
-  struct mode_data *wider_2x;  /* 2x wider mode */
 
   struct mode_data *contained;  /* Pointer to list of modes that have
                                   this mode as a component.  */
@@ -83,7 +82,7 @@ static struct mode_data *void_mode;
 static const struct mode_data blank_mode = {
   0, "<unknown>", MAX_MODE_CLASS,
   -1U, -1U, -1U, -1U,
-  0, 0, 0, 0, 0, 0,
+  0, 0, 0, 0, 0,
   "<unknown>", 0, 0, 0, 0
 };
 
@@ -790,7 +789,7 @@ calc_wider_mode (void)
 
   /* Allocate max_n_modes + 1 entries to leave room for the extra null
      pointer assigned after the qsort call below.  */
-  sortbuf = (struct mode_data **) alloca ((max_n_modes + 1) * sizeof (struct mode_data *));
+  sortbuf = XALLOCAVEC (struct mode_data *, max_n_modes + 1);
 
   for (c = 0; c < MAX_MODE_CLASS; c++)
     {
@@ -804,7 +803,6 @@ calc_wider_mode (void)
          for (prev = 0, m = modes[c]; m; m = next)
            {
              m->wider = void_mode;
-             m->wider_2x = void_mode;
 
              /* this is nreverse */
              next = m->next;
@@ -827,7 +825,6 @@ calc_wider_mode (void)
          for (j = 0; j < i; j++)
            sortbuf[j]->next = sortbuf[j]->wider = sortbuf[j + 1];
 
-
          modes[c] = sortbuf[0];
        }
     }
@@ -1062,6 +1059,21 @@ emit_mode_wider (void)
                continue;
            }
 
+         /* For vectors we want twice the number of components,
+            with the same element type.  */
+         if (m->cl == MODE_VECTOR_INT
+             || m->cl == MODE_VECTOR_FLOAT
+             || m->cl == MODE_VECTOR_FRACT
+             || m->cl == MODE_VECTOR_UFRACT
+             || m->cl == MODE_VECTOR_ACCUM
+             || m->cl == MODE_VECTOR_UACCUM)
+           {
+             if (m2->ncomponents != 2 * m->ncomponents)
+               continue;
+             if (m->component != m2->component)
+               continue;
+           }
+
          break;
        }
       if (m2 == void_mode)
index b965d0f..4a3f6f5 100644 (file)
@@ -221,6 +221,8 @@ extern const unsigned char mode_nunits[NUM_MACHINE_MODES];
 extern const unsigned char mode_wider[NUM_MACHINE_MODES];
 #define GET_MODE_WIDER_MODE(MODE) ((enum machine_mode) mode_wider[MODE])
 
+/* For scalars, this is a mode with twice the precision.  For vectors,
+   this is a mode with the same inner mode but with twice the elements.  */
 extern const unsigned char mode_2xwider[NUM_MACHINE_MODES];
 #define GET_MODE_2XWIDER_MODE(MODE) ((enum machine_mode) mode_2xwider[MODE])