use of jdk.vm.ci.meta.Value in project graal by oracle.
the class SSALinearScanResolveDataFlowPhase method resolveCollectMappings.
@Override
protected void resolveCollectMappings(AbstractBlockBase<?> fromBlock, AbstractBlockBase<?> toBlock, AbstractBlockBase<?> midBlock, MoveResolver moveResolver) {
super.resolveCollectMappings(fromBlock, toBlock, midBlock, moveResolver);
if (toBlock.getPredecessorCount() > 1) {
int toBlockFirstInstructionId = allocator.getFirstLirInstructionId(toBlock);
int fromBlockLastInstructionId = allocator.getLastLirInstructionId(fromBlock) + 1;
AbstractBlockBase<?> phiOutBlock = midBlock != null ? midBlock : fromBlock;
ArrayList<LIRInstruction> instructions = allocator.getLIR().getLIRforBlock(phiOutBlock);
int phiOutIdx = SSAUtil.phiOutIndex(allocator.getLIR(), phiOutBlock);
int phiOutId = midBlock != null ? fromBlockLastInstructionId : instructions.get(phiOutIdx).id();
assert phiOutId >= 0;
PhiValueVisitor visitor = new PhiValueVisitor() {
@Override
public void visit(Value phiIn, Value phiOut) {
assert !isRegister(phiOut) : "phiOut is a register: " + phiOut;
assert !isRegister(phiIn) : "phiIn is a register: " + phiIn;
Interval toInterval = allocator.splitChildAtOpId(allocator.intervalFor(phiIn), toBlockFirstInstructionId, LIRInstruction.OperandMode.DEF);
DebugContext debug = allocator.getDebug();
if (isConstantValue(phiOut)) {
numPhiResolutionMoves.increment(debug);
moveResolver.addMapping(asConstant(phiOut), toInterval);
} else {
Interval fromInterval = allocator.splitChildAtOpId(allocator.intervalFor(phiOut), phiOutId, LIRInstruction.OperandMode.DEF);
if (fromInterval != toInterval && !fromInterval.location().equals(toInterval.location())) {
numPhiResolutionMoves.increment(debug);
if (!(isStackSlotValue(toInterval.location()) && isStackSlotValue(fromInterval.location()))) {
moveResolver.addMapping(fromInterval, toInterval);
} else {
numStackToStackMoves.increment(debug);
moveResolver.addMapping(fromInterval, toInterval);
}
}
}
}
};
SSAUtil.forEachPhiValuePair(allocator.getLIR(), toBlock, phiOutBlock, visitor);
SSAUtil.removePhiOut(allocator.getLIR(), phiOutBlock);
}
}
use of jdk.vm.ci.meta.Value in project graal by oracle.
the class LinearScan method verifyIntervals.
@SuppressWarnings("try")
protected void verifyIntervals() {
try (Indent indent = debug.logAndIndent("verifying intervals")) {
int len = intervalsSize;
for (int i = 0; i < len; i++) {
Interval i1 = intervals[i];
if (i1 == null) {
continue;
}
i1.checkSplitChildren();
if (i1.operandNumber != i) {
debug.log("Interval %d is on position %d in list", i1.operandNumber, i);
debug.log(i1.logString(this));
throw new GraalError("");
}
if (isVariable(i1.operand) && i1.kind().equals(LIRKind.Illegal)) {
debug.log("Interval %d has no type assigned", i1.operandNumber);
debug.log(i1.logString(this));
throw new GraalError("");
}
if (i1.location() == null) {
debug.log("Interval %d has no register assigned", i1.operandNumber);
debug.log(i1.logString(this));
throw new GraalError("");
}
if (i1.first().isEndMarker()) {
debug.log("Interval %d has no Range", i1.operandNumber);
debug.log(i1.logString(this));
throw new GraalError("");
}
for (Range r = i1.first(); !r.isEndMarker(); r = r.next) {
if (r.from >= r.to) {
debug.log("Interval %d has zero length range", i1.operandNumber);
debug.log(i1.logString(this));
throw new GraalError("");
}
}
for (int j = i + 1; j < len; j++) {
Interval i2 = intervals[j];
if (i2 == null) {
continue;
}
// . ignore them because the range information has no meaning there
if (i1.from() == 1 && i1.to() == 2) {
continue;
}
if (i2.from() == 1 && i2.to() == 2) {
continue;
}
Value l1 = i1.location();
Value l2 = i2.location();
if (i1.intersects(i2) && !isIllegal(l1) && (l1.equals(l2))) {
throw GraalError.shouldNotReachHere(String.format("Intervals %d and %d overlap and have the same register assigned\n%s\n%s", i1.operandNumber, i2.operandNumber, i1.logString(this), i2.logString(this)));
}
}
}
}
}
use of jdk.vm.ci.meta.Value in project graal by oracle.
the class LinearScanIntervalDumper method printInterval.
private static void printInterval(Interval interval, IntervalVisitor visitor) {
Value hint = interval.locationHint(false) != null ? interval.locationHint(false).operand : null;
AllocatableValue operand = interval.operand;
String type = isRegister(operand) ? "fixed" : operand.getValueKind().getPlatformKind().toString();
visitor.visitIntervalStart(interval.splitParent().operand, operand, interval.location(), hint, type);
// print ranges
Range cur = interval.first();
while (!cur.isEndMarker()) {
visitor.visitRange(cur.from, cur.to);
cur = cur.next;
assert cur != null : "range list not closed with range sentinel";
}
// print use positions
int prev = -1;
UsePosList usePosList = interval.usePosList();
for (int i = usePosList.size() - 1; i >= 0; --i) {
assert prev < usePosList.usePos(i) : "use positions not sorted";
visitor.visitUsePos(usePosList.usePos(i), usePosList.registerPriority(i));
prev = usePosList.usePos(i);
}
visitor.visitIntervalEnd(interval.spillState());
}
use of jdk.vm.ci.meta.Value in project graal by oracle.
the class GlobalLivenessInfo method verifyBlock.
private boolean verifyBlock(AbstractBlockBase<?> block, LIR lir) {
BitSet liveSet = new BitSet(lir.numVariables());
int[] liveIn = getBlockIn(block);
for (int varNum : liveIn) {
liveSet.set(varNum);
}
ValueConsumer proc = new ValueConsumer() {
@Override
public void visitValue(Value value, OperandMode mode, EnumSet<OperandFlag> flags) {
if (LIRValueUtil.isVariable(value)) {
Variable var = LIRValueUtil.asVariable(value);
if (mode == OperandMode.DEF) {
liveSet.set(var.index);
} else {
assert liveSet.get(var.index) : String.format("Variable %s but not defined in block %s (liveIn: %s)", var, block, Arrays.toString(liveIn));
}
}
}
};
for (LIRInstruction op : lir.getLIRforBlock(block)) {
op.visitEachInput(proc);
op.visitEachAlive(proc);
op.visitEachState(proc);
op.visitEachOutput(proc);
// no need for checking temp
}
return true;
}
use of jdk.vm.ci.meta.Value in project graal by oracle.
the class TraceGlobalMoveResolver method verifyBeforeResolve.
private boolean verifyBeforeResolve() {
assert mappingFrom.size() == mappingTo.size() && mappingFrom.size() == mappingFromStack.size() : "length must be equal";
assert insertIdx != -1 : "insert position not set";
int i;
int j;
if (!areMultipleReadsAllowed()) {
for (i = 0; i < mappingFrom.size(); i++) {
for (j = i + 1; j < mappingFrom.size(); j++) {
assert mappingFrom.get(i) == null || mappingFrom.get(i) != mappingFrom.get(j) : "cannot read from same interval twice";
}
}
}
for (i = 0; i < mappingTo.size(); i++) {
for (j = i + 1; j < mappingTo.size(); j++) {
assert mappingTo.get(i) != mappingTo.get(j) : "cannot write to same interval twice";
}
}
for (i = 0; i < mappingTo.size(); i++) {
Value to = mappingTo.get(i);
assert !isStackSlotValue(to) || getStackArrayIndex(to) != STACK_SLOT_IN_CALLER_FRAME_IDX : "Cannot move to in argument: " + to;
}
HashSet<Value> usedRegs = new HashSet<>();
if (!areMultipleReadsAllowed()) {
for (i = 0; i < mappingFrom.size(); i++) {
Value from = mappingFrom.get(i);
if (from != null && !isIllegal(from)) {
boolean unique = usedRegs.add(from);
assert unique : "cannot read from same register twice";
}
}
}
usedRegs.clear();
for (i = 0; i < mappingTo.size(); i++) {
Value to = mappingTo.get(i);
if (isIllegal(to)) {
// intervals might be illegal.
continue;
}
boolean unique = usedRegs.add(to);
assert unique : "cannot write to same register twice";
}
return true;
}
Aggregations