src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/LIRKind.java
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
open Cdiff src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/LIRKind.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/LIRKind.java
Print this page
*** 31,42 ****
import jdk.vm.ci.meta.Value;
import jdk.vm.ci.meta.ValueKind;
/**
* Represents the type of values in the LIR. It is composed of a {@link PlatformKind} that gives the
! * low level representation of the value, and a {@link #referenceMask} that describes the location
! * of object references in the value, and optionally a {@link #derivedReferenceBase}.
*
* <h2>Constructing {@link LIRKind} instances</h2>
*
* During LIR generation, every new {@link Value} should get a {@link LIRKind} of the correct
* {@link PlatformKind} that also contains the correct reference information. {@linkplain LIRKind
--- 31,43 ----
import jdk.vm.ci.meta.Value;
import jdk.vm.ci.meta.ValueKind;
/**
* Represents the type of values in the LIR. It is composed of a {@link PlatformKind} that gives the
! * low level representation of the value, a {@link #referenceMask} that describes the location of
! * object references in the value, a {@link #referenceCompressionMask} that indicates which of these
! * references are compressed references, and for derived references a {@link #derivedReferenceBase}.
*
* <h2>Constructing {@link LIRKind} instances</h2>
*
* During LIR generation, every new {@link Value} should get a {@link LIRKind} of the correct
* {@link PlatformKind} that also contains the correct reference information. {@linkplain LIRKind
*** 50,60 ****
* If the result is an exact copy of one of the inputs, {@link Value#getValueKind()} can be used.
* Note that this is only correct for move-like operations, like conditional move or
* compare-and-swap. For convert operations, {@link LIRKind#combine} should be used.
* <p>
* If it is known that the result will be a reference (e.g. pointer arithmetic where the end result
! * is a valid oop), {@link LIRKind#reference} should be used.
* <p>
* If it is known that the result will neither be a reference nor be derived from a reference,
* {@link LIRKind#value} can be used. If the operation producing this value has inputs, this is very
* likely wrong, and {@link LIRKind#combine} should be used instead.
* <p>
--- 51,61 ----
* If the result is an exact copy of one of the inputs, {@link Value#getValueKind()} can be used.
* Note that this is only correct for move-like operations, like conditional move or
* compare-and-swap. For convert operations, {@link LIRKind#combine} should be used.
* <p>
* If it is known that the result will be a reference (e.g. pointer arithmetic where the end result
! * is a valid oop), {@link #reference} or {@link LIRKind#compressedReference} should be used.
* <p>
* If it is known that the result will neither be a reference nor be derived from a reference,
* {@link LIRKind#value} can be used. If the operation producing this value has inputs, this is very
* likely wrong, and {@link LIRKind#combine} should be used instead.
* <p>
*** 62,102 ****
* can not track, {@link LIRKind#unknownReference} can be used. In most cases,
* {@link LIRKind#combine} should be used instead, since it is able to detect this automatically.
*/
public final class LIRKind extends ValueKind<LIRKind> {
private final int referenceMask;
private AllocatableValue derivedReferenceBase;
private static final int UNKNOWN_REFERENCE = -1;
public static final LIRKind Illegal = unknownReference(ValueKind.Illegal.getPlatformKind());
! private LIRKind(PlatformKind platformKind, int referenceMask, AllocatableValue derivedReferenceBase) {
super(platformKind);
this.referenceMask = referenceMask;
this.derivedReferenceBase = derivedReferenceBase;
assert derivedReferenceBase == null || !derivedReferenceBase.getValueKind(LIRKind.class).isDerivedReference() : "derived reference can't have another derived reference as base";
}
/**
* Create a {@link LIRKind} of type {@code platformKind} that contains a primitive value. Should
* be only used when it's guaranteed that the value is not even indirectly derived from a
* reference. Otherwise, {@link #combine(Value...)} should be used instead.
*/
public static LIRKind value(PlatformKind platformKind) {
! return new LIRKind(platformKind, 0, null);
}
/**
! * Create a {@link LIRKind} of type {@code platformKind} that contains a single tracked oop
! * reference.
*/
public static LIRKind reference(PlatformKind platformKind) {
! return derivedReference(platformKind, null);
}
/**
* Create the correct {@link LIRKind} for a given {@link Architecture} and {@link JavaKind}.
*/
--- 63,120 ----
* can not track, {@link LIRKind#unknownReference} can be used. In most cases,
* {@link LIRKind#combine} should be used instead, since it is able to detect this automatically.
*/
public final class LIRKind extends ValueKind<LIRKind> {
+ /**
+ * The location of object references in the value. If the value is a vector type, each bit
+ * represents one component of the vector.
+ */
private final int referenceMask;
+ /** Mask with 1-bits indicating which references in {@link #referenceMask} are compressed. */
+ private final int referenceCompressionMask;
+
private AllocatableValue derivedReferenceBase;
private static final int UNKNOWN_REFERENCE = -1;
public static final LIRKind Illegal = unknownReference(ValueKind.Illegal.getPlatformKind());
! private LIRKind(PlatformKind platformKind, int referenceMask, int referenceCompressionMask, AllocatableValue derivedReferenceBase) {
super(platformKind);
this.referenceMask = referenceMask;
+ this.referenceCompressionMask = referenceCompressionMask;
this.derivedReferenceBase = derivedReferenceBase;
+ assert this.referenceCompressionMask == 0 || this.referenceMask == this.referenceCompressionMask : "mixing compressed and uncompressed references is untested";
assert derivedReferenceBase == null || !derivedReferenceBase.getValueKind(LIRKind.class).isDerivedReference() : "derived reference can't have another derived reference as base";
}
/**
* Create a {@link LIRKind} of type {@code platformKind} that contains a primitive value. Should
* be only used when it's guaranteed that the value is not even indirectly derived from a
* reference. Otherwise, {@link #combine(Value...)} should be used instead.
*/
public static LIRKind value(PlatformKind platformKind) {
! return new LIRKind(platformKind, 0, 0, null);
}
/**
! * Create a {@link LIRKind} of type {@code platformKind} that contains a single, tracked,
! * uncompressed oop reference.
*/
public static LIRKind reference(PlatformKind platformKind) {
! return derivedReference(platformKind, null, false);
! }
!
! /**
! * Create a {@link LIRKind} of type {@code platformKind} that contains a single, tracked,
! * compressed oop reference.
! */
! public static LIRKind compressedReference(PlatformKind platformKind) {
! return derivedReference(platformKind, null, true);
}
/**
* Create the correct {@link LIRKind} for a given {@link Architecture} and {@link JavaKind}.
*/
*** 110,133 ****
}
/**
* Create a {@link LIRKind} of type {@code platformKind} that contains a derived reference.
*/
! public static LIRKind derivedReference(PlatformKind platformKind, AllocatableValue base) {
int length = platformKind.getVectorLength();
assert 0 < length && length < 32 : "vector of " + length + " references not supported";
! return new LIRKind(platformKind, (1 << length) - 1, base);
}
/**
* Create a {@link LIRKind} of type {@code platformKind} that contains a value that is derived
* from a reference in a non-linear way. Values of this {@link LIRKind} can not be live at
* safepoints. In most cases, this should not be called directly. {@link #combine} should be
* used instead to automatically propagate this information.
*/
public static LIRKind unknownReference(PlatformKind platformKind) {
! return new LIRKind(platformKind, UNKNOWN_REFERENCE, null);
}
/**
* Create a derived reference.
*
--- 128,153 ----
}
/**
* Create a {@link LIRKind} of type {@code platformKind} that contains a derived reference.
*/
! public static LIRKind derivedReference(PlatformKind platformKind, AllocatableValue base, boolean compressed) {
int length = platformKind.getVectorLength();
assert 0 < length && length < 32 : "vector of " + length + " references not supported";
! int referenceMask = (1 << length) - 1;
! int referenceCompressionMask = (compressed ? referenceMask : 0);
! return new LIRKind(platformKind, referenceMask, referenceCompressionMask, base);
}
/**
* Create a {@link LIRKind} of type {@code platformKind} that contains a value that is derived
* from a reference in a non-linear way. Values of this {@link LIRKind} can not be live at
* safepoints. In most cases, this should not be called directly. {@link #combine} should be
* used instead to automatically propagate this information.
*/
public static LIRKind unknownReference(PlatformKind platformKind) {
! return new LIRKind(platformKind, UNKNOWN_REFERENCE, UNKNOWN_REFERENCE, null);
}
/**
* Create a derived reference.
*
*** 137,149 ****
assert !isUnknownReference() && derivedReferenceBase == null;
if (Value.ILLEGAL.equals(base)) {
return makeUnknownReference();
} else {
if (isValue()) {
! return derivedReference(getPlatformKind(), base);
} else {
! return new LIRKind(getPlatformKind(), referenceMask, base);
}
}
}
/**
--- 157,169 ----
assert !isUnknownReference() && derivedReferenceBase == null;
if (Value.ILLEGAL.equals(base)) {
return makeUnknownReference();
} else {
if (isValue()) {
! return derivedReference(getPlatformKind(), base, false);
} else {
! return new LIRKind(getPlatformKind(), referenceMask, referenceCompressionMask, base);
}
}
}
/**
*** 238,248 ****
return mergeKind.makeUnknownReference();
}
return mergeKind;
}
/* {@code mergeKind} is a reference. */
! if (mergeKind.referenceMask != inputKind.referenceMask) {
/*
* Reference masks do not match so the result can only be an unknown reference.
*/
return mergeKind.makeUnknownReference();
}
--- 258,268 ----
return mergeKind.makeUnknownReference();
}
return mergeKind;
}
/* {@code mergeKind} is a reference. */
! if (mergeKind.referenceMask != inputKind.referenceMask || mergeKind.referenceCompressionMask != inputKind.referenceCompressionMask) {
/*
* Reference masks do not match so the result can only be an unknown reference.
*/
return mergeKind.makeUnknownReference();
}
*** 282,294 ****
// value type
return LIRKind.value(newPlatformKind);
} else {
// reference type
int newLength = Math.min(32, newPlatformKind.getVectorLength());
! int newReferenceMask = referenceMask & (0xFFFFFFFF >>> (32 - newLength));
assert newReferenceMask != UNKNOWN_REFERENCE;
! return new LIRKind(newPlatformKind, newReferenceMask, derivedReferenceBase);
}
}
/**
* Create a new {@link LIRKind} with a new {@linkplain #getPlatformKind platform kind}. If the
--- 302,316 ----
// value type
return LIRKind.value(newPlatformKind);
} else {
// reference type
int newLength = Math.min(32, newPlatformKind.getVectorLength());
! int lengthMask = 0xFFFFFFFF >>> (32 - newLength);
! int newReferenceMask = referenceMask & lengthMask;
! int newReferenceCompressionMask = referenceCompressionMask & lengthMask;
assert newReferenceMask != UNKNOWN_REFERENCE;
! return new LIRKind(newPlatformKind, newReferenceMask, newReferenceCompressionMask, derivedReferenceBase);
}
}
/**
* Create a new {@link LIRKind} with a new {@linkplain #getPlatformKind platform kind}. If the
*** 306,330 ****
int newLength = newPlatformKind.getVectorLength();
assert oldLength <= newLength && newLength < 32 && (newLength % oldLength) == 0;
// repeat reference mask to fill new kind
int newReferenceMask = 0;
for (int i = 0; i < newLength; i += getPlatformKind().getVectorLength()) {
newReferenceMask |= referenceMask << i;
}
assert newReferenceMask != UNKNOWN_REFERENCE;
! return new LIRKind(newPlatformKind, newReferenceMask, derivedReferenceBase);
}
}
/**
* Create a new {@link LIRKind} with the same type, but marked as containing an
* {@link LIRKind#unknownReference}.
*/
public LIRKind makeUnknownReference() {
! return new LIRKind(getPlatformKind(), UNKNOWN_REFERENCE, null);
}
/**
* Check whether this value is a derived reference.
*/
--- 328,354 ----
int newLength = newPlatformKind.getVectorLength();
assert oldLength <= newLength && newLength < 32 && (newLength % oldLength) == 0;
// repeat reference mask to fill new kind
int newReferenceMask = 0;
+ int newReferenceCompressionMask = 0;
for (int i = 0; i < newLength; i += getPlatformKind().getVectorLength()) {
newReferenceMask |= referenceMask << i;
+ newReferenceCompressionMask |= referenceCompressionMask << i;
}
assert newReferenceMask != UNKNOWN_REFERENCE;
! return new LIRKind(newPlatformKind, newReferenceMask, newReferenceCompressionMask, derivedReferenceBase);
}
}
/**
* Create a new {@link LIRKind} with the same type, but marked as containing an
* {@link LIRKind#unknownReference}.
*/
public LIRKind makeUnknownReference() {
! return new LIRKind(getPlatformKind(), UNKNOWN_REFERENCE, UNKNOWN_REFERENCE, null);
}
/**
* Check whether this value is a derived reference.
*/
*** 383,392 ****
--- 407,427 ----
assert 0 <= idx && idx < getPlatformKind().getVectorLength() : "invalid index " + idx + " in " + this;
return !isUnknownReference() && (referenceMask & 1 << idx) != 0;
}
/**
+ * Check whether the {@code idx}th part of this value is a <b>compressed</b> reference.
+ *
+ * @param idx The index into the vector if this is a vector kind. Must be 0 if this is a scalar
+ * kind.
+ */
+ public boolean isCompressedReference(int idx) {
+ assert 0 <= idx && idx < getPlatformKind().getVectorLength() : "invalid index " + idx + " in " + this;
+ return !isUnknownReference() && (referenceCompressionMask & (1 << idx)) != 0;
+ }
+
+ /**
* Check whether this kind is a value type that doesn't need to be tracked at safepoints.
*/
public boolean isValue() {
return referenceMask == 0;
}
*** 430,439 ****
--- 465,475 ----
final int prime = 31;
int result = 1;
result = prime * result + ((getPlatformKind() == null) ? 0 : getPlatformKind().hashCode());
result = prime * result + ((getDerivedReferenceBase() == null) ? 0 : getDerivedReferenceBase().hashCode());
result = prime * result + referenceMask;
+ result = prime * result + referenceCompressionMask;
return result;
}
@Override
public boolean equals(Object obj) {
*** 443,453 ****
if (!(obj instanceof LIRKind)) {
return false;
}
LIRKind other = (LIRKind) obj;
! if (getPlatformKind() != other.getPlatformKind() || referenceMask != other.referenceMask) {
return false;
}
if (isDerivedReference()) {
if (!other.isDerivedReference()) {
return false;
--- 479,489 ----
if (!(obj instanceof LIRKind)) {
return false;
}
LIRKind other = (LIRKind) obj;
! if (getPlatformKind() != other.getPlatformKind() || referenceMask != other.referenceMask || referenceCompressionMask != other.referenceCompressionMask) {
return false;
}
if (isDerivedReference()) {
if (!other.isDerivedReference()) {
return false;
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core.common/src/org/graalvm/compiler/core/common/LIRKind.java
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File