use of org.graalvm.compiler.lir.LIRInstruction in project graal by oracle.
the class LinearScanResolveDataFlowPhase method resolveFindInsertPos.
void resolveFindInsertPos(AbstractBlockBase<?> fromBlock, AbstractBlockBase<?> toBlock, MoveResolver moveResolver) {
DebugContext debug = allocator.getDebug();
if (fromBlock.getSuccessorCount() <= 1) {
if (debug.isLogEnabled()) {
debug.log("inserting moves at end of fromBlock B%d", fromBlock.getId());
}
ArrayList<LIRInstruction> instructions = allocator.getLIR().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 (allocator.detailedAsserts) {
assert allocator.getLIR().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(allocator.getLIR().getLIRforBlock(toBlock), 1);
}
}
use of org.graalvm.compiler.lir.LIRInstruction in project graal by oracle.
the class LinearScanResolveDataFlowPhase method optimizeEmptyBlocks.
protected void optimizeEmptyBlocks(MoveResolver moveResolver, BitSet blockCompleted) {
for (AbstractBlockBase<?> block : allocator.sortedBlocks()) {
// check if block has only one predecessor and only one successor
if (block.getPredecessorCount() == 1 && block.getSuccessorCount() == 1) {
ArrayList<LIRInstruction> instructions = allocator.getLIR().getLIRforBlock(block);
assert instructions.get(0) instanceof StandardOp.LabelOp : "block must start with label";
assert instructions.get(instructions.size() - 1) instanceof StandardOp.JumpOp : "block with successor must end with unconditional jump";
// check if block is empty (only label and branch)
if (instructions.size() == 2) {
AbstractBlockBase<?> pred = block.getPredecessors()[0];
AbstractBlockBase<?> sux = block.getSuccessors()[0];
// prevent optimization of two consecutive blocks
if (!blockCompleted.get(pred.getLinearScanNumber()) && !blockCompleted.get(sux.getLinearScanNumber())) {
DebugContext debug = allocator.getDebug();
if (debug.isLogEnabled()) {
debug.log(" optimizing empty block B%d (pred: B%d, sux: B%d)", block.getId(), pred.getId(), sux.getId());
}
blockCompleted.set(block.getLinearScanNumber());
/*
* Directly resolve between pred and sux (without looking at the empty block
* between).
*/
resolveCollectMappings(pred, sux, block, moveResolver);
if (moveResolver.hasMappings()) {
moveResolver.setInsertPosition(instructions, 1);
moveResolver.resolveAndAppendMoves();
}
}
}
}
}
}
use of org.graalvm.compiler.lir.LIRInstruction 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 org.graalvm.compiler.lir.LIRInstruction in project graal by oracle.
the class TraceGlobalMoveResolutionPhase method interTraceEdge.
@SuppressWarnings("try")
private static void interTraceEdge(TraceBuilderResult resultTraces, GlobalLivenessInfo livenessInfo, LIR lir, TraceGlobalMoveResolver moveResolver, AbstractBlockBase<?> fromBlock, AbstractBlockBase<?> toBlock) {
DebugContext debug = lir.getDebug();
try (Indent indent0 = debug.logAndIndent("Handle trace edge from %s (Trace%d) to %s (Trace%d)", fromBlock, resultTraces.getTraceForBlock(fromBlock).getId(), toBlock, resultTraces.getTraceForBlock(toBlock).getId())) {
final ArrayList<LIRInstruction> instructions;
final int insertIdx;
if (fromBlock.getSuccessorCount() == 1) {
instructions = lir.getLIRforBlock(fromBlock);
insertIdx = instructions.size() - 1;
} else {
assert toBlock.getPredecessorCount() == 1;
instructions = lir.getLIRforBlock(toBlock);
insertIdx = 1;
}
moveResolver.setInsertPosition(instructions, insertIdx);
resolveEdge(lir, livenessInfo, moveResolver, fromBlock, toBlock);
moveResolver.resolveAndAppendMoves();
}
}
use of org.graalvm.compiler.lir.LIRInstruction in project graal by oracle.
the class TraceGlobalMoveResolver method insertMove.
private LIRInstruction insertMove(Value fromOperand, AllocatableValue toOperand) {
assert !fromOperand.equals(toOperand) : "from and to are equal: " + fromOperand + " vs. " + toOperand;
assert LIRKind.verifyMoveKinds(fromOperand.getValueKind(), fromOperand.getValueKind(), registerAllocationConfig) : "move between different types";
assert insertIdx != -1 : "must setup insert position first";
LIRInstruction move = createMove(fromOperand, toOperand);
insertionBuffer.append(insertIdx, move);
if (debug.isLogEnabled()) {
debug.log("insert move from %s to %s at %d", fromOperand, toOperand, insertIdx);
}
return move;
}
Aggregations