use of jdk.vm.ci.meta.Value in project graal by oracle.
the class MoveResolver method safeToProcessMove.
/**
* Checks if the {@linkplain Interval#location() location} of {@code to} is not blocked or is
* only blocked by {@code from}.
*/
private boolean safeToProcessMove(Interval from, Interval to) {
Value fromReg = from != null ? from.location() : null;
Value location = to.location();
if (mightBeBlocked(location)) {
if ((valueBlocked(location) > 1 || (valueBlocked(location) == 1 && !isMoveToSelf(fromReg, location)))) {
return false;
}
}
return true;
}
use of jdk.vm.ci.meta.Value in project graal by oracle.
the class RegisterVerifier method processOperations.
void processOperations(AbstractBlockBase<?> block, final Interval[] inputState) {
ArrayList<LIRInstruction> ops = allocator.getLIR().getLIRforBlock(block);
DebugContext debug = allocator.getDebug();
InstructionValueConsumer useConsumer = new InstructionValueConsumer() {
@Override
public void visitValue(LIRInstruction op, Value operand, OperandMode mode, EnumSet<OperandFlag> flags) {
// we skip spill moves inserted by the spill position optimization
if (LinearScan.isVariableOrRegister(operand) && allocator.isProcessed(operand) && op.id() != LinearScan.DOMINATOR_SPILL_MOVE_ID) {
Interval interval = intervalAt(operand);
if (op.id() != -1) {
interval = interval.getSplitChildAtOpId(op.id(), mode, allocator);
}
assert checkState(block, op, inputState, interval.operand, interval.location(), interval.splitParent());
}
}
};
InstructionValueConsumer defConsumer = (op, operand, mode, flags) -> {
if (LinearScan.isVariableOrRegister(operand) && allocator.isProcessed(operand)) {
Interval interval = intervalAt(operand);
if (op.id() != -1) {
interval = interval.getSplitChildAtOpId(op.id(), mode, allocator);
}
statePut(debug, inputState, interval.location(), interval.splitParent());
}
};
// visit all instructions of the block
for (int i = 0; i < ops.size(); i++) {
final LIRInstruction op = ops.get(i);
if (debug.isLogEnabled()) {
debug.log("%s", op.toStringWithIdPrefix());
}
// check if input operands are correct
op.visitEachInput(useConsumer);
// invalidate all caller save registers at calls
if (op.destroysCallerSavedRegisters()) {
for (Register r : allocator.getRegisterAllocationConfig().getRegisterConfig().getCallerSaveRegisters()) {
statePut(debug, inputState, r.asValue(), null);
}
}
op.visitEachAlive(useConsumer);
// set temp operands (some operations use temp operands also as output operands, so
// can't set them null)
op.visitEachTemp(defConsumer);
// set output operands
op.visitEachOutput(defConsumer);
}
}
use of jdk.vm.ci.meta.Value in project graal by oracle.
the class TraceGlobalMoveResolutionPhase method resolveEdge.
private static void resolveEdge(LIR lir, GlobalLivenessInfo livenessInfo, TraceGlobalMoveResolver moveResolver, AbstractBlockBase<?> fromBlock, AbstractBlockBase<?> toBlock) {
assert verifyEdge(fromBlock, toBlock);
if (SSAUtil.isMerge(toBlock)) {
// PHI
JumpOp blockEnd = SSAUtil.phiOut(lir, fromBlock);
LabelOp label = SSAUtil.phiIn(lir, toBlock);
for (int i = 0; i < label.getPhiSize(); i++) {
Value in = label.getIncomingValue(i);
Value out = blockEnd.getOutgoingValue(i);
addMapping(moveResolver, out, in);
}
}
// GLI
Value[] locFrom = livenessInfo.getOutLocation(fromBlock);
Value[] locTo = livenessInfo.getInLocation(toBlock);
if (locFrom == locTo) {
// a strategy might reuse the locations array if locations are the same
return;
}
assert locFrom.length == locTo.length;
for (int i = 0; i < locFrom.length; i++) {
addMapping(moveResolver, locFrom[i], locTo[i]);
}
}
use of jdk.vm.ci.meta.Value in project graal by oracle.
the class TraceGlobalMoveResolver method breakCycle.
@SuppressWarnings("try")
private void breakCycle(int spillCandidate) {
// (e.g. r1 . r2, r2 . r1), so one interval must be spilled to memory
assert spillCandidate != -1 : "no interval in register for spilling found";
// create a new spill interval and assign a stack slot to it
Value from = mappingFrom.get(spillCandidate);
try (Indent indent = debug.logAndIndent("BreakCycle: %s", from)) {
AllocatableValue spillSlot = null;
if (TraceRegisterAllocationPhase.Options.TraceRAreuseStackSlotsForMoveResolutionCycleBreaking.getValue(options) && !isStackSlotValue(from)) {
// don't use the stack slot if from is already the stack slot
Value fromStack = mappingFromStack.get(spillCandidate);
if (fromStack != null) {
spillSlot = (AllocatableValue) fromStack;
cycleBreakingSlotsReused.increment(debug);
debug.log("reuse slot for spilling: %s", spillSlot);
}
}
if (spillSlot == null) {
spillSlot = frameMapBuilder.allocateSpillSlot(from.getValueKind());
cycleBreakingSlotsAllocated.increment(debug);
debug.log("created new slot for spilling: %s", spillSlot);
// insert a move from register to stack and update the mapping
LIRInstruction move = insertMove(from, spillSlot);
move.setComment(res, "TraceGlobalMoveResolver: breakCycle");
}
block(spillSlot);
mappingFrom.set(spillCandidate, spillSlot);
unblock(from);
}
}
use of jdk.vm.ci.meta.Value in project graal by oracle.
the class SPARCMove method const2stack.
public static void const2stack(CompilationResultBuilder crb, SPARCMacroAssembler masm, Value result, Register constantTableBase, SPARCDelayedControlTransfer delaySlotLir, JavaConstant constant) {
if (constant.isDefaultForKind() || constant.isNull()) {
SPARCAddress resultAddress = (SPARCAddress) crb.asAddress(result);
emitStore(g0.asValue(LIRKind.combine(result)), resultAddress, result.getPlatformKind(), delaySlotLir, null, crb, masm);
} else {
try (ScratchRegister sc = masm.getScratchRegister()) {
Value scratchRegisterValue = sc.getRegister().asValue(LIRKind.combine(result));
const2reg(crb, masm, scratchRegisterValue, constantTableBase, constant, SPARCDelayedControlTransfer.DUMMY);
SPARCAddress resultAddress = (SPARCAddress) crb.asAddress(result);
emitStore(scratchRegisterValue, resultAddress, result.getPlatformKind(), delaySlotLir, null, crb, masm);
}
}
}
Aggregations