1 /* 2 * Copyright (c) 2013, 2019, 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. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 25 package org.graalvm.compiler.replacements.amd64; 26 27 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_512; 28 29 import org.graalvm.compiler.core.common.type.StampFactory; 30 import org.graalvm.compiler.graph.NodeClass; 31 import org.graalvm.compiler.graph.NodeInputList; 32 import org.graalvm.compiler.nodeinfo.InputType; 33 import org.graalvm.compiler.nodeinfo.NodeCycles; 34 import org.graalvm.compiler.nodeinfo.NodeInfo; 35 import org.graalvm.compiler.nodes.FixedWithNextNode; 36 import org.graalvm.compiler.nodes.NamedLocationIdentity; 37 import org.graalvm.compiler.nodes.ValueNode; 38 import org.graalvm.compiler.nodes.ValueNodeUtil; 39 import org.graalvm.compiler.nodes.memory.MemoryAccess; 40 import org.graalvm.compiler.nodes.memory.MemoryNode; 41 import org.graalvm.compiler.nodes.spi.LIRLowerable; 42 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool; 43 import jdk.internal.vm.compiler.word.LocationIdentity; 44 45 import jdk.vm.ci.meta.JavaKind; 46 import jdk.vm.ci.meta.Value; 47 48 @NodeInfo(size = SIZE_512, cycles = NodeCycles.CYCLES_UNKNOWN) 49 public class AMD64ArrayIndexOfNode extends FixedWithNextNode implements LIRLowerable, MemoryAccess { 50 51 public static final NodeClass<AMD64ArrayIndexOfNode> TYPE = NodeClass.create(AMD64ArrayIndexOfNode.class); 52 53 private final JavaKind arrayKind; 54 private final JavaKind valueKind; 55 private final boolean findTwoConsecutive; 56 57 @Input private ValueNode arrayPointer; 58 @Input private ValueNode arrayLength; 59 @Input private ValueNode fromIndex; 60 @Input private NodeInputList<ValueNode> searchValues; 61 62 @OptionalInput(InputType.Memory) private MemoryNode lastLocationAccess; 63 64 public AMD64ArrayIndexOfNode(@ConstantNodeParameter JavaKind arrayKind, @ConstantNodeParameter JavaKind valueKind, @ConstantNodeParameter boolean findTwoConsecutive, 65 ValueNode arrayPointer, ValueNode arrayLength, ValueNode fromIndex, ValueNode... searchValues) { 66 super(TYPE, StampFactory.forKind(JavaKind.Int)); 67 this.arrayKind = arrayKind; 68 this.valueKind = valueKind; 69 this.findTwoConsecutive = findTwoConsecutive; 70 this.arrayPointer = arrayPointer; 71 this.arrayLength = arrayLength; 72 this.fromIndex = fromIndex; 73 this.searchValues = new NodeInputList<>(this, searchValues); 74 } 75 76 public AMD64ArrayIndexOfNode(@ConstantNodeParameter JavaKind arrayKind, @ConstantNodeParameter JavaKind valueKind, 77 ValueNode arrayPointer, ValueNode arrayLength, ValueNode fromIndex, ValueNode... searchValues) { 78 this(arrayKind, valueKind, false, arrayPointer, arrayLength, fromIndex, searchValues); 79 } 80 81 @Override 82 public LocationIdentity getLocationIdentity() { 83 return NamedLocationIdentity.getArrayLocation(arrayKind); 84 } 85 86 @Override 87 public void generate(NodeLIRBuilderTool gen) { 88 Value[] searchValueOperands = new Value[searchValues.size()]; 89 for (int i = 0; i < searchValues.size(); i++) { 90 searchValueOperands[i] = gen.operand(searchValues.get(i)); 91 } 92 Value result = gen.getLIRGeneratorTool().emitArrayIndexOf(arrayKind, valueKind, findTwoConsecutive, 93 gen.operand(arrayPointer), gen.operand(arrayLength), gen.operand(fromIndex), searchValueOperands); 94 gen.setResult(this, result); 95 } 96 97 @Override 98 public MemoryNode getLastLocationAccess() { 99 return lastLocationAccess; 100 } 101 102 @Override 103 public void setLastLocationAccess(MemoryNode lla) { 104 updateUsages(ValueNodeUtil.asNode(lastLocationAccess), ValueNodeUtil.asNode(lla)); 105 lastLocationAccess = lla; 106 } 107 108 @NodeIntrinsic 109 private static native int optimizedArrayIndexOf( 110 @ConstantNodeParameter JavaKind arrayKind, 111 @ConstantNodeParameter JavaKind valueKind, 112 @ConstantNodeParameter boolean findTwoConsecutive, 113 Object array, int arrayLength, int fromIndex, byte v1); 114 115 @NodeIntrinsic 116 private static native int optimizedArrayIndexOf( 117 @ConstantNodeParameter JavaKind arrayKind, 118 @ConstantNodeParameter JavaKind valueKind, 119 @ConstantNodeParameter boolean findTwoConsecutive, 120 Object array, int arrayLength, int fromIndex, byte v1, byte v2); 121 122 @NodeIntrinsic 123 private static native int optimizedArrayIndexOf( 124 @ConstantNodeParameter JavaKind arrayKind, 125 @ConstantNodeParameter JavaKind valueKind, 126 @ConstantNodeParameter boolean findTwoConsecutive, 127 Object array, int arrayLength, int fromIndex, byte v1, byte v2, byte v3); 128 129 @NodeIntrinsic 130 private static native int optimizedArrayIndexOf( 131 @ConstantNodeParameter JavaKind arrayKind, 132 @ConstantNodeParameter JavaKind valueKind, 133 @ConstantNodeParameter boolean findTwoConsecutive, 134 Object array, int arrayLength, int fromIndex, byte v1, byte v2, byte v3, byte v4); 135 136 @NodeIntrinsic 137 private static native int optimizedArrayIndexOf( 138 @ConstantNodeParameter JavaKind arrayKind, 139 @ConstantNodeParameter JavaKind valueKind, 140 @ConstantNodeParameter boolean findTwoConsecutive, 141 Object array, int arrayLength, int fromIndex, char v1); 142 143 @NodeIntrinsic 144 private static native int optimizedArrayIndexOf( 145 @ConstantNodeParameter JavaKind arrayKind, 146 @ConstantNodeParameter JavaKind valueKind, 147 @ConstantNodeParameter boolean findTwoConsecutive, 148 Object array, int arrayLength, int fromIndex, char v1, char v2); 149 150 @NodeIntrinsic 151 private static native int optimizedArrayIndexOf( 152 @ConstantNodeParameter JavaKind arrayKind, 153 @ConstantNodeParameter JavaKind valueKind, 154 @ConstantNodeParameter boolean findTwoConsecutive, 155 Object array, int arrayLength, int fromIndex, char v1, char v2, char v3); 156 157 @NodeIntrinsic 158 private static native int optimizedArrayIndexOf( 159 @ConstantNodeParameter JavaKind arrayKind, 160 @ConstantNodeParameter JavaKind valueKind, 161 @ConstantNodeParameter boolean findTwoConsecutive, 162 Object array, int arrayLength, int fromIndex, char v1, char v2, char v3, char v4); 163 164 @NodeIntrinsic 165 private static native int optimizedArrayIndexOf( 166 @ConstantNodeParameter JavaKind arrayKind, 167 @ConstantNodeParameter JavaKind valueKind, 168 @ConstantNodeParameter boolean findTwoConsecutive, 169 Object array, int arrayLength, int fromIndex, int searchValue); 170 171 public static int indexOf(byte[] array, int arrayLength, int fromIndex, byte v1) { 172 return optimizedArrayIndexOf(JavaKind.Byte, JavaKind.Byte, false, array, arrayLength, fromIndex, v1); 173 } 174 175 public static int indexOf(byte[] array, int arrayLength, int fromIndex, byte v1, byte v2) { 176 return optimizedArrayIndexOf(JavaKind.Byte, JavaKind.Byte, false, array, arrayLength, fromIndex, v1, v2); 177 } 178 179 public static int indexOf(byte[] array, int arrayLength, int fromIndex, byte v1, byte v2, byte v3) { 180 return optimizedArrayIndexOf(JavaKind.Byte, JavaKind.Byte, false, array, arrayLength, fromIndex, v1, v2, v3); 181 } 182 183 public static int indexOf(byte[] array, int arrayLength, int fromIndex, byte v1, byte v2, byte v3, byte v4) { 184 return optimizedArrayIndexOf(JavaKind.Byte, JavaKind.Byte, false, array, arrayLength, fromIndex, v1, v2, v3, v4); 185 } 186 187 public static int indexOf(byte[] array, int arrayLength, int fromIndex, char v1) { 188 return optimizedArrayIndexOf(JavaKind.Byte, JavaKind.Char, false, array, arrayLength, fromIndex, v1); 189 } 190 191 public static int indexOf(byte[] array, int arrayLength, int fromIndex, char v1, char v2) { 192 return optimizedArrayIndexOf(JavaKind.Byte, JavaKind.Char, false, array, arrayLength, fromIndex, v1, v2); 193 } 194 195 public static int indexOf(byte[] array, int arrayLength, int fromIndex, char v1, char v2, char v3) { 196 return optimizedArrayIndexOf(JavaKind.Byte, JavaKind.Char, false, array, arrayLength, fromIndex, v1, v2, v3); 197 } 198 199 public static int indexOf(byte[] array, int arrayLength, int fromIndex, char v1, char v2, char v3, char v4) { 200 return optimizedArrayIndexOf(JavaKind.Byte, JavaKind.Char, false, array, arrayLength, fromIndex, v1, v2, v3, v4); 201 } 202 203 public static int indexOf(char[] array, int arrayLength, int fromIndex, char v1) { 204 return optimizedArrayIndexOf(JavaKind.Char, JavaKind.Char, false, array, arrayLength, fromIndex, v1); 205 } 206 207 public static int indexOf(char[] array, int arrayLength, int fromIndex, char v1, char v2) { 208 return optimizedArrayIndexOf(JavaKind.Char, JavaKind.Char, false, array, arrayLength, fromIndex, v1, v2); 209 } 210 211 public static int indexOf(char[] array, int arrayLength, int fromIndex, char v1, char v2, char v3) { 212 return optimizedArrayIndexOf(JavaKind.Char, JavaKind.Char, false, array, arrayLength, fromIndex, v1, v2, v3); 213 } 214 215 public static int indexOf(char[] array, int arrayLength, int fromIndex, char v1, char v2, char v3, char v4) { 216 return optimizedArrayIndexOf(JavaKind.Char, JavaKind.Char, false, array, arrayLength, fromIndex, v1, v2, v3, v4); 217 } 218 219 public static int indexOf2ConsecutiveBytes(byte[] array, int arrayLength, int fromIndex, int values) { 220 return optimizedArrayIndexOf(JavaKind.Byte, JavaKind.Byte, true, array, arrayLength, fromIndex, values); 221 } 222 223 public static int indexOf2ConsecutiveChars(byte[] array, int arrayLength, int fromIndex, int values) { 224 return optimizedArrayIndexOf(JavaKind.Byte, JavaKind.Char, true, array, arrayLength, fromIndex, values); 225 } 226 227 public static int indexOf2ConsecutiveChars(char[] array, int arrayLength, int fromIndex, int values) { 228 return optimizedArrayIndexOf(JavaKind.Char, JavaKind.Char, true, array, arrayLength, fromIndex, values); 229 } 230 }