src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanLifetimeAnalysisPhase.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File
*** old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanLifetimeAnalysisPhase.java	Fri Jul  7 09:30:40 2017
--- new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanLifetimeAnalysisPhase.java	Fri Jul  7 09:30:40 2017

*** 39,50 **** --- 39,49 ---- import org.graalvm.compiler.core.common.LIRKind; import org.graalvm.compiler.core.common.PermanentBailoutException; import org.graalvm.compiler.core.common.alloc.ComputeBlockOrder; import org.graalvm.compiler.core.common.cfg.AbstractBlockBase; import org.graalvm.compiler.core.common.util.BitMap2D; ! import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.debug.Debug.Scope; import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.debug.Indent; import org.graalvm.compiler.lir.InstructionValueConsumer; import org.graalvm.compiler.lir.LIRInstruction; import org.graalvm.compiler.lir.LIRInstruction.OperandFlag;
*** 71,92 **** --- 70,93 ---- import jdk.vm.ci.meta.ValueKind; public class LinearScanLifetimeAnalysisPhase extends LinearScanAllocationPhase { protected final LinearScan allocator; + protected final DebugContext debug; /** * @param linearScan */ protected LinearScanLifetimeAnalysisPhase(LinearScan linearScan) { allocator = linearScan; + debug = allocator.getDebug(); } @Override protected void run(TargetDescription target, LIRGenerationResult lirGenRes, AllocationContext context) { numberInstructions(); ! Debug.dump(Debug.VERBOSE_LEVEL, lirGenRes.getLIR(), "Before register allocation"); ! debug.dump(DebugContext.VERBOSE_LEVEL, lirGenRes.getLIR(), "Before register allocation"); computeLocalLiveSets(); computeGlobalLiveSets(); buildIntervals(DetailedAsserts.getValue(allocator.getOptions())); }
*** 158,168 **** --- 159,169 ---- intervalInLoop = new BitMap2D(allocator.operandSize(), allocator.numLoops()); // iterate all blocks for (final AbstractBlockBase<?> block : allocator.sortedBlocks()) { ! try (Indent indent = Debug.logAndIndent("compute local live sets for block %s", block)) { ! try (Indent indent = debug.logAndIndent("compute local live sets for block %s", block)) { final BitSet liveGen = new BitSet(liveSize); final BitSet liveKill = new BitSet(liveSize); ArrayList<LIRInstruction> instructions = allocator.getLIR().getLIRforBlock(block);
*** 171,182 **** --- 172,183 ---- ValueConsumer useConsumer = (operand, mode, flags) -> { if (isVariable(operand)) { int operandNum = allocator.operandNumber(operand); if (!liveKill.get(operandNum)) { liveGen.set(operandNum); ! if (Debug.isLogEnabled()) { ! Debug.log("liveGen for operand %d(%s)", operandNum, operand); ! if (debug.isLogEnabled()) { ! debug.log("liveGen for operand %d(%s)", operandNum, operand); } } if (block.getLoop() != null) { intervalInLoop.setBit(operandNum, block.getLoop().getIndex()); }
*** 189,210 **** --- 190,211 ---- ValueConsumer stateConsumer = (operand, mode, flags) -> { if (LinearScan.isVariableOrRegister(operand)) { int operandNum = allocator.operandNumber(operand); if (!liveKill.get(operandNum)) { liveGen.set(operandNum); ! if (Debug.isLogEnabled()) { ! Debug.log("liveGen in state for operand %d(%s)", operandNum, operand); ! if (debug.isLogEnabled()) { ! debug.log("liveGen in state for operand %d(%s)", operandNum, operand); } } } }; ValueConsumer defConsumer = (operand, mode, flags) -> { if (isVariable(operand)) { int varNum = allocator.operandNumber(operand); liveKill.set(varNum); ! if (Debug.isLogEnabled()) { ! Debug.log("liveKill for operand %d(%s)", varNum, operand); ! if (debug.isLogEnabled()) { ! debug.log("liveKill for operand %d(%s)", varNum, operand); } if (block.getLoop() != null) { intervalInLoop.setBit(varNum, block.getLoop().getIndex()); } }
*** 221,231 **** --- 222,232 ---- // iterate all instructions of the block for (int j = 0; j < numInst; j++) { final LIRInstruction op = instructions.get(j); ! try (Indent indent2 = Debug.logAndIndent("handle op %d: %s", op.id(), op)) { ! try (Indent indent2 = debug.logAndIndent("handle op %d: %s", op.id(), op)) { op.visitEachInput(useConsumer); op.visitEachAlive(useConsumer); /* * Add uses of live locals from interpreter's point of view for proper debug * information generation.
*** 240,252 **** --- 241,253 ---- blockSets.liveGen = liveGen; blockSets.liveKill = liveKill; blockSets.liveIn = new BitSet(liveSize); blockSets.liveOut = new BitSet(liveSize); ! if (Debug.isLogEnabled()) { ! Debug.log("liveGen B%d %s", block.getId(), blockSets.liveGen); ! Debug.log("liveKill B%d %s", block.getId(), blockSets.liveKill); ! if (debug.isLogEnabled()) { ! debug.log("liveGen B%d %s", block.getId(), blockSets.liveGen); ! debug.log("liveKill B%d %s", block.getId(), blockSets.liveKill); } } } // end of block iteration }
*** 280,290 **** --- 281,291 ---- * Performs a backward dataflow analysis to compute global live sets (i.e. * {@link BlockData#liveIn} and {@link BlockData#liveOut}) for each block. */ @SuppressWarnings("try") protected void computeGlobalLiveSets() { ! try (Indent indent = Debug.logAndIndent("compute global live sets")) { ! try (Indent indent = debug.logAndIndent("compute global live sets")) { int numBlocks = allocator.blockCount(); boolean changeOccurred; boolean changeOccurredInBlock; int iterationCount = 0; BitSet liveOut = new BitSet(allocator.liveSetSize()); // scratch set for calculations
*** 294,304 **** --- 295,305 ---- * The loop is executed until a fixpoint is reached (no changes in an iteration). */ do { changeOccurred = false; ! try (Indent indent2 = Debug.logAndIndent("new iteration %d", iterationCount)) { ! try (Indent indent2 = debug.logAndIndent("new iteration %d", iterationCount)) { // iterate all blocks in reverse order for (int i = numBlocks - 1; i >= 0; i--) { AbstractBlockBase<?> block = allocator.blockAt(i); BlockData blockSets = allocator.getBlockData(block);
*** 344,355 **** --- 345,356 ---- liveIn.clear(); liveIn.or(blockSets.liveOut); liveIn.andNot(blockSets.liveKill); liveIn.or(blockSets.liveGen); ! if (Debug.isLogEnabled()) { ! Debug.log("block %d: livein = %s, liveout = %s", block.getId(), liveIn, blockSets.liveOut); ! if (debug.isLogEnabled()) { ! debug.log("block %d: livein = %s, liveout = %s", block.getId(), liveIn, blockSets.liveOut); } } } iterationCount++;
*** 379,400 **** --- 380,401 ---- } } @SuppressWarnings("try") protected void reportFailure(int numBlocks) { ! try (Scope s = Debug.forceLog()) { ! try (Indent indent = Debug.logAndIndent("report failure")) { ! try (DebugContext.Scope s = debug.forceLog()) { ! try (Indent indent = debug.logAndIndent("report failure")) { BitSet startBlockLiveIn = allocator.getBlockData(allocator.getLIR().getControlFlowGraph().getStartBlock()).liveIn; ! try (Indent indent2 = Debug.logAndIndent("Error: liveIn set of first block must be empty (when this fails, variables are used before they are defined):")) { ! try (Indent indent2 = debug.logAndIndent("Error: liveIn set of first block must be empty (when this fails, variables are used before they are defined):")) { for (int operandNum = startBlockLiveIn.nextSetBit(0); operandNum >= 0; operandNum = startBlockLiveIn.nextSetBit(operandNum + 1)) { Interval interval = allocator.intervalFor(operandNum); if (interval != null) { Value operand = interval.operand; ! Debug.log("var %d; operand=%s; node=%s", operandNum, operand, getSourceForOperandFromDebugContext(operand)); ! debug.log("var %d; operand=%s; node=%s", operandNum, operand, getSourceForOperandFromDebugContext(debug, operand)); } else { ! Debug.log("var %d; missing operand", operandNum); ! debug.log("var %d; missing operand", operandNum); } } } // print some additional information to simplify debugging
*** 402,436 **** --- 403,437 ---- Interval interval = allocator.intervalFor(operandNum); Value operand = null; Object valueForOperandFromDebugContext = null; if (interval != null) { operand = interval.operand; ! valueForOperandFromDebugContext = getSourceForOperandFromDebugContext(debug, operand); } ! try (Indent indent2 = Debug.logAndIndent("---- Detailed information for var %d; operand=%s; node=%s ----", operandNum, operand, valueForOperandFromDebugContext)) { ! try (Indent indent2 = debug.logAndIndent("---- Detailed information for var %d; operand=%s; node=%s ----", operandNum, operand, valueForOperandFromDebugContext)) { ArrayDeque<AbstractBlockBase<?>> definedIn = new ArrayDeque<>(); EconomicSet<AbstractBlockBase<?>> usedIn = EconomicSet.create(Equivalence.IDENTITY); for (AbstractBlockBase<?> block : allocator.sortedBlocks()) { if (allocator.getBlockData(block).liveGen.get(operandNum)) { usedIn.add(block); ! try (Indent indent3 = Debug.logAndIndent("used in block B%d", block.getId())) { ! try (Indent indent3 = debug.logAndIndent("used in block B%d", block.getId())) { for (LIRInstruction ins : allocator.getLIR().getLIRforBlock(block)) { ! try (Indent indent4 = Debug.logAndIndent("%d: %s", ins.id(), ins)) { ! try (Indent indent4 = debug.logAndIndent("%d: %s", ins.id(), ins)) { ins.forEachState((liveStateOperand, mode, flags) -> { ! Debug.log("operand=%s", liveStateOperand); ! debug.log("operand=%s", liveStateOperand); return liveStateOperand; }); } } } } if (allocator.getBlockData(block).liveKill.get(operandNum)) { definedIn.add(block); ! try (Indent indent3 = Debug.logAndIndent("defined in block B%d", block.getId())) { ! try (Indent indent3 = debug.logAndIndent("defined in block B%d", block.getId())) { for (LIRInstruction ins : allocator.getLIR().getLIRforBlock(block)) { ! Debug.log("%d: %s", ins.id(), ins); ! debug.log("%d: %s", ins.id(), ins); } } } }
*** 449,468 **** --- 450,469 ---- definedIn.add(successor); } } } } ! try (Indent indent3 = Debug.logAndIndent("**** offending usages are in: ")) { ! try (Indent indent3 = debug.logAndIndent("**** offending usages are in: ")) { for (AbstractBlockBase<?> block : usedIn) { ! Debug.log("B%d", block.getId()); ! debug.log("B%d", block.getId()); } } } } } } catch (Throwable e) { ! throw Debug.handle(e); ! throw debug.handle(e); } } protected void verifyLiveness() { /*
*** 491,502 **** --- 492,503 ---- interval.addRange(from, to); // Register use position at even instruction id. interval.addUsePos(to & ~1, registerPriority, detailedAsserts); ! if (Debug.isLogEnabled()) { ! Debug.log("add use: %s, from %d to %d (%s)", interval, from, to, registerPriority.name()); ! if (debug.isLogEnabled()) { ! debug.log("add use: %s, from %d to %d (%s)", interval, from, to, registerPriority.name()); } } protected void addTemp(AllocatableValue operand, int tempPos, RegisterPriority registerPriority, ValueKind<?> kind, boolean detailedAsserts) { if (!allocator.isProcessed(operand)) {
*** 510,521 **** --- 511,522 ---- interval.addRange(tempPos, tempPos + 1); interval.addUsePos(tempPos, registerPriority, detailedAsserts); interval.addMaterializationValue(null); ! if (Debug.isLogEnabled()) { ! Debug.log("add temp: %s tempPos %d (%s)", interval, tempPos, RegisterPriority.MustHaveRegister.name()); ! if (debug.isLogEnabled()) { ! debug.log("add temp: %s tempPos %d (%s)", interval, tempPos, RegisterPriority.MustHaveRegister.name()); } } protected void addDef(AllocatableValue operand, LIRInstruction op, RegisterPriority registerPriority, ValueKind<?> kind, boolean detailedAsserts) { if (!allocator.isProcessed(operand)) {
*** 541,564 **** --- 542,565 ---- /* * Dead value - make vacuous interval also add register priority for dead intervals */ interval.addRange(defPos, defPos + 1); interval.addUsePos(defPos, registerPriority, detailedAsserts); ! if (Debug.isLogEnabled()) { ! Debug.log("Warning: def of operand %s at %d occurs without use", operand, defPos); ! if (debug.isLogEnabled()) { ! debug.log("Warning: def of operand %s at %d occurs without use", operand, defPos); } } changeSpillDefinitionPos(op, operand, interval, defPos); if (registerPriority == RegisterPriority.None && interval.spillState().ordinal() <= SpillState.StartInMemory.ordinal() && isStackSlot(operand)) { // detection of method-parameters and roundfp-results interval.setSpillState(SpillState.StartInMemory); } interval.addMaterializationValue(getMaterializedValue(op, operand, interval)); ! if (Debug.isLogEnabled()) { ! Debug.log("add def: %s defPos %d (%s)", interval, defPos, registerPriority.name()); ! if (debug.isLogEnabled()) { ! debug.log("add def: %s defPos %d (%s)", interval, defPos, registerPriority.name()); } } /** * Optimizes moves related to incoming stack based arguments. The interval for the destination
*** 572,583 **** --- 573,584 ---- if (DetailedAsserts.getValue(allocator.getOptions())) { assert op.id() > 0 : "invalid id"; assert allocator.blockForId(op.id()).getPredecessorCount() == 0 : "move from stack must be in first block"; assert isVariable(move.getResult()) : "result of move must be a variable"; ! if (Debug.isLogEnabled()) { ! Debug.log("found move from stack slot %s to %s", slot, move.getResult()); ! if (debug.isLogEnabled()) { ! debug.log("found move from stack slot %s to %s", slot, move.getResult()); } } Interval interval = allocator.intervalFor(move.getResult()); interval.setSpillSlot(slot);
*** 598,609 **** --- 599,610 ---- if (hintAtDef) { to.setLocationHint(from); } else { from.setLocationHint(to); } ! if (Debug.isLogEnabled()) { ! Debug.log("operation at opId %d: added hint from interval %d to %d", op.id(), from.operandNumber, to.operandNumber); ! if (debug.isLogEnabled()) { ! debug.log("operation at opId %d: added hint from interval %d to %d", op.id(), from.operandNumber, to.operandNumber); } return registerHint; } return null;
*** 683,693 **** --- 684,694 ---- } @SuppressWarnings("try") protected void buildIntervals(boolean detailedAsserts) { ! try (Indent indent = Debug.logAndIndent("build intervals")) { ! try (Indent indent = debug.logAndIndent("build intervals")) { InstructionValueConsumer outputConsumer = (op, operand, mode, flags) -> { if (LinearScan.isVariableOrRegister(operand)) { addDef((AllocatableValue) operand, op, registerPriorityOfOutputOperand(op), operand.getValueKind(), detailedAsserts); addRegisterHint(op, operand, mode, flags, true); }
*** 733,743 **** --- 734,744 ---- // iterate all blocks in reverse order for (int i = allocator.blockCount() - 1; i >= 0; i--) { AbstractBlockBase<?> block = allocator.blockAt(i); ! try (Indent indent2 = Debug.logAndIndent("handle block %d", block.getId())) { ! try (Indent indent2 = debug.logAndIndent("handle block %d", block.getId())) { ArrayList<LIRInstruction> instructions = allocator.getLIR().getLIRforBlock(block); final int blockFrom = allocator.getFirstLirInstructionId(block); int blockTo = allocator.getLastLirInstructionId(block);
*** 747,758 **** --- 748,759 ---- // Update intervals for operands live at the end of this block; BitSet live = allocator.getBlockData(block).liveOut; for (int operandNum = live.nextSetBit(0); operandNum >= 0; operandNum = live.nextSetBit(operandNum + 1)) { assert live.get(operandNum) : "should not stop here otherwise"; AllocatableValue operand = allocator.intervalFor(operandNum).operand; ! if (Debug.isLogEnabled()) { ! Debug.log("live in %d: %s", operandNum, operand); ! if (debug.isLogEnabled()) { ! debug.log("live in %d: %s", operandNum, operand); } addUse(operand, blockFrom, blockTo + 2, RegisterPriority.None, LIRKind.Illegal, detailedAsserts); /*
*** 771,792 **** --- 772,793 ---- */ for (int j = instructions.size() - 1; j >= 0; j--) { final LIRInstruction op = instructions.get(j); final int opId = op.id(); ! try (Indent indent3 = Debug.logAndIndent("handle inst %d: %s", opId, op)) { ! try (Indent indent3 = debug.logAndIndent("handle inst %d: %s", opId, op)) { // add a temp range for each register if operation destroys // caller-save registers if (op.destroysCallerSavedRegisters()) { for (Register r : callerSaveRegs) { if (allocator.attributes(r).isAllocatable()) { addTemp(r.asValue(), opId, RegisterPriority.None, LIRKind.Illegal, detailedAsserts); } } ! if (Debug.isLogEnabled()) { ! Debug.log("operation destroys all caller-save registers"); ! if (debug.isLogEnabled()) { ! debug.log("operation destroys all caller-save registers"); } } op.visitEachOutput(outputConsumer); op.visitEachTemp(tempConsumer);

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanLifetimeAnalysisPhase.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File