use of org.graalvm.compiler.debug.DebugContext in project graal by oracle.
the class RegisterVerifier method processBlock.
@SuppressWarnings("try")
private void processBlock(AbstractBlockBase<?> block) {
DebugContext debug = allocator.getDebug();
try (Indent indent = debug.logAndIndent("processBlock B%d", block.getId())) {
// must copy state because it is modified
Interval[] inputState = copy(stateForBlock(block));
try (Indent indent2 = debug.logAndIndent("Input-State of intervals:")) {
printState(inputState);
}
// process all operations of the block
processOperations(block, inputState);
try (Indent indent2 = debug.logAndIndent("Output-State of intervals:")) {
printState(inputState);
}
// iterate all successors
for (AbstractBlockBase<?> succ : block.getSuccessors()) {
processSuccessor(succ, inputState);
}
}
}
use of org.graalvm.compiler.debug.DebugContext 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 org.graalvm.compiler.debug.DebugContext 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.debug.DebugContext in project graal by oracle.
the class LinearScanResolveDataFlowPhase method resolveDataFlow0.
protected void resolveDataFlow0(MoveResolver moveResolver, BitSet blockCompleted) {
BitSet alreadyResolved = new BitSet(allocator.blockCount());
for (AbstractBlockBase<?> fromBlock : allocator.sortedBlocks()) {
if (!blockCompleted.get(fromBlock.getLinearScanNumber())) {
alreadyResolved.clear();
alreadyResolved.or(blockCompleted);
for (AbstractBlockBase<?> toBlock : fromBlock.getSuccessors()) {
/*
* Check for duplicate edges between the same blocks (can happen with switch
* blocks).
*/
if (!alreadyResolved.get(toBlock.getLinearScanNumber())) {
DebugContext debug = allocator.getDebug();
if (debug.isLogEnabled()) {
debug.log("processing edge between B%d and B%d", fromBlock.getId(), toBlock.getId());
}
alreadyResolved.set(toBlock.getLinearScanNumber());
// collect all intervals that have been split between
// fromBlock and toBlock
resolveCollectMappings(fromBlock, toBlock, null, moveResolver);
if (moveResolver.hasMappings()) {
resolveFindInsertPos(fromBlock, toBlock, moveResolver);
moveResolver.resolveAndAppendMoves();
}
}
}
}
}
}
use of org.graalvm.compiler.debug.DebugContext 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();
}
}
}
}
}
}
Aggregations