Mercurial > hg > truffle
diff graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScanWalker.java @ 13467:7c694e3e97e5
remove remaining old style TTY debug logging in LinearScan and remove TraceLinearScan option
author | Erik Eckstein <erik.eckstein@oracle.com> |
---|---|
date | Fri, 20 Dec 2013 08:08:06 +0100 |
parents | 424e2bfecb72 |
children | 43bd3d7254d1 |
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScanWalker.java Fri Dec 20 08:06:48 2013 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScanWalker.java Fri Dec 20 08:08:06 2013 +0100 @@ -293,9 +293,7 @@ int optimalSplitPos = -1; if (minSplitPos == maxSplitPos) { // trivial case, no optimization of split position possible - if (getTraceLevel() >= 4) { - TTY.println(" min-pos and max-pos are equal, no optimization possible"); - } + Debug.log("min-pos and max-pos are equal, no optimization possible"); optimalSplitPos = minSplitPos; } else { @@ -317,9 +315,7 @@ 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 (getTraceLevel() >= 4) { - TTY.println(" cannot move split pos to block boundary because minPos and maxPos are in same block"); - } + Debug.log("cannot move split pos to block boundary because minPos and maxPos are in same block"); optimalSplitPos = maxSplitPos; } else { @@ -329,25 +325,19 @@ // as mustHaveRegister) with a hole before each definition. When the register is // needed // for the second definition : an earlier reloading is unnecessary. - if (getTraceLevel() >= 4) { - TTY.println(" interval has hole just before maxSplitPos, so splitting at maxSplitPos"); - } + Debug.log("interval has hole just before maxSplitPos, so splitting at maxSplitPos"); optimalSplitPos = maxSplitPos; } else { // seach optimal block boundary between minSplitPos and maxSplitPos - if (getTraceLevel() >= 4) { - TTY.println(" moving split pos to optimal block boundary between block B%d and B%d", minBlock.getId(), maxBlock.getId()); - } + 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 (getTraceLevel() >= 4) { - TTY.println(" loop optimization: loop end found at pos %d", loopEndPos); - } + Debug.log("loop optimization: loop end found at pos %d", loopEndPos); assert loopEndPos > minSplitPos : "invalid order"; if (loopEndPos < maxSplitPos) { @@ -360,22 +350,15 @@ // of the interval (normally, only mustHaveRegister causes a reloading) Block loopBlock = allocator.blockForId(loopEndPos); - if (getTraceLevel() >= 4) { - TTY.println(" 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()); - } + 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"; optimalSplitPos = findOptimalSplitPos(minBlock, loopBlock, allocator.getLastLirInstructionId(loopBlock) + 2); if (optimalSplitPos == allocator.getLastLirInstructionId(loopBlock) + 2) { optimalSplitPos = -1; - if (getTraceLevel() >= 4) { - TTY.println(" loop optimization not necessary"); - } + Debug.log("loop optimization not necessary"); } else { - if (getTraceLevel() >= 4) { - TTY.println(" loop optimization successful"); - } + Debug.log("loop optimization successful"); } } } @@ -387,9 +370,7 @@ } } } - if (getTraceLevel() >= 4) { - TTY.println(" optimal split position: %d", optimalSplitPos); - } + Debug.log("optimal split position: %d", optimalSplitPos); return optimalSplitPos; } @@ -416,7 +397,7 @@ 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 - indent.log("no split necessary because optimal split position is at end of interval"); + Debug.log("no split necessary because optimal split position is at end of interval"); return; } @@ -429,7 +410,7 @@ optimalSplitPos = (optimalSplitPos - 1) | 1; } - indent.log("splitting at position %d", optimalSplitPos); + Debug.log("splitting at position %d", optimalSplitPos); assert allocator.isBlockBegin(optimalSplitPos) || (optimalSplitPos % 2 == 1) : "split pos must be odd when not on block boundary"; assert !allocator.isBlockBegin(optimalSplitPos) || (optimalSplitPos % 2 == 0) : "split pos must be even on block boundary"; @@ -442,8 +423,8 @@ unhandledLists.addToListSortedByStartAndUsePositions(RegisterBinding.Any, splitPart); if (Debug.isLogEnabled()) { - indent.log("left interval %s: %s", moveNecessary ? " " : "", interval.logString(allocator)); - indent.log("right interval %s: %s", moveNecessary ? "(move)" : "", splitPart.logString(allocator)); + Debug.log("left interval %s: %s", moveNecessary ? " " : "", interval.logString(allocator)); + Debug.log("right interval %s: %s", moveNecessary ? "(move)" : "", splitPart.logString(allocator)); } } } @@ -469,7 +450,7 @@ if (minSplitPos == interval.from()) { // the whole interval is never used, so spill it entirely to memory - try (Indent indent2 = indent.logAndIndent("spilling entire interval because split pos is at beginning of interval (use positions: %d)", interval.usePosList().size())) { + 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.ShouldHaveRegister) > currentPosition : "interval must not have use position before currentPosition"; @@ -486,7 +467,7 @@ if (isRegister(parent.location())) { if (parent.firstUsage(RegisterPriority.ShouldHaveRegister) == Integer.MAX_VALUE) { // parent is never used, so kick it out of its assigned register - indent2.log("kicking out interval %d out of its register because it is never used", parent.operandNumber); + Debug.log("kicking out interval %d out of its register because it is never used", parent.operandNumber); allocator.assignSpillSlot(parent); } else { // do not go further back because the register is actually used by @@ -510,7 +491,7 @@ optimalSplitPos = (optimalSplitPos - 1) | 1; } - try (Indent indent2 = indent.logAndIndent("splitting at position %d", optimalSplitPos)) { + try (Indent indent2 = Debug.logAndIndent("splitting at position %d", optimalSplitPos)) { assert allocator.isBlockBegin(optimalSplitPos) || (optimalSplitPos % 2 == 1) : "split pos must be odd when not on block boundary"; assert !allocator.isBlockBegin(optimalSplitPos) || (optimalSplitPos % 2 == 0) : "split pos must be even on block boundary"; @@ -519,7 +500,7 @@ allocator.changeSpillState(spilledPart, optimalSplitPos); if (!allocator.isBlockBegin(optimalSplitPos)) { - indent2.log("inserting move from interval %d to %d", interval.operandNumber, spilledPart.operandNumber); + Debug.log("inserting move from interval %d to %d", interval.operandNumber, spilledPart.operandNumber); insertMove(optimalSplitPos, interval, spilledPart); } @@ -528,8 +509,8 @@ spilledPart.makeCurrentSplitChild(); if (Debug.isLogEnabled()) { - indent2.log("left interval: %s", interval.logString(allocator)); - indent2.log("spilled interval : %s", spilledPart.logString(allocator)); + Debug.log("left interval: %s", interval.logString(allocator)); + Debug.log("spilled interval : %s", spilledPart.logString(allocator)); } } } @@ -575,90 +556,86 @@ } boolean allocFreeRegister(Interval interval) { - if (getTraceLevel() >= 2) { - TTY.println("trying to find free register for " + interval.logString(allocator)); - } - - initUseLists(true); - freeExcludeActiveFixed(); - freeExcludeActiveAny(); - freeCollectInactiveFixed(interval); - freeCollectInactiveAny(interval); - // freeCollectUnhandled(fixedKind, cur); - assert unhandledLists.get(RegisterBinding.Fixed) == Interval.EndMarker : "must not have unhandled fixed intervals because all fixed intervals have a use at position 0"; + try (Indent indent = Debug.logAndIndent("trying to find free register for %s", interval)) { - // 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 (getTraceLevel() >= 4) { - TTY.println(" state of registers:"); - for (Register register : availableRegs) { - int i = register.number; - TTY.println(" reg %d: usePos: %d", register.number, usePos[i]); - } - } + initUseLists(true); + freeExcludeActiveFixed(); + freeExcludeActiveAny(); + freeCollectInactiveFixed(interval); + freeCollectInactiveAny(interval); + // freeCollectUnhandled(fixedKind, cur); + assert unhandledLists.get(RegisterBinding.Fixed) == Interval.EndMarker : "must not have unhandled fixed intervals because all fixed intervals have a use at position 0"; - Register hint = null; - Interval locationHint = interval.locationHint(true); - if (locationHint != null && locationHint.location() != null && isRegister(locationHint.location())) { - hint = asRegister(locationHint.location()); - if (getTraceLevel() >= 4) { - TTY.println(" hint register %d from interval %s", hint.number, locationHint.logString(allocator)); - } - } - assert interval.location() == null : "register already assigned to interval"; - - // the register must be free at least until this position - int regNeededUntil = interval.from() + 1; - int intervalTo = interval.to(); - - boolean needSplit = false; - int splitPos = -1; - - Register reg = null; - Register minFullReg = null; - Register maxPartialReg = null; - - for (int i = 0; i < availableRegs.length; ++i) { - Register availableReg = availableRegs[i]; - int number = availableReg.number; - if (usePos[number] >= intervalTo) { - // this register is free for the full interval - if (minFullReg == null || availableReg.equals(hint) || (usePos[number] < usePos[minFullReg.number] && !minFullReg.equals(hint))) { - minFullReg = availableReg; - } - } else if (usePos[number] > regNeededUntil) { - // this register is at least free until regNeededUntil - if (maxPartialReg == null || availableReg.equals(hint) || (usePos[number] > usePos[maxPartialReg.number] && !maxPartialReg.equals(hint))) { - maxPartialReg = availableReg; + // 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(false, "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()); + Debug.log("hint register %d from interval %s", hint.number, locationHint); + } + assert interval.location() == null : "register already assigned to interval"; - if (minFullReg != null) { - reg = minFullReg; - } else if (maxPartialReg != null) { - needSplit = true; - reg = maxPartialReg; - } else { - return false; - } + // the register must be free at least until this position + int regNeededUntil = interval.from() + 1; + int intervalTo = interval.to(); + + boolean needSplit = false; + int splitPos = -1; + + Register reg = null; + Register minFullReg = null; + Register maxPartialReg = null; - splitPos = usePos[reg.number]; - interval.assignLocation(reg.asValue(interval.kind())); - if (getTraceLevel() >= 2) { - TTY.println("selected register %d", reg.number); - } + for (int i = 0; i < availableRegs.length; ++i) { + Register availableReg = availableRegs[i]; + int number = availableReg.number; + if (usePos[number] >= intervalTo) { + // this register is free for the full interval + if (minFullReg == null || availableReg.equals(hint) || (usePos[number] < usePos[minFullReg.number] && !minFullReg.equals(hint))) { + minFullReg = availableReg; + } + } else if (usePos[number] > regNeededUntil) { + // this register is at least free until regNeededUntil + if (maxPartialReg == null || availableReg.equals(hint) || (usePos[number] > usePos[maxPartialReg.number] && !maxPartialReg.equals(hint))) { + maxPartialReg = availableReg; + } + } + } - assert splitPos > 0 : "invalid splitPos"; - if (needSplit) { - // register not available for full interval, so split it - splitWhenPartialRegisterAvailable(interval, splitPos); + if (minFullReg != null) { + reg = minFullReg; + } else if (maxPartialReg != null) { + needSplit = true; + reg = maxPartialReg; + } else { + return false; + } + + splitPos = usePos[reg.number]; + interval.assignLocation(reg.asValue(interval.kind())); + Debug.log("selected register %d", reg.number); + + assert splitPos > 0 : "invalid splitPos"; + if (needSplit) { + // register not available for full interval, so split it + splitWhenPartialRegisterAvailable(interval, splitPos); + } + // only return true if interval is completely assigned + return true; } - - // only return true if interval is completely assigned - return true; } void splitAndSpillIntersectingIntervals(Register reg) { @@ -673,85 +650,81 @@ // Split an Interval and spill it to memory so that cur can be placed in a register void allocLockedRegister(Interval interval) { - if (getTraceLevel() >= 2) { - TTY.println("need to split and spill to get register for " + interval.logString(allocator)); - } + try (Indent indent = Debug.logAndIndent("alloc locked register: need to split and spill to get register for %s", interval)) { - // collect current usage of registers - initUseLists(false); - spillExcludeActiveFixed(); - // spillBlockUnhandledFixed(cur); - assert unhandledLists.get(RegisterBinding.Fixed) == Interval.EndMarker : "must not have unhandled fixed intervals because all fixed intervals have a use at position 0"; - spillBlockInactiveFixed(interval); - spillCollectActiveAny(); - spillCollectInactiveAny(interval); + // collect current usage of registers + initUseLists(false); + spillExcludeActiveFixed(); + // spillBlockUnhandledFixed(cur); + assert unhandledLists.get(RegisterBinding.Fixed) == Interval.EndMarker : "must not have unhandled fixed intervals because all fixed intervals have a use at position 0"; + spillBlockInactiveFixed(interval); + spillCollectActiveAny(); + spillCollectInactiveAny(interval); - if (getTraceLevel() >= 4) { - TTY.println(" state of registers:"); - for (Register reg : availableRegs) { - int i = reg.number; - TTY.print(" reg %d: usePos: %d, blockPos: %d, intervals: ", i, usePos[i], blockPos[i]); - for (int j = 0; j < spillIntervals[i].size(); j++) { - TTY.print("%d ", spillIntervals[i].get(j).operandNumber); - } - TTY.println(); - } - } - - // the register must be free at least until this position - int firstUsage = interval.firstUsage(RegisterPriority.MustHaveRegister); - int regNeededUntil = Math.min(firstUsage, interval.from() + 1); - int intervalTo = interval.to(); - assert regNeededUntil > 0 && regNeededUntil < Integer.MAX_VALUE : "interval has no use"; - - Register reg = null; - Register ignore = interval.location() != null && isRegister(interval.location()) ? asRegister(interval.location()) : null; - for (Register availableReg : availableRegs) { - int number = availableReg.number; - if (availableReg.equals(ignore)) { - // this register must be ignored - } else if (usePos[number] > regNeededUntil) { - if (reg == null || (usePos[number] > usePos[reg.number])) { - reg = availableReg; + if (Debug.isLogEnabled()) { + 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("%d ", spillIntervals[i].get(j).operandNumber); + } + } + } } } - } + + // the register must be free at least until this position + int firstUsage = interval.firstUsage(RegisterPriority.MustHaveRegister); + int regNeededUntil = Math.min(firstUsage, interval.from() + 1); + int intervalTo = interval.to(); + assert regNeededUntil > 0 && regNeededUntil < Integer.MAX_VALUE : "interval has no use"; - if (reg == null || usePos[reg.number] <= firstUsage) { - // the first use of cur is later than the spilling position -> spill cur - if (getTraceLevel() >= 4) { - TTY.println("able to spill current interval. firstUsage(register): %d, usePos: %d", firstUsage, reg == null ? 0 : usePos[reg.number]); - } - - if (firstUsage <= interval.from() + 1) { - assert false : "cannot spill interval that is used in first instruction (possible reason: no register found) firstUsage=" + firstUsage + ", interval.from()=" + interval.from(); - // assign a reasonable register and do a bailout in product mode to avoid errors - allocator.assignSpillSlot(interval); - throw new BailoutException("LinearScan: no register found"); + Register reg = null; + Register ignore = interval.location() != null && isRegister(interval.location()) ? asRegister(interval.location()) : null; + for (Register availableReg : availableRegs) { + int number = availableReg.number; + if (availableReg.equals(ignore)) { + // this register must be ignored + } else if (usePos[number] > regNeededUntil) { + if (reg == null || (usePos[number] > usePos[reg.number])) { + reg = availableReg; + } + } } - splitAndSpillInterval(interval); - return; - } + int regUsePos = (reg == null ? 0 : usePos[reg.number]); + if (regUsePos <= firstUsage) { + Debug.log("able to spill current interval. firstUsage(register): %d, usePos: %d", firstUsage, regUsePos); + + if (firstUsage <= interval.from() + 1) { + assert false : "cannot spill interval that is used in first instruction (possible reason: no register found) firstUsage=" + firstUsage + ", interval.from()=" + interval.from(); + // assign a reasonable register and do a bailout in product mode to avoid errors + allocator.assignSpillSlot(interval); + throw new BailoutException("LinearScan: no register found"); + } + + splitAndSpillInterval(interval); + return; + } - boolean needSplit = blockPos[reg.number] <= intervalTo; + boolean needSplit = blockPos[reg.number] <= intervalTo; + + int splitPos = blockPos[reg.number]; + + Debug.log("decided to use register %d", reg.number); + assert splitPos > 0 : "invalid splitPos"; + assert needSplit || splitPos > interval.from() : "splitting interval at from"; - int splitPos = blockPos[reg.number]; + interval.assignLocation(reg.asValue(interval.kind())); + if (needSplit) { + // register not available for full interval : so split it + splitWhenPartialRegisterAvailable(interval, splitPos); + } - if (getTraceLevel() >= 4) { - TTY.println("decided to use register %d", reg.number); + // perform splitting and spilling for all affected intervals + splitAndSpillIntersectingIntervals(reg); } - assert splitPos > 0 : "invalid splitPos"; - assert needSplit || splitPos > interval.from() : "splitting interval at from"; - - interval.assignLocation(reg.asValue(interval.kind())); - if (needSplit) { - // register not available for full interval : so split it - splitWhenPartialRegisterAvailable(interval, splitPos); - } - - // perform splitting and spilling for all affected intervals - splitAndSpillIntersectingIntervals(reg); } boolean noAllocationPossible(Interval interval) { @@ -766,9 +739,7 @@ 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 (getTraceLevel() >= 4) { - TTY.println(" free register cannot be available because all registers blocked by following call"); - } + 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"; @@ -858,14 +829,14 @@ Interval interval = currentInterval; boolean result = true; - Indent indent = Debug.logAndIndent("activating interval %s, splitParent: %d, insertMoveWhenActivated: %b", interval, interval.splitParent().operandNumber); + Indent indent = Debug.logAndIndent("activating interval %s, splitParent: %d", interval, interval.splitParent().operandNumber); final Value operand = interval.operand; if (interval.location() != null && isStackSlot(interval.location())) { // activating an interval that has a stack slot assigned . split it at first use // position // used for method parameters - indent.log("interval has spill slot assigned (method parameter) . split it before first use"); + Debug.log("interval has spill slot assigned (method parameter) . split it before first use"); splitStackInterval(interval); result = false; @@ -873,9 +844,7 @@ if (interval.location() == null) { // interval has not assigned register . normal allocation // (this is the normal case for most intervals) - if (getTraceLevel() >= 4) { - TTY.println(" normal allocation of register"); - } + Debug.log("normal allocation of register"); // assign same spill slot to non-intersecting intervals combineSpilledIntervals(interval); @@ -899,7 +868,7 @@ assert interval.isSplitChild(); assert interval.currentSplitChild() != null; assert !interval.currentSplitChild().operand.equals(operand) : "cannot insert move between same interval"; - indent.log("Inserting move from interval %d to %d because insertMoveWhenActivated is set", interval.currentSplitChild().operandNumber, interval.operandNumber); + Debug.log("Inserting move from interval %d to %d because insertMoveWhenActivated is set", interval.currentSplitChild().operandNumber, interval.operandNumber); insertMove(interval.from(), interval.currentSplitChild(), interval); }