1 /* 2 * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. 3 * Copyright (c) 2019, 2020, Arm Limited. All rights reserved. 4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5 * 6 * This code is free software; you can redistribute it and/or modify it 7 * under the terms of the GNU General Public License version 2 only, as 8 * published by the Free Software Foundation. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 */ 24 25 26 package org.graalvm.compiler.core.aarch64.test; 27 28 import org.graalvm.compiler.api.directives.GraalDirectives; 29 import org.graalvm.compiler.lir.LIRInstruction; 30 import org.graalvm.compiler.lir.aarch64.AArch64ArithmeticOp.ExtendedAddSubShiftOp; 31 import org.junit.Test; 32 33 import java.util.ArrayDeque; 34 import java.util.HashSet; 35 import java.util.Set; 36 import java.util.function.Predicate; 37 38 public class AArch64ArrayAddressTest extends AArch64MatchRuleTest { 39 private static final Predicate<LIRInstruction> predicate = op -> (op instanceof ExtendedAddSubShiftOp); 40 loadByte(byte[] arr, int n)41 public static byte loadByte(byte[] arr, int n) { 42 return arr[n]; 43 } 44 45 @Test testLoadByte()46 public void testLoadByte() { 47 byte[] arr = {3, 4, 5, 6, 7, 8}; 48 test("loadByte", arr, 5); 49 checkLIR("loadByte", predicate, 1, 1); 50 } 51 loadChar(char[] arr, int n)52 public static char loadChar(char[] arr, int n) { 53 return arr[n]; 54 } 55 56 @Test testLoadChar()57 public void testLoadChar() { 58 char[] arr = {'a', 'b', 'c', 'd', 'e', 'f', 'g'}; 59 test("loadChar", arr, 5); 60 checkLIR("loadChar", predicate, 1, 1); 61 } 62 loadShort(short[] arr, int n)63 public static short loadShort(short[] arr, int n) { 64 return arr[n]; 65 } 66 67 @Test testLoadShort()68 public void testLoadShort() { 69 short[] arr = {3, 4, 5, 6, 7, 8}; 70 test("loadShort", arr, 5); 71 checkLIR("loadShort", predicate, 1, 1); 72 } 73 loadInt(int[] arr, int n)74 public static int loadInt(int[] arr, int n) { 75 return arr[n]; 76 } 77 78 @Test testLoadInt()79 public void testLoadInt() { 80 int[] arr = {3, 4, 5, 6, 7, 8}; 81 test("loadInt", arr, 5); 82 checkLIR("loadInt", predicate, 1, 1); 83 } 84 loadLong(long[] arr, int n)85 public static long loadLong(long[] arr, int n) { 86 return arr[n]; 87 } 88 89 @Test testLoadLong()90 public void testLoadLong() { 91 long[] arr = {3L, 4L, 5L, 6L, 7L, 8L}; 92 test("loadLong", arr, 5); 93 checkLIR("loadLong", predicate, 1, 1); 94 } 95 loadFloat(float[] arr, int n)96 public static float loadFloat(float[] arr, int n) { 97 return arr[n]; 98 } 99 100 @Test testLoadFloat()101 public void testLoadFloat() { 102 float[] arr = {3.0F, 4.0F, 5.0F, 6.0F, 7.0F, 8.0F}; 103 test("loadFloat", arr, 5); 104 checkLIR("loadFloat", predicate, 1, 1); 105 } 106 loadDouble(double[] arr, int n)107 public static double loadDouble(double[] arr, int n) { 108 return arr[n]; 109 } 110 111 @Test testLoadDouble()112 public void testLoadDouble() { 113 double[] arr = {3.0, 4.0, 5.0, 6.0, 7.0, 8.0}; 114 test("loadDouble", arr, 5); 115 checkLIR("loadDouble", predicate, 1, 1); 116 } 117 loadObject(String[] arr, int n)118 public static String loadObject(String[] arr, int n) { 119 return arr[n]; 120 } 121 122 @Test testLoadObject()123 public void testLoadObject() { 124 String[] arr = {"ac", "ad", "ew", "asf", "sdad", "aff"}; 125 test("loadObject", arr, 5); 126 checkLIRforAll("loadObject", predicate, 1); 127 } 128 storeInt(int[] arr, int n)129 public static int storeInt(int[] arr, int n) { 130 arr[n] = n * n; 131 return arr[n]; 132 } 133 134 @Test testStoreInt()135 public void testStoreInt() { 136 int[] arr = {3, 4, 5, 6, 7, 8}; 137 test("storeInt", arr, 5); 138 checkLIRforAll("storeInt", predicate, 1); 139 } 140 loadAndStoreObject(Integer[] arr, int i)141 public static Integer loadAndStoreObject(Integer[] arr, int i) { 142 if (arr[i] > 0) { 143 return 0; 144 } 145 arr[i] += 3; 146 return arr[i]; 147 } 148 149 @Test testLoadAndStoreObject()150 public void testLoadAndStoreObject() { 151 Integer[] arr = new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; 152 test("loadAndStoreObject", arr, 2); 153 checkLIRforAll("loadAndStoreObject", predicate, 2); 154 } 155 useArrayInLoop(int[] arr)156 public static int useArrayInLoop(int[] arr) { 157 int ret = 0; 158 for (int i = 0; i < arr.length; i++) { 159 ret += GraalDirectives.opaque(arr[i]); 160 } 161 return ret; 162 } 163 164 @Test testUseArrayInLoop()165 public void testUseArrayInLoop() { 166 int[] arr = {1, 2, 3, 4, 5, 6, 7, 8}; 167 test("useArrayInLoop", arr); 168 checkLIRforAll("useArrayInLoop", predicate, 1); 169 } 170 useArrayDeque(ArrayDeque<Integer> ad)171 public static int useArrayDeque(ArrayDeque<Integer> ad) { 172 ad.addFirst(4); 173 return ad.removeFirst(); 174 } 175 176 @Test testUseArrayDeque()177 public void testUseArrayDeque() { 178 ArrayDeque<Integer> ad = new ArrayDeque<>(); 179 test("useArrayDeque", ad); 180 } 181 182 // Array load test when the index is narrowed firstly. 183 private static class Frame { 184 int index; 185 Frame(int index)186 Frame(int index) { 187 this.index = index; 188 } 189 } 190 191 private static final Frame[] frameCache = new Frame[256]; 192 newFrame(byte data)193 private static Frame newFrame(byte data) { 194 return frameCache[data & 255]; 195 } 196 getFrameIndex(int n)197 public static int getFrameIndex(int n) { 198 return newFrame((byte) n).index; 199 } 200 201 @Test testGetFrameIndex()202 public void testGetFrameIndex() { 203 for (int i = 0; i < 256; i++) { 204 frameCache[i] = new Frame(i * i); 205 } 206 test("getFrameIndex", 258); 207 checkLIRforAll("getFrameIndex", predicate, 1); 208 } 209 210 static Set<Long> allBarcodes = new HashSet<>(); 211 static Set<Long> localBarcodes = new HashSet<>(); 212 useConstReferenceAsBase(long l)213 public static long useConstReferenceAsBase(long l) { 214 localBarcodes.add(l); 215 allBarcodes.add(l); 216 return l; 217 } 218 219 @Test testUseConstReferenceAsBase()220 public void testUseConstReferenceAsBase() { 221 test("useConstReferenceAsBase", 2L); 222 int l = localBarcodes.size() + allBarcodes.size(); 223 test("useConstReferenceAsBase", (long) l); 224 } 225 } 226