< prev index next >
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir.amd64/src/org/graalvm/compiler/lir/amd64/AMD64ArrayEqualsOp.java
Print this page
rev 56282 : [mq]: graal
@@ -1,7 +1,7 @@
/*
- * Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2013, 2019, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
@@ -22,17 +22,18 @@
*/
package org.graalvm.compiler.lir.amd64;
-import jdk.vm.ci.amd64.AMD64;
-import jdk.vm.ci.amd64.AMD64.CPUFeature;
-import jdk.vm.ci.amd64.AMD64Kind;
-import jdk.vm.ci.code.Register;
-import jdk.vm.ci.code.TargetDescription;
-import jdk.vm.ci.meta.JavaKind;
-import jdk.vm.ci.meta.Value;
+import static jdk.vm.ci.code.ValueUtil.asRegister;
+import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.XOR;
+import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.CONST;
+import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
+import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
+
+import java.util.Objects;
+
import org.graalvm.compiler.asm.Label;
import org.graalvm.compiler.asm.amd64.AMD64Address;
import org.graalvm.compiler.asm.amd64.AMD64Address.Scale;
import org.graalvm.compiler.asm.amd64.AMD64Assembler;
import org.graalvm.compiler.asm.amd64.AMD64Assembler.ConditionFlag;
@@ -41,20 +42,22 @@
import org.graalvm.compiler.asm.amd64.AMD64MacroAssembler;
import org.graalvm.compiler.asm.amd64.AVXKind;
import org.graalvm.compiler.core.common.LIRKind;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.lir.LIRInstructionClass;
+import org.graalvm.compiler.lir.LIRValueUtil;
import org.graalvm.compiler.lir.Opcode;
import org.graalvm.compiler.lir.asm.CompilationResultBuilder;
import org.graalvm.compiler.lir.gen.LIRGeneratorTool;
-import static jdk.vm.ci.code.ValueUtil.asRegister;
-import static org.graalvm.compiler.asm.amd64.AMD64Assembler.AMD64BinaryArithmetic.XOR;
-import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.ILLEGAL;
-import static org.graalvm.compiler.lir.LIRInstruction.OperandFlag.REG;
-
-import java.util.Objects;
+import jdk.vm.ci.amd64.AMD64;
+import jdk.vm.ci.amd64.AMD64.CPUFeature;
+import jdk.vm.ci.amd64.AMD64Kind;
+import jdk.vm.ci.code.Register;
+import jdk.vm.ci.code.TargetDescription;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.Value;
/**
* Emits code which compares two arrays of the same length. If the CPU supports any vector
* instructions specialized code is emitted to leverage these instructions.
*
@@ -71,17 +74,16 @@
private final int arrayBaseOffset1;
private final int arrayBaseOffset2;
private final Scale arrayIndexScale1;
private final Scale arrayIndexScale2;
private final AVXKind.AVXSize vectorSize;
- private final int constantLength;
private final boolean signExtend;
@Def({REG}) private Value resultValue;
@Alive({REG}) private Value array1Value;
@Alive({REG}) private Value array2Value;
- @Alive({REG}) private Value lengthValue;
+ @Alive({REG, CONST}) private Value lengthValue;
@Temp({REG, ILLEGAL}) private Value temp1;
@Temp({REG, ILLEGAL}) private Value temp2;
@Temp({REG}) private Value temp3;
@Temp({REG, ILLEGAL}) private Value temp4;
@@ -92,11 +94,11 @@
@Temp({REG, ILLEGAL}) private Value vectorTemp2;
@Temp({REG, ILLEGAL}) private Value vectorTemp3;
@Temp({REG, ILLEGAL}) private Value vectorTemp4;
public AMD64ArrayEqualsOp(LIRGeneratorTool tool, JavaKind kind1, JavaKind kind2, Value result, Value array1, Value array2, Value length,
- int constantLength, boolean directPointers, int maxVectorSize) {
+ boolean directPointers, int maxVectorSize) {
super(TYPE);
this.kind1 = kind1;
this.kind2 = kind2;
this.signExtend = kind1 != JavaKind.Char && kind2 != JavaKind.Char;
@@ -105,11 +107,10 @@
this.arrayBaseOffset1 = directPointers ? 0 : tool.getProviders().getMetaAccess().getArrayBaseOffset(kind1);
this.arrayBaseOffset2 = directPointers ? 0 : tool.getProviders().getMetaAccess().getArrayBaseOffset(kind2);
this.arrayIndexScale1 = Objects.requireNonNull(Scale.fromInt(tool.getProviders().getMetaAccess().getArrayIndexScale(kind1)));
this.arrayIndexScale2 = Objects.requireNonNull(Scale.fromInt(tool.getProviders().getMetaAccess().getArrayIndexScale(kind2)));
this.vectorSize = ((AMD64) tool.target().arch).getFeatures().contains(CPUFeature.AVX2) && (maxVectorSize < 0 || maxVectorSize >= 32) ? AVXKind.AVXSize.YMM : AVXKind.AVXSize.XMM;
- this.constantLength = constantLength;
this.resultValue = result;
this.array1Value = array1;
this.array2Value = array2;
this.lengthValue = length;
@@ -160,11 +161,15 @@
this.vectorTemp4 = Value.ILLEGAL;
}
}
private boolean canGenerateConstantLengthCompare(TargetDescription target) {
- return constantLength >= 0 && kind1.isNumericInteger() && (kind1 == kind2 || getElementsPerVector(AVXKind.AVXSize.XMM) <= constantLength) && supportsSSE41(target);
+ return LIRValueUtil.isJavaConstant(lengthValue) && kind1.isNumericInteger() && (kind1 == kind2 || getElementsPerVector(AVXKind.AVXSize.XMM) <= constantLength()) && supportsSSE41(target);
+ }
+
+ private int constantLength() {
+ return LIRValueUtil.asJavaConstant(lengthValue).asInt();
}
@Override
public void emitCode(CompilationResultBuilder crb, AMD64MacroAssembler masm) {
Register result = asRegister(resultValue);
@@ -181,11 +186,15 @@
// Load array base addresses.
masm.leaq(array1, new AMD64Address(asRegister(array1Value), arrayBaseOffset1));
masm.leaq(array2, new AMD64Address(asRegister(array2Value), arrayBaseOffset2));
Register length = asRegister(temp3);
// Get array length.
+ if (LIRValueUtil.isJavaConstant(lengthValue)) {
+ masm.movl(length, constantLength());
+ } else {
masm.movl(length, asRegister(lengthValue));
+ }
// copy
masm.movl(result, length);
emitArrayCompare(crb, masm, result, array1, array2, length, trueLabel, falseLabel);
}
@@ -714,14 +723,14 @@
masm.subq(index, range);
}
private boolean constantLengthCompareNeedsTmpArrayPointers() {
AVXKind.AVXSize vSize = vectorSize;
- if (constantLength < getElementsPerVector(vectorSize)) {
+ if (constantLength() < getElementsPerVector(vectorSize)) {
vSize = AVXKind.AVXSize.XMM;
}
- int vectorCount = constantLength & ~(2 * getElementsPerVector(vSize) - 1);
+ int vectorCount = constantLength() & ~(2 * getElementsPerVector(vSize) - 1);
return vectorCount > 0;
}
/**
* Emits specialized assembly for checking equality of memory regions
@@ -731,25 +740,25 @@
private void emitConstantLengthArrayCompareBytes(
CompilationResultBuilder crb,
AMD64MacroAssembler asm,
Register[] tmpVectors,
Label noMatch) {
- if (constantLength == 0) {
+ if (constantLength() == 0) {
// do nothing
return;
}
Register arrayPtr1 = asRegister(array1Value);
Register arrayPtr2 = asRegister(array2Value);
Register tmp = asRegister(temp3);
AVXKind.AVXSize vSize = vectorSize;
- if (constantLength < getElementsPerVector(vectorSize)) {
+ if (constantLength() < getElementsPerVector(vectorSize)) {
vSize = AVXKind.AVXSize.XMM;
}
int elementsPerVector = getElementsPerVector(vSize);
- if (elementsPerVector > constantLength) {
+ if (elementsPerVector > constantLength()) {
assert kind1 == kind2;
- int byteLength = constantLength << arrayIndexScale1.log2;
+ int byteLength = constantLength() << arrayIndexScale1.log2;
// array is shorter than any vector register, use regular XOR instructions
int movSize = (byteLength < 2) ? 1 : ((byteLength < 4) ? 2 : ((byteLength < 8) ? 4 : 8));
emitMovBytes(asm, tmp, new AMD64Address(arrayPtr1, arrayBaseOffset1), movSize);
emitXorBytes(asm, tmp, new AMD64Address(arrayPtr2, arrayBaseOffset2), movSize);
asm.jccb(AMD64Assembler.ConditionFlag.NotZero, noMatch);
@@ -758,12 +767,12 @@
emitXorBytes(asm, tmp, new AMD64Address(arrayPtr2, arrayBaseOffset2 + byteLength - movSize), movSize);
asm.jccb(AMD64Assembler.ConditionFlag.NotZero, noMatch);
}
} else {
int elementsPerVectorLoop = 2 * elementsPerVector;
- int tailCount = constantLength & (elementsPerVectorLoop - 1);
- int vectorCount = constantLength & ~(elementsPerVectorLoop - 1);
+ int tailCount = constantLength() & (elementsPerVectorLoop - 1);
+ int vectorCount = constantLength() & ~(elementsPerVectorLoop - 1);
int bytesPerVector = vSize.getBytes();
if (vectorCount > 0) {
Label loopBegin = new Label();
Register tmpArrayPtr1 = asRegister(temp1);
Register tmpArrayPtr2 = asRegister(temp2);
< prev index next >