changeset 14871:667710021ea1

removed methods in Indent that are redundant with those in Debug
author Doug Simon <doug.simon@oracle.com>
date Fri, 28 Mar 2014 11:41:42 +0100
parents a8dce92315a2
children e6ce6d9f477f
files graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineCompiler.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScanWalker.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRGenerator.java graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Indent.java graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/RedundantMoveElimination.java
diffstat 9 files changed, 882 insertions(+), 903 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineCompiler.java	Fri Mar 28 09:47:42 2014 +0100
+++ b/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineCompiler.java	Fri Mar 28 11:41:42 2014 +0100
@@ -506,10 +506,10 @@
     }
 
     public void processBlock(BciBlock block) {
-        Indent indent = Debug.logAndIndent("Parsing block %s  firstInstruction: %s  loopHeader: %b", block, block.firstInstruction, block.isLoopHeader);
-        currentBlock = block;
-        iterateBytecodesForBlock(block);
-        indent.outdent();
+        try (Indent indent = Debug.logAndIndent("Parsing block %s  firstInstruction: %s  loopHeader: %b", block, block.firstInstruction, block.isLoopHeader)) {
+            currentBlock = block;
+            iterateBytecodesForBlock(block);
+        }
     }
 
     private void createExceptionDispatch(ExceptionDispatchBlock block) {
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java	Fri Mar 28 09:47:42 2014 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java	Fri Mar 28 11:41:42 2014 +0100
@@ -279,7 +279,7 @@
 
     /**
      * Creates a new interval.
-     * 
+     *
      * @param operand the operand for the interval
      * @return the created interval
      */
@@ -295,7 +295,7 @@
 
     /**
      * Creates an interval as a result of splitting or spilling another interval.
-     * 
+     *
      * @param source an interval being split of spilled
      * @return a new interval derived from {@code source}
      */
@@ -376,7 +376,7 @@
 
     /**
      * Retrieves the {@link LIRInstruction} based on its {@linkplain LIRInstruction#id id}.
-     * 
+     *
      * @param opId an instruction {@linkplain LIRInstruction#id id}
      * @return the instruction whose {@linkplain LIRInstruction#id} {@code == id}
      */
@@ -389,7 +389,7 @@
 
     /**
      * Gets the block containing a given instruction.
-     * 
+     *
      * @param opId an instruction {@linkplain LIRInstruction#id id}
      * @return the block containing the instruction denoted by {@code opId}
      */
@@ -408,7 +408,7 @@
 
     /**
      * Determines if an {@link LIRInstruction} destroys all caller saved registers.
-     * 
+     *
      * @param opId an instruction {@linkplain LIRInstruction#id id}
      * @return {@code true} if the instruction denoted by {@code id} destroys all caller saved
      *         registers.
@@ -505,79 +505,82 @@
 
     // called once before assignment of register numbers
     void eliminateSpillMoves() {
-        Indent indent = Debug.logAndIndent("Eliminating unnecessary spill moves");
+        try (Indent indent = Debug.logAndIndent("Eliminating unnecessary spill moves")) {
+
+            // collect all intervals that must be stored after their definition.
+            // the list is sorted by Interval.spillDefinitionPos
+            Interval interval;
+            interval = createUnhandledLists(mustStoreAtDefinition, null).first;
+            if (DetailedAsserts.getValue()) {
+                checkIntervals(interval);
+            }
+
+            LIRInsertionBuffer insertionBuffer = new LIRInsertionBuffer();
+            for (AbstractBlock<?> block : sortedBlocks) {
+                List<LIRInstruction> instructions = ir.getLIRforBlock(block);
+                int numInst = instructions.size();
 
-        // collect all intervals that must be stored after their definition.
-        // the list is sorted by Interval.spillDefinitionPos
-        Interval interval;
-        interval = createUnhandledLists(mustStoreAtDefinition, null).first;
-        if (DetailedAsserts.getValue()) {
-            checkIntervals(interval);
-        }
+                // iterate all instructions of the block. skip the first
+                // because it is always a label
+                for (int j = 1; j < numInst; j++) {
+                    LIRInstruction op = instructions.get(j);
+                    int opId = op.id();
 
-        LIRInsertionBuffer insertionBuffer = new LIRInsertionBuffer();
-        for (AbstractBlock<?> block : sortedBlocks) {
-            List<LIRInstruction> instructions = ir.getLIRforBlock(block);
-            int numInst = instructions.size();
+                    if (opId == -1) {
+                        MoveOp move = (MoveOp) op;
+                        // remove move from register to stack if the stack slot is guaranteed to be
+                        // correct.
+                        // only moves that have been inserted by LinearScan can be removed.
+                        assert isVariable(move.getResult()) : "LinearScan inserts only moves to variables";
+
+                        Interval curInterval = intervalFor(move.getResult());
 
-            // iterate all instructions of the block. skip the first because it is always a label
-            for (int j = 1; j < numInst; j++) {
-                LIRInstruction op = instructions.get(j);
-                int opId = op.id();
+                        if (!isRegister(curInterval.location()) && curInterval.alwaysInMemory()) {
+                            // move target is a stack slot that is always correct, so eliminate
+                            // instruction
+                            if (Debug.isLogEnabled()) {
+                                Debug.log("eliminating move from interval %d to %d", operandNumber(move.getInput()), operandNumber(move.getResult()));
+                            }
+                            // null-instructions are deleted by assignRegNum
+                            instructions.set(j, null);
+                        }
+
+                    } else {
+                        // insert move from register to stack just after
+                        // the beginning of the interval
+                        assert interval == Interval.EndMarker || interval.spillDefinitionPos() >= opId : "invalid order";
+                        assert interval == Interval.EndMarker || (interval.isSplitParent() && interval.spillState() == SpillState.StoreAtDefinition) : "invalid interval";
 
-                if (opId == -1) {
-                    MoveOp move = (MoveOp) op;
-                    // remove move from register to stack if the stack slot is guaranteed to be
-                    // correct.
-                    // only moves that have been inserted by LinearScan can be removed.
-                    assert isVariable(move.getResult()) : "LinearScan inserts only moves to variables";
+                        while (interval != Interval.EndMarker && interval.spillDefinitionPos() == opId) {
+                            if (!interval.canMaterialize()) {
+                                if (!insertionBuffer.initialized()) {
+                                    // prepare insertion buffer (appended when all instructions in
+                                    // the block are processed)
+                                    insertionBuffer.init(instructions);
+                                }
 
-                    Interval curInterval = intervalFor(move.getResult());
+                                AllocatableValue fromLocation = interval.location();
+                                AllocatableValue toLocation = canonicalSpillOpr(interval);
+
+                                assert isRegister(fromLocation) : "from operand must be a register but is: " + fromLocation + " toLocation=" + toLocation + " spillState=" + interval.spillState();
+                                assert isStackSlot(toLocation) : "to operand must be a stack slot";
 
-                    if (!isRegister(curInterval.location()) && curInterval.alwaysInMemory()) {
-                        // move target is a stack slot that is always correct, so eliminate
-                        // instruction
-                        if (Debug.isLogEnabled()) {
-                            Debug.log("eliminating move from interval %d to %d", operandNumber(move.getInput()), operandNumber(move.getResult()));
+                                insertionBuffer.append(j + 1, ir.getSpillMoveFactory().createMove(toLocation, fromLocation));
+
+                                Debug.log("inserting move after definition of interval %d to stack slot %s at opId %d", interval.operandNumber, interval.spillSlot(), opId);
+                            }
+                            interval = interval.next;
                         }
-                        instructions.set(j, null); // null-instructions are deleted by assignRegNum
                     }
-
-                } else {
-                    // insert move from register to stack just after the beginning of the interval
-                    assert interval == Interval.EndMarker || interval.spillDefinitionPos() >= opId : "invalid order";
-                    assert interval == Interval.EndMarker || (interval.isSplitParent() && interval.spillState() == SpillState.StoreAtDefinition) : "invalid interval";
-
-                    while (interval != Interval.EndMarker && interval.spillDefinitionPos() == opId) {
-                        if (!interval.canMaterialize()) {
-                            if (!insertionBuffer.initialized()) {
-                                // prepare insertion buffer (appended when all instructions of the
-                                // block are processed)
-                                insertionBuffer.init(instructions);
-                            }
-
-                            AllocatableValue fromLocation = interval.location();
-                            AllocatableValue toLocation = canonicalSpillOpr(interval);
+                } // end of instruction iteration
 
-                            assert isRegister(fromLocation) : "from operand must be a register but is: " + fromLocation + " toLocation=" + toLocation + " spillState=" + interval.spillState();
-                            assert isStackSlot(toLocation) : "to operand must be a stack slot";
-
-                            insertionBuffer.append(j + 1, ir.getSpillMoveFactory().createMove(toLocation, fromLocation));
-
-                            Debug.log("inserting move after definition of interval %d to stack slot %s at opId %d", interval.operandNumber, interval.spillSlot(), opId);
-                        }
-                        interval = interval.next;
-                    }
+                if (insertionBuffer.initialized()) {
+                    insertionBuffer.finish();
                 }
-            } // end of instruction iteration
+            } // end of block iteration
 
-            if (insertionBuffer.initialized()) {
-                insertionBuffer.finish();
-            }
-        } // end of block iteration
-
-        assert interval == Interval.EndMarker : "missed an interval";
-        indent.outdent();
+            assert interval == Interval.EndMarker : "missed an interval";
+        }
     }
 
     private static void checkIntervals(Interval interval) {
@@ -676,95 +679,95 @@
 
         // iterate all blocks
         for (final AbstractBlock<?> block : sortedBlocks) {
-            Indent indent = Debug.logAndIndent("compute local live sets for block %d", block.getId());
+            try (Indent indent = Debug.logAndIndent("compute local live sets for block %d", block.getId())) {
+
+                final BitSet liveGen = new BitSet(liveSize);
+                final BitSet liveKill = new BitSet(liveSize);
 
-            final BitSet liveGen = new BitSet(liveSize);
-            final BitSet liveKill = new BitSet(liveSize);
+                List<LIRInstruction> instructions = ir.getLIRforBlock(block);
+                int numInst = instructions.size();
 
-            List<LIRInstruction> instructions = ir.getLIRforBlock(block);
-            int numInst = instructions.size();
+                // iterate all instructions of the block
+                for (int j = 0; j < numInst; j++) {
+                    final LIRInstruction op = instructions.get(j);
+
+                    ValueProcedure useProc = new ValueProcedure() {
 
-            // iterate all instructions of the block
-            for (int j = 0; j < numInst; j++) {
-                final LIRInstruction op = instructions.get(j);
+                        @Override
+                        protected Value doValue(Value operand) {
+                            if (isVariable(operand)) {
+                                int operandNum = operandNumber(operand);
+                                if (!liveKill.get(operandNum)) {
+                                    liveGen.set(operandNum);
+                                    Debug.log("liveGen for operand %d", operandNum);
+                                }
+                                if (block.getLoop() != null) {
+                                    intervalInLoop.setBit(operandNum, block.getLoop().index);
+                                }
+                            }
 
-                ValueProcedure useProc = new ValueProcedure() {
+                            if (DetailedAsserts.getValue()) {
+                                verifyInput(block, liveKill, operand);
+                            }
+                            return operand;
+                        }
+                    };
+                    ValueProcedure stateProc = new ValueProcedure() {
 
-                    @Override
-                    protected Value doValue(Value operand) {
-                        if (isVariable(operand)) {
+                        @Override
+                        public Value doValue(Value operand) {
                             int operandNum = operandNumber(operand);
                             if (!liveKill.get(operandNum)) {
                                 liveGen.set(operandNum);
-                                Debug.log("liveGen for operand %d", operandNum);
-                            }
-                            if (block.getLoop() != null) {
-                                intervalInLoop.setBit(operandNum, block.getLoop().index);
+                                Debug.log("liveGen in state for operand %d", operandNum);
                             }
-                        }
-
-                        if (DetailedAsserts.getValue()) {
-                            verifyInput(block, liveKill, operand);
+                            return operand;
                         }
-                        return operand;
-                    }
-                };
-                ValueProcedure stateProc = new ValueProcedure() {
+                    };
+                    ValueProcedure defProc = new ValueProcedure() {
 
-                    @Override
-                    public Value doValue(Value operand) {
-                        int operandNum = operandNumber(operand);
-                        if (!liveKill.get(operandNum)) {
-                            liveGen.set(operandNum);
-                            Debug.log("liveGen in state for operand %d", operandNum);
-                        }
-                        return operand;
-                    }
-                };
-                ValueProcedure defProc = new ValueProcedure() {
+                        @Override
+                        public Value doValue(Value operand) {
+                            if (isVariable(operand)) {
+                                int varNum = operandNumber(operand);
+                                liveKill.set(varNum);
+                                Debug.log("liveKill for operand %d", varNum);
+                                if (block.getLoop() != null) {
+                                    intervalInLoop.setBit(varNum, block.getLoop().index);
+                                }
+                            }
 
-                    @Override
-                    public Value doValue(Value operand) {
-                        if (isVariable(operand)) {
-                            int varNum = operandNumber(operand);
-                            liveKill.set(varNum);
-                            Debug.log("liveKill for operand %d", varNum);
-                            if (block.getLoop() != null) {
-                                intervalInLoop.setBit(varNum, block.getLoop().index);
+                            if (DetailedAsserts.getValue()) {
+                                // fixed intervals are never live at block boundaries, so
+                                // they need not be processed in live sets
+                                // process them only in debug mode so that this can be checked
+                                verifyTemp(liveKill, operand);
                             }
+                            return operand;
                         }
-
-                        if (DetailedAsserts.getValue()) {
-                            // fixed intervals are never live at block boundaries, so
-                            // they need not be processed in live sets
-                            // process them only in debug mode so that this can be checked
-                            verifyTemp(liveKill, operand);
-                        }
-                        return operand;
-                    }
-                };
+                    };
 
-                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
+                    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);
-            blockSets.liveGen = liveGen;
-            blockSets.liveKill = liveKill;
-            blockSets.liveIn = new BitSet(liveSize);
-            blockSets.liveOut = new BitSet(liveSize);
+                BlockData blockSets = blockData.get(block);
+                blockSets.liveGen = liveGen;
+                blockSets.liveKill = liveKill;
+                blockSets.liveIn = new BitSet(liveSize);
+                blockSets.liveOut = new BitSet(liveSize);
 
-            Debug.log("liveGen  B%d %s", block.getId(), blockSets.liveGen);
-            Debug.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
     }
 
@@ -797,87 +800,88 @@
      * {@link BlockData#liveIn} and {@link BlockData#liveOut}) for each block.
      */
     void computeGlobalLiveSets() {
-        Indent indent = Debug.logAndIndent("compute global live sets");
-        int numBlocks = blockCount();
-        boolean changeOccurred;
-        boolean changeOccurredInBlock;
-        int iterationCount = 0;
-        BitSet liveOut = new BitSet(liveSetSize()); // scratch set for calculations
+        try (Indent indent = Debug.logAndIndent("compute global live sets")) {
+            int numBlocks = blockCount();
+            boolean changeOccurred;
+            boolean changeOccurredInBlock;
+            int iterationCount = 0;
+            BitSet liveOut = new BitSet(liveSetSize()); // scratch set for calculations
 
-        // Perform a backward dataflow analysis to compute liveOut and liveIn for each block.
-        // The loop is executed until a fixpoint is reached (no changes in an iteration)
-        do {
-            changeOccurred = false;
+            // Perform a backward dataflow analysis to compute liveOut and liveIn for each block.
+            // The loop is executed until a fixpoint is reached (no changes in an iteration)
+            do {
+                changeOccurred = false;
 
-            Indent indent2 = Debug.logAndIndent("new iteration %d", iterationCount);
+                try (Indent indent2 = Debug.logAndIndent("new iteration %d", iterationCount)) {
 
-            // iterate all blocks in reverse order
-            for (int i = numBlocks - 1; i >= 0; i--) {
-                AbstractBlock<?> block = blockAt(i);
-                BlockData blockSets = blockData.get(block);
+                    // iterate all blocks in reverse order
+                    for (int i = numBlocks - 1; i >= 0; i--) {
+                        AbstractBlock<?> block = blockAt(i);
+                        BlockData blockSets = blockData.get(block);
 
-                changeOccurredInBlock = false;
+                        changeOccurredInBlock = false;
 
-                // liveOut(block) is the union of liveIn(sux), for successors sux of block
-                int n = block.getSuccessorCount();
-                if (n > 0) {
-                    // block has successors
-                    if (n > 0) {
-                        liveOut.clear();
-                        for (AbstractBlock<?> successor : block.getSuccessors()) {
-                            liveOut.or(blockData.get(successor).liveIn);
+                        // liveOut(block) is the union of liveIn(sux), for successors sux of block
+                        int n = block.getSuccessorCount();
+                        if (n > 0) {
+                            // block has successors
+                            if (n > 0) {
+                                liveOut.clear();
+                                for (AbstractBlock<?> successor : block.getSuccessors()) {
+                                    liveOut.or(blockData.get(successor).liveIn);
+                                }
+                            } else {
+                                liveOut.clear();
+                            }
+
+                            if (!blockSets.liveOut.equals(liveOut)) {
+                                // A change occurred. Swap the old and new live out
+                                // sets to avoid copying.
+                                BitSet temp = blockSets.liveOut;
+                                blockSets.liveOut = liveOut;
+                                liveOut = temp;
+
+                                changeOccurred = true;
+                                changeOccurredInBlock = true;
+                            }
                         }
-                    } else {
-                        liveOut.clear();
-                    }
 
-                    if (!blockSets.liveOut.equals(liveOut)) {
-                        // A change occurred. Swap the old and new live out sets to avoid copying.
-                        BitSet temp = blockSets.liveOut;
-                        blockSets.liveOut = liveOut;
-                        liveOut = temp;
+                        if (iterationCount == 0 || changeOccurredInBlock) {
+                            // liveIn(block) is the union of liveGen(block) with (liveOut(block) &
+                            // !liveKill(block))
+                            // note: liveIn has to be computed only in first iteration
+                            // or if liveOut has changed!
+                            BitSet liveIn = blockSets.liveIn;
+                            liveIn.clear();
+                            liveIn.or(blockSets.liveOut);
+                            liveIn.andNot(blockSets.liveKill);
+                            liveIn.or(blockSets.liveGen);
 
-                        changeOccurred = true;
-                        changeOccurredInBlock = true;
+                            Debug.log("block %d: livein = %s,  liveout = %s", block.getId(), liveIn, blockSets.liveOut);
+                        }
+                    }
+                    iterationCount++;
+
+                    if (changeOccurred && iterationCount > 50) {
+                        throw new BailoutException("too many iterations in computeGlobalLiveSets");
                     }
                 }
+            } while (changeOccurred);
 
-                if (iterationCount == 0 || changeOccurredInBlock) {
-                    // liveIn(block) is the union of liveGen(block) with (liveOut(block) &
-                    // !liveKill(block))
-                    // note: liveIn has to be computed only in first iteration or if liveOut has
-                    // changed!
-                    BitSet liveIn = blockSets.liveIn;
-                    liveIn.clear();
-                    liveIn.or(blockSets.liveOut);
-                    liveIn.andNot(blockSets.liveKill);
-                    liveIn.or(blockSets.liveGen);
-
-                    Debug.log("block %d: livein = %s,  liveout = %s", block.getId(), liveIn, blockSets.liveOut);
-                }
+            if (DetailedAsserts.getValue()) {
+                verifyLiveness();
             }
-            iterationCount++;
 
-            if (changeOccurred && iterationCount > 50) {
-                throw new BailoutException("too many iterations in computeGlobalLiveSets");
+            // check that the liveIn set of the first block is empty
+            AbstractBlock<?> startBlock = ir.getControlFlowGraph().getStartBlock();
+            if (blockData.get(startBlock).liveIn.cardinality() != 0) {
+                if (DetailedAsserts.getValue()) {
+                    reportFailure(numBlocks);
+                }
+                // bailout if this occurs in product mode.
+                throw new GraalInternalError("liveIn set of first block must be empty: " + blockData.get(startBlock).liveIn);
             }
-            indent2.outdent();
-        } while (changeOccurred);
-
-        if (DetailedAsserts.getValue()) {
-            verifyLiveness();
         }
-
-        // check that the liveIn set of the first block is empty
-        AbstractBlock<?> startBlock = ir.getControlFlowGraph().getStartBlock();
-        if (blockData.get(startBlock).liveIn.cardinality() != 0) {
-            if (DetailedAsserts.getValue()) {
-                reportFailure(numBlocks);
-            }
-            // bailout if this occurs in product mode.
-            throw new GraalInternalError("liveIn set of first block must be empty: " + blockData.get(startBlock).liveIn);
-        }
-        indent.outdent();
     }
 
     private static NodeLIRGenerator getNodeLIRGeneratorFromDebugContext() {
@@ -899,76 +903,76 @@
 
     private void reportFailure(int numBlocks) {
         try (Scope s = Debug.forceLog()) {
-            Indent indent = Debug.logAndIndent("report failure");
+            try (Indent indent = Debug.logAndIndent("report failure")) {
 
-            BitSet startBlockLiveIn = blockData.get(ir.getControlFlowGraph().getStartBlock()).liveIn;
-            try (Indent indent2 = Debug.logAndIndent("Error: liveIn set of first block must be empty (when this fails, variables are used before they are defined):")) {
+                BitSet startBlockLiveIn = blockData.get(ir.getControlFlowGraph().getStartBlock()).liveIn;
+                try (Indent indent2 = Debug.logAndIndent("Error: liveIn set of first block must be empty (when this fails, variables are used before they are defined):")) {
+                    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, getValueForOperandFromDebugContext(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);
-                    Debug.log("var %d; operand=%s; node=%s", operandNum, operand, getValueForOperandFromDebugContext(operand));
-                }
-            }
+                    try (Indent indent2 = Debug.logAndIndent("---- Detailed information for var %d; operand=%s; node=%s ----", operandNum, operand, getValueForOperandFromDebugContext(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 = Debug.logAndIndent("---- Detailed information for var %d; operand=%s; node=%s ----", operandNum, operand, getValueForOperandFromDebugContext(operand));
+                        Deque<AbstractBlock<?>> definedIn = new ArrayDeque<>();
+                        HashSet<AbstractBlock<?>> usedIn = new HashSet<>();
+                        for (AbstractBlock<?> block : sortedBlocks) {
+                            if (blockData.get(block).liveGen.get(operandNum)) {
+                                usedIn.add(block);
+                                try (Indent indent3 = Debug.logAndIndent("used in block B%d", block.getId())) {
+                                    for (LIRInstruction ins : ir.getLIRforBlock(block)) {
+                                        try (Indent indent4 = Debug.logAndIndent("%d: %s", ins.id(), ins)) {
+                                            ins.forEachState(new ValueProcedure() {
 
-                Deque<AbstractBlock<?>> definedIn = new ArrayDeque<>();
-                HashSet<AbstractBlock<?>> usedIn = new HashSet<>();
-                for (AbstractBlock<?> block : sortedBlocks) {
-                    if (blockData.get(block).liveGen.get(operandNum)) {
-                        usedIn.add(block);
-                        try (Indent indent3 = Debug.logAndIndent("used in block B%d", block.getId())) {
-                            for (LIRInstruction ins : ir.getLIRforBlock(block)) {
-                                try (Indent indent4 = Debug.logAndIndent("%d: %s", ins.id(), ins)) {
-                                    ins.forEachState(new ValueProcedure() {
-
-                                        @Override
-                                        public Value doValue(Value liveStateOperand) {
-                                            Debug.log("operand=%s", liveStateOperand);
-                                            return liveStateOperand;
+                                                @Override
+                                                public Value doValue(Value liveStateOperand) {
+                                                    Debug.log("operand=%s", liveStateOperand);
+                                                    return liveStateOperand;
+                                                }
+                                            });
                                         }
-                                    });
+                                    }
+                                }
+                            }
+                            if (blockData.get(block).liveKill.get(operandNum)) {
+                                definedIn.add(block);
+                                try (Indent indent3 = Debug.logAndIndent("defined in block B%d", block.getId())) {
+                                    for (LIRInstruction ins : ir.getLIRforBlock(block)) {
+                                        Debug.log("%d: %s", ins.id(), ins);
+                                    }
                                 }
                             }
                         }
-                    }
-                    if (blockData.get(block).liveKill.get(operandNum)) {
-                        definedIn.add(block);
-                        try (Indent indent3 = Debug.logAndIndent("defined in block B%d", block.getId())) {
-                            for (LIRInstruction ins : ir.getLIRforBlock(block)) {
-                                Debug.log("%d: %s", ins.id(), ins);
+
+                        int[] hitCount = new int[numBlocks];
+
+                        while (!definedIn.isEmpty()) {
+                            AbstractBlock<?> block = definedIn.removeFirst();
+                            usedIn.remove(block);
+                            for (AbstractBlock<?> successor : block.getSuccessors()) {
+                                if (successor.isLoopHeader()) {
+                                    if (!block.isLoopEnd()) {
+                                        definedIn.add(successor);
+                                    }
+                                } else {
+                                    if (++hitCount[successor.getId()] == successor.getPredecessorCount()) {
+                                        definedIn.add(successor);
+                                    }
+                                }
+                            }
+                        }
+                        try (Indent indent3 = Debug.logAndIndent("**** offending usages are in: ")) {
+                            for (AbstractBlock<?> block : usedIn) {
+                                Debug.log("B%d", block.getId());
                             }
                         }
                     }
                 }
-
-                int[] hitCount = new int[numBlocks];
-
-                while (!definedIn.isEmpty()) {
-                    AbstractBlock<?> block = definedIn.removeFirst();
-                    usedIn.remove(block);
-                    for (AbstractBlock<?> successor : block.getSuccessors()) {
-                        if (successor.isLoopHeader()) {
-                            if (!block.isLoopEnd()) {
-                                definedIn.add(successor);
-                            }
-                        } else {
-                            if (++hitCount[successor.getId()] == successor.getPredecessorCount()) {
-                                definedIn.add(successor);
-                            }
-                        }
-                    }
-                }
-                try (Indent indent3 = Debug.logAndIndent("**** offending usages are in: ")) {
-                    for (AbstractBlock<?> block : usedIn) {
-                        Debug.log("B%d", block.getId());
-                    }
-                }
-                indent2.outdent();
             }
-            indent.outdent();
         }
     }
 
@@ -1147,140 +1151,142 @@
 
     void buildIntervals() {
 
-        Indent indent = Debug.logAndIndent("build intervals");
+        try (Indent indent = Debug.logAndIndent("build intervals")) {
 
-        intervalsSize = operandSize();
-        intervals = new Interval[intervalsSize + INITIAL_SPLIT_INTERVALS_CAPACITY];
+            intervalsSize = operandSize();
+            intervals = new Interval[intervalsSize + INITIAL_SPLIT_INTERVALS_CAPACITY];
 
-        // create a list with all caller-save registers (cpu, fpu, xmm)
-        Register[] callerSaveRegs = frameMap.registerConfig.getCallerSaveRegisters();
+            // create a list with all caller-save registers (cpu, fpu, xmm)
+            Register[] callerSaveRegs = frameMap.registerConfig.getCallerSaveRegisters();
 
-        // iterate all blocks in reverse order
-        for (int i = blockCount() - 1; i >= 0; i--) {
-
-            AbstractBlock<?> block = blockAt(i);
-            Indent indent2 = Debug.logAndIndent("handle block %d", block.getId());
+            // iterate all blocks in reverse order
+            for (int i = blockCount() - 1; i >= 0; i--) {
 
-            List<LIRInstruction> instructions = ir.getLIRforBlock(block);
-            final int blockFrom = getFirstLirInstructionId(block);
-            int blockTo = getLastLirInstructionId(block);
+                AbstractBlock<?> block = blockAt(i);
+                try (Indent indent2 = Debug.logAndIndent("handle block %d", block.getId())) {
 
-            assert blockFrom == instructions.get(0).id();
-            assert blockTo == instructions.get(instructions.size() - 1).id();
+                    List<LIRInstruction> instructions = ir.getLIRforBlock(block);
+                    final int blockFrom = getFirstLirInstructionId(block);
+                    int blockTo = getLastLirInstructionId(block);
 
-            // Update intervals for operands live at the end of this block;
-            BitSet live = blockData.get(block).liveOut;
-            for (int operandNum = live.nextSetBit(0); operandNum >= 0; operandNum = live.nextSetBit(operandNum + 1)) {
-                assert live.get(operandNum) : "should not stop here otherwise";
-                AllocatableValue operand = operandFor(operandNum);
-                Debug.log("live in %d: %s", operandNum, operand);
-
-                addUse(operand, blockFrom, blockTo + 2, RegisterPriority.None, Kind.Illegal);
+                    assert blockFrom == instructions.get(0).id();
+                    assert blockTo == instructions.get(instructions.size() - 1).id();
 
-                // add special use positions for loop-end blocks when the
-                // interval is used anywhere inside this loop. It's possible
-                // that the block was part of a non-natural loop, so it might
-                // have an invalid loop index.
-                if (block.isLoopEnd() && block.getLoop() != null && isIntervalInLoop(operandNum, block.getLoop().index)) {
-                    intervalFor(operand).addUsePos(blockTo + 1, RegisterPriority.LiveAtLoopEnd);
-                }
-            }
+                    // Update intervals for operands live at the end of this block;
+                    BitSet live = blockData.get(block).liveOut;
+                    for (int operandNum = live.nextSetBit(0); operandNum >= 0; operandNum = live.nextSetBit(operandNum + 1)) {
+                        assert live.get(operandNum) : "should not stop here otherwise";
+                        AllocatableValue operand = operandFor(operandNum);
+                        Debug.log("live in %d: %s", operandNum, operand);
 
-            // iterate all instructions of the block in reverse order.
-            // definitions of intervals are processed before uses
-            for (int j = instructions.size() - 1; j >= 0; j--) {
-                final LIRInstruction op = instructions.get(j);
-                final int opId = op.id();
+                        addUse(operand, blockFrom, blockTo + 2, RegisterPriority.None, Kind.Illegal);
 
-                Indent indent3 = Debug.logAndIndent("handle inst %d: %s", opId, op);
-
-                // add a temp range for each register if operation destroys caller-save registers
-                if (op.destroysCallerSavedRegisters()) {
-                    for (Register r : callerSaveRegs) {
-                        if (attributes(r).isAllocatable()) {
-                            addTemp(r.asValue(), opId, RegisterPriority.None, Kind.Illegal);
+                        // add special use positions for loop-end blocks when the
+                        // interval is used anywhere inside this loop. It's possible
+                        // that the block was part of a non-natural loop, so it might
+                        // have an invalid loop index.
+                        if (block.isLoopEnd() && block.getLoop() != null && isIntervalInLoop(operandNum, block.getLoop().index)) {
+                            intervalFor(operand).addUsePos(blockTo + 1, RegisterPriority.LiveAtLoopEnd);
                         }
                     }
-                    Debug.log("operation destroys all caller-save registers");
-                }
 
-                op.forEachOutput(new ValueProcedure() {
+                    // iterate all instructions of the block in reverse order.
+                    // definitions of intervals are processed before uses
+                    for (int j = instructions.size() - 1; j >= 0; j--) {
+                        final LIRInstruction op = instructions.get(j);
+                        final int opId = op.id();
+
+                        try (Indent indent3 = Debug.logAndIndent("handle inst %d: %s", opId, op)) {
 
-                    @Override
-                    public Value doValue(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) {
-                        if (isVariableOrRegister(operand)) {
-                            addDef((AllocatableValue) operand, op, registerPriorityOfOutputOperand(op), operand.getPlatformKind());
-                            addRegisterHint(op, operand, mode, flags, true);
-                        }
-                        return operand;
-                    }
-                });
-                op.forEachTemp(new ValueProcedure() {
+                            // add a temp range for each register if operation destroys
+                            // caller-save registers
+                            if (op.destroysCallerSavedRegisters()) {
+                                for (Register r : callerSaveRegs) {
+                                    if (attributes(r).isAllocatable()) {
+                                        addTemp(r.asValue(), opId, RegisterPriority.None, Kind.Illegal);
+                                    }
+                                }
+                                Debug.log("operation destroys all caller-save registers");
+                            }
+
+                            op.forEachOutput(new ValueProcedure() {
 
-                    @Override
-                    public Value doValue(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) {
-                        if (isVariableOrRegister(operand)) {
-                            addTemp((AllocatableValue) operand, opId, RegisterPriority.MustHaveRegister, operand.getPlatformKind());
-                            addRegisterHint(op, operand, mode, flags, false);
-                        }
-                        return operand;
-                    }
-                });
-                op.forEachAlive(new ValueProcedure() {
+                                @Override
+                                public Value doValue(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) {
+                                    if (isVariableOrRegister(operand)) {
+                                        addDef((AllocatableValue) operand, op, registerPriorityOfOutputOperand(op), operand.getPlatformKind());
+                                        addRegisterHint(op, operand, mode, flags, true);
+                                    }
+                                    return operand;
+                                }
+                            });
+                            op.forEachTemp(new ValueProcedure() {
 
-                    @Override
-                    public Value doValue(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) {
-                        if (isVariableOrRegister(operand)) {
-                            RegisterPriority p = registerPriorityOfInputOperand(flags);
-                            addUse((AllocatableValue) operand, blockFrom, opId + 1, p, operand.getPlatformKind());
-                            addRegisterHint(op, operand, mode, flags, false);
-                        }
-                        return operand;
-                    }
-                });
-                op.forEachInput(new ValueProcedure() {
+                                @Override
+                                public Value doValue(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) {
+                                    if (isVariableOrRegister(operand)) {
+                                        addTemp((AllocatableValue) operand, opId, RegisterPriority.MustHaveRegister, operand.getPlatformKind());
+                                        addRegisterHint(op, operand, mode, flags, false);
+                                    }
+                                    return operand;
+                                }
+                            });
+                            op.forEachAlive(new ValueProcedure() {
 
-                    @Override
-                    public Value doValue(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) {
-                        if (isVariableOrRegister(operand)) {
-                            RegisterPriority p = registerPriorityOfInputOperand(flags);
-                            addUse((AllocatableValue) operand, blockFrom, opId, p, operand.getPlatformKind());
-                            addRegisterHint(op, operand, mode, flags, false);
-                        }
-                        return operand;
-                    }
-                });
+                                @Override
+                                public Value doValue(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) {
+                                    if (isVariableOrRegister(operand)) {
+                                        RegisterPriority p = registerPriorityOfInputOperand(flags);
+                                        addUse((AllocatableValue) operand, blockFrom, opId + 1, p, operand.getPlatformKind());
+                                        addRegisterHint(op, operand, mode, flags, false);
+                                    }
+                                    return operand;
+                                }
+                            });
+                            op.forEachInput(new ValueProcedure() {
 
-                // Add uses of live locals from interpreter's point of view for proper
-                // debug information generation
-                // Treat these operands as temp values (if the live range is extended
-                // to a call site, the value would be in a register at the call otherwise)
-                op.forEachState(new ValueProcedure() {
+                                @Override
+                                public Value doValue(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) {
+                                    if (isVariableOrRegister(operand)) {
+                                        RegisterPriority p = registerPriorityOfInputOperand(flags);
+                                        addUse((AllocatableValue) operand, blockFrom, opId, p, operand.getPlatformKind());
+                                        addRegisterHint(op, operand, mode, flags, false);
+                                    }
+                                    return operand;
+                                }
+                            });
 
-                    @Override
-                    public Value doValue(Value operand) {
-                        addUse((AllocatableValue) operand, blockFrom, opId + 1, RegisterPriority.None, operand.getPlatformKind());
-                        return operand;
-                    }
-                });
+                            // Add uses of live locals from interpreter's point of view for proper
+                            // debug information generation
+                            // Treat these operands as temp values (if the live range is extended
+                            // to a call site, the value would be in a register at
+                            // the call otherwise)
+                            op.forEachState(new ValueProcedure() {
 
-                // special steps for some instructions (especially moves)
-                handleMethodArguments(op);
+                                @Override
+                                public Value doValue(Value operand) {
+                                    addUse((AllocatableValue) operand, blockFrom, opId + 1, RegisterPriority.None, operand.getPlatformKind());
+                                    return operand;
+                                }
+                            });
 
-                indent3.outdent();
+                            // special steps for some instructions (especially moves)
+                            handleMethodArguments(op);
 
-            } // end of instruction iteration
-            indent2.outdent();
-        } // end of block iteration
+                        }
 
-        // add the range [0, 1] to all fixed intervals.
-        // the register allocator need not handle unhandled fixed intervals
-        for (Interval interval : intervals) {
-            if (interval != null && isRegister(interval.operand)) {
-                interval.addRange(0, 1);
+                    } // end of instruction iteration
+                }
+            } // end of block iteration
+
+            // add the range [0, 1] to all fixed intervals.
+            // the register allocator need not handle unhandled fixed intervals
+            for (Interval interval : intervals) {
+                if (interval != null && isRegister(interval.operand)) {
+                    interval.addRange(0, 1);
+                }
             }
         }
-        indent.outdent();
     }
 
     // * Phase 5: actual register allocation
@@ -1432,19 +1438,19 @@
     };
 
     public void allocateRegisters() {
-        Indent indent = Debug.logAndIndent("allocate registers");
-        Interval precoloredIntervals;
-        Interval notPrecoloredIntervals;
+        try (Indent indent = Debug.logAndIndent("allocate registers")) {
+            Interval precoloredIntervals;
+            Interval notPrecoloredIntervals;
 
-        Interval.Pair result = createUnhandledLists(IS_PRECOLORED_INTERVAL, IS_VARIABLE_INTERVAL);
-        precoloredIntervals = result.first;
-        notPrecoloredIntervals = result.second;
+            Interval.Pair result = createUnhandledLists(IS_PRECOLORED_INTERVAL, IS_VARIABLE_INTERVAL);
+            precoloredIntervals = result.first;
+            notPrecoloredIntervals = result.second;
 
-        // allocate cpu registers
-        LinearScanWalker lsw = new LinearScanWalker(this, precoloredIntervals, notPrecoloredIntervals);
-        lsw.walk();
-        lsw.finishAllocation();
-        indent.outdent();
+            // allocate cpu registers
+            LinearScanWalker lsw = new LinearScanWalker(this, precoloredIntervals, notPrecoloredIntervals);
+            lsw.walk();
+            lsw.finishAllocation();
+        }
     }
 
     // * Phase 6: resolve data flow
@@ -1543,69 +1549,71 @@
      * have been split.
      */
     void resolveDataFlow() {
-        Indent indent = Debug.logAndIndent("resolve data flow");
+        try (Indent indent = Debug.logAndIndent("resolve data flow")) {
 
-        int numBlocks = blockCount();
-        MoveResolver moveResolver = new MoveResolver(this);
-        BitSet blockCompleted = new BitSet(numBlocks);
-        BitSet alreadyResolved = new BitSet(numBlocks);
+            int numBlocks = blockCount();
+            MoveResolver moveResolver = new MoveResolver(this);
+            BitSet blockCompleted = new BitSet(numBlocks);
+            BitSet alreadyResolved = new BitSet(numBlocks);
+
+            for (AbstractBlock<?> block : sortedBlocks) {
 
-        for (AbstractBlock<?> block : sortedBlocks) {
+                // check if block has only one predecessor and only one successor
+                if (block.getPredecessorCount() == 1 && block.getSuccessorCount() == 1) {
+                    List<LIRInstruction> instructions = ir.getLIRforBlock(block);
+                    assert instructions.get(0) instanceof StandardOp.LabelOp : "block must start with label";
+                    assert instructions.get(instructions.size() - 1) instanceof StandardOp.JumpOp : "block with successor must end with unconditional jump";
 
-            // check if block has only one predecessor and only one successor
-            if (block.getPredecessorCount() == 1 && block.getSuccessorCount() == 1) {
-                List<LIRInstruction> instructions = ir.getLIRforBlock(block);
-                assert instructions.get(0) instanceof StandardOp.LabelOp : "block must start with label";
-                assert instructions.get(instructions.size() - 1) instanceof StandardOp.JumpOp : "block with successor must end with unconditional jump";
+                    // check if block is empty (only label and branch)
+                    if (instructions.size() == 2) {
+                        AbstractBlock<?> pred = block.getPredecessors().iterator().next();
+                        AbstractBlock<?> sux = block.getSuccessors().iterator().next();
+
+                        // prevent optimization of two consecutive blocks
+                        if (!blockCompleted.get(pred.getLinearScanNumber()) && !blockCompleted.get(sux.getLinearScanNumber())) {
+                            Debug.log(" optimizing empty block B%d (pred: B%d, sux: B%d)", block.getId(), pred.getId(), sux.getId());
+
+                            blockCompleted.set(block.getLinearScanNumber());
 
-                // check if block is empty (only label and branch)
-                if (instructions.size() == 2) {
-                    AbstractBlock<?> pred = block.getPredecessors().iterator().next();
-                    AbstractBlock<?> sux = block.getSuccessors().iterator().next();
-
-                    // prevent optimization of two consecutive blocks
-                    if (!blockCompleted.get(pred.getLinearScanNumber()) && !blockCompleted.get(sux.getLinearScanNumber())) {
-                        Debug.log(" optimizing empty block B%d (pred: B%d, sux: B%d)", block.getId(), pred.getId(), sux.getId());
+                            // directly resolve between pred and sux (without looking
+                            // at the empty block
+                            // between)
+                            resolveCollectMappings(pred, sux, moveResolver);
+                            if (moveResolver.hasMappings()) {
+                                moveResolver.setInsertPosition(instructions, 1);
+                                moveResolver.resolveAndAppendMoves();
+                            }
+                        }
+                    }
+                }
+            }
 
-                        blockCompleted.set(block.getLinearScanNumber());
+            for (AbstractBlock<?> fromBlock : sortedBlocks) {
+                if (!blockCompleted.get(fromBlock.getLinearScanNumber())) {
+                    alreadyResolved.clear();
+                    alreadyResolved.or(blockCompleted);
+
+                    for (AbstractBlock<?> toBlock : fromBlock.getSuccessors()) {
 
-                        // directly resolve between pred and sux (without looking at the empty block
-                        // between)
-                        resolveCollectMappings(pred, sux, moveResolver);
-                        if (moveResolver.hasMappings()) {
-                            moveResolver.setInsertPosition(instructions, 1);
-                            moveResolver.resolveAndAppendMoves();
+                        // check for duplicate edges between the same blocks (can happen with switch
+                        // blocks)
+                        if (!alreadyResolved.get(toBlock.getLinearScanNumber())) {
+                            Debug.log("processing edge between B%d and B%d", fromBlock.getId(), toBlock.getId());
+
+                            alreadyResolved.set(toBlock.getLinearScanNumber());
+
+                            // collect all intervals that have been split between
+                            // fromBlock and toBlock
+                            resolveCollectMappings(fromBlock, toBlock, moveResolver);
+                            if (moveResolver.hasMappings()) {
+                                resolveFindInsertPos(fromBlock, toBlock, moveResolver);
+                                moveResolver.resolveAndAppendMoves();
+                            }
                         }
                     }
                 }
             }
         }
-
-        for (AbstractBlock<?> fromBlock : sortedBlocks) {
-            if (!blockCompleted.get(fromBlock.getLinearScanNumber())) {
-                alreadyResolved.clear();
-                alreadyResolved.or(blockCompleted);
-
-                for (AbstractBlock<?> toBlock : fromBlock.getSuccessors()) {
-
-                    // check for duplicate edges between the same blocks (can happen with switch
-                    // blocks)
-                    if (!alreadyResolved.get(toBlock.getLinearScanNumber())) {
-                        Debug.log("processing edge between B%d and B%d", fromBlock.getId(), toBlock.getId());
-
-                        alreadyResolved.set(toBlock.getLinearScanNumber());
-
-                        // collect all intervals that have been split between fromBlock and toBlock
-                        resolveCollectMappings(fromBlock, toBlock, moveResolver);
-                        if (moveResolver.hasMappings()) {
-                            resolveFindInsertPos(fromBlock, toBlock, moveResolver);
-                            moveResolver.resolveAndAppendMoves();
-                        }
-                    }
-                }
-            }
-        }
-        indent.outdent();
     }
 
     // * Phase 7: assign register numbers back to LIR
@@ -1618,7 +1626,7 @@
 
     /**
      * Assigns the allocated location for an LIR instruction operand back into the instruction.
-     * 
+     *
      * @param operand an LIR instruction operand
      * @param opId the id of the LIR instruction using {@code operand}
      * @param mode the usage mode for {@code operand} by the instruction
@@ -1857,57 +1865,57 @@
         /*
          * This is the point to enable debug logging for the whole register allocation.
          */
-        Indent indent = Debug.logAndIndent("LinearScan allocate");
-
-        try (Scope s = Debug.scope("LifetimeAnalysis")) {
-            numberInstructions();
-            printLir("Before register allocation", true);
-            computeLocalLiveSets();
-            computeGlobalLiveSets();
-            buildIntervals();
-            sortIntervalsBeforeAllocation();
-        } catch (Throwable e) {
-            throw Debug.handle(e);
-        }
+        try (Indent indent = Debug.logAndIndent("LinearScan allocate")) {
 
-        try (Scope s = Debug.scope("RegisterAllocation")) {
-            printIntervals("Before register allocation");
-            allocateRegisters();
-        } catch (Throwable e) {
-            throw Debug.handle(e);
-        }
+            try (Scope s = Debug.scope("LifetimeAnalysis")) {
+                numberInstructions();
+                printLir("Before register allocation", true);
+                computeLocalLiveSets();
+                computeGlobalLiveSets();
+                buildIntervals();
+                sortIntervalsBeforeAllocation();
+            } catch (Throwable e) {
+                throw Debug.handle(e);
+            }
 
-        try (Scope s = Debug.scope("ResolveDataFlow")) {
-            resolveDataFlow();
-        } catch (Throwable e) {
-            throw Debug.handle(e);
-        }
+            try (Scope s = Debug.scope("RegisterAllocation")) {
+                printIntervals("Before register allocation");
+                allocateRegisters();
+            } catch (Throwable e) {
+                throw Debug.handle(e);
+            }
 
-        try (Scope s = Debug.scope("DebugInfo")) {
-            frameMap.finish();
-
-            printIntervals("After register allocation");
-            printLir("After register allocation", true);
-
-            sortIntervalsAfterAllocation();
-
-            if (DetailedAsserts.getValue()) {
-                verify();
+            try (Scope s = Debug.scope("ResolveDataFlow")) {
+                resolveDataFlow();
+            } catch (Throwable e) {
+                throw Debug.handle(e);
             }
 
-            eliminateSpillMoves();
-            assignLocations();
+            try (Scope s = Debug.scope("DebugInfo")) {
+                frameMap.finish();
+
+                printIntervals("After register allocation");
+                printLir("After register allocation", true);
+
+                sortIntervalsAfterAllocation();
 
-            if (DetailedAsserts.getValue()) {
-                verifyIntervals();
+                if (DetailedAsserts.getValue()) {
+                    verify();
+                }
+
+                eliminateSpillMoves();
+                assignLocations();
+
+                if (DetailedAsserts.getValue()) {
+                    verifyIntervals();
+                }
+            } catch (Throwable e) {
+                throw Debug.handle(e);
             }
-        } catch (Throwable e) {
-            throw Debug.handle(e);
-        }
 
-        printLir("After register number assignment", true);
+            printLir("After register number assignment", true);
 
-        indent.outdent();
+        }
     }
 
     void printIntervals(String label) {
@@ -2114,7 +2122,7 @@
 
     /**
      * Returns a value for a interval definition, which can be used for re-materialization.
-     * 
+     *
      * @param op An instruction which defines a value
      * @param operand The destination operand of the instruction
      * @param interval The interval for this defined value.
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScanWalker.java	Fri Mar 28 09:47:42 2014 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScanWalker.java	Fri Mar 28 11:41:42 2014 +0100
@@ -450,82 +450,82 @@
         int maxSplitPos = currentPosition;
         int minSplitPos = Math.max(interval.previousUsage(RegisterPriority.ShouldHaveRegister, maxSplitPos) + 1, interval.from());
 
-        Indent indent = Debug.logAndIndent("splitting and spilling interval %s between %d and %d", interval, minSplitPos, maxSplitPos);
+        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";
+            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
 
-        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())) {
 
-            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";
+
+                    allocator.assignSpillSlot(interval);
+                    allocator.changeSpillState(interval, minSplitPos);
 
-                assert interval.firstUsage(RegisterPriority.ShouldHaveRegister) > currentPosition : "interval must not have use position before currentPosition";
-
-                allocator.assignSpillSlot(interval);
-                allocator.changeSpillState(interval, minSplitPos);
+                    // Also kick parent intervals out of register to memory when they have no use
+                    // position. This avoids short interval in register surrounded by intervals in
+                    // memory . avoid useless moves from memory to register and back
+                    Interval parent = interval;
+                    while (parent != null && parent.isSplitChild()) {
+                        parent = parent.getSplitChildBeforeOpId(parent.from());
 
-                // Also kick parent intervals out of register to memory when they have no use
-                // position. This avoids short interval in register surrounded by intervals in
-                // memory . avoid useless moves from memory to register and back
-                Interval parent = interval;
-                while (parent != null && parent.isSplitChild()) {
-                    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
+                                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
+                                // the interval
+                                parent = null;
+                            }
+                        }
+                    }
+                }
+
+            } else {
+                // search optimal split pos, split interval and spill only the right hand part
+                int optimalSplitPos = findOptimalSplitPos(interval, minSplitPos, maxSplitPos, false);
+
+                assert minSplitPos <= optimalSplitPos && optimalSplitPos <= maxSplitPos : "out of range";
+                assert optimalSplitPos < interval.to() : "cannot split at end of interval";
+                assert optimalSplitPos >= interval.from() : "cannot split before start of interval";
 
-                    if (isRegister(parent.location())) {
-                        if (parent.firstUsage(RegisterPriority.ShouldHaveRegister) == Integer.MAX_VALUE) {
-                            // parent is never used, so kick it out of its assigned register
-                            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
-                            // the interval
-                            parent = null;
-                        }
+                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);
+                    allocator.changeSpillState(spilledPart, optimalSplitPos);
+
+                    if (!allocator.isBlockBegin(optimalSplitPos)) {
+                        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));
                     }
                 }
             }
-
-        } else {
-            // search optimal split pos, split interval and spill only the right hand part
-            int optimalSplitPos = findOptimalSplitPos(interval, minSplitPos, maxSplitPos, false);
-
-            assert minSplitPos <= optimalSplitPos && optimalSplitPos <= maxSplitPos : "out of range";
-            assert optimalSplitPos < interval.to() : "cannot split at end of interval";
-            assert optimalSplitPos >= interval.from() : "cannot split before start of interval";
-
-            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);
-                allocator.changeSpillState(spilledPart, optimalSplitPos);
-
-                if (!allocator.isBlockBegin(optimalSplitPos)) {
-                    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));
-                }
-            }
         }
-        indent.outdent();
     }
 
     void splitStackInterval(Interval interval) {
@@ -840,52 +840,52 @@
         Interval interval = currentInterval;
         boolean result = true;
 
-        Indent indent = Debug.logAndIndent("activating interval %s,  splitParent: %d", interval, interval.splitParent().operandNumber);
+        try (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
-            Debug.log("interval has spill slot assigned (method parameter) . split it before first use");
-            splitStackInterval(interval);
-            result = false;
+            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
+                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)
-                Debug.log("normal allocation of register");
+            } else {
+                if (interval.location() == null) {
+                    // interval has not assigned register . normal allocation
+                    // (this is the normal case for most intervals)
+                    Debug.log("normal allocation of register");
 
-                // assign same spill slot to non-intersecting intervals
-                combineSpilledIntervals(interval);
+                    // assign same spill slot to non-intersecting intervals
+                    combineSpilledIntervals(interval);
 
-                initVarsForAlloc(interval);
-                if (noAllocationPossible(interval) || !allocFreeRegister(interval)) {
-                    // no empty register available.
-                    // split and spill another interval so that this interval gets a register
-                    allocLockedRegister(interval);
-                }
+                    initVarsForAlloc(interval);
+                    if (noAllocationPossible(interval) || !allocFreeRegister(interval)) {
+                        // no empty register available.
+                        // split and spill another interval so that this interval gets a register
+                        allocLockedRegister(interval);
+                    }
 
-                // spilled intervals need not be move to active-list
-                if (!isRegister(interval.location())) {
-                    result = false;
+                    // spilled intervals need not be move to active-list
+                    if (!isRegister(interval.location())) {
+                        result = false;
+                    }
                 }
             }
-        }
 
-        // 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";
-            Debug.log("Inserting move from interval %d to %d because insertMoveWhenActivated is set", interval.currentSplitChild().operandNumber, interval.operandNumber);
+            // 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";
+                Debug.log("Inserting move from interval %d to %d because insertMoveWhenActivated is set", interval.currentSplitChild().operandNumber, interval.operandNumber);
 
-            insertMove(interval.from(), interval.currentSplitChild(), interval);
+                insertMove(interval.from(), interval.currentSplitChild(), interval);
+            }
+            interval.makeCurrentSplitChild();
+
         }
-        interval.makeCurrentSplitChild();
-
-        indent.outdent();
 
         return result; // true = interval is moved to active list
     }
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRGenerator.java	Fri Mar 28 09:47:42 2014 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRGenerator.java	Fri Mar 28 11:41:42 2014 +0100
@@ -334,7 +334,7 @@
                                     int start = nodes.indexOf(access);
                                     int end = nodes.indexOf(operation);
                                     for (int i1 = Math.min(start, end); i1 <= Math.max(start, end); i1++) {
-                                        indent.log("%d: (%d) %1s", i1, nodes.get(i1).usages().count(), nodes.get(i1));
+                                        Debug.log("%d: (%d) %1s", i1, nodes.get(i1).usages().count(), nodes.get(i1));
                                     }
                                 }
                                 return 0;
@@ -349,7 +349,7 @@
                                 int start = nodes.indexOf(access);
                                 int end = nodes.indexOf(operation);
                                 for (int i1 = Math.min(start, end); i1 <= Math.max(start, end); i1++) {
-                                    indent.log("%d: (%d) %1s", i1, nodes.get(i1).usages().count(), nodes.get(i1));
+                                    Debug.log("%d: (%d) %1s", i1, nodes.get(i1).usages().count(), nodes.get(i1));
                                 }
                             }
                         }
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java	Fri Mar 28 09:47:42 2014 +0100
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java	Fri Mar 28 11:41:42 2014 +0100
@@ -371,8 +371,8 @@
     }
 
     /**
-     * This override exists the catch cases when log is called with one argument from a method which
-     * is vararg. It will bind to this method instead of the single arg variant and produce a
+     * This override exists to catch cases when log is called with one argument bound to a varargs
+     * method parameter. It will bind to this method instead of the single arg variant and produce a
      * deprecation warning instead of silently wrapping the Object[] inside of another Object[].
      */
     @Deprecated
@@ -396,64 +396,99 @@
         }
     }
 
-    private static final class NoLogger implements Indent {
-
-        @Override
-        public void log(String msg, Object... args) {
-        }
-
-        @Override
-        public Indent indent() {
-            return this;
-        }
-
-        @Override
-        public Indent logAndIndent(String msg, Object... args) {
-            return this;
-        }
-
-        @Override
-        public Indent outdent() {
-            return this;
-        }
-
-        @Override
-        public void close() {
-        }
-    }
-
-    private static final NoLogger noLoggerInstance = new NoLogger();
-
     /**
-     * Creates a new indentation level (by adding some spaces) based on the last used Indent of the
-     * current DebugScope.
+     * Opens a new indentation level (by adding some spaces) based on the current indentation level.
+     * This should be used in a {@linkplain Indent try-with-resources} pattern.
      *
-     * @return The new indentation level
-     * @see Indent#indent
+     * @return an object that reverts to the current indentation level when
+     *         {@linkplain Indent#close() closed} or null if debugging is disabled
+     * @see #logAndIndent(String)
+     * @see #logAndIndent(String, Object)
      */
     public static Indent indent() {
         if (ENABLED) {
             DebugScope scope = DebugScope.getInstance();
             return scope.pushIndentLogger();
         }
-        return noLoggerInstance;
+        return null;
+    }
+
+    /**
+     * A convenience function which combines {@link #log(String)} and {@link #indent()}.
+     *
+     * @param msg the message to log
+     * @return an object that reverts to the current indentation level when
+     *         {@linkplain Indent#close() closed} or null if debugging is disabled
+     */
+    public static Indent logAndIndent(String msg) {
+        if (ENABLED) {
+            return logvAndIndent(msg);
+        }
+        return null;
+    }
+
+    /**
+     * A convenience function which combines {@link #log(String, Object)} and {@link #indent()}.
+     *
+     * @param format a format string
+     * @param arg the argument referenced by the format specifiers in {@code format}
+     * @return an object that reverts to the current indentation level when
+     *         {@linkplain Indent#close() closed} or null if debugging is disabled
+     */
+    public static Indent logAndIndent(String format, Object arg) {
+        if (ENABLED) {
+            return logvAndIndent(format, arg);
+        }
+        return null;
     }
 
     /**
-     * A convenience function which combines {@link #log} and {@link #indent()}.
+     * @see #logAndIndent(String, Object)
+     */
+    public static Indent logAndIndent(String format, Object arg1, Object arg2) {
+        if (ENABLED) {
+            return logvAndIndent(format, arg1, arg2);
+        }
+        return null;
+    }
+
+    /**
+     * @see #logAndIndent(String, Object)
+     */
+    public static Indent logAndIndent(String format, Object arg1, Object arg2, Object arg3) {
+        if (ENABLED) {
+            return logvAndIndent(format, arg1, arg2, arg3);
+        }
+        return null;
+    }
+
+    /**
+     * A convenience function which combines {@link #logv(String, Object...)} and {@link #indent()}.
      *
-     * @param msg The format string of the log message
-     * @param args The arguments referenced by the log message string
-     * @return The new indentation level
-     * @see Indent#logAndIndent
+     * @param format a format string
+     * @param args the arguments referenced by the format specifiers in {@code format}
+     * @return an object that reverts to the current indentation level when
+     *         {@linkplain Indent#close() closed} or null if debugging is disabled
      */
-    public static Indent logAndIndent(String msg, Object... args) {
+    public static Indent logvAndIndent(String format, Object... args) {
         if (ENABLED) {
             DebugScope scope = DebugScope.getInstance();
-            scope.log(msg, args);
+            scope.log(format, args);
             return scope.pushIndentLogger();
         }
-        return noLoggerInstance;
+        throw new InternalError("Use of Debug.logvAndIndent() must be guarded by a test of Debug.isEnabled()");
+    }
+
+    /**
+     * This override exists to catch cases when {@link #logAndIndent(String, Object)} is called with
+     * one argument bound to a varargs method parameter. It will bind to this method instead of the
+     * single arg variant and produce a deprecation warning instead of silently wrapping the
+     * Object[] inside of another Object[].
+     */
+    @Deprecated
+    public static void logAndIndent(String format, Object[] args) {
+        assert false : "shouldn't use this";
+        logvAndIndent(format, args);
     }
 
     public static Iterable<Object> context() {
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Indent.java	Fri Mar 28 09:47:42 2014 +0100
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Indent.java	Fri Mar 28 11:41:42 2014 +0100
@@ -23,80 +23,29 @@
 package com.oracle.graal.debug;
 
 /**
- * Represents an indentation level for logging.
- * <p>
- * Note that calling the logging/indent/outdent methods of this interface updates the last used
- * Indent of the current DebugScope. If no instance of Indent is available (e.g. at the beginning of
- * a method), then the corresponding static methods of the Debug class should be used. They perform
- * logging and indentation based on the last used Indent of the current DebugScope.
+ * Object used to close a debug {@link Debug#indent() indentation} scope.
  * <p>
  * Example usage:
- * 
+ *
  * <pre>
- *      void method() {
- *      
- *          Indent in = Debug.logIndent("header message");
+ *
+ *      try (Indent i1 = Debug.logAndIndent("header message")) {
  *          ...
- *          in.log("message");
- *          ...
- *          Indent in2 = in.logIndent("sub-header message");
- *          ...
- *          {
- *              in2.log("inner message");
- *          }
+ *          Debug.log("message");
  *          ...
- *          in.outdent();
+ *          try (Indent i2 = Debug.logAndIndent(sub-header message")) {
+ *              ...
+ *              Debug.log("inner message");
+ *              ...
+ *          }
  *      }
- * </pre>
- * 
- * Example usage with try-with-resources:
- * 
- * <pre>
- * 
- *      try (Indent in = Debug.logIndent("header message")) {
- *          ...
- *          in.log("message");
- *          ...
- *      }
- * 
+ *
  * </pre>
  */
 public interface Indent extends AutoCloseable {
 
     /**
-     * Prints an indented message to the DebugLevel's logging stream if logging is enabled.
-     * 
-     * @param msg The format string of the log message
-     * @param args The arguments referenced by the log message string
-     * @see Debug#log
-     */
-    void log(String msg, Object... args);
-
-    /**
-     * Creates a new indentation level (by adding some spaces).
-     * 
-     * @return The new indentation level
-     * @see Debug#indent
+     * Closes the current indentation scope.
      */
-    Indent indent();
-
-    /**
-     * A convenience function which combines {@link #log} and {@link #indent}.
-     * 
-     * @param msg The format string of the log message
-     * @param args The arguments referenced by the log message string
-     * @return The new indentation level
-     * @see Debug#logAndIndent
-     */
-    Indent logAndIndent(String msg, Object... args);
-
-    /**
-     * Restores the previous indent level. Calling this method is important to restore the correct
-     * last used Indent in the current DebugScope.
-     * 
-     * @return The indent level from which this Indent was created.
-     */
-    Indent outdent();
-
     void close();
 }
--- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java	Fri Mar 28 09:47:42 2014 +0100
+++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java	Fri Mar 28 11:41:42 2014 +0100
@@ -52,7 +52,6 @@
             }
         }
 
-        @Override
         public void log(String msg, Object... args) {
             if (isLogEnabled()) {
                 printScopeName();
@@ -61,29 +60,16 @@
             }
         }
 
-        @Override
-        public Indent indent() {
+        IndentImpl indent() {
             lastUsedIndent = new IndentImpl(this);
             return lastUsedIndent;
         }
 
         @Override
-        public Indent logAndIndent(String msg, Object... args) {
-            log(msg, args);
-            return indent();
-        }
-
-        @Override
-        public Indent outdent() {
+        public void close() {
             if (parentIndent != null) {
                 lastUsedIndent = parentIndent;
             }
-            return lastUsedIndent;
-        }
-
-        @Override
-        public void close() {
-            outdent();
         }
     }
 
@@ -224,7 +210,7 @@
     /**
      * Creates and enters a new debug scope which is either a child of the current scope or a
      * disjoint top level scope.
-     * 
+     *
      * @param name the name of the new scope
      * @param sandboxConfig the configuration to use for a new top level scope, or null if the new
      *            scope should be a child scope
@@ -387,7 +373,7 @@
     }
 
     public Indent pushIndentLogger() {
-        lastUsedIndent = (IndentImpl) lastUsedIndent.indent();
+        lastUsedIndent = lastUsedIndent.indent();
         return lastUsedIndent;
     }
 }
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Fri Mar 28 09:47:42 2014 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Fri Mar 28 11:41:42 2014 +0100
@@ -224,68 +224,68 @@
                 TTY.println(MetaUtil.indent(MetaUtil.profileToString(profilingInfo, method, CodeUtil.NEW_LINE), "  "));
             }
 
-            Indent indent = Debug.logAndIndent("build graph for %s", method);
+            try (Indent indent = Debug.logAndIndent("build graph for %s", method)) {
 
-            // compute the block map, setup exception handlers and get the entrypoint(s)
-            BciBlockMapping blockMap = BciBlockMapping.create(method);
-            loopHeaders = blockMap.loopHeaders;
-            liveness = blockMap.liveness;
+                // compute the block map, setup exception handlers and get the entrypoint(s)
+                BciBlockMapping blockMap = BciBlockMapping.create(method);
+                loopHeaders = blockMap.loopHeaders;
+                liveness = blockMap.liveness;
 
-            lastInstr = currentGraph.start();
-            if (isSynchronized(method.getModifiers())) {
-                // add a monitor enter to the start block
-                currentGraph.start().setStateAfter(frameState.create(FrameState.BEFORE_BCI));
-                methodSynchronizedObject = synchronizedObject(frameState, method);
-                lastInstr = genMonitorEnter(methodSynchronizedObject);
-            }
-            frameState.clearNonLiveLocals(blockMap.startBlock, liveness, true);
-            ((StateSplit) lastInstr).setStateAfter(frameState.create(0));
-            finishPrepare(lastInstr);
+                lastInstr = currentGraph.start();
+                if (isSynchronized(method.getModifiers())) {
+                    // add a monitor enter to the start block
+                    currentGraph.start().setStateAfter(frameState.create(FrameState.BEFORE_BCI));
+                    methodSynchronizedObject = synchronizedObject(frameState, method);
+                    lastInstr = genMonitorEnter(methodSynchronizedObject);
+                }
+                frameState.clearNonLiveLocals(blockMap.startBlock, liveness, true);
+                ((StateSplit) lastInstr).setStateAfter(frameState.create(0));
+                finishPrepare(lastInstr);
 
-            if (graphBuilderConfig.eagerInfopointMode()) {
-                InfopointNode ipn = currentGraph.add(new InfopointNode(InfopointReason.METHOD_START, frameState.create(0)));
-                lastInstr.setNext(ipn);
-                lastInstr = ipn;
-            }
+                if (graphBuilderConfig.eagerInfopointMode()) {
+                    InfopointNode ipn = currentGraph.add(new InfopointNode(InfopointReason.METHOD_START, frameState.create(0)));
+                    lastInstr.setNext(ipn);
+                    lastInstr = ipn;
+                }
 
-            currentBlock = blockMap.startBlock;
-            blockMap.startBlock.entryState = frameState;
-            if (blockMap.startBlock.isLoopHeader) {
-                /*
-                 * TODO(lstadler,gduboscq) createTarget might not be safe at this position, since it
-                 * expects currentBlock, etc. to be set up correctly. A better solution to this
-                 * problem of start blocks that are loop headers would be to create a dummy block in
-                 * BciBlockMapping.
-                 */
-                appendGoto(createTarget(blockMap.startBlock, frameState));
-            } else {
-                blockMap.startBlock.firstInstruction = lastInstr;
-            }
+                currentBlock = blockMap.startBlock;
+                blockMap.startBlock.entryState = frameState;
+                if (blockMap.startBlock.isLoopHeader) {
+                    /*
+                     * TODO(lstadler,gduboscq) createTarget might not be safe at this position,
+                     * since it expects currentBlock, etc. to be set up correctly. A better solution
+                     * to this problem of start blocks that are loop headers would be to create a
+                     * dummy block in BciBlockMapping.
+                     */
+                    appendGoto(createTarget(blockMap.startBlock, frameState));
+                } else {
+                    blockMap.startBlock.firstInstruction = lastInstr;
+                }
 
-            for (BciBlock block : blockMap.blocks) {
-                processBlock(block);
-            }
-            processBlock(unwindBlock);
+                for (BciBlock block : blockMap.blocks) {
+                    processBlock(block);
+                }
+                processBlock(unwindBlock);
 
-            Debug.dump(currentGraph, "After bytecode parsing");
+                Debug.dump(currentGraph, "After bytecode parsing");
+
+                connectLoopEndToBegin();
 
-            connectLoopEndToBegin();
+                // remove Placeholders
+                for (BlockPlaceholderNode n = placeholders; n != null; n = n.nextPlaceholder()) {
+                    if (!n.isDeleted()) {
+                        currentGraph.removeFixed(n);
+                    }
+                }
+                placeholders = null;
 
-            // remove Placeholders
-            for (BlockPlaceholderNode n = placeholders; n != null; n = n.nextPlaceholder()) {
-                if (!n.isDeleted()) {
-                    currentGraph.removeFixed(n);
+                // remove dead FrameStates
+                for (Node n : currentGraph.getNodes(FrameState.class)) {
+                    if (n.usages().isEmpty() && n.predecessor() == null) {
+                        n.safeDelete();
+                    }
                 }
             }
-            placeholders = null;
-
-            // remove dead FrameStates
-            for (Node n : currentGraph.getNodes(FrameState.class)) {
-                if (n.usages().isEmpty() && n.predecessor() == null) {
-                    n.safeDelete();
-                }
-            }
-            indent.outdent();
         }
 
         /**
@@ -1613,32 +1613,32 @@
                 Debug.log("Ignoring block %s", block);
                 return;
             }
-            Indent indent = Debug.logAndIndent("Parsing block %s  firstInstruction: %s  loopHeader: %b", block, block.firstInstruction, block.isLoopHeader);
+            try (Indent indent = Debug.logAndIndent("Parsing block %s  firstInstruction: %s  loopHeader: %b", block, block.firstInstruction, block.isLoopHeader)) {
+
+                lastInstr = block.firstInstruction;
+                frameState = block.entryState;
+                parseHelper.setCurrentFrameState(frameState);
+                currentBlock = block;
 
-            lastInstr = block.firstInstruction;
-            frameState = block.entryState;
-            parseHelper.setCurrentFrameState(frameState);
-            currentBlock = block;
-
-            frameState.cleanupDeletedPhis();
-            if (lastInstr instanceof MergeNode) {
-                int bci = block.startBci;
-                if (block instanceof ExceptionDispatchBlock) {
-                    bci = ((ExceptionDispatchBlock) block).deoptBci;
+                frameState.cleanupDeletedPhis();
+                if (lastInstr instanceof MergeNode) {
+                    int bci = block.startBci;
+                    if (block instanceof ExceptionDispatchBlock) {
+                        bci = ((ExceptionDispatchBlock) block).deoptBci;
+                    }
+                    ((MergeNode) lastInstr).setStateAfter(frameState.create(bci));
                 }
-                ((MergeNode) lastInstr).setStateAfter(frameState.create(bci));
+
+                if (block == unwindBlock) {
+                    frameState.setRethrowException(false);
+                    createUnwind();
+                } else if (block instanceof ExceptionDispatchBlock) {
+                    createExceptionDispatch((ExceptionDispatchBlock) block);
+                } else {
+                    frameState.setRethrowException(false);
+                    iterateBytecodesForBlock(block);
+                }
             }
-
-            if (block == unwindBlock) {
-                frameState.setRethrowException(false);
-                createUnwind();
-            } else if (block instanceof ExceptionDispatchBlock) {
-                createExceptionDispatch((ExceptionDispatchBlock) block);
-            } else {
-                frameState.setRethrowException(false);
-                iterateBytecodesForBlock(block);
-            }
-            indent.outdent();
         }
 
         private void connectLoopEndToBegin() {
--- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/RedundantMoveElimination.java	Fri Mar 28 09:47:42 2014 +0100
+++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/RedundantMoveElimination.java	Fri Mar 28 11:41:42 2014 +0100
@@ -50,7 +50,7 @@
      * instruction. Note that because instructions can have multiple outputs it is not possible to
      * use the instruction id for value numbering. In addition, the result of merging at block
      * entries (= phi values) get unique value numbers.
-     * 
+     *
      * The value numbers also contain information if it is an object kind value or not: if the
      * number is negative it is an object kind value.
      */
@@ -176,100 +176,101 @@
 
     /**
      * Calculates the entry and exit states for all basic blocks.
-     * 
+     *
      * @return Returns true on success and false if the the control flow is too complex.
      */
     private boolean solveDataFlow(LIR lir) {
 
-        Indent indent = Debug.logAndIndent("solve data flow");
+        try (Indent indent = Debug.logAndIndent("solve data flow")) {
 
-        List<? extends AbstractBlock<?>> blocks = lir.linearScanOrder();
+            List<? extends AbstractBlock<?>> blocks = lir.linearScanOrder();
 
-        int numIter = 0;
+            int numIter = 0;
 
-        /*
-         * Iterate until there are no more changes.
-         */
-        int currentValueNum = 1;
-        boolean firstRound = true;
-        boolean changed;
-        do {
-            changed = false;
-            Indent indent2 = indent.logAndIndent("new iteration");
+            /*
+             * Iterate until there are no more changes.
+             */
+            int currentValueNum = 1;
+            boolean firstRound = true;
+            boolean changed;
+            do {
+                changed = false;
+                try (Indent indent2 = Debug.logAndIndent("new iteration")) {
+
+                    for (AbstractBlock<?> block : blocks) {
 
-            for (AbstractBlock<?> block : blocks) {
+                        BlockData data = blockData.get(block);
+                        /*
+                         * Initialize the number for global value numbering for this block. It is
+                         * essential that the starting number for a block is consistent at all
+                         * iterations and also in eliminateMoves().
+                         */
+                        if (firstRound) {
+                            data.entryValueNum = currentValueNum;
+                        }
+                        int valueNum = data.entryValueNum;
+                        assert valueNum > 0;
+                        boolean newState = false;
 
-                BlockData data = blockData.get(block);
-                /*
-                 * Initialize the number for global value numbering for this block. It is essential
-                 * that the starting number for a block is consistent at all iterations and also in
-                 * eliminateMoves().
-                 */
-                if (firstRound) {
-                    data.entryValueNum = currentValueNum;
-                }
-                int valueNum = data.entryValueNum;
-                assert valueNum > 0;
-                boolean newState = false;
+                        if (block == blocks.get(0) || block.isExceptionEntry()) {
+                            /*
+                             * The entry block has undefined values. And also exception handler
+                             * blocks: the LinearScan can insert moves at the end of an exception
+                             * handler predecessor block (after the invoke, which throws the
+                             * exception), and in reality such moves are not in the control flow in
+                             * case of an exception. So we assume a save default for exception
+                             * handler blocks.
+                             */
+                            Debug.log("kill all values at entry of block %d", block.getId());
+                            clearValues(data.entryState, valueNum);
+                        } else {
+                            /*
+                             * Merge the states of predecessor blocks
+                             */
+                            for (AbstractBlock<?> predecessor : block.getPredecessors()) {
+                                BlockData predData = blockData.get(predecessor);
+                                newState |= mergeState(data.entryState, predData.exitState, valueNum);
+                            }
+                        }
+                        // Advance by the value numbers which are "consumed" by
+                        // clearValues and mergeState
+                        valueNum += data.entryState.length;
 
-                if (block == blocks.get(0) || block.isExceptionEntry()) {
+                        if (newState || firstRound) {
+                            try (Indent indent3 = Debug.logAndIndent("update block %d", block.getId())) {
+
+                                /*
+                                 * Derive the exit state from the entry state by iterating through
+                                 * all instructions of the block.
+                                 */
+                                int[] iterState = data.exitState;
+                                copyState(iterState, data.entryState);
+                                List<LIRInstruction> instructions = lir.getLIRforBlock(block);
+
+                                for (LIRInstruction op : instructions) {
+                                    valueNum = updateState(iterState, op, valueNum);
+                                }
+                                changed = true;
+                            }
+                        }
+                        if (firstRound) {
+                            currentValueNum = valueNum;
+                        }
+                    }
+                    firstRound = false;
+                }
+                numIter++;
+
+                if (numIter > 5) {
                     /*
-                     * The entry block has undefined values. And also exception handler blocks: the
-                     * LinearScan can insert moves at the end of an exception handler predecessor
-                     * block (after the invoke, which throws the exception), and in reality such
-                     * moves are not in the control flow in case of an exception. So we assume a
-                     * save default for exception handler blocks.
-                     */
-                    indent2.log("kill all values at entry of block %d", block.getId());
-                    clearValues(data.entryState, valueNum);
-                } else {
-                    /*
-                     * Merge the states of predecessor blocks
+                     * This is _very_ seldom.
                      */
-                    for (AbstractBlock<?> predecessor : block.getPredecessors()) {
-                        BlockData predData = blockData.get(predecessor);
-                        newState |= mergeState(data.entryState, predData.exitState, valueNum);
-                    }
+                    return false;
                 }
-                // Advance by the value numbers which are "consumed" by clearValues and mergeState
-                valueNum += data.entryState.length;
-
-                if (newState || firstRound) {
-
-                    Indent indent3 = indent2.logAndIndent("update block %d", block.getId());
-
-                    /*
-                     * Derive the exit state from the entry state by iterating through all
-                     * instructions of the block.
-                     */
-                    int[] iterState = data.exitState;
-                    copyState(iterState, data.entryState);
-                    List<LIRInstruction> instructions = lir.getLIRforBlock(block);
 
-                    for (LIRInstruction op : instructions) {
-                        valueNum = updateState(iterState, op, valueNum);
-                    }
-                    changed = true;
-                    indent3.outdent();
-                }
-                if (firstRound) {
-                    currentValueNum = valueNum;
-                }
-            }
-            firstRound = false;
-            indent2.outdent();
-            numIter++;
+            } while (changed);
 
-            if (numIter > 5) {
-                /*
-                 * This is _very_ seldom.
-                 */
-                return false;
-            }
-
-        } while (changed);
-
-        indent.outdent();
+        }
 
         return true;
     }
@@ -279,47 +280,48 @@
      */
     private void eliminateMoves(LIR lir) {
 
-        Indent indent = Debug.logAndIndent("eliminate moves");
+        try (Indent indent = Debug.logAndIndent("eliminate moves")) {
+
+            List<? extends AbstractBlock<?>> blocks = lir.linearScanOrder();
 
-        List<? extends AbstractBlock<?>> blocks = lir.linearScanOrder();
+            for (AbstractBlock<?> block : blocks) {
 
-        for (AbstractBlock<?> block : blocks) {
+                try (Indent indent2 = Debug.logAndIndent("eliminate moves in block %d", block.getId())) {
 
-            Indent indent2 = indent.logAndIndent("eliminate moves in block %d", block.getId());
+                    List<LIRInstruction> instructions = lir.getLIRforBlock(block);
+                    BlockData data = blockData.get(block);
+                    boolean hasDead = false;
 
-            List<LIRInstruction> instructions = lir.getLIRforBlock(block);
-            BlockData data = blockData.get(block);
-            boolean hasDead = false;
+                    // Reuse the entry state for iteration, we don't need it later.
+                    int[] iterState = data.entryState;
 
-            // Reuse the entry state for iteration, we don't need it later.
-            int[] iterState = data.entryState;
+                    // Add the values which are "consumed" by clearValues and
+                    // mergeState in solveDataFlow
+                    int valueNum = data.entryValueNum + data.entryState.length;
 
-            // Add the values which are "consumed" by clearValues and mergeState in solveDataFlow
-            int valueNum = data.entryValueNum + data.entryState.length;
-
-            int numInsts = instructions.size();
-            for (int idx = 0; idx < numInsts; idx++) {
-                LIRInstruction op = instructions.get(idx);
-                if (isEligibleMove(op)) {
-                    MoveOp moveOp = (MoveOp) op;
-                    int sourceIdx = getStateIdx(moveOp.getInput());
-                    int destIdx = getStateIdx(moveOp.getResult());
-                    if (sourceIdx >= 0 && destIdx >= 0 && iterState[sourceIdx] == iterState[destIdx]) {
-                        assert iterState[sourceIdx] != INIT_VALUE;
-                        indent2.log("delete move %s", op);
-                        instructions.set(idx, null);
-                        hasDead = true;
+                    int numInsts = instructions.size();
+                    for (int idx = 0; idx < numInsts; idx++) {
+                        LIRInstruction op = instructions.get(idx);
+                        if (isEligibleMove(op)) {
+                            MoveOp moveOp = (MoveOp) op;
+                            int sourceIdx = getStateIdx(moveOp.getInput());
+                            int destIdx = getStateIdx(moveOp.getResult());
+                            if (sourceIdx >= 0 && destIdx >= 0 && iterState[sourceIdx] == iterState[destIdx]) {
+                                assert iterState[sourceIdx] != INIT_VALUE;
+                                Debug.log("delete move %s", op);
+                                instructions.set(idx, null);
+                                hasDead = true;
+                            }
+                        }
+                        // It doesn't harm if updateState is also called for a deleted move
+                        valueNum = updateState(iterState, op, valueNum);
+                    }
+                    if (hasDead) {
+                        instructions.removeAll(Collections.singleton(null));
                     }
                 }
-                // It doesn't harm if updateState is also called for a deleted move
-                valueNum = updateState(iterState, op, valueNum);
             }
-            if (hasDead) {
-                instructions.removeAll(Collections.singleton(null));
-            }
-            indent2.outdent();
         }
-        indent.outdent();
     }
 
     /**
@@ -338,7 +340,7 @@
                 if (sourceIdx >= 0 && destIdx >= 0) {
                     assert isObjectValue(state[sourceIdx]) || (moveOp.getInput().getKind() != Kind.Object) : "move op moves object but input is not defined as object";
                     state[destIdx] = state[sourceIdx];
-                    indent.log("move value %d from %d to %d", state[sourceIdx], sourceIdx, destIdx);
+                    Debug.log("move value %d from %d to %d", state[sourceIdx], sourceIdx, destIdx);
                     return initValueNum;
                 }
             }
@@ -346,7 +348,7 @@
             int valueNum = initValueNum;
 
             if (op.destroysCallerSavedRegisters()) {
-                indent.log("kill all caller save regs");
+                Debug.log("kill all caller save regs");
 
                 for (Register reg : callerSaveRegs) {
                     if (reg.number < numRegs) {
@@ -375,7 +377,7 @@
                          * Assign a unique number to the output or temp location.
                          */
                         state[stateIdx] = encodeValueNum(opValueNum++, operand.getKind() == Kind.Object);
-                        indent.log("set def %d for register %s(%d): %d", opValueNum, operand, stateIdx, state[stateIdx]);
+                        Debug.log("set def %d for register %s(%d): %d", opValueNum, operand, stateIdx, state[stateIdx]);
                     }
                     return operand;
                 }
@@ -395,12 +397,11 @@
                 /*
                  * All instructions with framestates (mostly method calls), may do garbage
                  * collection. GC will rewrite all object references which are live at this point.
-                 * So we can't rely on their values.
-                 * 
-                 * It would be sufficient to just kill all values which are referenced in the state
-                 * (or all values which are not), but for simplicity we kill all values.
+                 * So we can't rely on their values. It would be sufficient to just kill all values
+                 * which are referenced in the state (or all values which are not), but for
+                 * simplicity we kill all values.
                  */
-                indent.log("kill all object values");
+                Debug.log("kill all object values");
                 clearValuesOfKindObject(state, valueNum);
                 valueNum += state.length;
             }