1 /*
   2  * Copyright (c) 2013, 2018, 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 }