< prev index next >

src/jdk.incubator.vector/share/classes/jdk/incubator/vector/AbstractMask.java

Print this page

  7  * published by the Free Software Foundation.  Oracle designates this
  8  * particular file as subject to the "Classpath" exception as provided
  9  * by Oracle in the LICENSE file that accompanied this code.
 10  *
 11  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  * version 2 for more details (a copy is included in the LICENSE file that
 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  */
 25 package jdk.incubator.vector;
 26 


 27 import jdk.internal.vm.annotation.ForceInline;
 28 
 29 import static jdk.incubator.vector.VectorOperators.*;
 30 
 31 abstract class AbstractMask<E> extends VectorMask<E> {
 32     AbstractMask(boolean[] bits) {
 33         super(bits);
 34     }
 35 
 36     /*package-private*/
 37     abstract boolean[] getBits();
 38 
 39     // Unary operator
 40 
 41     interface MUnOp {
 42         boolean apply(int i, boolean a);
 43     }
 44 
 45     abstract AbstractMask<E> uOp(MUnOp f);
 46 
 47     // Binary operator
 48 
 49     interface MBinOp {
 50         boolean apply(int i, boolean a, boolean b);
 51     }
 52 
 53     abstract AbstractMask<E> bOp(VectorMask<E> o, MBinOp f);
 54 
 55     /*package-private*/
 56     abstract AbstractSpecies<E> vspecies();
 57 
 58     @Override
 59     @ForceInline
 60     public final VectorSpecies<E> vectorSpecies() {
 61         return vspecies();
 62     }
 63 
 64     @Override
 65     public boolean laneIsSet(int i) {
 66         return getBits()[i];
 67     }
 68 
 69     @Override
 70     public long toLong() {
 71         // FIXME: This should be an intrinsic.
 72         if (length() > Long.SIZE) {
 73             throw new UnsupportedOperationException("too many lanes for one long");
 74         }
 75         long res = 0;
 76         long set = 1;
 77         boolean[] bits = getBits();
 78         for (int i = 0; i < bits.length; i++) {
 79             res = bits[i] ? res | set : res;
 80             set = set << 1;
 81         }
 82         return res;
 83     }
 84 
 85     @Override
 86     public void intoArray(boolean[] bits, int i) {
 87         System.arraycopy(getBits(), 0, bits, i, length());
 88     }
 89 
 90     @Override
 91     public boolean[] toArray() {
 92         return getBits().clone();
 93     }
 94 
 95     @Override
 96     @ForceInline
 97     @SuppressWarnings("unchecked")
 98     public
 99     <F> VectorMask<F> check(Class<F> elementType) {
100         if (vectorSpecies().elementType() != elementType) {
101             throw AbstractSpecies.checkFailed(this, elementType);
102         }
103         return (VectorMask<F>) this;
104     }
105 
106     @Override
107     @ForceInline
108     @SuppressWarnings("unchecked")
109     public
110     <F> VectorMask<F> check(VectorSpecies<F> species) {
111         if (species != vectorSpecies()) {
112             throw AbstractSpecies.checkFailed(this, species);
113         }
114         return (VectorMask<F>) this;
115     }
116 

















117     @Override
118     public VectorMask<E> andNot(VectorMask<E> m) {
119         return and(m.not());
120     }
121 
122     /*package-private*/
123     static boolean anyTrueHelper(boolean[] bits) {
124         // FIXME: Maybe use toLong() != 0 here.
125         for (boolean i : bits) {
126             if (i) return true;
127         }
128         return false;
129     }
130 
131     /*package-private*/
132     static boolean allTrueHelper(boolean[] bits) {
133         // FIXME: Maybe use not().toLong() == 0 here.
134         for (boolean i : bits) {
135             if (!i) return false;
136         }

145         }
146         return c;
147     }
148 
149     /*package-private*/
150     static int firstTrueHelper(boolean[] bits) {
151         for (int i = 0; i < bits.length; i++) {
152             if (bits[i])  return i;
153         }
154         return bits.length;
155     }
156 
157     /*package-private*/
158     static int lastTrueHelper(boolean[] bits) {
159         for (int i = bits.length-1; i >= 0; i--) {
160             if (bits[i])  return i;
161         }
162         return -1;
163     }
164 











165     @Override
166     @ForceInline
167     public VectorMask<E> indexInRange(int offset, int limit) {
168         int vlength = length();
169         Vector<E> iota = vectorSpecies().zero().addIndex(1);
170         VectorMask<E> badMask = checkIndex0(offset, limit, iota, vlength);
171         return this.andNot(badMask);
172     }
173 
174     /*package-private*/
175     @ForceInline
176     AbstractVector<E>
177     toVectorTemplate() {
178         AbstractSpecies<E> vsp = vspecies();
179         Vector<E> zero = vsp.broadcast(0);
180         Vector<E> mone = vsp.broadcast(-1);
181         // -1 will result in the most significant bit being set in
182         // addition to some or all other lane bits.
183         // For integral types, *all* lane bits will be set.
184         // The bits for -1.0 are like {0b10111*0000*}.

198                           Vector<E> iota,
199                           int esize) {
200         if (VectorIntrinsics.VECTOR_ACCESS_OOB_CHECK == 0) {
201             return;
202         }
203         // Although the specification is simple, the implementation is
204         // tricky, because the value iota*esize might possibly
205         // overflow.  So we calculate our test values as scalars,
206         // clipping to the range [-1..VLENGTH], and test them against
207         // the unscaled iota vector, whose values are in [0..VLENGTH-1].
208         int vlength = length();
209         VectorMask<E> badMask;
210         if (esize == 1) {
211             badMask = checkIndex0(offset, alength, iota, vlength);
212         } else if (offset >= 0) {
213             // Masked access to multi-byte lanes in byte array.
214             // It could be aligned anywhere.
215             int elemCount = Math.min(vlength, (alength - offset) / esize);
216             badMask = checkIndex0(0, elemCount, iota, vlength);
217         } else {
218             // This requires a split test.
219             int clipOffset = Math.max(offset, -(vlength * esize));
220             int elemCount = Math.min(vlength, (alength - clipOffset) / esize);
221             badMask = checkIndex0(0, elemCount, iota, vlength);
222             clipOffset &= (esize - 1);  // power of two, so OK
223             VectorMask<E> badMask2 = checkIndex0(clipOffset / esize, vlength,
224                                                  iota, vlength);
225             badMask = badMask.or(badMask2);
226         }
227         badMask = badMask.and(this);
228         if (badMask.anyTrue()) {
229             int badLane = badMask.firstTrue();
230             throw ((AbstractMask<E>)badMask)
231                    .checkIndexFailed(offset, badLane, alength, esize);
232         }
233     }
234 
235     private
236     @ForceInline
237     VectorMask<E> checkIndex0(int offset, int alength,
238                               Vector<E> iota, int vlength) {
239         // An active lane is bad if its number is greater than
240         // alength-offset, since when added to offset it will step off
241         // of the end of the array.  To avoid overflow when
242         // converting, clip the comparison value to [0..vlength]
243         // inclusive.
244         int indexLimit = Math.max(0, Math.min(alength - offset, vlength));
245         VectorMask<E> badMask =

  7  * published by the Free Software Foundation.  Oracle designates this
  8  * particular file as subject to the "Classpath" exception as provided
  9  * by Oracle in the LICENSE file that accompanied this code.
 10  *
 11  * This code is distributed in the hope that it will be useful, but WITHOUT
 12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 14  * version 2 for more details (a copy is included in the LICENSE file that
 15  * accompanied this code).
 16  *
 17  * You should have received a copy of the GNU General Public License version
 18  * 2 along with this work; if not, write to the Free Software Foundation,
 19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 20  *
 21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 22  * or visit www.oracle.com if you need additional information or have any
 23  * questions.
 24  */
 25 package jdk.incubator.vector;
 26 
 27 import java.util.Objects;
 28 
 29 import jdk.internal.vm.annotation.ForceInline;
 30 
 31 import static jdk.incubator.vector.VectorOperators.*;
 32 
 33 abstract class AbstractMask<E> extends VectorMask<E> {
 34     AbstractMask(boolean[] bits) {
 35         super(bits);
 36     }
 37 
 38     /*package-private*/
 39     abstract boolean[] getBits();
 40 
 41     // Unary operator
 42 
 43     interface MUnOp {
 44         boolean apply(int i, boolean a);
 45     }
 46 
 47     abstract AbstractMask<E> uOp(MUnOp f);
 48 
 49     // Binary operator
 50 
 51     interface MBinOp {
 52         boolean apply(int i, boolean a, boolean b);
 53     }
 54 
 55     abstract AbstractMask<E> bOp(VectorMask<E> o, MBinOp f);
 56 
 57     /*package-private*/
 58     abstract AbstractSpecies<E> vspecies();
 59 
 60     @Override
 61     @ForceInline
 62     public final VectorSpecies<E> vectorSpecies() {
 63         return vspecies();
 64     }
 65 
 66     @Override
 67     public boolean laneIsSet(int i) {
 68         int length = length();
 69         Objects.checkIndex(i, length);
 70         if (length <= Long.SIZE) {
 71             return ((toLong() >>> i) & 1L) == 1;
 72         } else {
 73             return getBits()[i];









 74         }

 75     }
 76 
 77     @Override
 78     public void intoArray(boolean[] bits, int i) {
 79         System.arraycopy(getBits(), 0, bits, i, length());
 80     }
 81 
 82     @Override
 83     public boolean[] toArray() {
 84         return getBits().clone();
 85     }
 86 
 87     @Override
 88     @ForceInline
 89     @SuppressWarnings("unchecked")
 90     public
 91     <F> VectorMask<F> check(Class<F> elementType) {
 92         if (vectorSpecies().elementType() != elementType) {
 93             throw AbstractSpecies.checkFailed(this, elementType);
 94         }
 95         return (VectorMask<F>) this;
 96     }
 97 
 98     @Override
 99     @ForceInline
100     @SuppressWarnings("unchecked")
101     public
102     <F> VectorMask<F> check(VectorSpecies<F> species) {
103         if (species != vectorSpecies()) {
104             throw AbstractSpecies.checkFailed(this, species);
105         }
106         return (VectorMask<F>) this;
107     }
108 
109     @Override
110     @ForceInline
111     @SuppressWarnings("unchecked")
112     <F> VectorMask<F> check(Class<? extends VectorMask<F>> maskClass, Vector<F> vector) {
113         if (!sameSpecies(maskClass, vector)) {
114             throw AbstractSpecies.checkFailed(this, vector);
115         }
116         return (VectorMask<F>) this;
117     }
118 
119     @ForceInline
120     private <F> boolean sameSpecies(Class<? extends VectorMask<F>> maskClass, Vector<F> vector) {
121         boolean same = getClass() == maskClass;
122         assert (same == (vectorSpecies() == vector.species())) : same;
123         return same;
124     }
125 
126     @Override
127     public VectorMask<E> andNot(VectorMask<E> m) {
128         return and(m.not());
129     }
130 
131     /*package-private*/
132     static boolean anyTrueHelper(boolean[] bits) {
133         // FIXME: Maybe use toLong() != 0 here.
134         for (boolean i : bits) {
135             if (i) return true;
136         }
137         return false;
138     }
139 
140     /*package-private*/
141     static boolean allTrueHelper(boolean[] bits) {
142         // FIXME: Maybe use not().toLong() == 0 here.
143         for (boolean i : bits) {
144             if (!i) return false;
145         }

154         }
155         return c;
156     }
157 
158     /*package-private*/
159     static int firstTrueHelper(boolean[] bits) {
160         for (int i = 0; i < bits.length; i++) {
161             if (bits[i])  return i;
162         }
163         return bits.length;
164     }
165 
166     /*package-private*/
167     static int lastTrueHelper(boolean[] bits) {
168         for (int i = bits.length-1; i >= 0; i--) {
169             if (bits[i])  return i;
170         }
171         return -1;
172     }
173 
174     /*package-private*/
175     static long toLongHelper(boolean[] bits) {
176         long res = 0;
177         long set = 1;
178         for (int i = 0; i < bits.length; i++) {
179             res = bits[i] ? res | set : res;
180             set = set << 1;
181         }
182         return res;
183     }
184 
185     @Override
186     @ForceInline
187     public VectorMask<E> indexInRange(int offset, int limit) {
188         int vlength = length();
189         Vector<E> iota = vectorSpecies().zero().addIndex(1);
190         VectorMask<E> badMask = checkIndex0(offset, limit, iota, vlength);
191         return this.andNot(badMask);
192     }
193 
194     /*package-private*/
195     @ForceInline
196     AbstractVector<E>
197     toVectorTemplate() {
198         AbstractSpecies<E> vsp = vspecies();
199         Vector<E> zero = vsp.broadcast(0);
200         Vector<E> mone = vsp.broadcast(-1);
201         // -1 will result in the most significant bit being set in
202         // addition to some or all other lane bits.
203         // For integral types, *all* lane bits will be set.
204         // The bits for -1.0 are like {0b10111*0000*}.

218                           Vector<E> iota,
219                           int esize) {
220         if (VectorIntrinsics.VECTOR_ACCESS_OOB_CHECK == 0) {
221             return;
222         }
223         // Although the specification is simple, the implementation is
224         // tricky, because the value iota*esize might possibly
225         // overflow.  So we calculate our test values as scalars,
226         // clipping to the range [-1..VLENGTH], and test them against
227         // the unscaled iota vector, whose values are in [0..VLENGTH-1].
228         int vlength = length();
229         VectorMask<E> badMask;
230         if (esize == 1) {
231             badMask = checkIndex0(offset, alength, iota, vlength);
232         } else if (offset >= 0) {
233             // Masked access to multi-byte lanes in byte array.
234             // It could be aligned anywhere.
235             int elemCount = Math.min(vlength, (alength - offset) / esize);
236             badMask = checkIndex0(0, elemCount, iota, vlength);
237         } else {

238             int clipOffset = Math.max(offset, -(vlength * esize));
239             badMask = checkIndex0(clipOffset, alength,
240                                   iota.lanewise(VectorOperators.MUL, esize),
241                                   vlength * esize);



242         }
243         badMask = badMask.and(this);
244         if (badMask.anyTrue()) {
245             int badLane = badMask.firstTrue();
246             throw ((AbstractMask<E>)badMask)
247                    .checkIndexFailed(offset, badLane, alength, esize);
248         }
249     }
250 
251     private
252     @ForceInline
253     VectorMask<E> checkIndex0(int offset, int alength,
254                               Vector<E> iota, int vlength) {
255         // An active lane is bad if its number is greater than
256         // alength-offset, since when added to offset it will step off
257         // of the end of the array.  To avoid overflow when
258         // converting, clip the comparison value to [0..vlength]
259         // inclusive.
260         int indexLimit = Math.max(0, Math.min(alength - offset, vlength));
261         VectorMask<E> badMask =
< prev index next >