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.nodes;
26
27 import static org.graalvm.compiler.nodeinfo.InputType.Memory;
28
29 import org.graalvm.compiler.api.replacements.Snippet;
30 import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
31 import org.graalvm.compiler.core.common.type.StampFactory;
32 import org.graalvm.compiler.graph.Node;
33 import org.graalvm.compiler.graph.NodeClass;
34 import org.graalvm.compiler.graph.spi.Canonicalizable;
35 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
36 import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
37 import org.graalvm.compiler.nodeinfo.NodeCycles;
38 import org.graalvm.compiler.nodeinfo.NodeInfo;
39 import org.graalvm.compiler.nodeinfo.NodeSize;
40 import org.graalvm.compiler.nodes.ConstantNode;
41 import org.graalvm.compiler.nodes.FixedWithNextNode;
42 import org.graalvm.compiler.nodes.NamedLocationIdentity;
43 import org.graalvm.compiler.nodes.NodeView;
44 import org.graalvm.compiler.nodes.ValueNode;
45 import org.graalvm.compiler.nodes.ValueNodeUtil;
46 import org.graalvm.compiler.nodes.memory.MemoryAccess;
47 import org.graalvm.compiler.nodes.memory.MemoryNode;
48 import org.graalvm.compiler.nodes.spi.LIRLowerable;
49 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
50 import org.graalvm.compiler.nodes.spi.Virtualizable;
51 import org.graalvm.compiler.nodes.spi.VirtualizerTool;
52 import org.graalvm.compiler.nodes.util.GraphUtil;
53 import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
54 import org.graalvm.compiler.options.Option;
55 import org.graalvm.compiler.options.OptionKey;
56 import jdk.internal.vm.compiler.word.LocationIdentity;
57
58 import jdk.vm.ci.meta.ConstantReflectionProvider;
59 import jdk.vm.ci.meta.JavaConstant;
60 import jdk.vm.ci.meta.JavaKind;
61 import jdk.vm.ci.meta.ResolvedJavaMethod;
62 import jdk.vm.ci.meta.Value;
63
64 // JaCoCo Exclude
65
66 /**
67 * Compares two arrays with the same length.
68 */
69 @NodeInfo(cycles = NodeCycles.CYCLES_UNKNOWN, size = NodeSize.SIZE_128)
70 public final class ArrayEqualsNode extends FixedWithNextNode implements LIRLowerable, Canonicalizable, Virtualizable, MemoryAccess {
71
72 public static class Options {
73 // @formatter:off
74 @Option(help = "Use Array equals stubs instead of embedding all the emitted code.")
75 public static final OptionKey<Boolean> ArrayEqualsStubs = new OptionKey<>(true);
76 // @formatter:on
77 }
78
79 public static final NodeClass<ArrayEqualsNode> TYPE = NodeClass.create(ArrayEqualsNode.class);
80 /** {@link JavaKind} of the arrays to compare. */
81 protected final JavaKind kind;
82
83 /** One array to be tested for equality. */
84 @Input ValueNode array1;
85
86 /** The other array to be tested for equality. */
87 @Input ValueNode array2;
88
89 /** Length of both arrays. */
90 @Input ValueNode length;
91
92 @OptionalInput(Memory) MemoryNode lastLocationAccess;
93
94 public ArrayEqualsNode(ValueNode array1, ValueNode array2, ValueNode length, @ConstantNodeParameter JavaKind kind) {
95 super(TYPE, StampFactory.forKind(JavaKind.Boolean));
96 this.kind = kind;
97 this.array1 = array1;
98 this.array2 = array2;
208 public static boolean equals(short[] array1, short[] array2, int length) {
209 return equals(array1, array2, length, JavaKind.Short);
210 }
211
212 public static boolean equals(int[] array1, int[] array2, int length) {
213 return equals(array1, array2, length, JavaKind.Int);
214 }
215
216 public static boolean equals(long[] array1, long[] array2, int length) {
217 return equals(array1, array2, length, JavaKind.Long);
218 }
219
220 public static boolean equals(float[] array1, float[] array2, int length) {
221 return equals(array1, array2, length, JavaKind.Float);
222 }
223
224 public static boolean equals(double[] array1, double[] array2, int length) {
225 return equals(array1, array2, length, JavaKind.Double);
226 }
227
228 @Override
229 public void generate(NodeLIRBuilderTool gen) {
230 LIRGeneratorTool tool = gen.getLIRGeneratorTool();
231 int constantLength = -1;
232 if (length.isConstant()) {
233 constantLength = length.asJavaConstant().asInt();
234 }
235
236 if (Options.ArrayEqualsStubs.getValue(graph().getOptions())) {
237 ResolvedJavaMethod method = graph().method();
238 if (method != null && method.getAnnotation(Snippet.class) == null) {
239 ForeignCallLinkage linkage = tool.lookupArrayEqualsStub(kind, constantLength);
240 if (linkage != null) {
241 Value result = tool.emitForeignCall(linkage, null, gen.operand(array1), gen.operand(array2), gen.operand(length));
242 gen.setResult(this, result);
243 return;
244 }
245 }
246 }
247
248 Value result = tool.emitArrayEquals(kind, gen.operand(array1), gen.operand(array2), gen.operand(length), constantLength, false);
249 gen.setResult(this, result);
250 }
251
252 @Override
253 public LocationIdentity getLocationIdentity() {
254 return NamedLocationIdentity.getArrayLocation(kind);
255 }
256
257 @Override
258 public MemoryNode getLastLocationAccess() {
259 return lastLocationAccess;
260 }
261
262 @Override
263 public void setLastLocationAccess(MemoryNode lla) {
264 updateUsages(ValueNodeUtil.asNode(lastLocationAccess), ValueNodeUtil.asNode(lla));
265 lastLocationAccess = lla;
266 }
267 }
|
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.nodes;
26
27 import static org.graalvm.compiler.core.common.GraalOptions.UseGraalStubs;
28 import static org.graalvm.compiler.nodeinfo.InputType.Memory;
29
30 import org.graalvm.compiler.core.common.spi.ForeignCallLinkage;
31 import org.graalvm.compiler.core.common.type.StampFactory;
32 import org.graalvm.compiler.graph.Node;
33 import org.graalvm.compiler.graph.NodeClass;
34 import org.graalvm.compiler.graph.spi.Canonicalizable;
35 import org.graalvm.compiler.graph.spi.CanonicalizerTool;
36 import org.graalvm.compiler.nodeinfo.NodeCycles;
37 import org.graalvm.compiler.nodeinfo.NodeInfo;
38 import org.graalvm.compiler.nodeinfo.NodeSize;
39 import org.graalvm.compiler.nodes.ConstantNode;
40 import org.graalvm.compiler.nodes.FixedWithNextNode;
41 import org.graalvm.compiler.nodes.NamedLocationIdentity;
42 import org.graalvm.compiler.nodes.NodeView;
43 import org.graalvm.compiler.nodes.ValueNode;
44 import org.graalvm.compiler.nodes.ValueNodeUtil;
45 import org.graalvm.compiler.nodes.memory.MemoryAccess;
46 import org.graalvm.compiler.nodes.memory.MemoryNode;
47 import org.graalvm.compiler.nodes.spi.LIRLowerable;
48 import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
49 import org.graalvm.compiler.nodes.spi.Virtualizable;
50 import org.graalvm.compiler.nodes.spi.VirtualizerTool;
51 import org.graalvm.compiler.nodes.util.GraphUtil;
52 import org.graalvm.compiler.nodes.virtual.VirtualObjectNode;
53 import jdk.internal.vm.compiler.word.LocationIdentity;
54
55 import jdk.vm.ci.meta.ConstantReflectionProvider;
56 import jdk.vm.ci.meta.JavaConstant;
57 import jdk.vm.ci.meta.JavaKind;
58 import jdk.vm.ci.meta.Value;
59
60 // JaCoCo Exclude
61
62 /**
63 * Compares two arrays with the same length.
64 */
65 @NodeInfo(cycles = NodeCycles.CYCLES_UNKNOWN, size = NodeSize.SIZE_128)
66 public final class ArrayEqualsNode extends FixedWithNextNode implements LIRLowerable, Canonicalizable, Virtualizable, MemoryAccess {
67
68 public static final NodeClass<ArrayEqualsNode> TYPE = NodeClass.create(ArrayEqualsNode.class);
69 /** {@link JavaKind} of the arrays to compare. */
70 protected final JavaKind kind;
71
72 /** One array to be tested for equality. */
73 @Input ValueNode array1;
74
75 /** The other array to be tested for equality. */
76 @Input ValueNode array2;
77
78 /** Length of both arrays. */
79 @Input ValueNode length;
80
81 @OptionalInput(Memory) MemoryNode lastLocationAccess;
82
83 public ArrayEqualsNode(ValueNode array1, ValueNode array2, ValueNode length, @ConstantNodeParameter JavaKind kind) {
84 super(TYPE, StampFactory.forKind(JavaKind.Boolean));
85 this.kind = kind;
86 this.array1 = array1;
87 this.array2 = array2;
197 public static boolean equals(short[] array1, short[] array2, int length) {
198 return equals(array1, array2, length, JavaKind.Short);
199 }
200
201 public static boolean equals(int[] array1, int[] array2, int length) {
202 return equals(array1, array2, length, JavaKind.Int);
203 }
204
205 public static boolean equals(long[] array1, long[] array2, int length) {
206 return equals(array1, array2, length, JavaKind.Long);
207 }
208
209 public static boolean equals(float[] array1, float[] array2, int length) {
210 return equals(array1, array2, length, JavaKind.Float);
211 }
212
213 public static boolean equals(double[] array1, double[] array2, int length) {
214 return equals(array1, array2, length, JavaKind.Double);
215 }
216
217 public ValueNode getLength() {
218 return length;
219 }
220
221 public JavaKind getKind() {
222 return kind;
223 }
224
225 @Override
226 public void generate(NodeLIRBuilderTool gen) {
227 if (UseGraalStubs.getValue(graph().getOptions())) {
228 ForeignCallLinkage linkage = gen.lookupGraalStub(this);
229 if (linkage != null) {
230 Value result = gen.getLIRGeneratorTool().emitForeignCall(linkage, null, gen.operand(array1), gen.operand(array2), gen.operand(length));
231 gen.setResult(this, result);
232 return;
233 }
234 }
235
236 int constantLength = -1;
237 if (length.isConstant()) {
238 constantLength = length.asJavaConstant().asInt();
239 }
240 Value result = gen.getLIRGeneratorTool().emitArrayEquals(kind, gen.operand(array1), gen.operand(array2), gen.operand(length), constantLength, false);
241 gen.setResult(this, result);
242 }
243
244 @Override
245 public LocationIdentity getLocationIdentity() {
246 return NamedLocationIdentity.getArrayLocation(kind);
247 }
248
249 @Override
250 public MemoryNode getLastLocationAccess() {
251 return lastLocationAccess;
252 }
253
254 @Override
255 public void setLastLocationAccess(MemoryNode lla) {
256 updateUsages(ValueNodeUtil.asNode(lastLocationAccess), ValueNodeUtil.asNode(lla));
257 lastLocationAccess = lla;
258 }
259 }
|