1 /* 2 * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 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 26 import jdk.experimental.value.ValueType; 27 28 import java.lang.invoke.MethodHandle; 29 import java.lang.invoke.MethodHandles; 30 31 import static java.lang.invoke.MethodType.methodType; 32 import org.testng.annotations.*; 33 34 import static org.testng.Assert.assertEquals; 35 36 /* 37 * @test 38 * @run testng/othervm -XX:+EnableMVT VectorTest 39 */ 40 41 @Test 42 public class VectorTest { 43 static final ValueType<?> VT = ValueType.forClass(Long2.class); 44 45 static /* QLong2[] */ Object initL2Array(int length) { 46 try { 47 Object arr = MethodHandles.arrayConstructor(VT.arrayValueClass()).invoke(length); 48 for (int i = 0; i < length; i++) { 49 Long2 v = new Long2(2 * i, 2 * i + 1); 50 MethodHandles.arrayElementSetter(VT.arrayValueClass()).invoke(arr, i, v); 51 } 52 return arr; 53 } catch (Throwable e) { 54 throw new Error(e); 55 } 56 } 57 58 static final MethodHandle SUM_ARRAY_L2 = 59 VectorUtils.reducerLoop(VT, VectorLibrary.L2.ADD_L, VectorLibrary.L2.HADD_L, VT.defaultValueConstant()). 60 asType(methodType(long.class, Object.class)); 61 62 /** 63 * long sum(QLong2[] a) { 64 * QLong2 v = QLong2.default; // (0,0) 65 * for (int i = 0; i < a.length; i++) { 66 * v = QLong2(v.lo + a[i].lo, v.hi + a[i].hi); 67 * } 68 * return v.lo + v.hi; 69 * } 70 */ 71 // @DontInline 72 static long sumArrayL2(Object arr) { 73 try { 74 return (long) SUM_ARRAY_L2.invokeExact(arr); 75 } catch (Throwable e) { 76 throw new Error(e); 77 } 78 } 79 80 @Test(dataProvider = "arraySizes") 81 public void testSumArray(Integer size) { 82 Object arr = initL2Array(size); // QLong2[size] 83 long expected = size * (2*size - 1); 84 for (int i = 0; i < 20_000; i++) { 85 long sum = sumArrayL2(arr); 86 assertEquals(expected, sum); 87 } 88 } 89 90 /*========================================================*/ 91 92 static MethodHandle createConditional() { 93 // T target(A...,B...); 94 // T fallback(A...,B...); 95 // T adapter(A... a,B... b) { 96 // if (test(a...)) 97 // return target(a..., b...); 98 // else 99 // return fallback(a..., b...); 100 // } 101 MethodHandle test = MethodHandles.identity(boolean.class); 102 103 MethodHandle add = VectorLibrary.L2.ADD_L; 104 MethodHandle addVL = MethodHandles.filterArguments(add, 1, VT.unbox()); 105 MethodHandle inc = MethodHandles.insertArguments(addVL, 1, new Long2(1L, 1L)); 106 MethodHandle incZ = MethodHandles.dropArguments(inc, 0, boolean.class); 107 108 MethodHandle idZ = MethodHandles.dropArguments(VT.identity(), 0, boolean.class); 109 110 // (boolean, QLong2)QLong2 111 MethodHandle gwt = MethodHandles.guardWithTest(test, incZ, idZ); 112 return gwt; 113 } 114 115 static final MethodHandle conditionalMH = createConditional(). 116 asType(methodType(Long2.class, boolean.class, Long2.class)); 117 118 // @DontInline 119 static Long2 conditional(boolean b, Long2 v) { 120 try { 121 return (Long2) conditionalMH.invokeExact(b, v); 122 } catch (Throwable e) { 123 throw new Error(e); 124 } 125 } 126 127 public void testConditional() { 128 Long2 v = new Long2(1L, 2L); 129 for (int i = 0; i < 20_000; i++) { 130 conditional(true, v); 131 conditional(false, v); 132 } 133 } 134 135 @DataProvider(name = "arraySizes") 136 public Object[][] arraySizes() { 137 return new Object[][] { 138 new Object[] { 1 }, 139 new Object[] { 5 }, 140 new Object[] { 10 }, 141 new Object[] { 0 } 142 }; 143 } 144 } 145