use of org.graalvm.compiler.lir.LIRInstruction in project graal by oracle.
the class TraceGlobalMoveResolver method resolveMappings.
@SuppressWarnings("try")
private void resolveMappings() {
try (Indent indent = debug.logAndIndent("resolveMapping")) {
assert verifyBeforeResolve();
if (debug.isLogEnabled()) {
printMapping();
}
// This is necessary for detecting cycles in moves.
for (int i = mappingFrom.size() - 1; i >= 0; i--) {
Value from = mappingFrom.get(i);
block(from);
}
ArrayList<AllocatableValue> busySpillSlots = null;
while (mappingFrom.size() > 0) {
boolean processedInterval = false;
int spillCandidate = -1;
for (int i = mappingFrom.size() - 1; i >= 0; i--) {
Value fromLocation = mappingFrom.get(i);
AllocatableValue toLocation = mappingTo.get(i);
if (safeToProcessMove(fromLocation, toLocation)) {
// this interval can be processed because target is free
LIRInstruction move = insertMove(fromLocation, toLocation);
move.setComment(res, "TraceGlobalMoveResolver: resolveMapping");
unblock(fromLocation);
if (isStackSlotValue(toLocation)) {
if (busySpillSlots == null) {
busySpillSlots = new ArrayList<>(2);
}
busySpillSlots.add(toLocation);
}
mappingFrom.remove(i);
mappingFromStack.remove(i);
mappingTo.remove(i);
processedInterval = true;
} else if (fromLocation != null) {
if (isRegister(fromLocation) && (busySpillSlots == null || !busySpillSlots.contains(mappingFromStack.get(i)))) {
// this interval cannot be processed now because target is not free
// it starts in a register, so it is a possible candidate for spilling
spillCandidate = i;
} else if (isStackSlotValue(fromLocation) && spillCandidate == -1) {
// fall back to spill a stack slot in case no other candidate is found
spillCandidate = i;
}
}
}
if (!processedInterval) {
breakCycle(spillCandidate);
}
}
}
// check that all intervals have been processed
assert checkEmpty();
}
use of org.graalvm.compiler.lir.LIRInstruction in project graal by oracle.
the class BottomUpAllocator method resolveFindInsertPos.
private void resolveFindInsertPos(AbstractBlockBase<?> fromBlock, AbstractBlockBase<?> toBlock) {
LIR lir = lirGenRes.getLIR();
if (fromBlock.getSuccessorCount() <= 1) {
if (debug.isLogEnabled()) {
debug.log("inserting moves at end of fromBlock B%d", fromBlock.getId());
}
ArrayList<LIRInstruction> instructions = lir.getLIRforBlock(fromBlock);
LIRInstruction instr = instructions.get(instructions.size() - 1);
if (instr instanceof StandardOp.JumpOp) {
// insert moves before branch
moveResolver.setInsertPosition(instructions, instructions.size() - 1);
} else {
moveResolver.setInsertPosition(instructions, instructions.size());
}
} else {
if (debug.isLogEnabled()) {
debug.log("inserting moves at beginning of toBlock B%d", toBlock.getId());
}
if (Assertions.detailedAssertionsEnabled(getLIR().getOptions())) {
assert lir.getLIRforBlock(fromBlock).get(0) instanceof StandardOp.LabelOp : "block does not start with a label";
/*
* Because the number of predecessor edges matches the number of successor edges,
* blocks which are reached by switch statements may have be more than one
* predecessor but it will be guaranteed that all predecessors will be the same.
*/
for (AbstractBlockBase<?> predecessor : toBlock.getPredecessors()) {
assert fromBlock == predecessor : "all critical edges must be broken";
}
}
moveResolver.setInsertPosition(lir.getLIRforBlock(toBlock), 1);
}
}
use of org.graalvm.compiler.lir.LIRInstruction in project graal by oracle.
the class UseEntry method replaceValue.
private static void replaceValue(LIRInstruction op, Value oldValue, Value newValue) {
ValueProcedure proc = (value, mode, flags) -> value.identityEquals(oldValue) ? newValue : value;
op.forEachAlive(proc);
op.forEachInput(proc);
op.forEachOutput(proc);
op.forEachTemp(proc);
op.forEachState(proc);
}
use of org.graalvm.compiler.lir.LIRInstruction in project graal by oracle.
the class SaveCalleeSaveRegisters method restoreAtExit.
private static void restoreAtExit(LIR lir, LIRGeneratorTool.MoveFactory moveFactory, LIRGenerationResult lirGenRes, RegisterMap<Variable> calleeSaveRegisters, AbstractBlockBase<?> block) {
ArrayList<LIRInstruction> instructions = lir.getLIRforBlock(block);
int insertionIndex = instructions.size() - 1;
LIRInsertionBuffer buffer = new LIRInsertionBuffer();
buffer.init(instructions);
assert instructions.get(insertionIndex) instanceof StandardOp.BlockEndOp;
calleeSaveRegisters.forEach((Register register, Variable saved) -> {
LIRInstruction restore = moveFactory.createMove(register.asValue(saved.getValueKind()), saved);
buffer.append(insertionIndex, restore);
restore.setComment(lirGenRes, "SaveCalleeSavedRegisters: restoreAtExit");
});
buffer.finish();
}
use of org.graalvm.compiler.lir.LIRInstruction in project graal by oracle.
the class SaveCalleeSaveRegisters method saveAtEntry.
private static RegisterMap<Variable> saveAtEntry(LIR lir, LIRGeneratorTool lirGen, LIRGenerationResult lirGenRes, RegisterArray calleeSaveRegisters, Architecture arch) {
AbstractBlockBase<?> startBlock = lir.getControlFlowGraph().getStartBlock();
ArrayList<LIRInstruction> instructions = lir.getLIRforBlock(startBlock);
int insertionIndex = 1;
LIRInsertionBuffer buffer = new LIRInsertionBuffer();
buffer.init(instructions);
StandardOp.LabelOp entry = (StandardOp.LabelOp) instructions.get(insertionIndex - 1);
RegisterValue[] savedRegisterValues = new RegisterValue[calleeSaveRegisters.size()];
int savedRegisterValueIndex = 0;
RegisterMap<Variable> saveMap = new RegisterMap<>(arch);
for (Register register : calleeSaveRegisters) {
PlatformKind registerPlatformKind = arch.getLargestStorableKind(register.getRegisterCategory());
LIRKind lirKind = LIRKind.value(registerPlatformKind);
RegisterValue registerValue = register.asValue(lirKind);
Variable saveVariable = lirGen.newVariable(lirKind);
LIRInstruction save = lirGen.getSpillMoveFactory().createMove(saveVariable, registerValue);
buffer.append(insertionIndex, save);
save.setComment(lirGenRes, "SaveCalleeSavedRegisters: saveAtEntry");
saveMap.put(register, saveVariable);
savedRegisterValues[savedRegisterValueIndex++] = registerValue;
}
entry.addIncomingValues(savedRegisterValues);
buffer.finish();
return saveMap;
}
Aggregations