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

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanWalker.java

Print this page

        

*** 34,44 **** import java.util.List; import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig.AllocatableRegisters; import org.graalvm.compiler.core.common.cfg.AbstractBlockBase; import org.graalvm.compiler.core.common.util.Util; ! import org.graalvm.compiler.debug.Debug; import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.debug.Indent; import org.graalvm.compiler.lir.LIRInstruction; import org.graalvm.compiler.lir.StandardOp.ValueMoveOp; import org.graalvm.compiler.lir.alloc.OutOfRegistersException; --- 34,44 ---- import java.util.List; import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig.AllocatableRegisters; import org.graalvm.compiler.core.common.cfg.AbstractBlockBase; import org.graalvm.compiler.core.common.util.Util; ! import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.debug.Indent; import org.graalvm.compiler.lir.LIRInstruction; import org.graalvm.compiler.lir.StandardOp.ValueMoveOp; import org.graalvm.compiler.lir.alloc.OutOfRegistersException;
*** 321,335 **** return optimalSplitPos; } int findOptimalSplitPos(Interval interval, int minSplitPos, int maxSplitPos, boolean doLoopOptimization) { int optimalSplitPos = -1; if (minSplitPos == maxSplitPos) { // trivial case, no optimization of split position possible ! if (Debug.isLogEnabled()) { ! Debug.log("min-pos and max-pos are equal, no optimization possible"); } optimalSplitPos = minSplitPos; } else { assert minSplitPos < maxSplitPos : "must be true then"; --- 321,336 ---- return optimalSplitPos; } int findOptimalSplitPos(Interval interval, int minSplitPos, int maxSplitPos, boolean doLoopOptimization) { + DebugContext debug = allocator.getDebug(); int optimalSplitPos = -1; if (minSplitPos == maxSplitPos) { // trivial case, no optimization of split position possible ! if (debug.isLogEnabled()) { ! debug.log("min-pos and max-pos are equal, no optimization possible"); } optimalSplitPos = minSplitPos; } else { assert minSplitPos < maxSplitPos : "must be true then";
*** 348,387 **** AbstractBlockBase<?> maxBlock = allocator.blockForId(maxSplitPos - 1); assert minBlock.getLinearScanNumber() <= maxBlock.getLinearScanNumber() : "invalid order"; if (minBlock == maxBlock) { // split position cannot be moved to block boundary : so split as late as possible ! if (Debug.isLogEnabled()) { ! Debug.log("cannot move split pos to block boundary because minPos and maxPos are in same block"); } optimalSplitPos = maxSplitPos; } else { if (interval.hasHoleBetween(maxSplitPos - 1, maxSplitPos) && !allocator.isBlockBegin(maxSplitPos)) { // Do not move split position if the interval has a hole before maxSplitPos. // Intervals resulting from Phi-Functions have more than one definition (marked // as mustHaveRegister) with a hole before each definition. When the register is // needed // for the second definition : an earlier reloading is unnecessary. ! if (Debug.isLogEnabled()) { ! Debug.log("interval has hole just before maxSplitPos, so splitting at maxSplitPos"); } optimalSplitPos = maxSplitPos; } else { // seach optimal block boundary between minSplitPos and maxSplitPos ! if (Debug.isLogEnabled()) { ! Debug.log("moving split pos to optimal block boundary between block B%d and B%d", minBlock.getId(), maxBlock.getId()); } if (doLoopOptimization) { // Loop optimization: if a loop-end marker is found between min- and // max-position : // then split before this loop int loopEndPos = interval.nextUsageExact(RegisterPriority.LiveAtLoopEnd, allocator.getLastLirInstructionId(minBlock) + 2); ! if (Debug.isLogEnabled()) { ! Debug.log("loop optimization: loop end found at pos %d", loopEndPos); } assert loopEndPos > minSplitPos : "invalid order"; if (loopEndPos < maxSplitPos) { // loop-end marker found between min- and max-position --- 349,388 ---- AbstractBlockBase<?> maxBlock = allocator.blockForId(maxSplitPos - 1); assert minBlock.getLinearScanNumber() <= maxBlock.getLinearScanNumber() : "invalid order"; if (minBlock == maxBlock) { // split position cannot be moved to block boundary : so split as late as possible ! if (debug.isLogEnabled()) { ! debug.log("cannot move split pos to block boundary because minPos and maxPos are in same block"); } optimalSplitPos = maxSplitPos; } else { if (interval.hasHoleBetween(maxSplitPos - 1, maxSplitPos) && !allocator.isBlockBegin(maxSplitPos)) { // Do not move split position if the interval has a hole before maxSplitPos. // Intervals resulting from Phi-Functions have more than one definition (marked // as mustHaveRegister) with a hole before each definition. When the register is // needed // for the second definition : an earlier reloading is unnecessary. ! if (debug.isLogEnabled()) { ! debug.log("interval has hole just before maxSplitPos, so splitting at maxSplitPos"); } optimalSplitPos = maxSplitPos; } else { // seach optimal block boundary between minSplitPos and maxSplitPos ! if (debug.isLogEnabled()) { ! debug.log("moving split pos to optimal block boundary between block B%d and B%d", minBlock.getId(), maxBlock.getId()); } if (doLoopOptimization) { // Loop optimization: if a loop-end marker is found between min- and // max-position : // then split before this loop int loopEndPos = interval.nextUsageExact(RegisterPriority.LiveAtLoopEnd, allocator.getLastLirInstructionId(minBlock) + 2); ! if (debug.isLogEnabled()) { ! debug.log("loop optimization: loop end found at pos %d", loopEndPos); } assert loopEndPos > minSplitPos : "invalid order"; if (loopEndPos < maxSplitPos) { // loop-end marker found between min- and max-position
*** 391,415 **** // Desired result: uses tagged as shouldHaveRegister inside a loop cause // a reloading // of the interval (normally, only mustHaveRegister causes a reloading) AbstractBlockBase<?> loopBlock = allocator.blockForId(loopEndPos); ! if (Debug.isLogEnabled()) { ! Debug.log("interval is used in loop that ends in block B%d, so trying to move maxBlock back from B%d to B%d", loopBlock.getId(), maxBlock.getId(), loopBlock.getId()); } assert loopBlock != minBlock : "loopBlock and minBlock must be different because block boundary is needed between"; int maxSpillPos = allocator.getLastLirInstructionId(loopBlock) + 2; optimalSplitPos = findOptimalSplitPos(minBlock, loopBlock, maxSpillPos); if (optimalSplitPos == maxSpillPos) { optimalSplitPos = -1; ! if (Debug.isLogEnabled()) { ! Debug.log("loop optimization not necessary"); } } else { ! if (Debug.isLogEnabled()) { ! Debug.log("loop optimization successful"); } } } } --- 392,416 ---- // Desired result: uses tagged as shouldHaveRegister inside a loop cause // a reloading // of the interval (normally, only mustHaveRegister causes a reloading) AbstractBlockBase<?> loopBlock = allocator.blockForId(loopEndPos); ! if (debug.isLogEnabled()) { ! debug.log("interval is used in loop that ends in block B%d, so trying to move maxBlock back from B%d to B%d", loopBlock.getId(), maxBlock.getId(), loopBlock.getId()); } assert loopBlock != minBlock : "loopBlock and minBlock must be different because block boundary is needed between"; int maxSpillPos = allocator.getLastLirInstructionId(loopBlock) + 2; optimalSplitPos = findOptimalSplitPos(minBlock, loopBlock, maxSpillPos); if (optimalSplitPos == maxSpillPos) { optimalSplitPos = -1; ! if (debug.isLogEnabled()) { ! debug.log("loop optimization not necessary"); } } else { ! if (debug.isLogEnabled()) { ! debug.log("loop optimization successful"); } } } }
*** 418,429 **** optimalSplitPos = findOptimalSplitPos(minBlock, maxBlock, maxSplitPos); } } } } ! if (Debug.isLogEnabled()) { ! Debug.log("optimal split position: %d", optimalSplitPos); } return optimalSplitPos; } --- 419,430 ---- optimalSplitPos = findOptimalSplitPos(minBlock, maxBlock, maxSplitPos); } } } } ! if (debug.isLogEnabled()) { ! debug.log("optimal split position: %d", optimalSplitPos); } return optimalSplitPos; }
*** 431,442 **** // maxSplitPos in two parts: // 1) the left part has already a location assigned // 2) the right part is sorted into to the unhandled-list @SuppressWarnings("try") void splitBeforeUsage(Interval interval, int minSplitPos, int maxSplitPos) { ! ! try (Indent indent = Debug.logAndIndent("splitting interval %s between %d and %d", interval, minSplitPos, maxSplitPos)) { assert interval.from() < minSplitPos : "cannot split at start of interval"; assert currentPosition < minSplitPos : "cannot split before current position"; assert minSplitPos <= maxSplitPos : "invalid order"; assert maxSplitPos <= interval.to() : "cannot split after end of interval"; --- 432,443 ---- // maxSplitPos in two parts: // 1) the left part has already a location assigned // 2) the right part is sorted into to the unhandled-list @SuppressWarnings("try") void splitBeforeUsage(Interval interval, int minSplitPos, int maxSplitPos) { ! DebugContext debug = allocator.getDebug(); ! try (Indent indent = debug.logAndIndent("splitting interval %s between %d and %d", interval, minSplitPos, maxSplitPos)) { assert interval.from() < minSplitPos : "cannot split at start of interval"; assert currentPosition < minSplitPos : "cannot split before current position"; assert minSplitPos <= maxSplitPos : "invalid order"; assert maxSplitPos <= interval.to() : "cannot split after end of interval";
*** 448,459 **** assert optimalSplitPos > interval.from() : "cannot split at start of interval"; if (optimalSplitPos == interval.to() && interval.nextUsage(RegisterPriority.MustHaveRegister, minSplitPos) == Integer.MAX_VALUE) { // the split position would be just before the end of the interval // . no split at all necessary ! if (Debug.isLogEnabled()) { ! Debug.log("no split necessary because optimal split position is at end of interval"); } return; } // must calculate this before the actual split is performed and before split position is --- 449,460 ---- assert optimalSplitPos > interval.from() : "cannot split at start of interval"; if (optimalSplitPos == interval.to() && interval.nextUsage(RegisterPriority.MustHaveRegister, minSplitPos) == Integer.MAX_VALUE) { // the split position would be just before the end of the interval // . no split at all necessary ! if (debug.isLogEnabled()) { ! debug.log("no split necessary because optimal split position is at end of interval"); } return; } // must calculate this before the actual split is performed and before split position is
*** 463,474 **** if (!allocator.isBlockBegin(optimalSplitPos)) { // move position before actual instruction (odd opId) optimalSplitPos = (optimalSplitPos - 1) | 1; } ! if (Debug.isLogEnabled()) { ! Debug.log("splitting at position %d", optimalSplitPos); } assert allocator.isBlockBegin(optimalSplitPos) || ((optimalSplitPos & 1) == 1) : "split pos must be odd when not on block boundary"; assert !allocator.isBlockBegin(optimalSplitPos) || ((optimalSplitPos & 1) == 0) : "split pos must be even on block boundary"; --- 464,475 ---- if (!allocator.isBlockBegin(optimalSplitPos)) { // move position before actual instruction (odd opId) optimalSplitPos = (optimalSplitPos - 1) | 1; } ! if (debug.isLogEnabled()) { ! debug.log("splitting at position %d", optimalSplitPos); } assert allocator.isBlockBegin(optimalSplitPos) || ((optimalSplitPos & 1) == 1) : "split pos must be odd when not on block boundary"; assert !allocator.isBlockBegin(optimalSplitPos) || ((optimalSplitPos & 1) == 0) : "split pos must be even on block boundary";
*** 477,499 **** splitPart.setInsertMoveWhenActivated(moveNecessary); assert splitPart.from() >= currentPosition : "cannot append new interval before current walk position"; unhandledLists.addToListSortedByStartAndUsePositions(RegisterBinding.Any, splitPart); ! if (Debug.isLogEnabled()) { ! Debug.log("left interval %s: %s", moveNecessary ? " " : "", interval.logString(allocator)); ! Debug.log("right interval %s: %s", moveNecessary ? "(move)" : "", splitPart.logString(allocator)); } } } // split an interval at the optimal position between minSplitPos and // maxSplitPos in two parts: // 1) the left part has already a location assigned // 2) the right part is always on the stack and therefore ignored in further processing @SuppressWarnings("try") void splitForSpilling(Interval interval) { // calculate allowed range of splitting position int maxSplitPos = currentPosition; int previousUsage = interval.previousUsage(RegisterPriority.ShouldHaveRegister, maxSplitPos); if (previousUsage == currentPosition) { /* --- 478,501 ---- splitPart.setInsertMoveWhenActivated(moveNecessary); assert splitPart.from() >= currentPosition : "cannot append new interval before current walk position"; unhandledLists.addToListSortedByStartAndUsePositions(RegisterBinding.Any, splitPart); ! if (debug.isLogEnabled()) { ! debug.log("left interval %s: %s", moveNecessary ? " " : "", interval.logString(allocator)); ! debug.log("right interval %s: %s", moveNecessary ? "(move)" : "", splitPart.logString(allocator)); } } } // split an interval at the optimal position between minSplitPos and // maxSplitPos in two parts: // 1) the left part has already a location assigned // 2) the right part is always on the stack and therefore ignored in further processing @SuppressWarnings("try") void splitForSpilling(Interval interval) { + DebugContext debug = allocator.getDebug(); // calculate allowed range of splitting position int maxSplitPos = currentPosition; int previousUsage = interval.previousUsage(RegisterPriority.ShouldHaveRegister, maxSplitPos); if (previousUsage == currentPosition) { /*
*** 503,524 **** */ previousUsage = interval.previousUsage(RegisterPriority.MustHaveRegister, maxSplitPos); } int minSplitPos = Math.max(previousUsage + 1, interval.from()); ! try (Indent indent = Debug.logAndIndent("splitting and spilling interval %s between %d and %d", interval, minSplitPos, maxSplitPos)) { assert interval.state == State.Active : "why spill interval that is not active?"; assert interval.from() <= minSplitPos : "cannot split before start of interval"; assert minSplitPos <= maxSplitPos : "invalid order"; assert maxSplitPos < interval.to() : "cannot split at end end of interval"; assert currentPosition < interval.to() : "interval must not end before current position"; if (minSplitPos == interval.from()) { // the whole interval is never used, so spill it entirely to memory ! try (Indent indent2 = Debug.logAndIndent("spilling entire interval because split pos is at beginning of interval (use positions: %d)", interval.usePosList().size())) { assert interval.firstUsage(RegisterPriority.MustHaveRegister) > currentPosition : String.format("interval %s must not have use position before currentPosition %d", interval, currentPosition); allocator.assignSpillSlot(interval); --- 505,526 ---- */ previousUsage = interval.previousUsage(RegisterPriority.MustHaveRegister, maxSplitPos); } int minSplitPos = Math.max(previousUsage + 1, interval.from()); ! try (Indent indent = debug.logAndIndent("splitting and spilling interval %s between %d and %d", interval, minSplitPos, maxSplitPos)) { assert interval.state == State.Active : "why spill interval that is not active?"; assert interval.from() <= minSplitPos : "cannot split before start of interval"; assert minSplitPos <= maxSplitPos : "invalid order"; assert maxSplitPos < interval.to() : "cannot split at end end of interval"; assert currentPosition < interval.to() : "interval must not end before current position"; if (minSplitPos == interval.from()) { // the whole interval is never used, so spill it entirely to memory ! try (Indent indent2 = debug.logAndIndent("spilling entire interval because split pos is at beginning of interval (use positions: %d)", interval.usePosList().size())) { assert interval.firstUsage(RegisterPriority.MustHaveRegister) > currentPosition : String.format("interval %s must not have use position before currentPosition %d", interval, currentPosition); allocator.assignSpillSlot(interval);
*** 533,544 **** parent = parent.getSplitChildBeforeOpId(parent.from()); if (isRegister(parent.location())) { if (parent.firstUsage(RegisterPriority.ShouldHaveRegister) == Integer.MAX_VALUE) { // parent is never used, so kick it out of its assigned register ! if (Debug.isLogEnabled()) { ! Debug.log("kicking out interval %d out of its register because it is never used", parent.operandNumber); } allocator.assignSpillSlot(parent); handleSpillSlot(parent); } else { // do not go further back because the register is actually used by --- 535,546 ---- parent = parent.getSplitChildBeforeOpId(parent.from()); if (isRegister(parent.location())) { if (parent.firstUsage(RegisterPriority.ShouldHaveRegister) == Integer.MAX_VALUE) { // parent is never used, so kick it out of its assigned register ! if (debug.isLogEnabled()) { ! debug.log("kicking out interval %d out of its register because it is never used", parent.operandNumber); } allocator.assignSpillSlot(parent); handleSpillSlot(parent); } else { // do not go further back because the register is actually used by
*** 560,592 **** if (!allocator.isBlockBegin(optimalSplitPos)) { // move position before actual instruction (odd opId) optimalSplitPos = (optimalSplitPos - 1) | 1; } ! try (Indent indent2 = Debug.logAndIndent("splitting at position %d", optimalSplitPos)) { assert allocator.isBlockBegin(optimalSplitPos) || ((optimalSplitPos & 1) == 1) : "split pos must be odd when not on block boundary"; assert !allocator.isBlockBegin(optimalSplitPos) || ((optimalSplitPos & 1) == 0) : "split pos must be even on block boundary"; Interval spilledPart = interval.split(optimalSplitPos, allocator); allocator.assignSpillSlot(spilledPart); handleSpillSlot(spilledPart); changeSpillState(spilledPart, optimalSplitPos); if (!allocator.isBlockBegin(optimalSplitPos)) { ! if (Debug.isLogEnabled()) { ! Debug.log("inserting move from interval %d to %d", interval.operandNumber, spilledPart.operandNumber); } insertMove(optimalSplitPos, interval, spilledPart); } // the currentSplitChild is needed later when moves are inserted for reloading assert spilledPart.currentSplitChild() == interval : "overwriting wrong currentSplitChild"; spilledPart.makeCurrentSplitChild(); ! if (Debug.isLogEnabled()) { ! Debug.log("left interval: %s", interval.logString(allocator)); ! Debug.log("spilled interval : %s", spilledPart.logString(allocator)); } } } } } --- 562,594 ---- if (!allocator.isBlockBegin(optimalSplitPos)) { // move position before actual instruction (odd opId) optimalSplitPos = (optimalSplitPos - 1) | 1; } ! try (Indent indent2 = debug.logAndIndent("splitting at position %d", optimalSplitPos)) { assert allocator.isBlockBegin(optimalSplitPos) || ((optimalSplitPos & 1) == 1) : "split pos must be odd when not on block boundary"; assert !allocator.isBlockBegin(optimalSplitPos) || ((optimalSplitPos & 1) == 0) : "split pos must be even on block boundary"; Interval spilledPart = interval.split(optimalSplitPos, allocator); allocator.assignSpillSlot(spilledPart); handleSpillSlot(spilledPart); changeSpillState(spilledPart, optimalSplitPos); if (!allocator.isBlockBegin(optimalSplitPos)) { ! if (debug.isLogEnabled()) { ! debug.log("inserting move from interval %d to %d", interval.operandNumber, spilledPart.operandNumber); } insertMove(optimalSplitPos, interval, spilledPart); } // the currentSplitChild is needed later when moves are inserted for reloading assert spilledPart.currentSplitChild() == interval : "overwriting wrong currentSplitChild"; spilledPart.makeCurrentSplitChild(); ! if (debug.isLogEnabled()) { ! debug.log("left interval: %s", interval.logString(allocator)); ! debug.log("spilled interval : %s", spilledPart.logString(allocator)); } } } } }
*** 695,705 **** } } @SuppressWarnings("try") boolean allocFreeRegister(Interval interval) { ! try (Indent indent = Debug.logAndIndent("trying to find free register for %s", interval)) { initUseLists(true); freeExcludeActiveFixed(); freeExcludeActiveAny(); freeCollectInactiveFixed(interval); --- 697,708 ---- } } @SuppressWarnings("try") boolean allocFreeRegister(Interval interval) { ! DebugContext debug = allocator.getDebug(); ! try (Indent indent = debug.logAndIndent("trying to find free register for %s", interval)) { initUseLists(true); freeExcludeActiveFixed(); freeExcludeActiveAny(); freeCollectInactiveFixed(interval);
*** 709,734 **** // usePos contains the start of the next interval that has this register assigned // (either as a fixed register or a normal allocated register in the past) // only intervals overlapping with cur are processed, non-overlapping invervals can be // ignored safely ! if (Debug.isLogEnabled()) { // Enable this logging to see all register states ! try (Indent indent2 = Debug.logAndIndent("state of registers:")) { for (Register register : availableRegs) { int i = register.number; ! Debug.log("reg %d: usePos: %d", register.number, usePos[i]); } } } Register hint = null; Interval locationHint = interval.locationHint(true); if (locationHint != null && locationHint.location() != null && isRegister(locationHint.location())) { hint = asRegister(locationHint.location()); ! if (Debug.isLogEnabled()) { ! Debug.log("hint register %d from interval %s", hint.number, locationHint); } } assert interval.location() == null : "register already assigned to interval"; // the register must be free at least until this position --- 712,737 ---- // usePos contains the start of the next interval that has this register assigned // (either as a fixed register or a normal allocated register in the past) // only intervals overlapping with cur are processed, non-overlapping invervals can be // ignored safely ! if (debug.isLogEnabled()) { // Enable this logging to see all register states ! try (Indent indent2 = debug.logAndIndent("state of registers:")) { for (Register register : availableRegs) { int i = register.number; ! debug.log("reg %d: usePos: %d", register.number, usePos[i]); } } } Register hint = null; Interval locationHint = interval.locationHint(true); if (locationHint != null && locationHint.location() != null && isRegister(locationHint.location())) { hint = asRegister(locationHint.location()); ! if (debug.isLogEnabled()) { ! debug.log("hint register %d from interval %s", hint.number, locationHint); } } assert interval.location() == null : "register already assigned to interval"; // the register must be free at least until this position
*** 766,777 **** return false; } splitPos = usePos[reg.number]; interval.assignLocation(reg.asValue(interval.kind())); ! if (Debug.isLogEnabled()) { ! Debug.log("selected register %d", reg.number); } assert splitPos > 0 : "invalid splitPos"; if (needSplit) { // register not available for full interval, so split it --- 769,780 ---- return false; } splitPos = usePos[reg.number]; interval.assignLocation(reg.asValue(interval.kind())); ! if (debug.isLogEnabled()) { ! debug.log("selected register %d", reg.number); } assert splitPos > 0 : "invalid splitPos"; if (needSplit) { // register not available for full interval, so split it
*** 793,803 **** } // Split an Interval and spill it to memory so that cur can be placed in a register @SuppressWarnings("try") void allocLockedRegister(Interval interval) { ! try (Indent indent = Debug.logAndIndent("alloc locked register: need to split and spill to get register for %s", interval)) { // the register must be free at least until this position int firstUsage = interval.firstUsage(RegisterPriority.MustHaveRegister); int firstShouldHaveUsage = interval.firstUsage(RegisterPriority.ShouldHaveRegister); int regNeededUntil = Math.min(firstUsage, interval.from() + 1); --- 796,807 ---- } // Split an Interval and spill it to memory so that cur can be placed in a register @SuppressWarnings("try") void allocLockedRegister(Interval interval) { ! DebugContext debug = allocator.getDebug(); ! try (Indent indent = debug.logAndIndent("alloc locked register: need to split and spill to get register for %s", interval)) { // the register must be free at least until this position int firstUsage = interval.firstUsage(RegisterPriority.MustHaveRegister); int firstShouldHaveUsage = interval.firstUsage(RegisterPriority.ShouldHaveRegister); int regNeededUntil = Math.min(firstUsage, interval.from() + 1);
*** 819,829 **** // spillBlockUnhandledFixed(cur); assert unhandledLists.get(RegisterBinding.Fixed).isEndMarker() : "must not have unhandled fixed intervals because all fixed intervals have a use at position 0"; spillBlockInactiveFixed(interval); spillCollectActiveAny(registerPriority); spillCollectInactiveAny(interval); ! if (Debug.isLogEnabled()) { printRegisterState(); } reg = null; ignore = interval.location() != null && isRegister(interval.location()) ? asRegister(interval.location()) : null; --- 823,833 ---- // spillBlockUnhandledFixed(cur); assert unhandledLists.get(RegisterBinding.Fixed).isEndMarker() : "must not have unhandled fixed intervals because all fixed intervals have a use at position 0"; spillBlockInactiveFixed(interval); spillCollectActiveAny(registerPriority); spillCollectInactiveAny(interval); ! if (debug.isLogEnabled()) { printRegisterState(); } reg = null; ignore = interval.location() != null && isRegister(interval.location()) ? asRegister(interval.location()) : null;
*** 839,869 **** } } int regUsePos = (reg == null ? 0 : usePos[reg.number]); if (regUsePos <= firstShouldHaveUsage) { ! if (Debug.isLogEnabled()) { ! Debug.log("able to spill current interval. firstUsage(register): %d, usePos: %d", firstUsage, regUsePos); } if (firstUsage <= interval.from() + 1) { if (registerPriority.equals(RegisterPriority.LiveAtLoopEnd)) { /* * Tool of last resort: we can not spill the current interval so we try * to spill an active interval that has a usage but do not require a * register. */ ! Debug.log("retry with register priority must have register"); continue; } String description = generateOutOfRegErrorMsg(interval, firstUsage, availableRegs); /* * assign a reasonable register and do a bailout in product mode to avoid * errors */ allocator.assignSpillSlot(interval); ! Debug.dump(Debug.INFO_LEVEL, allocator.getLIR(), description); allocator.printIntervals(description); throw new OutOfRegistersException("LinearScan: no register found", description); } splitAndSpillInterval(interval); --- 843,873 ---- } } int regUsePos = (reg == null ? 0 : usePos[reg.number]); if (regUsePos <= firstShouldHaveUsage) { ! if (debug.isLogEnabled()) { ! debug.log("able to spill current interval. firstUsage(register): %d, usePos: %d", firstUsage, regUsePos); } if (firstUsage <= interval.from() + 1) { if (registerPriority.equals(RegisterPriority.LiveAtLoopEnd)) { /* * Tool of last resort: we can not spill the current interval so we try * to spill an active interval that has a usage but do not require a * register. */ ! debug.log("retry with register priority must have register"); continue; } String description = generateOutOfRegErrorMsg(interval, firstUsage, availableRegs); /* * assign a reasonable register and do a bailout in product mode to avoid * errors */ allocator.assignSpillSlot(interval); ! debug.dump(DebugContext.INFO_LEVEL, allocator.getLIR(), description); allocator.printIntervals(description); throw new OutOfRegistersException("LinearScan: no register found", description); } splitAndSpillInterval(interval);
*** 874,885 **** boolean needSplit = blockPos[reg.number] <= intervalTo; int splitPos = blockPos[reg.number]; ! if (Debug.isLogEnabled()) { ! Debug.log("decided to use register %d", reg.number); } assert splitPos > 0 : "invalid splitPos"; assert needSplit || splitPos > interval.from() : "splitting interval at from"; interval.assignLocation(reg.asValue(interval.kind())); --- 878,889 ---- boolean needSplit = blockPos[reg.number] <= intervalTo; int splitPos = blockPos[reg.number]; ! if (debug.isLogEnabled()) { ! debug.log("decided to use register %d", reg.number); } assert splitPos > 0 : "invalid splitPos"; assert needSplit || splitPos > interval.from() : "splitting interval at from"; interval.assignLocation(reg.asValue(interval.kind()));
*** 899,914 **** ", interval.from()=" + interval.from() + "; already used candidates: " + Arrays.toString(availableRegs); } @SuppressWarnings("try") void printRegisterState() { ! try (Indent indent2 = Debug.logAndIndent("state of registers:")) { for (Register reg : availableRegs) { int i = reg.number; ! try (Indent indent3 = Debug.logAndIndent("reg %d: usePos: %d, blockPos: %d, intervals: ", i, usePos[i], blockPos[i])) { for (int j = 0; j < spillIntervals[i].size(); j++) { ! Debug.log("%s ", spillIntervals[i].get(j)); } } } } } --- 903,919 ---- ", interval.from()=" + interval.from() + "; already used candidates: " + Arrays.toString(availableRegs); } @SuppressWarnings("try") void printRegisterState() { ! DebugContext debug = allocator.getDebug(); ! try (Indent indent2 = debug.logAndIndent("state of registers:")) { for (Register reg : availableRegs) { int i = reg.number; ! try (Indent indent3 = debug.logAndIndent("reg %d: usePos: %d, blockPos: %d, intervals: ", i, usePos[i], blockPos[i])) { for (int j = 0; j < spillIntervals[i].size(); j++) { ! debug.log("%s ", spillIntervals[i].get(j)); } } } } }
*** 923,934 **** // (an interval got a register until this position) int pos = interval.from(); if (isOdd(pos)) { // the current instruction is a call that blocks all registers if (pos < allocator.maxOpId() && allocator.hasCall(pos + 1) && interval.to() > pos + 1) { ! if (Debug.isLogEnabled()) { ! Debug.log("free register cannot be available because all registers blocked by following call"); } // safety check that there is really no register available assert !allocFreeRegister(interval) : "found a register for this interval"; return true; --- 928,940 ---- // (an interval got a register until this position) int pos = interval.from(); if (isOdd(pos)) { // the current instruction is a call that blocks all registers if (pos < allocator.maxOpId() && allocator.hasCall(pos + 1) && interval.to() > pos + 1) { ! DebugContext debug = allocator.getDebug(); ! if (debug.isLogEnabled()) { ! debug.log("free register cannot be available because all registers blocked by following call"); } // safety check that there is really no register available assert !allocFreeRegister(interval) : "found a register for this interval"; return true;
*** 1017,1046 **** // allocate a physical register or memory location to an interval @Override @SuppressWarnings("try") protected boolean activateCurrent(Interval interval) { boolean result = true; ! ! try (Indent indent = Debug.logAndIndent("activating interval %s, splitParent: %d", interval, interval.splitParent().operandNumber)) { final Value operand = interval.operand; if (interval.location() != null && isStackSlotValue(interval.location())) { // activating an interval that has a stack slot assigned . split it at first use // position // used for method parameters ! if (Debug.isLogEnabled()) { ! Debug.log("interval has spill slot assigned (method parameter) . split it before first use"); } splitStackInterval(interval); result = false; } else { if (interval.location() == null) { // interval has not assigned register . normal allocation // (this is the normal case for most intervals) ! if (Debug.isLogEnabled()) { ! Debug.log("normal allocation of register"); } // assign same spill slot to non-intersecting intervals combineSpilledIntervals(interval); --- 1023,1052 ---- // allocate a physical register or memory location to an interval @Override @SuppressWarnings("try") protected boolean activateCurrent(Interval interval) { boolean result = true; ! DebugContext debug = allocator.getDebug(); ! try (Indent indent = debug.logAndIndent("activating interval %s, splitParent: %d", interval, interval.splitParent().operandNumber)) { final Value operand = interval.operand; if (interval.location() != null && isStackSlotValue(interval.location())) { // activating an interval that has a stack slot assigned . split it at first use // position // used for method parameters ! if (debug.isLogEnabled()) { ! debug.log("interval has spill slot assigned (method parameter) . split it before first use"); } splitStackInterval(interval); result = false; } else { if (interval.location() == null) { // interval has not assigned register . normal allocation // (this is the normal case for most intervals) ! if (debug.isLogEnabled()) { ! debug.log("normal allocation of register"); } // assign same spill slot to non-intersecting intervals combineSpilledIntervals(interval);
*** 1061,1072 **** // load spilled values that become active from stack slot to register if (interval.insertMoveWhenActivated()) { assert interval.isSplitChild(); assert interval.currentSplitChild() != null; assert !interval.currentSplitChild().operand.equals(operand) : "cannot insert move between same interval"; ! if (Debug.isLogEnabled()) { ! Debug.log("Inserting move from interval %d to %d because insertMoveWhenActivated is set", interval.currentSplitChild().operandNumber, interval.operandNumber); } insertMove(interval.from(), interval.currentSplitChild(), interval); } interval.makeCurrentSplitChild(); --- 1067,1078 ---- // load spilled values that become active from stack slot to register if (interval.insertMoveWhenActivated()) { assert interval.isSplitChild(); assert interval.currentSplitChild() != null; assert !interval.currentSplitChild().operand.equals(operand) : "cannot insert move between same interval"; ! if (debug.isLogEnabled()) { ! debug.log("Inserting move from interval %d to %d because insertMoveWhenActivated is set", interval.currentSplitChild().operandNumber, interval.operandNumber); } insertMove(interval.from(), interval.currentSplitChild(), interval); } interval.makeCurrentSplitChild();
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanWalker.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File