changeset 58921:c7ae168bfe55 vectorIntrinsics

8222755: [vector] Add files which were left out while pushing changeset for 8222584 Summary: Add files which were left out while pushing changeset for 8222584 Reviewed-by: briangoetz, vlivanov
author kkharbas
date Thu, 18 Apr 2019 23:47:37 -0700
parents 0678bd75278c
children 82a6fe9fb2b8 82514a6254e6
files src/jdk.incubator.vector/share/classes/jdk/incubator/vector/AbstractSpecies.java src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorMask.java src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorShape.java src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorShuffle.java src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorSpecies.java
diffstat 5 files changed, 975 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/AbstractSpecies.java	Thu Apr 18 23:47:37 2019 -0700
@@ -0,0 +1,146 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have
+ * questions.
+ */
+package jdk.incubator.vector;
+
+import jdk.internal.vm.annotation.ForceInline;
+import jdk.internal.vm.annotation.Stable;
+import java.util.function.Function;
+import java.util.function.IntUnaryOperator;
+
+abstract class AbstractSpecies<E> implements VectorSpecies<E> {
+    @FunctionalInterface
+    interface fShuffleFromArray<E> {
+        VectorShuffle<E> apply(int[] reorder, int idx);
+    }
+
+    final Function<boolean[], VectorMask<E>> maskFactory;
+    final Function<IntUnaryOperator, VectorShuffle<E>> shuffleFromOpFactory;
+    final fShuffleFromArray<E> shuffleFromArrayFactory;
+
+    @Stable
+    protected final VectorShape shape;
+    @Stable
+    protected final Class<E> elementType;
+    @Stable
+    protected final int elementSize;
+    @Stable
+    protected final Class<?> boxType;
+    @Stable
+    protected final Class<?> maskType;
+    @Stable
+    protected final VectorShape indexShape;
+
+    AbstractSpecies(VectorShape shape, Class<E> elementType, int elementSize,
+                    Class<?> boxType, Class<?> maskType, Function<boolean[], VectorMask<E>> maskFactory,
+                    Function<IntUnaryOperator, VectorShuffle<E>> shuffleFromOpFactory,
+                    fShuffleFromArray<E> shuffleFromArrayFactory) {
+
+        this.maskFactory = maskFactory;
+        this.shuffleFromArrayFactory = shuffleFromArrayFactory;
+        this.shuffleFromOpFactory = shuffleFromOpFactory;
+
+        this.shape = shape;
+        this.elementType = elementType;
+        this.elementSize = elementSize;
+        this.boxType = boxType;
+        this.maskType = maskType;
+
+        if (boxType == Long64Vector.class || boxType == Double64Vector.class) {
+            indexShape = VectorShape.S_64_BIT;
+        }
+        else {
+            int bitSize = Vector.bitSizeForVectorLength(int.class, shape.bitSize() / elementSize);
+            indexShape = VectorShape.forBitSize(bitSize);
+        }
+    }
+
+    @Override
+    @ForceInline
+    public int bitSize() {
+        return shape.bitSize();
+    }
+
+    @Override
+    @ForceInline
+    public int length() {
+        return shape.bitSize() / elementSize;
+    }
+
+    @Override
+    @ForceInline
+    public Class<E> elementType() {
+        return elementType;
+    }
+
+    @Override
+    @ForceInline
+    public Class<?> boxType() {
+        return boxType;
+    }
+
+    @Override
+    @ForceInline
+    public Class<?> maskType() {
+        return maskType;
+    }
+
+    @Override
+    @ForceInline
+    public int elementSize() {
+        return elementSize;
+    }
+
+    @Override
+    @ForceInline
+    public VectorShape shape() {
+        return shape;
+    }
+
+    @Override
+    @ForceInline
+    public VectorShape indexShape() { return indexShape; }
+
+    @Override
+    public String toString() {
+        return new StringBuilder("Shape[")
+                .append(bitSize()).append(" bits, ")
+                .append(length()).append(" ").append(elementType.getSimpleName()).append("s x ")
+                .append(elementSize()).append(" bits")
+                .append("]")
+                .toString();
+    }
+
+    interface FOpm {
+        boolean apply(int i);
+    }
+
+    VectorMask<E> opm(AbstractSpecies.FOpm f) {
+        boolean[] res = new boolean[length()];
+        for (int i = 0; i < length(); i++) {
+            res[i] = f.apply(i);
+        }
+        return maskFactory.apply(res);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorMask.java	Thu Apr 18 23:47:37 2019 -0700
@@ -0,0 +1,327 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have
+ * questions.
+ */
+package jdk.incubator.vector;
+
+import jdk.internal.misc.Unsafe;
+import jdk.internal.vm.annotation.ForceInline;
+
+import java.util.Objects;
+
+/**
+ * A {@code VectorMask} represents an ordered immutable sequence of {@code boolean}
+ * values.  A VectorMask can be used with a mask accepting vector operation to
+ * control the selection and operation of lane elements of input vectors.
+ * <p>
+ * The number of values in the sequence is referred to as the VectorMask
+ * {@link #length() length}. The length also corresponds to the number of
+ * VectorMask lanes.  The lane element at lane index {@code N} (from {@code 0},
+ * inclusive, to length, exclusive) corresponds to the {@code N + 1}'th
+ * value in the sequence.
+ * A VectorMask and Vector of the same element type and shape have the same number
+ * of lanes.
+ * <p>
+ * A lane is said to be <em>set</em> if the lane element is {@code true},
+ * otherwise a lane is said to be <em>unset</em> if the lane element is
+ * {@code false}.
+ * <p>
+ * VectorMask declares a limited set of unary, binary and reductive mask
+ * operations.
+ * <ul>
+ * <li>
+ * A mask unary operation (1-ary) operates on one input mask to produce a
+ * result mask.
+ * For each lane of the input mask the
+ * lane element is operated on using the specified scalar unary operation and
+ * the boolean result is placed into the mask result at the same lane.
+ * The following pseudocode expresses the behaviour of this operation category:
+ *
+ * <pre>{@code
+ * VectorMask<E> a = ...;
+ * boolean[] ar = new boolean[a.length()];
+ * for (int i = 0; i < a.length(); i++) {
+ *     ar[i] = boolean_unary_op(a.isSet(i));
+ * }
+ * VectorMask<E> r = VectorMask.fromArray(ar, 0);
+ * }</pre>
+ *
+ * <li>
+ * A mask binary operation (2-ary) operates on two input
+ * masks to produce a result mask.
+ * For each lane of the two input masks,
+ * a and b say, the corresponding lane elements from a and b are operated on
+ * using the specified scalar binary operation and the boolean result is placed
+ * into the mask result at the same lane.
+ * The following pseudocode expresses the behaviour of this operation category:
+ *
+ * <pre>{@code
+ * VectorMask<E> a = ...;
+ * VectorMask<E> b = ...;
+ * boolean[] ar = new boolean[a.length()];
+ * for (int i = 0; i < a.length(); i++) {
+ *     ar[i] = scalar_binary_op(a.isSet(i), b.isSet(i));
+ * }
+ * VectorMask<E> r = VectorMask.fromArray(ar, 0);
+ * }</pre>
+ *
+ * </ul>
+ * @param <E> the boxed element type of this mask
+ */
+public abstract class VectorMask<E> {
+    VectorMask() {}
+
+    /**
+     * Returns the species of this mask.
+     *
+     * @return the species of this mask
+     */
+    public abstract VectorSpecies<E> species();
+
+    /**
+     * Returns the number of mask lanes (the length).
+     *
+     * @return the number of mask lanes
+     */
+    public int length() { return species().length(); }
+
+    /**
+     * Returns a mask where each lane is set or unset according to given
+     * {@code boolean} values
+     * <p>
+     * For each mask lane, where {@code N} is the mask lane index,
+     * if the given {@code boolean} value at index {@code N} is {@code true}
+     * then the mask lane at index {@code N} is set, otherwise it is unset.
+     *
+     * @param species mask species
+     * @param bits the given {@code boolean} values
+     * @return a mask where each lane is set or unset according to the given {@code boolean} value
+     * @throws IndexOutOfBoundsException if {@code bits.length < species.length()}
+     */
+    @ForceInline
+    public static <E> VectorMask<E> fromValues(VectorSpecies<E> species, boolean... bits) {
+        return fromArray(species, bits, 0);
+    }
+
+    /**
+     * Loads a mask from a {@code boolean} array starting at an offset.
+     * <p>
+     * For each mask lane, where {@code N} is the mask lane index,
+     * if the array element at index {@code ix + N} is {@code true} then the
+     * mask lane at index {@code N} is set, otherwise it is unset.
+     *
+     * @param species mask species
+     * @param bits the {@code boolean} array
+     * @param ix the offset into the array
+     * @return the mask loaded from a {@code boolean} array
+     * @throws IndexOutOfBoundsException if {@code ix < 0}, or
+     * {@code ix > bits.length - species.length()}
+     */
+    @ForceInline
+    @SuppressWarnings("unchecked")
+    public static <E> VectorMask<E> fromArray(VectorSpecies<E> species, boolean[] bits, int ix) {
+        Objects.requireNonNull(bits);
+        ix = VectorIntrinsics.checkIndex(ix, bits.length, species.length());
+        return VectorIntrinsics.load((Class<VectorMask<E>>) species.maskType(), species.elementType(), species.length(),
+                bits, (long) ix + Unsafe.ARRAY_BOOLEAN_BASE_OFFSET,
+                bits, ix, species,
+                (boolean[] c, int idx, VectorSpecies<E> s) -> ((AbstractSpecies<E>)s).opm(n -> c[idx + n]));
+    }
+
+    /**
+     * Returns a mask where all lanes are set.
+     *
+     * @param species mask species
+     * @return a mask where all lanes are set
+     */
+    @ForceInline
+    @SuppressWarnings("unchecked")
+    public static <E> VectorMask<E> maskAllTrue(VectorSpecies<E> species) {
+        return VectorIntrinsics.broadcastCoerced((Class<VectorMask<E>>) species.maskType(), species.elementType(), species.length(),
+                -1,  species,
+                ((z, s) -> AbstractMask.trueMask(s)));
+    }
+
+    /**
+     * Returns a mask where all lanes are unset.
+     *
+     * @param species mask species
+     * @return a mask where all lanes are unset
+     */
+    @ForceInline
+    @SuppressWarnings("unchecked")
+    public static <E> VectorMask<E> maskAllFalse(VectorSpecies<E> species) {
+        return VectorIntrinsics.broadcastCoerced((Class<VectorMask<E>>) species.maskType(), species.elementType(), species.length(),
+                0, species,
+                ((z, s) -> AbstractMask.falseMask(s)));
+    }
+
+    /**
+     * Converts this mask to a mask of the given species shape of element type {@code F}.
+     * <p>
+     * For each mask lane, where {@code N} is the lane index, if the
+     * mask lane at index {@code N} is set, then the mask lane at index
+     * {@code N} of the resulting mask is set, otherwise that mask lane is
+     * not set.
+     *
+     * @param s the species of the desired mask
+     * @param <F> the boxed element type of the species
+     * @return a mask converted by shape and element type
+     * @throws IllegalArgumentException if this mask length and the species
+     * length differ
+     */
+    public abstract <F> VectorMask<F> cast(VectorSpecies<F> s);
+
+    /**
+     * Returns the lane elements of this mask packed into a {@code long}
+     * value for at most the first 64 lane elements.
+     * <p>
+     * The lane elements are packed in the order of least significant bit
+     * to most significant bit.
+     * For each mask lane where {@code N} is the mask lane index, if the
+     * mask lane is set then the {@code N}'th bit is set to one in the
+     * resulting {@code long} value, otherwise the {@code N}'th bit is set
+     * to zero.
+     *
+     * @return the lane elements of this mask packed into a {@code long}
+     * value.
+     */
+    public abstract long toLong();
+
+    /**
+     * Returns an {@code boolean} array containing the lane elements of this
+     * mask.
+     * <p>
+     * This method behaves as if it {@link #intoArray(boolean[], int)} stores}
+     * this mask into an allocated array and returns that array as
+     * follows:
+     * <pre>{@code
+     * boolean[] a = new boolean[this.length()];
+     * this.intoArray(a, 0);
+     * return a;
+     * }</pre>
+     *
+     * @return an array containing the the lane elements of this vector
+     */
+    public abstract boolean[] toArray();
+
+    /**
+     * Stores this mask into a {@code boolean} array starting at offset.
+     * <p>
+     * For each mask lane, where {@code N} is the mask lane index,
+     * the lane element at index {@code N} is stored into the array at index
+     * {@code i + N}.
+     *
+     * @param a the array
+     * @param i the offset into the array
+     * @throws IndexOutOfBoundsException if {@code i < 0}, or
+     * {@code i > a.length - this.length()}
+     */
+    public abstract void intoArray(boolean[] a, int i);
+
+    /**
+     * Returns {@code true} if any of the mask lanes are set.
+     *
+     * @return {@code true} if any of the mask lanes are set, otherwise
+     * {@code false}.
+     */
+    public abstract boolean anyTrue();
+
+    /**
+     * Returns {@code true} if all of the mask lanes are set.
+     *
+     * @return {@code true} if all of the mask lanes are set, otherwise
+     * {@code false}.
+     */
+    public abstract boolean allTrue();
+
+    /**
+     * Returns the number of mask lanes that are set.
+     *
+     * @return the number of mask lanes that are set.
+     */
+    public abstract int trueCount();
+
+    /**
+     * Logically ands this mask with an input mask.
+     * <p>
+     * This is a mask binary operation where the logical and operation
+     * ({@code &&} is applied to lane elements.
+     *
+     * @param o the input mask
+     * @return the result of logically and'ing this mask with an input mask
+     */
+    public abstract VectorMask<E> and(VectorMask<E> o);
+
+    /**
+     * Logically ors this mask with an input mask.
+     * <p>
+     * This is a mask binary operation where the logical or operation
+     * ({@code ||} is applied to lane elements.
+     *
+     * @param o the input mask
+     * @return the result of logically or'ing this mask with an input mask
+     */
+    public abstract VectorMask<E> or(VectorMask<E> o);
+
+    /**
+     * Logically negates this mask.
+     * <p>
+     * This is a mask unary operation where the logical not operation
+     * ({@code !} is applied to lane elements.
+     *
+     * @return the result of logically negating this mask.
+     */
+    public abstract VectorMask<E> not();
+
+    /**
+     * Returns a vector representation of this mask.
+     * <p>
+     * For each mask lane, where {@code N} is the mask lane index,
+     * if the mask lane is set then an element value whose most significant
+     * bit is set is placed into the resulting vector at lane index
+     * {@code N}, otherwise the default element value is placed into the
+     * resulting vector at lane index {@code N}.
+     *
+     * @return a vector representation of this mask.
+     */
+    public abstract Vector<E> toVector();
+
+    /**
+     * Tests if the lane at index {@code i} is set
+     * @param i the lane index
+     *
+     * @return true if the lane at index {@code i} is set, otherwise false
+     */
+    public abstract boolean getElement(int i);
+
+    /**
+     * Tests if the lane at index {@code i} is set
+     * @param i the lane index
+     * @return true if the lane at index {@code i} is set, otherwise false
+     * @see #getElement
+     */
+    public boolean isSet(int i) {
+        return getElement(i);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorShape.java	Thu Apr 18 23:47:37 2019 -0700
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have
+ * questions.
+ */
+package jdk.incubator.vector;
+
+import jdk.internal.misc.Unsafe;
+import jdk.internal.vm.annotation.Stable;
+
+/**
+ * A {@code VectorShape} governs the total size, in bits, of a
+ * {@link Vector}, {@link VectorMask}, or {@link VectorShuffle}.  The shape in
+ * combination with the element type together govern the number of lanes.
+ */
+public enum VectorShape {
+    /** Shape of length 64 bits */
+    S_64_BIT(64),
+    /** Shape of length 128 bits */
+    S_128_BIT(128),
+    /** Shape of length 256 bits */
+    S_256_BIT(256),
+    /** Shape of length 512 bits */
+    S_512_BIT(512),
+    /** Shape of maximum length supported on the platform */
+    S_Max_BIT(Unsafe.getUnsafe().getMaxVectorSize(byte.class) * 8);
+
+    @Stable
+    final int bitSize;
+
+    VectorShape(int bitSize) {
+        this.bitSize = bitSize;
+    }
+
+    /**
+     * Returns the size, in bits, of this shape.
+     *
+     * @return the size, in bits, of this shape.
+     */
+    public int bitSize() {
+        return bitSize;
+    }
+
+    /**
+     * Return the number of lanes of a vector of this shape and whose element
+     * type is of the provided species
+     *
+     * @param s the species describing the element type
+     * @return the number of lanes
+     */
+    int length(VectorSpecies<?> s) {
+        return bitSize() / s.elementSize();
+    }
+
+    /**
+     * Finds appropriate shape depending on bitsize.
+     *
+     * @param bitSize the size in bits
+     * @return the shape corresponding to bitsize
+     * @see #bitSize
+     */
+    public static VectorShape forBitSize(int bitSize) {
+        switch (bitSize) {
+            case 64:
+                return VectorShape.S_64_BIT;
+            case 128:
+                return VectorShape.S_128_BIT;
+            case 256:
+                return VectorShape.S_256_BIT;
+            case 512:
+                return VectorShape.S_512_BIT;
+            default:
+                if ((bitSize > 0) && (bitSize <= 2048) && (bitSize % 128 == 0)) {
+                    return VectorShape.S_Max_BIT;
+                } else {
+                    throw new IllegalArgumentException("Bad vector bit size: " + bitSize);
+                }
+        }
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorShuffle.java	Thu Apr 18 23:47:37 2019 -0700
@@ -0,0 +1,244 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have
+ * questions.
+ */
+package jdk.incubator.vector;
+
+import jdk.internal.vm.annotation.ForceInline;
+import java.util.function.IntUnaryOperator;
+
+/**
+ * A {@code VectorShuffle} represents an ordered immutable sequence of
+ * {@code int} values.  A VectorShuffle can be used with a shuffle accepting
+ * vector operation to control the rearrangement of lane elements of input
+ * vectors
+ * <p>
+ * The number of values in the sequence is referred to as the shuffle
+ * {@link #length() length}.  The length also corresponds to the number of
+ * shuffle lanes.  The lane element at lane index {@code N} (from {@code 0},
+ * inclusive, to length, exclusive) corresponds to the {@code N + 1}'th
+ * value in the sequence.
+ * A VectorShuffle and Vector of the same element type and shape have the same
+ * number of lanes.
+ * <p>
+ * A VectorShuffle describes how a lane element of a vector may cross lanes from
+ * its lane index, {@code i} say, to another lane index whose value is the
+ * shuffle's lane element at lane index {@code i}.  VectorShuffle lane elements
+ * will be in the range of {@code 0} (inclusive) to the shuffle length
+ * (exclusive), and therefore cannot induce out of bounds errors when
+ * used with vectors operations and vectors of the same length.
+ *
+ * @param <E> the boxed element type of this mask
+ */
+public abstract class VectorShuffle<E> {
+    VectorShuffle() {}
+
+    /**
+     * Returns the species of this shuffle.
+     *
+     * @return the species of this shuffle
+     */
+    public abstract VectorSpecies<E> species();
+
+    /**
+     * Returns the number of shuffle lanes (the length).
+     *
+     * @return the number of shuffle lanes
+     */
+    public int length() { return species().length(); }
+
+    /**
+     * Converts this shuffle to a shuffle of the given species of element type {@code F}.
+     * <p>
+     * For each shuffle lane, where {@code N} is the lane index, the
+     * shuffle element at index {@code N} is placed, unmodified, into the
+     * resulting shuffle at index {@code N}.
+     *
+     * @param species species of desired shuffle
+     * @param <F> the boxed element type of the species
+     * @return a shuffle converted by shape and element type
+     * @throws IllegalArgumentException if this shuffle length and the
+     * species length differ
+     */
+    public abstract <F> VectorShuffle<F> cast(VectorSpecies<F> species);
+
+    /**
+     * Returns a shuffle of mapped indexes where each lane element is
+     * the result of applying a mapping function to the corresponding lane
+     * index.
+     * <p>
+     * Care should be taken to ensure VectorShuffle values produced from this
+     * method are consumed as constants to ensure optimal generation of
+     * code.  For example, values held in static final fields or values
+     * held in loop constant local variables.
+     * <p>
+     * This method behaves as if a shuffle is created from an array of
+     * mapped indexes as follows:
+     * <pre>{@code
+     *   int[] a = new int[species.length()];
+     *   for (int i = 0; i < a.length; i++) {
+     *       a[i] = f.applyAsInt(i);
+     *   }
+     *   return VectorShuffle.fromValues(a);
+     * }</pre>
+     *
+     * @param species shuffle species
+     * @param f the lane index mapping function
+     * @return a shuffle of mapped indexes
+     */
+    @ForceInline
+    public static <E> VectorShuffle<E> shuffle(VectorSpecies<E> species, IntUnaryOperator f) {
+        return ((AbstractSpecies<E>) species).shuffleFromOpFactory.apply(f);
+    }
+
+    /**
+     * Returns a shuffle where each lane element is the value of its
+     * corresponding lane index.
+     * <p>
+     * This method behaves as if a shuffle is created from an identity
+     * index mapping function as follows:
+     * <pre>{@code
+     *   return VectorShuffle.shuffle(i -> i);
+     * }</pre>
+     *
+     * @param species shuffle species
+     * @return a shuffle of lane indexes
+     */
+    @ForceInline
+    public static <E> VectorShuffle<E> shuffleIota(VectorSpecies<E> species) {
+        return ((AbstractSpecies<E>) species).shuffleFromOpFactory.apply(AbstractShuffle.IDENTITY);
+    }
+
+    /**
+     * Returns a shuffle where each lane element is set to a given
+     * {@code int} value logically AND'ed by the species length minus one.
+     * <p>
+     * For each shuffle lane, where {@code N} is the shuffle lane index, the
+     * the {@code int} value at index {@code N} logically AND'ed by
+     * {@code species.length() - 1} is placed into the resulting shuffle at
+     * lane index {@code N}.
+     *
+     * @param species shuffle species
+     * @param ixs the given {@code int} values
+     * @return a shuffle where each lane element is set to a given
+     * {@code int} value
+     * @throws IndexOutOfBoundsException if the number of int values is
+     * {@code < species.length()}
+     */
+    @ForceInline
+    public static <E> VectorShuffle<E> fromValues(VectorSpecies<E> species, int... ixs) {
+        return ((AbstractSpecies<E>) species).shuffleFromArrayFactory.apply(ixs, 0);
+    }
+
+    /**
+     * Loads a shuffle from an {@code int} array starting at an offset.
+     * <p>
+     * For each shuffle lane, where {@code N} is the shuffle lane index, the
+     * array element at index {@code i + N} logically AND'ed by
+     * {@code species.length() - 1} is placed into the resulting shuffle at lane
+     * index {@code N}.
+     *
+     * @param species shuffle species
+     * @param ixs the {@code int} array
+     * @param i the offset into the array
+     * @return a shuffle loaded from the {@code int} array
+     * @throws IndexOutOfBoundsException if {@code i < 0}, or
+     * {@code i > a.length - species.length()}
+     */
+    @ForceInline
+    public static <E> VectorShuffle<E> fromArray(VectorSpecies<E> species, int[] ixs, int i) {
+        return ((AbstractSpecies<E>) species).shuffleFromArrayFactory.apply(ixs, i);
+    }
+
+    /**
+     * Returns an {@code int} array containing the lane elements of this
+     * shuffle.
+     * <p>
+     * This method behaves as if it {@link #intoArray(int[], int)} stores}
+     * this shuffle into an allocated array and returns that array as
+     * follows:
+     * <pre>{@code
+     *   int[] a = new int[this.length()];
+     *   VectorShuffle.intoArray(a, 0);
+     *   return a;
+     * }</pre>
+     *
+     * @return an array containing the the lane elements of this vector
+     */
+    public abstract int[] toArray();
+
+    /**
+     * Stores this shuffle into an {@code int} array starting at offset.
+     * <p>
+     * For each shuffle lane, where {@code N} is the shuffle lane index,
+     * the lane element at index {@code N} is stored into the array at index
+     * {@code i + N}.
+     *
+     * @param a the array
+     * @param i the offset into the array
+     * @throws IndexOutOfBoundsException if {@code i < 0}, or
+     * {@code i > a.length - this.length()}
+     */
+    public abstract void intoArray(int[] a, int i);
+
+    /**
+     * Converts this shuffle into a vector, creating a vector from shuffle
+     * lane elements (int values) cast to the vector element type.
+     * <p>
+     * This method behaves as if it returns the result of creating a
+     * vector given an {@code int} array obtained from this shuffle's
+     * lane elements, as follows:
+     * <pre>{@code
+     *   int[] sa = this.toArray();
+     *   $type$[] va = new $type$[a.length];
+     *   for (int i = 0; i < a.length; i++) {
+     *       va[i] = ($type$) sa[i];
+     *   }
+     *   return IntVector.fromArray(va, 0);
+     * }</pre>
+     *
+     * @return a vector representation of this shuffle
+     */
+    public abstract Vector<E> toVector();
+
+    /**
+     * Gets the {@code int} lane element at lane index {@code i}
+     *
+     * @param i the lane index
+     * @return the {@code int} lane element at lane index {@code i}
+     */
+    public int getElement(int i) { return toArray()[i]; }
+
+    /**
+     * Rearranges the lane elements of this shuffle selecting lane indexes
+     * controlled by another shuffle.
+     * <p>
+     * For each lane of the specified shuffle, at lane index {@code N} with lane
+     * element {@code I}, the lane element at {@code I} from this shuffle is
+     * selected and placed into the resulting shuffle at {@code N}.
+     *
+     * @param s the shuffle controlling lane index selection
+     * @return the rearrangement of the lane elements of this shuffle
+     */
+    public abstract VectorShuffle<E> rearrange(VectorShuffle<E> s);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/jdk.incubator.vector/share/classes/jdk/incubator/vector/VectorSpecies.java	Thu Apr 18 23:47:37 2019 -0700
@@ -0,0 +1,158 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have
+ * questions.
+ */
+package jdk.incubator.vector;
+
+import jdk.internal.misc.Unsafe;
+import jdk.internal.vm.annotation.ForceInline;
+import java.util.function.Function;
+import java.util.function.IntUnaryOperator;
+
+/**
+ * Interface supporting vectors of same element type, {@code E} and {@link VectorShape shape}.
+ *
+ * @param <E> the boxed element type of this species
+ */
+public interface VectorSpecies<E> {
+    /**
+     * Returns the primitive element type of vectors produced by this
+     * species.
+     *
+     * @return the primitive element type
+     */
+    public abstract Class<E> elementType();
+
+    /**
+     * Returns the vector box type for this species
+     *
+     * @return the box type
+     */
+    abstract Class<?> boxType();
+
+    /**
+     * Returns the vector mask type for this species
+     *
+     * @return the box type
+     */
+    abstract Class<?> maskType();
+
+    /**
+     * Returns the element size, in bits, of vectors produced by this
+     * species.
+     *
+     * @return the element size, in bits
+     */
+    public abstract int elementSize();
+
+    /**
+     * Returns the shape of masks, shuffles, and vectors produced by this
+     * species.
+     *
+     * @return the primitive element type
+     */
+    public abstract VectorShape shape();
+
+    /**
+     * Returns the shape of the corresponding index species
+     * @return the shape
+     */
+    @ForceInline
+    public abstract VectorShape indexShape();
+
+    /**
+     * Returns the mask, shuffe, or vector lanes produced by this species.
+     *
+     * @return the the number of lanes
+     */
+    default public int length() { return shape().length(this); }
+
+    /**
+     * Returns the total vector size, in bits, of vectors produced by this
+     * species.
+     *
+     * @return the total vector size, in bits
+     */
+    default public int bitSize() { return shape().bitSize(); }
+
+    // Factory
+
+    /**
+     * Finds a species for an element type and shape.
+     *
+     * @param c the element type
+     * @param s the shape
+     * @param <E> the boxed element type
+     * @return a species for an element type and shape
+     * @throws IllegalArgumentException if no such species exists for the
+     * element type and/or shape
+     */
+    @SuppressWarnings("unchecked")
+    public static <E> VectorSpecies<E> of(Class<E> c, VectorShape s) {
+        if (c == float.class) {
+            return (VectorSpecies<E>) FloatVector.species(s);
+        }
+        else if (c == double.class) {
+            return (VectorSpecies<E>) DoubleVector.species(s);
+        }
+        else if (c == byte.class) {
+            return (VectorSpecies<E>) ByteVector.species(s);
+        }
+        else if (c == short.class) {
+            return (VectorSpecies<E>) ShortVector.species(s);
+        }
+        else if (c == int.class) {
+            return (VectorSpecies<E>) IntVector.species(s);
+        }
+        else if (c == long.class) {
+            return (VectorSpecies<E>) LongVector.species(s);
+        }
+        else {
+            throw new IllegalArgumentException("Bad vector element type: " + c.getName());
+        }
+    }
+
+    /**
+     * Finds a preferred species for an element type.
+     * <p>
+     * A preferred species is a species chosen by the platform that has a
+     * shape of maximal bit size.  A preferred species for different element
+     * types will have the same shape, and therefore vectors created from
+     * such species will be shape compatible.
+     *
+     * @param c the element type
+     * @param <E> the boxed element type
+     * @return a preferred species for an element type
+     * @throws IllegalArgumentException if no such species exists for the
+     * element type
+     */
+    public static <E> VectorSpecies<E> ofPreferred(Class<E> c) {
+        Unsafe u = Unsafe.getUnsafe();
+
+        int vectorLength = u.getMaxVectorSize(c);
+        int vectorBitSize = Vector.bitSizeForVectorLength(c, vectorLength);
+        VectorShape s = VectorShape.forBitSize(vectorBitSize);
+        return VectorSpecies.of(c, s);
+    }
+}
+