src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/lsra/TraceInterval.java
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
hotspot Cdiff src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/lsra/TraceInterval.java
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/lsra/TraceInterval.java
Print this page
*** 20,37 ****
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.lir.alloc.trace.lsra;
- import static org.graalvm.compiler.core.common.GraalOptions.DetailedAsserts;
- import static org.graalvm.compiler.lir.LIRValueUtil.isStackSlotValue;
- import static org.graalvm.compiler.lir.LIRValueUtil.isVariable;
- import static org.graalvm.compiler.lir.LIRValueUtil.isVirtualStackSlot;
import static jdk.vm.ci.code.ValueUtil.asRegister;
import static jdk.vm.ci.code.ValueUtil.isIllegal;
import static jdk.vm.ci.code.ValueUtil.isRegister;
import static jdk.vm.ci.code.ValueUtil.isStackSlot;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
--- 20,37 ----
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package org.graalvm.compiler.lir.alloc.trace.lsra;
import static jdk.vm.ci.code.ValueUtil.asRegister;
import static jdk.vm.ci.code.ValueUtil.isIllegal;
import static jdk.vm.ci.code.ValueUtil.isRegister;
import static jdk.vm.ci.code.ValueUtil.isStackSlot;
+ import static org.graalvm.compiler.core.common.GraalOptions.DetailedAsserts;
+ import static org.graalvm.compiler.lir.LIRValueUtil.isStackSlotValue;
+ import static org.graalvm.compiler.lir.LIRValueUtil.isVariable;
+ import static org.graalvm.compiler.lir.LIRValueUtil.isVirtualStackSlot;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.EnumSet;
*** 41,50 ****
--- 41,51 ----
import org.graalvm.compiler.core.common.util.Util;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.lir.LIRInstruction;
import org.graalvm.compiler.lir.Variable;
import org.graalvm.compiler.lir.alloc.trace.lsra.TraceLinearScanPhase.TraceLinearScan;
+ import org.graalvm.compiler.options.OptionValues;
import jdk.vm.ci.code.RegisterValue;
import jdk.vm.ci.code.StackSlot;
import jdk.vm.ci.meta.AllocatableValue;
import jdk.vm.ci.meta.JavaConstant;
*** 337,347 ****
/**
* List of all intervals that are split off from this interval. This is only used if this is a
* {@linkplain #isSplitParent() split parent}.
*/
! private List<TraceInterval> splitChildren = Collections.emptyList();
/**
* Current split child that has been active or inactive last (always stored in split parents).
*/
private TraceInterval currentSplitChild;
--- 338,348 ----
/**
* List of all intervals that are split off from this interval. This is only used if this is a
* {@linkplain #isSplitParent() split parent}.
*/
! private ArrayList<TraceInterval> splitChildren = null;
/**
* Current split child that has been active or inactive last (always stored in split parents).
*/
private TraceInterval currentSplitChild;
*** 376,385 ****
--- 377,393 ----
/**
* The number of times {@link #addMaterializationValue(JavaConstant)} is called.
*/
private int numMaterializationValuesAdded;
+ private final OptionValues options;
+
+ private boolean splitChildrenEmpty() {
+ assert splitChildren == null || !splitChildren.isEmpty();
+ return splitChildren == null;
+ }
+
void assignLocation(AllocatableValue newLocation) {
if (isRegister(newLocation)) {
assert this.location == null : "cannot re-assign location for " + this;
if (newLocation.getValueKind().equals(LIRKind.Illegal) && !kind().equals(LIRKind.Illegal)) {
this.location = asRegister(newLocation).asValue(kind());
*** 438,447 ****
--- 446,459 ----
public void setLocationHint(IntervalHint interval) {
locationHint = interval;
}
+ public boolean hasHint() {
+ return locationHint != null;
+ }
+
public boolean isSplitParent() {
return splitParent == this;
}
boolean isSplitChild() {
*** 539,554 ****
}
/**
* Sentinel interval to denote the end of an interval list.
*/
! static final TraceInterval EndMarker = new TraceInterval(Value.ILLEGAL, -1);
! TraceInterval(AllocatableValue operand, int operandNumber) {
assert operand != null;
this.operand = operand;
this.operandNumber = operandNumber;
if (isRegister(operand)) {
location = operand;
} else {
assert isIllegal(operand) || isVariable(operand);
}
--- 551,567 ----
}
/**
* Sentinel interval to denote the end of an interval list.
*/
! static final TraceInterval EndMarker = new TraceInterval(Value.ILLEGAL, -1, null);
! TraceInterval(AllocatableValue operand, int operandNumber, OptionValues options) {
assert operand != null;
this.operand = operand;
this.operandNumber = operandNumber;
+ this.options = options;
if (isRegister(operand)) {
location = operand;
} else {
assert isIllegal(operand) || isVariable(operand);
}
*** 590,600 ****
return splitParent().materializedValue;
}
// consistency check of split-children
boolean checkSplitChildren() {
! if (!splitChildren.isEmpty()) {
assert isSplitParent() : "only split parents can have children";
for (int i = 0; i < splitChildren.size(); i++) {
TraceInterval i1 = splitChildren.get(i);
--- 603,613 ----
return splitParent().materializedValue;
}
// consistency check of split-children
boolean checkSplitChildren() {
! if (!splitChildrenEmpty()) {
assert isSplitParent() : "only split parents can have children";
for (int i = 0; i < splitChildren.size(); i++) {
TraceInterval i1 = splitChildren.get(i);
*** 630,640 ****
if (locationHint.location() != null && isRegister(locationHint.location())) {
return locationHint;
} else if (locationHint instanceof TraceInterval) {
TraceInterval hint = (TraceInterval) locationHint;
! if (!hint.splitChildren.isEmpty()) {
// search the first split child that has a register assigned
int len = hint.splitChildren.size();
for (int i = 0; i < len; i++) {
TraceInterval interval = hint.splitChildren.get(i);
if (interval.location != null && isRegister(interval.location)) {
--- 643,653 ----
if (locationHint.location() != null && isRegister(locationHint.location())) {
return locationHint;
} else if (locationHint instanceof TraceInterval) {
TraceInterval hint = (TraceInterval) locationHint;
! if (!hint.splitChildrenEmpty()) {
// search the first split child that has a register assigned
int len = hint.splitChildren.size();
for (int i = 0; i < len; i++) {
TraceInterval interval = hint.splitChildren.get(i);
if (interval.location != null && isRegister(interval.location)) {
*** 647,661 ****
// no hint interval found that has a register assigned
return null;
}
TraceInterval getSplitChildAtOpId(int opId, LIRInstruction.OperandMode mode) {
assert isSplitParent() : "can only be called for split parents";
assert opId >= 0 : "invalid opId (method cannot be called for spill moves)";
! if (splitChildren.isEmpty()) {
assert this.covers(opId, mode) : this + " does not cover " + opId;
return this;
} else {
TraceInterval result = null;
int len = splitChildren.size();
--- 660,689 ----
// no hint interval found that has a register assigned
return null;
}
+ TraceInterval getSplitChildAtOpIdOrNull(int opId, LIRInstruction.OperandMode mode) {
+ /*
+ * TODO(je) could be replace by a simple range check by caching `to` in the split parent
+ * when creating split children.
+ */
+ return getSplitChildAtOpIdIntern(opId, mode, true);
+ }
+
TraceInterval getSplitChildAtOpId(int opId, LIRInstruction.OperandMode mode) {
+ return getSplitChildAtOpIdIntern(opId, mode, false);
+ }
+
+ private TraceInterval getSplitChildAtOpIdIntern(int opId, LIRInstruction.OperandMode mode, boolean returnNull) {
assert isSplitParent() : "can only be called for split parents";
assert opId >= 0 : "invalid opId (method cannot be called for spill moves)";
! if (splitChildrenEmpty()) {
! if (returnNull) {
! return covers(opId, mode) ? this : null;
! }
assert this.covers(opId, mode) : this + " does not cover " + opId;
return this;
} else {
TraceInterval result = null;
int len = splitChildren.size();
*** 678,705 ****
result = cur;
break;
}
}
! assert checkSplitChild(result, opId, toOffset, mode);
return result;
}
}
private boolean checkSplitChild(TraceInterval result, int opId, int toOffset, LIRInstruction.OperandMode mode) {
if (result == null) {
// this is an error
StringBuilder msg = new StringBuilder(this.toString()).append(" has no child at ").append(opId);
! if (!splitChildren.isEmpty()) {
TraceInterval firstChild = splitChildren.get(0);
TraceInterval lastChild = splitChildren.get(splitChildren.size() - 1);
msg.append(" (first = ").append(firstChild).append(", last = ").append(lastChild).append(")");
}
throw new GraalError("Linear Scan Error: %s", msg);
}
! if (!splitChildren.isEmpty()) {
for (TraceInterval interval : splitChildren) {
if (interval != result && interval.from() <= opId && opId < interval.to() + toOffset) {
/*
* Should not happen: Try another compilation as it is very unlikely to happen
* again.
--- 706,733 ----
result = cur;
break;
}
}
! assert returnNull || checkSplitChild(result, opId, toOffset, mode);
return result;
}
}
private boolean checkSplitChild(TraceInterval result, int opId, int toOffset, LIRInstruction.OperandMode mode) {
if (result == null) {
// this is an error
StringBuilder msg = new StringBuilder(this.toString()).append(" has no child at ").append(opId);
! if (!splitChildrenEmpty()) {
TraceInterval firstChild = splitChildren.get(0);
TraceInterval lastChild = splitChildren.get(splitChildren.size() - 1);
msg.append(" (first = ").append(firstChild).append(", last = ").append(lastChild).append(")");
}
throw new GraalError("Linear Scan Error: %s", msg);
}
! if (!splitChildrenEmpty()) {
for (TraceInterval interval : splitChildren) {
if (interval != result && interval.from() <= opId && opId < interval.to() + toOffset) {
/*
* Should not happen: Try another compilation as it is very unlikely to happen
* again.
*** 723,733 ****
}
TraceInterval parent = splitParent();
TraceInterval result = null;
! assert !parent.splitChildren.isEmpty() : "no split children available";
int len = parent.splitChildren.size();
for (int i = len - 1; i >= 0; i--) {
TraceInterval cur = parent.splitChildren.get(i);
if (cur.from() <= opId && opId < cur.to()) {
--- 751,761 ----
}
TraceInterval parent = splitParent();
TraceInterval result = null;
! assert !parent.splitChildrenEmpty() : "no split children available";
int len = parent.splitChildren.size();
for (int i = len - 1; i >= 0; i--) {
TraceInterval cur = parent.splitChildren.get(i);
if (cur.from() <= opId && opId < cur.to()) {
*** 744,754 ****
assert opId >= 0 : "invalid opId";
TraceInterval parent = splitParent();
TraceInterval result = null;
! assert !parent.splitChildren.isEmpty() : "no split children available";
int len = parent.splitChildren.size();
for (int i = len - 1; i >= 0; i--) {
TraceInterval cur = parent.splitChildren.get(i);
if (cur.to() <= opId && (result == null || result.to() < cur.to())) {
--- 772,782 ----
assert opId >= 0 : "invalid opId";
TraceInterval parent = splitParent();
TraceInterval result = null;
! assert !parent.splitChildrenEmpty() : "no split children available";
int len = parent.splitChildren.size();
for (int i = len - 1; i >= 0; i--) {
TraceInterval cur = parent.splitChildren.get(i);
if (cur.to() <= opId && (result == null || result.to() < cur.to())) {
*** 763,773 ****
// checks if opId is covered by any split child
boolean splitChildCovers(int opId, LIRInstruction.OperandMode mode) {
assert isSplitParent() : "can only be called for split parents";
assert opId >= 0 : "invalid opId (method can not be called for spill moves)";
! if (splitChildren.isEmpty()) {
// simple case if interval was not split
return covers(opId, mode);
} else {
// extended case: check all split children
--- 791,801 ----
// checks if opId is covered by any split child
boolean splitChildCovers(int opId, LIRInstruction.OperandMode mode) {
assert isSplitParent() : "can only be called for split parents";
assert opId >= 0 : "invalid opId (method can not be called for spill moves)";
! if (splitChildrenEmpty()) {
// simple case if interval was not split
return covers(opId, mode);
} else {
// extended case: check all split children
*** 850,860 ****
public void addUsePos(int pos, RegisterPriority registerPriority) {
assert isEmpty() || covers(pos, LIRInstruction.OperandMode.USE) : String.format("use position %d not covered by live range of interval %s", pos, this);
// do not add use positions for precolored intervals because they are never used
if (registerPriority != RegisterPriority.None && isVariable(operand)) {
! if (DetailedAsserts.getValue()) {
for (int i = 0; i < numUsePos(); i++) {
assert pos <= getUsePos(i) : "already added a use-position with lower position";
if (i > 0) {
assert getUsePos(i) < getUsePos(i - 1) : "not sorted descending";
}
--- 878,888 ----
public void addUsePos(int pos, RegisterPriority registerPriority) {
assert isEmpty() || covers(pos, LIRInstruction.OperandMode.USE) : String.format("use position %d not covered by live range of interval %s", pos, this);
// do not add use positions for precolored intervals because they are never used
if (registerPriority != RegisterPriority.None && isVariable(operand)) {
! if (DetailedAsserts.getValue(options)) {
for (int i = 0; i < numUsePos(); i++) {
assert pos <= getUsePos(i) : "already added a use-position with lower position";
if (i > 0) {
assert getUsePos(i) < getUsePos(i - 1) : "not sorted descending";
}
*** 891,901 ****
result.splitParent = parent;
result.setLocationHint(parent);
// insert new interval in children-list of parent
! if (parent.splitChildren.isEmpty()) {
assert isSplitParent() : "list must be initialized at first split";
// Create new non-shared list
parent.splitChildren = new ArrayList<>(4);
parent.splitChildren.add(this);
--- 919,929 ----
result.splitParent = parent;
result.setLocationHint(parent);
// insert new interval in children-list of parent
! if (parent.splitChildrenEmpty()) {
assert isSplitParent() : "list must be initialized at first split";
// Create new non-shared list
parent.splitChildren = new ArrayList<>(4);
parent.splitChildren.add(this);
*** 931,941 ****
intTo = splitPos;
// split list of use positions
splitUsePosAt(result, splitPos);
! if (DetailedAsserts.getValue()) {
for (int i = 0; i < numUsePos(); i++) {
assert getUsePos(i) < splitPos;
}
for (int i = 0; i < result.numUsePos(); i++) {
assert result.getUsePos(i) >= splitPos;
--- 959,969 ----
intTo = splitPos;
// split list of use positions
splitUsePosAt(result, splitPos);
! if (DetailedAsserts.getValue(options)) {
for (int i = 0; i < numUsePos(); i++) {
assert getUsePos(i) < splitPos;
}
for (int i = 0; i < result.numUsePos(); i++) {
assert result.getUsePos(i) >= splitPos;
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/lsra/TraceInterval.java
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File