src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/Interval.java
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File
*** old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/Interval.java Mon Mar 20 17:39:46 2017
--- new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/Interval.java Mon Mar 20 17:39:46 2017
*** 40,50 ****
--- 40,49 ----
import org.graalvm.compiler.core.common.util.IntList;
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 jdk.vm.ci.code.RegisterValue;
import jdk.vm.ci.code.StackSlot;
import jdk.vm.ci.meta.AllocatableValue;
import jdk.vm.ci.meta.Constant;
import jdk.vm.ci.meta.Value;
*** 54,77 ****
--- 53,62 ----
* Represents an interval in the {@linkplain LinearScan linear scan register allocator}.
*/
public final class Interval {
/**
* A pair of intervals.
*/
static final class Pair {
public final Interval first;
public final Interval second;
Pair(Interval first, Interval second) {
this.first = first;
this.second = second;
}
}
/**
* A set of interval lists, one per {@linkplain RegisterBinding binding} type.
*/
static final class RegisterBindingLists {
/**
*** 194,204 ****
--- 179,189 ----
public void remove(RegisterBinding binding, Interval i) {
Interval list = get(binding);
Interval prev = null;
Interval cur = list;
while (cur != i) {
! assert cur != null && cur != Interval.EndMarker : "interval has not been found in list: " + i;
! assert cur != null && !cur.isEndMarker() : "interval has not been found in list: " + i;
prev = cur;
cur = cur.next;
}
if (prev == null) {
set(binding, cur.next);
*** 446,455 ****
--- 431,442 ----
}
return buf.append("]").toString();
}
}
+ protected static final int END_MARKER_OPERAND_NUMBER = Integer.MIN_VALUE;
+
/**
* The {@linkplain RegisterValue register} or {@linkplain Variable variable} for this interval
* prior to register allocation.
*/
public final AllocatableValue operand;
*** 491,501 ****
--- 478,489 ----
* Iterator used to traverse the ranges of an interval.
*/
private Range current;
/**
- * Link to next interval in a sorted list of intervals that ends with {@link #EndMarker}.
+ * LinearScan.intervalEndMarker.
*/
Interval next;
/**
* The linear-scan state of this interval.
*** 569,578 ****
--- 557,571 ----
assert newLocation.getValueKind().equals(this.kind);
}
this.location = newLocation;
}
+ /** Returns true is this is the sentinel interval that denotes the end of an interval list. */
+ public boolean isEndMarker() {
+ return operandNumber == END_MARKER_OPERAND_NUMBER;
+ }
+
/**
* Gets the {@linkplain RegisterValue register} or {@linkplain StackSlot spill slot} assigned to
* this interval.
*/
public AllocatableValue location() {
*** 699,709 ****
--- 692,702 ----
void rewindRange() {
current = first;
}
void nextRange() {
! assert this != EndMarker : "not allowed on sentinel";
! assert !this.isEndMarker() : "not allowed on sentinel";
current = current.next;
}
int currentFrom() {
return current.from;
*** 712,751 ****
--- 705,739 ----
int currentTo() {
return current.to;
}
boolean currentAtEnd() {
! return current == Range.EndMarker;
! return current.isEndMarker();
}
boolean currentIntersects(Interval it) {
return current.intersects(it.current);
}
int currentIntersectsAt(Interval it) {
return current.intersectsAt(it.current);
}
/**
* Sentinel interval to denote the end of an interval list.
*/
static final Interval EndMarker = new Interval(Value.ILLEGAL, -1);
Interval(AllocatableValue operand, int operandNumber) {
+ Interval(AllocatableValue operand, int operandNumber, Interval intervalEndMarker, Range rangeEndMarker) {
assert operand != null;
this.operand = operand;
this.operandNumber = operandNumber;
if (isRegister(operand)) {
location = operand;
} else {
assert isIllegal(operand) || isVariable(operand);
}
this.kind = LIRKind.Illegal;
! this.first = Range.EndMarker;
! this.first = rangeEndMarker;
this.usePosList = new UsePosList(4);
! this.current = Range.EndMarker;
! this.next = EndMarker;
! this.current = rangeEndMarker;
! this.next = intervalEndMarker;
this.cachedTo = -1;
this.spillState = SpillState.NoDefinitionFound;
this.spillDefinitionPos = -1;
splitParent = this;
currentSplitChild = this;
*** 778,791 ****
--- 766,779 ----
public Constant getMaterializedValue() {
return splitParent().materializedValue;
}
int calcTo() {
! assert first != Range.EndMarker : "interval has no range";
! assert !first.isEndMarker() : "interval has no range";
Range r = first;
! while (r.next != Range.EndMarker) {
! while (!r.next.isEndMarker()) {
r = r.next;
}
return r.to;
}
*** 1041,1056 ****
--- 1029,1044 ----
}
}
return prev;
}
! public void addUsePos(int pos, RegisterPriority registerPriority, boolean detailedAsserts) {
assert 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()) {
! if (detailedAsserts) {
for (int i = 0; i < usePosList.size(); i++) {
assert pos <= usePosList.usePos(i) : "already added a use-position with lower position";
if (i > 0) {
assert usePosList.usePos(i) < usePosList.usePos(i - 1) : "not sorted descending";
}
*** 1069,1083 ****
--- 1057,1071 ----
}
}
public void addRange(int from, int to) {
assert from < to : "invalid range";
! assert first() == Range.EndMarker || to < first().next.from : "not inserting at begin of interval";
! assert first().isEndMarker() || to < first().next.from : "not inserting at begin of interval";
assert from <= first().to : "not inserting at begin of interval";
if (first.from <= to) {
! assert first != Range.EndMarker;
! assert !first.isEndMarker();
// join intersecting ranges
first.from = Math.min(from, first().from);
first.to = Math.max(to, first().to);
} else {
// insert new range
*** 1128,1160 ****
--- 1116,1148 ----
Interval result = newSplitChild(allocator);
// split the ranges
Range prev = null;
Range cur = first;
! while (cur != Range.EndMarker && cur.to <= splitPos) {
! while (!cur.isEndMarker() && cur.to <= splitPos) {
prev = cur;
cur = cur.next;
}
! assert cur != Range.EndMarker : "split interval after end of last range";
! assert !cur.isEndMarker() : "split interval after end of last range";
if (cur.from < splitPos) {
result.first = new Range(splitPos, cur.to, cur.next);
cur.to = splitPos;
! cur.next = Range.EndMarker;
! cur.next = allocator.rangeEndMarker;
} else {
assert prev != null : "split before start of first range";
result.first = cur;
! prev.next = Range.EndMarker;
! prev.next = allocator.rangeEndMarker;
}
result.current = result.first;
cachedTo = -1; // clear cached value
// split list of use positions
result.usePosList = usePosList.splitAt(splitPos);
! if (DetailedAsserts.getValue(allocator.getOptions())) {
for (int i = 0; i < usePosList.size(); i++) {
assert usePosList.usePos(i) < splitPos;
}
for (int i = 0; i < result.usePosList.size(); i++) {
assert result.usePosList.usePos(i) >= splitPos;
*** 1182,1192 ****
--- 1170,1180 ----
// the new interval has only one range (checked by assertion above,
// so the splitting of the ranges is very simple
result.addRange(first.from, splitPos);
if (splitPos == first.to) {
! assert first.next != Range.EndMarker : "must not be at end";
! assert !first.next.isEndMarker() : "must not be at end";
first = first.next;
} else {
first.from = splitPos;
}
*** 1195,1208 ****
--- 1183,1196 ----
// returns true if the opId is inside the interval
boolean covers(int opId, LIRInstruction.OperandMode mode) {
Range cur = first;
! while (cur != Range.EndMarker && cur.to < opId) {
! while (!cur.isEndMarker() && cur.to < opId) {
cur = cur.next;
}
! if (cur != Range.EndMarker) {
! if (!cur.isEndMarker()) {
assert cur.to != cur.next.from : "ranges not separated";
if (mode == LIRInstruction.OperandMode.DEF) {
return cur.from <= opId && opId < cur.to;
} else {
*** 1217,1227 ****
--- 1205,1215 ----
boolean hasHoleBetween(int holeFrom, int holeTo) {
assert holeFrom < holeTo : "check";
assert from() <= holeFrom && holeTo <= to() : "index out of interval";
Range cur = first;
! while (cur != Range.EndMarker) {
! while (!cur.isEndMarker()) {
assert cur.to < cur.next.from : "no space between ranges";
// hole-range starts before this range . hole
if (holeFrom < cur.from) {
return true;
*** 1247,1257 ****
--- 1235,1245 ----
@Override
public String toString() {
String from = "?";
String to = "?";
! if (first != null && first != Range.EndMarker) {
! if (first != null && !first.isEndMarker()) {
from = String.valueOf(from());
// to() may cache a computed value, modifying the current object, which is a bad idea
// for a printing function. Compute it directly instead.
to = String.valueOf(calcTo());
}
*** 1287,1297 ****
--- 1275,1285 ----
}
buf.append("} ranges{");
// print ranges
Range cur = first;
! while (cur != Range.EndMarker) {
! while (!cur.isEndMarker()) {
if (cur != first) {
buf.append(", ");
}
buf.append(cur);
cur = cur.next;
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/Interval.java
Index
Unified diffs
Context diffs
Sdiffs
Patch
New
Old
Previous File
Next File