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 jdk.vm.ci.meta.JavaKind;
28 import jdk.vm.ci.meta.Value;
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 import jdk.internal.vm.compiler.word.Pointer;
45 
46 import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_512;
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 kind;
54     private final boolean findTwoConsecutive;
55 
56     @Input private ValueNode arrayPointer;
57     @Input private ValueNode arrayLength;
58     @Input private NodeInputList<ValueNode> searchValues;
59 
60     @OptionalInput(InputType.Memory) private MemoryNode lastLocationAccess;
61 
AMD64ArrayIndexOfNode(@onstantNodeParameter JavaKind kind, @ConstantNodeParameter boolean findTwoConsecutive, ValueNode arrayPointer, ValueNode arrayLength, ValueNode... searchValues)62     public AMD64ArrayIndexOfNode(@ConstantNodeParameter JavaKind kind, @ConstantNodeParameter boolean findTwoConsecutive,
63                     ValueNode arrayPointer, ValueNode arrayLength, ValueNode... searchValues) {
64         super(TYPE, StampFactory.forKind(JavaKind.Int));
65         this.kind = kind;
66         this.findTwoConsecutive = findTwoConsecutive;
67         this.arrayPointer = arrayPointer;
68         this.arrayLength = arrayLength;
69         this.searchValues = new NodeInputList<>(this, searchValues);
70     }
71 
AMD64ArrayIndexOfNode(@onstantNodeParameter JavaKind kind, ValueNode arrayPointer, ValueNode arrayLength, ValueNode... searchValues)72     public AMD64ArrayIndexOfNode(@ConstantNodeParameter JavaKind kind, ValueNode arrayPointer, ValueNode arrayLength, ValueNode... searchValues) {
73         this(kind, false, arrayPointer, arrayLength, searchValues);
74     }
75 
76     @Override
getLocationIdentity()77     public LocationIdentity getLocationIdentity() {
78         return NamedLocationIdentity.getArrayLocation(kind);
79     }
80 
81     @Override
generate(NodeLIRBuilderTool gen)82     public void generate(NodeLIRBuilderTool gen) {
83         Value[] searchValueOperands = new Value[searchValues.size()];
84         for (int i = 0; i < searchValues.size(); i++) {
85             searchValueOperands[i] = gen.operand(searchValues.get(i));
86         }
87         Value result = gen.getLIRGeneratorTool().emitArrayIndexOf(kind, findTwoConsecutive, gen.operand(arrayPointer), gen.operand(arrayLength), searchValueOperands);
88         gen.setResult(this, result);
89     }
90 
91     @Override
getLastLocationAccess()92     public MemoryNode getLastLocationAccess() {
93         return lastLocationAccess;
94     }
95 
96     @Override
setLastLocationAccess(MemoryNode lla)97     public void setLastLocationAccess(MemoryNode lla) {
98         updateUsages(ValueNodeUtil.asNode(lastLocationAccess), ValueNodeUtil.asNode(lla));
99         lastLocationAccess = lla;
100     }
101 
102     @NodeIntrinsic
optimizedArrayIndexOf(@onstantNodeParameter JavaKind kind, @ConstantNodeParameter boolean findTwoConsecutive, Pointer arrayPointer, int arrayLength, int searchValue)103     public static native int optimizedArrayIndexOf(@ConstantNodeParameter JavaKind kind, @ConstantNodeParameter boolean findTwoConsecutive,
104                     Pointer arrayPointer, int arrayLength, int searchValue);
105 
106     @NodeIntrinsic
optimizedArrayIndexOf(@onstantNodeParameter JavaKind kind, Pointer arrayPointer, int arrayLength, char c1)107     public static native int optimizedArrayIndexOf(@ConstantNodeParameter JavaKind kind, Pointer arrayPointer, int arrayLength, char c1);
108 
109     @NodeIntrinsic
optimizedArrayIndexOf(@onstantNodeParameter JavaKind kind, Pointer arrayPointer, int arrayLength, char c1, char c2)110     public static native int optimizedArrayIndexOf(@ConstantNodeParameter JavaKind kind, Pointer arrayPointer, int arrayLength, char c1, char c2);
111 
112     @NodeIntrinsic
optimizedArrayIndexOf(@onstantNodeParameter JavaKind kind, Pointer arrayPointer, int arrayLength, char c1, char c2, char c3)113     public static native int optimizedArrayIndexOf(@ConstantNodeParameter JavaKind kind, Pointer arrayPointer, int arrayLength, char c1, char c2, char c3);
114 
115     @NodeIntrinsic
optimizedArrayIndexOf(@onstantNodeParameter JavaKind kind, Pointer arrayPointer, int arrayLength, char c1, char c2, char c3, char c4)116     public static native int optimizedArrayIndexOf(@ConstantNodeParameter JavaKind kind, Pointer arrayPointer, int arrayLength, char c1, char c2, char c3, char c4);
117 
118     @NodeIntrinsic
optimizedArrayIndexOf(@onstantNodeParameter JavaKind kind, Pointer arrayPointer, int arrayLength, byte c1)119     public static native int optimizedArrayIndexOf(@ConstantNodeParameter JavaKind kind, Pointer arrayPointer, int arrayLength, byte c1);
120 
121     @NodeIntrinsic
optimizedArrayIndexOf(@onstantNodeParameter JavaKind kind, Pointer arrayPointer, int arrayLength, byte c1, byte c2)122     public static native int optimizedArrayIndexOf(@ConstantNodeParameter JavaKind kind, Pointer arrayPointer, int arrayLength, byte c1, byte c2);
123 
124     @NodeIntrinsic
optimizedArrayIndexOf(@onstantNodeParameter JavaKind kind, Pointer arrayPointer, int arrayLength, byte c1, byte c2, byte c3)125     public static native int optimizedArrayIndexOf(@ConstantNodeParameter JavaKind kind, Pointer arrayPointer, int arrayLength, byte c1, byte c2, byte c3);
126 
127     @NodeIntrinsic
optimizedArrayIndexOf(@onstantNodeParameter JavaKind kind, Pointer arrayPointer, int arrayLength, byte c1, byte c2, byte c3, byte c4)128     public static native int optimizedArrayIndexOf(@ConstantNodeParameter JavaKind kind, Pointer arrayPointer, int arrayLength, byte c1, byte c2, byte c3, byte c4);
129 }
130