# HG changeset patch # User Erik Eckstein # Date 1387523286 -3600 # Node ID 7c694e3e97e540ef4e9b836ee3bca5e51dd335a8 # Parent 51d31106cd5e2d012db69eaaa1d8db9d483f2537 remove remaining old style TTY debug logging in LinearScan and remove TraceLinearScan option diff -r 51d31106cd5e -r 7c694e3e97e5 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/Interval.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/Interval.java Fri Dec 20 08:06:48 2013 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/Interval.java Fri Dec 20 08:08:06 2013 +0100 @@ -722,14 +722,14 @@ /** * Returns true if this interval can be re-materialized when spilled. This means that no - * spill-moves are needed. Instead of restore-moves the materializeValue is restored. + * spill-moves are needed. Instead of restore-moves the {@link #materializedValue} is restored. */ public boolean canMaterialize() { return getMaterializedValue() != null; } /** - * Returns the value which is moved to a register instead of a restore-move from stack. + * Returns a value which can be moved to a register instead of a restore-move from stack. */ public Constant getMaterializedValue() { return splitParent().materializedValue; @@ -909,7 +909,7 @@ private RegisterPriority adaptPriority(RegisterPriority priority) { /* * In case of re-materialized values we require that use-operands are registers, because we - * don't have the value at a stack location. (Note that ShouldHaveRegister means that the + * don't have the value in a stack location. (Note that ShouldHaveRegister means that the * operand can also be a StackSlot). */ if (priority == RegisterPriority.ShouldHaveRegister && canMaterialize()) { diff -r 51d31106cd5e -r 7c694e3e97e5 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/IntervalWalker.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/IntervalWalker.java Fri Dec 20 08:06:48 2013 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/IntervalWalker.java Fri Dec 20 08:08:06 2013 +0100 @@ -201,23 +201,12 @@ currentInterval.rewindRange(); } - int getTraceLevel() { - return allocator.getTraceLevel(); - } - void walkTo(int toOpId) { assert currentPosition <= toOpId : "can not walk backwards"; while (currentInterval != null) { boolean isActive = currentInterval.from() <= toOpId; int opId = isActive ? currentInterval.from() : toOpId; - if (getTraceLevel() >= 2 && !TTY.isSuppressed()) { - if (currentPosition < opId) { - TTY.println(); - TTY.println("walkTo(%d) *", opId); - } - } - // set currentPosition prior to call of walkTo currentPosition = opId; @@ -226,13 +215,15 @@ walkTo(State.Inactive, opId); if (isActive) { - currentInterval.state = State.Active; - if (activateCurrent()) { - activeLists.addToListSortedByCurrentFromPositions(currentBinding, currentInterval); - intervalMoved(currentInterval, State.Unhandled, State.Active); + try (Indent indent = Debug.logAndIndent("walk to op %d", opId)) { + currentInterval.state = State.Active; + if (activateCurrent()) { + activeLists.addToListSortedByCurrentFromPositions(currentBinding, currentInterval); + intervalMoved(currentInterval, State.Unhandled, State.Active); + } + + nextInterval(); } - - nextInterval(); } else { return; } @@ -242,10 +233,8 @@ private void intervalMoved(Interval interval, State from, State to) { // intervalMoved() is called whenever an interval moves from one interval list to another. // In the implementation of this method it is prohibited to move the interval to any list. - if (getTraceLevel() >= 4 && !TTY.isSuppressed()) { - TTY.print(from.toString() + " to " + to.toString()); - TTY.fillTo(23); - TTY.out().println(interval.logString(allocator)); + if (Debug.isLogEnabled()) { + Debug.log("interval moved from %s to %s: %s", from, to, interval.logString(allocator)); } } } diff -r 51d31106cd5e -r 7c694e3e97e5 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Fri Dec 20 08:06:48 2013 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Fri Dec 20 08:08:06 2013 +0100 @@ -46,7 +46,6 @@ import com.oracle.graal.lir.LIRInstruction.ValueProcedure; import com.oracle.graal.lir.StandardOp.MoveOp; import com.oracle.graal.nodes.cfg.*; -import com.oracle.graal.options.*; import com.oracle.graal.phases.util.*; /** @@ -57,13 +56,6 @@ */ public final class LinearScan { - static class Options { - // @formatter:off - @Option(help = "The trace level for the linear scan register allocator") - public static final OptionValue TraceLinearScanLevel = new OptionValue<>(0); - // @formatter:on - } - final TargetDescription target; final LIR ir; final LIRGenerator gen; @@ -166,8 +158,6 @@ */ private final int firstVariableNumber; - private final int traceLevel; - public LinearScan(TargetDescription target, LIR ir, LIRGenerator gen, FrameMap frameMap) { this.target = target; this.ir = ir; @@ -180,11 +170,6 @@ this.firstVariableNumber = registers.length; this.variables = new ArrayList<>(ir.numVariables() * 3 / 2); this.blockData = new BlockMap<>(ir.cfg); - traceLevel = Options.TraceLinearScanLevel.getValue(); - } - - int getTraceLevel() { - return traceLevel; } public int getFirstLirInstructionId(Block block) { @@ -553,7 +538,9 @@ if (!isRegister(curInterval.location()) && curInterval.alwaysInMemory()) { // move target is a stack slot that is always correct, so eliminate // instruction - indent.log("eliminating move from interval %d to %d", operandNumber(move.getInput()), operandNumber(move.getResult())); + if (Debug.isLogEnabled()) { + Debug.log("eliminating move from interval %d to %d", operandNumber(move.getInput()), operandNumber(move.getResult())); + } instructions.set(j, null); // null-instructions are deleted by assignRegNum } @@ -578,7 +565,7 @@ insertionBuffer.append(j + 1, ir.spillMoveFactory.createMove(toLocation, fromLocation)); - indent.log("inserting move after definition of interval %d to stack slot %s at opId %d", interval.operandNumber, interval.spillSlot(), opId); + Debug.log("inserting move after definition of interval %d to stack slot %s at opId %d", interval.operandNumber, interval.spillSlot(), opId); } interval = interval.next; } @@ -758,15 +745,15 @@ } }; - Indent indent2 = indent.logAndIndent("handle op %d", op.id()); - op.forEachInput(useProc); - op.forEachAlive(useProc); - // Add uses of live locals from interpreter's point of view for proper debug - // information generation - op.forEachState(stateProc); - op.forEachTemp(defProc); - op.forEachOutput(defProc); - indent2.outdent(); + try (Indent indent2 = Debug.logAndIndent("handle op %d", op.id())) { + op.forEachInput(useProc); + op.forEachAlive(useProc); + // Add uses of live locals from interpreter's point of view for proper debug + // information generation + op.forEachState(stateProc); + op.forEachTemp(defProc); + op.forEachOutput(defProc); + } } // end of instruction iteration BlockData blockSets = blockData.get(block); @@ -775,8 +762,8 @@ blockSets.liveIn = new BitSet(liveSize); blockSets.liveOut = new BitSet(liveSize); - indent.log("liveGen B%d %s", block.getId(), blockSets.liveGen); - indent.log("liveKill B%d %s", block.getId(), blockSets.liveKill); + Debug.log("liveGen B%d %s", block.getId(), blockSets.liveGen); + Debug.log("liveKill B%d %s", block.getId(), blockSets.liveKill); indent.outdent(); } // end of block iteration @@ -823,7 +810,7 @@ do { changeOccurred = false; - Indent indent2 = indent.logAndIndent("new iteration %d", iterationCount); + Indent indent2 = Debug.logAndIndent("new iteration %d", iterationCount); // iterate all blocks in reverse order for (int i = numBlocks - 1; i >= 0; i--) { @@ -867,7 +854,7 @@ liveIn.andNot(blockSets.liveKill); liveIn.or(blockSets.liveGen); - indent2.log("block %d: livein = %s, liveout = %s", block.getId(), liveIn, blockSets.liveOut); + Debug.log("block %d: livein = %s, liveout = %s", block.getId(), liveIn, blockSets.liveOut); } } iterationCount++; @@ -895,46 +882,48 @@ } private void reportFailure(int numBlocks) { - Indent indent = Debug.logAndIndent("report failure"); - indent.log("graph: %s", gen.getGraph()); - indent.log("Error: liveIn set of first block must be empty (when this fails, variables are used before they are defined):"); + Indent indent = Debug.logAndIndent("report failure, graph: %s", gen.getGraph()); + BitSet startBlockLiveIn = blockData.get(ir.cfg.getStartBlock()).liveIn; - for (int operandNum = startBlockLiveIn.nextSetBit(0); operandNum >= 0; operandNum = startBlockLiveIn.nextSetBit(operandNum + 1)) { - Value operand = operandFor(operandNum); - indent.log(" var %d; operand=%s; node=%s", operandNum, operand, gen.valueForOperand(operand)); + 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)) { + Value operand = operandFor(operandNum); + Debug.log("var %d; operand=%s; node=%s", operandNum, operand, gen.valueForOperand(operand)); + } } // print some additional information to simplify debugging for (int operandNum = startBlockLiveIn.nextSetBit(0); operandNum >= 0; operandNum = startBlockLiveIn.nextSetBit(operandNum + 1)) { Value operand = operandFor(operandNum); - final Indent indent2 = indent.logAndIndent("---- Detailed information for var %d; operand=%s; node=%s ----", operandNum, operand, gen.valueForOperand(operand)); + final Indent indent2 = Debug.logAndIndent("---- Detailed information for var %d; operand=%s; node=%s ----", operandNum, operand, gen.valueForOperand(operand)); Deque definedIn = new ArrayDeque<>(); HashSet usedIn = new HashSet<>(); for (Block block : sortedBlocks) { if (blockData.get(block).liveGen.get(operandNum)) { usedIn.add(block); - indent2.log("used in block B%d {", block.getId()); - for (LIRInstruction ins : ir.lir(block)) { - indent2.log(" %d: %s", ins.id(), ins); - ins.forEachState(new ValueProcedure() { + try (Indent indent3 = Debug.logAndIndent("used in block B%d", block.getId())) { + for (LIRInstruction ins : ir.lir(block)) { + try (Indent indent4 = Debug.logAndIndent("%d: %s", ins.id(), ins)) { + ins.forEachState(new ValueProcedure() { - @Override - public Value doValue(Value liveStateOperand) { - indent2.log(" operand=" + liveStateOperand); - return liveStateOperand; + @Override + public Value doValue(Value liveStateOperand) { + Debug.log("operand=%s", liveStateOperand); + return liveStateOperand; + } + }); } - }); + } } - indent2.log("}"); } if (blockData.get(block).liveKill.get(operandNum)) { definedIn.add(block); - indent2.log("defined in block B%d {", block.getId()); - for (LIRInstruction ins : ir.lir(block)) { - indent2.log(" %d: %s", ins.id(), ins); + try (Indent indent3 = Debug.logAndIndent("defined in block B%d", block.getId())) { + for (LIRInstruction ins : ir.lir(block)) { + Debug.log("%d: %s", ins.id(), ins); + } } - indent2.log("}"); } } @@ -955,9 +944,10 @@ } } } - indent.log("**** offending usages are in: "); - for (Block block : usedIn) { - indent2.log("B%d ", block.getId()); + try (Indent indent3 = Debug.logAndIndent("**** offending usages are in: ")) { + for (Block block : usedIn) { + Debug.log("B%d", block.getId()); + } } indent2.outdent(); } @@ -1100,9 +1090,7 @@ assert 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 (getTraceLevel() >= 4) { - TTY.println("found move from stack slot %s to %s", slot, move.getResult()); - } + Debug.log("found move from stack slot %s to %s", slot, move.getResult()); } Interval interval = intervalFor(move.getResult()); @@ -1129,10 +1117,8 @@ } else { from.setLocationHint(to); } + Debug.log("operation at opId %d: added hint from interval %d to %d", op.id(), from.operandNumber, to.operandNumber); - if (getTraceLevel() >= 4) { - TTY.println("operation at opId %d: added hint from interval %d to %d", op.id(), from.operandNumber, to.operandNumber); - } return registerHint; } return null; @@ -1155,7 +1141,7 @@ for (int i = blockCount() - 1; i >= 0; i--) { Block block = blockAt(i); - Indent indent2 = indent.logAndIndent("handle block %d", block.getId()); + Indent indent2 = Debug.logAndIndent("handle block %d", block.getId()); List instructions = ir.lir(block); final int blockFrom = getFirstLirInstructionId(block); @@ -1169,7 +1155,7 @@ for (int operandNum = live.nextSetBit(0); operandNum >= 0; operandNum = live.nextSetBit(operandNum + 1)) { assert live.get(operandNum) : "should not stop here otherwise"; AllocatableValue operand = operandFor(operandNum); - indent.log("live in %d: %s", operandNum, operand); + Debug.log("live in %d: %s", operandNum, operand); addUse(operand, blockFrom, blockTo + 2, RegisterPriority.None, Kind.Illegal); @@ -1188,7 +1174,7 @@ final LIRInstruction op = instructions.get(j); final int opId = op.id(); - Indent indent3 = indent2.logAndIndent("handle inst %d: %s", opId, op); + 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()) { @@ -1197,7 +1183,7 @@ addTemp(r.asValue(), opId, RegisterPriority.None, Kind.Illegal); } } - indent.log("operation destroys all caller-save registers"); + Debug.log("operation destroys all caller-save registers"); } op.forEachOutput(new ValueProcedure() { @@ -1452,9 +1438,7 @@ Interval result = interval.getSplitChildAtOpId(opId, mode, this); if (result != null) { - if (getTraceLevel() >= 4) { - TTY.println("Split child at pos " + opId + " of interval " + interval.toString() + " is " + result.toString()); - } + Debug.log("Split child at pos %d of interval %s is %s", opId, interval, result); return result; } @@ -1506,9 +1490,7 @@ void resolveFindInsertPos(Block fromBlock, Block toBlock, MoveResolver moveResolver) { if (fromBlock.getSuccessorCount() <= 1) { - if (getTraceLevel() >= 4) { - TTY.println("inserting moves at end of fromBlock B%d", fromBlock.getId()); - } + Debug.log("inserting moves at end of fromBlock B%d", fromBlock.getId()); List instructions = ir.lir(fromBlock); LIRInstruction instr = instructions.get(instructions.size() - 1); @@ -1520,9 +1502,7 @@ } } else { - if (getTraceLevel() >= 4) { - TTY.println("inserting moves at beginning of toBlock B%d", toBlock.getId()); - } + Debug.log("inserting moves at beginning of toBlock B%d", toBlock.getId()); if (DetailedAsserts.getValue()) { assert ir.lir(fromBlock).get(0) instanceof StandardOp.LabelOp : "block does not start with a label"; @@ -1567,9 +1547,8 @@ // prevent optimization of two consecutive blocks if (!blockCompleted.get(pred.getLinearScanNumber()) && !blockCompleted.get(sux.getLinearScanNumber())) { - if (getTraceLevel() >= 3) { - TTY.println(" optimizing empty block B%d (pred: B%d, sux: B%d)", block.getId(), pred.getId(), sux.getId()); - } + 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 @@ -1594,9 +1573,8 @@ // check for duplicate edges between the same blocks (can happen with switch // blocks) if (!alreadyResolved.get(toBlock.getLinearScanNumber())) { - if (getTraceLevel() >= 3) { - TTY.println(" processing edge between B%d and B%d", fromBlock.getId(), toBlock.getId()); - } + 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 @@ -1695,9 +1673,7 @@ * maps. */ void markFrameLocations(IntervalWalker iw, LIRInstruction op, LIRFrameState info) { - if (getTraceLevel() >= 3) { - TTY.println("creating oop map at opId %d", op.id()); - } + Debug.log("creating oop map at opId %d", op.id()); // walk before the current operation . intervals that start at // the operation (i.e. output operands of the operation) are not @@ -1849,14 +1825,21 @@ private void assignLocations() { IntervalWalker iw = initIntervalWalker(IS_STACK_INTERVAL); - for (Block block : sortedBlocks) { - assignLocations(ir.lir(block), iw); + try (Indent indent = Debug.logAndIndent("assign locations")) { + for (Block block : sortedBlocks) { + try (Indent indent2 = Debug.logAndIndent("assign locations in block B%d", block.getId())) { + assignLocations(ir.lir(block), iw); + } + } } } public void allocate() { - Indent indent = Debug.logAndIndent(false, "allocate %s", gen.getGraph().method()); + /* + * This is the point to enable debug logging for the whole register allocation. + */ + Indent indent = Debug.logAndIndent(false, "LinearScan allocate %s", gen.getGraph().method()); try (Scope s = Debug.scope("LifetimeAnalysis")) { numberInstructions(); @@ -1919,27 +1902,22 @@ } void printIntervals(String label) { - if (getTraceLevel() >= 1) { - int i; - TTY.println(); - TTY.println(label); + if (Debug.isLogEnabled()) { + try (Indent indent = Debug.logAndIndent("intervals %s", label)) { + for (Interval interval : intervals) { + if (interval != null) { + Debug.log("%s", interval.logString(this)); + } + } - for (Interval interval : intervals) { - if (interval != null) { - TTY.out().println(interval.logString(this)); + try (Indent indent2 = Debug.logAndIndent("Basic Blocks")) { + for (int i = 0; i < blockCount(); i++) { + Block block = blockAt(i); + Debug.log("B%d [%d, %d, %s] ", block.getId(), getFirstLirInstructionId(block), getLastLirInstructionId(block), block.getLoop()); + } } } - - TTY.println(); - TTY.println("--- Basic Blocks ---"); - for (i = 0; i < blockCount(); i++) { - Block block = blockAt(i); - TTY.print("B%d [%d, %d, %s] ", block.getId(), getFirstLirInstructionId(block), getLastLirInstructionId(block), block.getLoop()); - } - TTY.println(); - TTY.println(); } - Debug.dump(Arrays.copyOf(intervals, intervalsSize), label); } @@ -1949,104 +1927,95 @@ boolean verify() { // (check that all intervals have a correct register and that no registers are overwritten) - if (getTraceLevel() >= 2) { - TTY.println(" verifying intervals *"); - } verifyIntervals(); - if (getTraceLevel() >= 2) { - TTY.println(" verifying that no oops are in fixed intervals *"); - } // verifyNoOopsInFixedIntervals(); - if (getTraceLevel() >= 2) { - TTY.println(" verifying that unpinned constants are not alive across block boundaries"); - } verifyConstants(); - if (getTraceLevel() >= 2) { - TTY.println(" verifying register allocation *"); - } verifyRegisters(); - if (getTraceLevel() >= 2) { - TTY.println(" no errors found *"); - } + Debug.log("no errors found"); return true; } private void verifyRegisters() { - RegisterVerifier verifier = new RegisterVerifier(this); - verifier.verify(blockAt(0)); + // Enable this logging to get output for the verification process. + try (Indent indent = Debug.logAndIndent(false, "verifying register allocation")) { + RegisterVerifier verifier = new RegisterVerifier(this); + verifier.verify(blockAt(0)); + } } void verifyIntervals() { - int len = intervalsSize; - - for (int i = 0; i < len; i++) { - Interval i1 = intervals[i]; - if (i1 == null) { - continue; - } - - i1.checkSplitChildren(); - - if (i1.operandNumber != i) { - TTY.println("Interval %d is on position %d in list", i1.operandNumber, i); - TTY.println(i1.logString(this)); - throw new GraalInternalError(""); - } - - if (isVariable(i1.operand) && i1.kind() == Kind.Illegal) { - TTY.println("Interval %d has no type assigned", i1.operandNumber); - TTY.println(i1.logString(this)); - throw new GraalInternalError(""); - } + try (Indent indent = Debug.logAndIndent("verifying intervals")) { + int len = intervalsSize; - if (i1.location() == null) { - TTY.println("Interval %d has no register assigned", i1.operandNumber); - TTY.println(i1.logString(this)); - throw new GraalInternalError(""); - } - - if (i1.first() == Range.EndMarker) { - TTY.println("Interval %d has no Range", i1.operandNumber); - TTY.println(i1.logString(this)); - throw new GraalInternalError(""); - } - - for (Range r = i1.first(); r != Range.EndMarker; r = r.next) { - if (r.from >= r.to) { - TTY.println("Interval %d has zero length range", i1.operandNumber); - TTY.println(i1.logString(this)); - throw new GraalInternalError(""); - } - } - - for (int j = i + 1; j < len; j++) { - Interval i2 = intervals[j]; - if (i2 == null) { + for (int i = 0; i < len; i++) { + Interval i1 = intervals[i]; + if (i1 == null) { continue; } - // special intervals that are created in MoveResolver - // . ignore them because the range information has no meaning there - if (i1.from() == 1 && i1.to() == 2) { - continue; + i1.checkSplitChildren(); + + if (i1.operandNumber != i) { + Debug.log("Interval %d is on position %d in list", i1.operandNumber, i); + Debug.log(i1.logString(this)); + throw new GraalInternalError(""); } - if (i2.from() == 1 && i2.to() == 2) { - continue; + + if (isVariable(i1.operand) && i1.kind() == Kind.Illegal) { + Debug.log("Interval %d has no type assigned", i1.operandNumber); + Debug.log(i1.logString(this)); + throw new GraalInternalError(""); + } + + if (i1.location() == null) { + Debug.log("Interval %d has no register assigned", i1.operandNumber); + Debug.log(i1.logString(this)); + throw new GraalInternalError(""); + } + + if (i1.first() == Range.EndMarker) { + Debug.log("Interval %d has no Range", i1.operandNumber); + Debug.log(i1.logString(this)); + throw new GraalInternalError(""); } - Value l1 = i1.location(); - Value l2 = i2.location(); - if (i1.intersects(i2) && !isIllegal(l1) && (l1.equals(l2))) { - if (DetailedAsserts.getValue()) { - TTY.println("Intervals %d and %d overlap and have the same register assigned", i1.operandNumber, i2.operandNumber); - TTY.println(i1.logString(this)); - TTY.println(i2.logString(this)); + + for (Range r = i1.first(); r != Range.EndMarker; r = r.next) { + if (r.from >= r.to) { + Debug.log("Interval %d has zero length range", i1.operandNumber); + Debug.log(i1.logString(this)); + throw new GraalInternalError(""); + } + } + + for (int j = i + 1; j < len; j++) { + Interval i2 = intervals[j]; + if (i2 == null) { + continue; } - throw new BailoutException(""); + + // special intervals that are created in MoveResolver + // . ignore them because the range information has no meaning there + if (i1.from() == 1 && i1.to() == 2) { + continue; + } + if (i2.from() == 1 && i2.to() == 2) { + continue; + } + Value l1 = i1.location(); + Value l2 = i2.location(); + if (i1.intersects(i2) && !isIllegal(l1) && (l1.equals(l2))) { + if (DetailedAsserts.getValue()) { + Debug.log("Intervals %d and %d overlap and have the same register assigned", i1.operandNumber, i2.operandNumber); + Debug.log(i1.logString(this)); + Debug.log(i2.logString(this)); + } + throw new BailoutException(""); + } } } } @@ -2069,44 +2038,46 @@ } void verifyNoOopsInFixedIntervals() { - CheckProcedure checkProc = new CheckProcedure(); + try (Indent indent = Debug.logAndIndent("verifying that no oops are in fixed intervals *")) { + CheckProcedure checkProc = new CheckProcedure(); - Interval fixedIntervals; - Interval otherIntervals; - fixedIntervals = createUnhandledLists(IS_PRECOLORED_INTERVAL, null).first; - // to ensure a walking until the last instruction id, add a dummy interval - // with a high operation id - otherIntervals = new Interval(Value.ILLEGAL, -1); - otherIntervals.addRange(Integer.MAX_VALUE - 2, Integer.MAX_VALUE - 1); - IntervalWalker iw = new IntervalWalker(this, fixedIntervals, otherIntervals); + Interval fixedIntervals; + Interval otherIntervals; + fixedIntervals = createUnhandledLists(IS_PRECOLORED_INTERVAL, null).first; + // to ensure a walking until the last instruction id, add a dummy interval + // with a high operation id + otherIntervals = new Interval(Value.ILLEGAL, -1); + otherIntervals.addRange(Integer.MAX_VALUE - 2, Integer.MAX_VALUE - 1); + IntervalWalker iw = new IntervalWalker(this, fixedIntervals, otherIntervals); - for (Block block : sortedBlocks) { - List instructions = ir.lir(block); + for (Block block : sortedBlocks) { + List instructions = ir.lir(block); - for (int j = 0; j < instructions.size(); j++) { - LIRInstruction op = instructions.get(j); + for (int j = 0; j < instructions.size(); j++) { + LIRInstruction op = instructions.get(j); - if (op.hasState()) { - iw.walkBefore(op.id()); - boolean checkLive = true; + if (op.hasState()) { + iw.walkBefore(op.id()); + boolean checkLive = true; - // Make sure none of the fixed registers is live across an - // oopmap since we can't handle that correctly. - if (checkLive) { - for (Interval interval = iw.activeLists.get(RegisterBinding.Fixed); interval != Interval.EndMarker; interval = interval.next) { - if (interval.currentTo() > op.id() + 1) { - // This interval is live out of this op so make sure - // that this interval represents some value that's - // referenced by this op either as an input or output. - checkProc.curInterval = interval; - checkProc.ok = false; + // Make sure none of the fixed registers is live across an + // oopmap since we can't handle that correctly. + if (checkLive) { + for (Interval interval = iw.activeLists.get(RegisterBinding.Fixed); interval != Interval.EndMarker; interval = interval.next) { + if (interval.currentTo() > op.id() + 1) { + // This interval is live out of this op so make sure + // that this interval represents some value that's + // referenced by this op either as an input or output. + checkProc.curInterval = interval; + checkProc.ok = false; - op.forEachInput(checkProc); - op.forEachAlive(checkProc); - op.forEachTemp(checkProc); - op.forEachOutput(checkProc); + op.forEachInput(checkProc); + op.forEachAlive(checkProc); + op.forEachTemp(checkProc); + op.forEachOutput(checkProc); - assert checkProc.ok : "fixed intervals should never be live across an oopmap point"; + assert checkProc.ok : "fixed intervals should never be live across an oopmap point"; + } } } } @@ -2116,18 +2087,18 @@ } void verifyConstants() { - for (Block block : sortedBlocks) { - BitSet liveAtEdge = blockData.get(block).liveIn; + try (Indent indent = Debug.logAndIndent("verifying that unpinned constants are not alive across block boundaries")) { + for (Block block : sortedBlocks) { + BitSet liveAtEdge = blockData.get(block).liveIn; - // visit all operands where the liveAtEdge bit is set - for (int operandNum = liveAtEdge.nextSetBit(0); operandNum >= 0; operandNum = liveAtEdge.nextSetBit(operandNum + 1)) { - if (getTraceLevel() >= 4) { - TTY.println("checking interval %d of block B%d", operandNum, block.getId()); + // visit all operands where the liveAtEdge bit is set + for (int operandNum = liveAtEdge.nextSetBit(0); operandNum >= 0; operandNum = liveAtEdge.nextSetBit(operandNum + 1)) { + Debug.log("checking interval %d of block B%d", operandNum, block.getId()); + Value operand = operandFor(operandNum); + assert isVariable(operand) : "value must have variable operand"; + // TKR assert value.asConstant() == null || value.isPinned() : + // "only pinned constants can be alive accross block boundaries"; } - Value operand = operandFor(operandNum); - assert isVariable(operand) : "value must have variable operand"; - // TKR assert value.asConstant() == null || value.isPinned() : - // "only pinned constants can be alive accross block boundaries"; } } } diff -r 51d31106cd5e -r 7c694e3e97e5 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScanWalker.java --- 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); } diff -r 51d31106cd5e -r 7c694e3e97e5 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/RegisterVerifier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/RegisterVerifier.java Fri Dec 20 08:06:48 2013 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/RegisterVerifier.java Fri Dec 20 08:08:06 2013 +0100 @@ -90,34 +90,27 @@ } private void processBlock(Block block) { - if (allocator.getTraceLevel() >= 2) { - TTY.println(); - TTY.println("processBlock B%d", block.getId()); - } - - // must copy state because it is modified - Interval[] inputState = copy(stateForBlock(block)); + try (Indent indent = Debug.logAndIndent("processBlock B%d", block.getId())) { + // must copy state because it is modified + Interval[] inputState = copy(stateForBlock(block)); - if (allocator.getTraceLevel() >= 4) { - TTY.println("Input-State of intervals:"); - TTY.print(" "); - for (int i = 0; i < stateSize(); i++) { - if (inputState[i] != null) { - TTY.print(" %4d", inputState[i].operandNumber); - } else { - TTY.print(" __"); + try (Indent indent2 = Debug.logAndIndent("Input-State of intervals:")) { + for (int i = 0; i < stateSize(); i++) { + if (inputState[i] != null) { + Debug.log(" %4d", inputState[i].operandNumber); + } else { + Debug.log(" __"); + } } } - TTY.println(); - TTY.println(); - } + + // process all operations of the block + processOperations(allocator.ir.lir(block), inputState); - // process all operations of the block - processOperations(allocator.ir.lir(block), inputState); - - // iterate all successors - for (Block succ : block.getSuccessors()) { - processSuccessor(succ, inputState); + // iterate all successors + for (Block succ : block.getSuccessors()) { + processSuccessor(succ, inputState); + } } } @@ -140,31 +133,23 @@ savedStateCorrect = false; savedState[i] = null; - if (allocator.getTraceLevel() >= 4) { - TTY.println("processSuccessor B%d: invalidating slot %d", block.getId(), i); - } + Debug.log("processSuccessor B%d: invalidating slot %d", block.getId(), i); } } } if (savedStateCorrect) { // already processed block with correct inputState - if (allocator.getTraceLevel() >= 2) { - TTY.println("processSuccessor B%d: previous visit already correct", block.getId()); - } + Debug.log("processSuccessor B%d: previous visit already correct", block.getId()); } else { // must re-visit this block - if (allocator.getTraceLevel() >= 2) { - TTY.println("processSuccessor B%d: must re-visit because input state changed", block.getId()); - } + Debug.log("processSuccessor B%d: must re-visit because input state changed", block.getId()); addToWorkList(block); } } else { // block was not processed before, so set initial inputState - if (allocator.getTraceLevel() >= 2) { - TTY.println("processSuccessor B%d: initial visit", block.getId()); - } + Debug.log("processSuccessor B%d: initial visit", block.getId()); setStateForBlock(block, copy(inputState)); addToWorkList(block); @@ -175,18 +160,14 @@ return inputState.clone(); } - static void statePut(Interval[] inputState, Value location, Interval interval, int traceLevel) { + static void statePut(Interval[] inputState, Value location, Interval interval) { if (location != null && isRegister(location)) { Register reg = asRegister(location); int regNum = reg.number; if (interval != null) { - if (traceLevel >= 4) { - TTY.println(" %s = %s", reg, interval.operand); - } + Debug.log("%s = %s", reg, interval.operand); } else if (inputState[regNum] != null) { - if (traceLevel >= 4) { - TTY.println(" %s = null", reg); - } + Debug.log("%s = null", reg); } inputState[regNum] = interval; @@ -207,8 +188,8 @@ for (int i = 0; i < ops.size(); i++) { final LIRInstruction op = ops.get(i); - if (allocator.getTraceLevel() >= 4) { - TTY.println(op.toStringWithIdPrefix()); + if (Debug.isLogEnabled()) { + Debug.log("%s", op.toStringWithIdPrefix()); } ValueProcedure useProc = new ValueProcedure() { @@ -237,7 +218,7 @@ interval = interval.getSplitChildAtOpId(op.id(), mode, allocator); } - statePut(inputState, interval.location(), interval.splitParent(), allocator.getTraceLevel()); + statePut(inputState, interval.location(), interval.splitParent()); } return operand; } @@ -248,7 +229,7 @@ // invalidate all caller save registers at calls if (op.destroysCallerSavedRegisters()) { for (Register r : allocator.frameMap.registerConfig.getCallerSaveRegisters()) { - statePut(inputState, r.asValue(), null, allocator.getTraceLevel()); + statePut(inputState, r.asValue(), null); } } op.forEachAlive(useProc);