< 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 >