changeset 12683:5c5b02a165d4

moved a number of options to be declared closer to usage and cached some heavily accessed options in fields
author Doug Simon <doug.simon@oracle.com>
date Tue, 05 Nov 2013 19:03:37 +0100
parents 5dbfb4d5eaba
children ec224fef3012
files graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/IntervalWalker.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/alloc/MoveResolver.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/RegisterVerifier.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java
diffstat 8 files changed, 143 insertions(+), 117 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/IntervalWalker.java	Tue Nov 05 19:02:50 2013 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/IntervalWalker.java	Tue Nov 05 19:03:37 2013 +0100
@@ -22,8 +22,6 @@
  */
 package com.oracle.graal.compiler.alloc;
 
-import static com.oracle.graal.phases.GraalOptions.*;
-
 import com.oracle.graal.compiler.alloc.Interval.RegisterBinding;
 import com.oracle.graal.compiler.alloc.Interval.RegisterBindingLists;
 import com.oracle.graal.compiler.alloc.Interval.State;
@@ -203,13 +201,17 @@
         currentInterval.rewindRange();
     }
 
+    int getTraceLevel() {
+        return allocator.getTraceLevel();
+    }
+
     void walkTo(int toOpId) {
         assert currentPosition <= toOpId : "can not walk backwards";
         while (currentInterval != null) {
             boolean isActive = currentInterval.from() <= toOpId;
             int opId = isActive ? currentInterval.from() : toOpId;
 
-            if (TraceLinearScanLevel.getValue() >= 2 && !TTY.isSuppressed()) {
+            if (getTraceLevel() >= 2 && !TTY.isSuppressed()) {
                 if (currentPosition < opId) {
                     TTY.println();
                     TTY.println("walkTo(%d) *", opId);
@@ -240,7 +242,7 @@
     private void intervalMoved(Interval interval, State from, State to) {
         // intervalMoved() is called whenever an interval moves from one interval list to another.
         // In the implementation of this method it is prohibited to move the interval to any list.
-        if (TraceLinearScanLevel.getValue() >= 4 && !TTY.isSuppressed()) {
+        if (getTraceLevel() >= 4 && !TTY.isSuppressed()) {
             TTY.print(from.toString() + " to " + to.toString());
             TTY.fillTo(23);
             TTY.out().println(interval.logString(allocator));
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java	Tue Nov 05 19:02:50 2013 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java	Tue Nov 05 19:03:37 2013 +0100
@@ -26,7 +26,6 @@
 import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.compiler.GraalDebugConfig.*;
 import static com.oracle.graal.lir.LIRValueUtil.*;
-import static com.oracle.graal.phases.GraalOptions.*;
 
 import java.util.*;
 
@@ -46,6 +45,7 @@
 import com.oracle.graal.lir.LIRInstruction.ValueProcedure;
 import com.oracle.graal.lir.StandardOp.MoveOp;
 import com.oracle.graal.nodes.cfg.*;
+import com.oracle.graal.options.*;
 import com.oracle.graal.phases.util.*;
 
 /**
@@ -56,6 +56,13 @@
  */
 public final class LinearScan {
 
+    static class Options {
+        // @formatter:off
+        @Option(help = "The trace level for the linear scan register allocator")
+        public static final OptionValue<Integer> TraceLinearScanLevel = new OptionValue<>(0);
+        // @formatter:on
+    }
+
     final TargetDescription target;
     final LIR ir;
     final LIRGenerator gen;
@@ -158,6 +165,8 @@
      */
     private final int firstVariableNumber;
 
+    private final int traceLevel;
+
     public LinearScan(TargetDescription target, LIR ir, LIRGenerator gen, FrameMap frameMap) {
         this.target = target;
         this.ir = ir;
@@ -170,6 +179,11 @@
         this.firstVariableNumber = registers.length;
         this.variables = new ArrayList<>(ir.numVariables() * 3 / 2);
         this.blockData = new BlockMap<>(ir.cfg);
+        traceLevel = Options.TraceLinearScanLevel.getValue();
+    }
+
+    int getTraceLevel() {
+        return traceLevel;
     }
 
     public int getFirstLirInstructionId(Block block) {
@@ -504,7 +518,7 @@
 
     // called once before assignment of register numbers
     void eliminateSpillMoves() {
-        if (TraceLinearScanLevel.getValue() >= 3) {
+        if (getTraceLevel() >= 3) {
             TTY.println(" Eliminating unnecessary spill moves");
         }
 
@@ -513,7 +527,7 @@
         Interval interval;
         interval = createUnhandledLists(mustStoreAtDefinition, null).first;
         if (DetailedAsserts.getValue()) {
-            checkIntervals(interval);
+            checkIntervals(interval, getTraceLevel());
         }
 
         LIRInsertionBuffer insertionBuffer = new LIRInsertionBuffer();
@@ -538,7 +552,7 @@
                     if (!isRegister(curInterval.location()) && curInterval.alwaysInMemory()) {
                         // move target is a stack slot that is always correct, so eliminate
                         // instruction
-                        if (TraceLinearScanLevel.getValue() >= 4) {
+                        if (getTraceLevel() >= 4) {
                             TTY.println("eliminating move from interval %d to %d", operandNumber(move.getInput()), operandNumber(move.getResult()));
                         }
                         instructions.set(j, null); // null-instructions are deleted by assignRegNum
@@ -564,7 +578,7 @@
 
                         insertionBuffer.append(j + 1, ir.spillMoveFactory.createMove(toLocation, fromLocation));
 
-                        if (TraceLinearScanLevel.getValue() >= 4) {
+                        if (getTraceLevel() >= 4) {
                             StackSlot slot = interval.spillSlot();
                             TTY.println("inserting move after definition of interval %d to stack slot %s at opId %d", interval.operandNumber, slot, opId);
                         }
@@ -582,7 +596,7 @@
         assert interval == Interval.EndMarker : "missed an interval";
     }
 
-    private static void checkIntervals(Interval interval) {
+    private static void checkIntervals(Interval interval, int traceLevel) {
         Interval prev = null;
         Interval temp = interval;
         while (temp != Interval.EndMarker) {
@@ -596,7 +610,7 @@
             assert temp.spillDefinitionPos() >= temp.from() : "invalid order";
             assert temp.spillDefinitionPos() <= temp.from() + 2 : "only intervals defined once at their start-pos can be optimized";
 
-            if (TraceLinearScanLevel.getValue() >= 4) {
+            if (traceLevel >= 4) {
                 TTY.println("interval %d (from %d to %d) must be stored at %d", temp.operandNumber, temp.from(), temp.to(), temp.spillDefinitionPos());
             }
 
@@ -698,7 +712,7 @@
                             int operandNum = operandNumber(operand);
                             if (!liveKill.get(operandNum)) {
                                 liveGen.set(operandNum);
-                                if (TraceLinearScanLevel.getValue() >= 4) {
+                                if (getTraceLevel() >= 4) {
                                     TTY.println("  Setting liveGen for operand %d at instruction %d", operandNum, op.id());
                                 }
                             }
@@ -720,7 +734,7 @@
                         int operandNum = operandNumber(operand);
                         if (!liveKill.get(operandNum)) {
                             liveGen.set(operandNum);
-                            if (TraceLinearScanLevel.getValue() >= 4) {
+                            if (getTraceLevel() >= 4) {
                                 TTY.println("  Setting liveGen for LIR opId %d, operand %d because of state for %s", op.id(), operandNum, op);
                             }
                         }
@@ -763,7 +777,7 @@
             blockData.get(block).liveIn = new BitSet(liveSize);
             blockData.get(block).liveOut = new BitSet(liveSize);
 
-            if (TraceLinearScanLevel.getValue() >= 4) {
+            if (getTraceLevel() >= 4) {
                 TTY.println("liveGen  B%d %s", block.getId(), blockData.get(block).liveGen);
                 TTY.println("liveKill B%d %s", block.getId(), blockData.get(block).liveKill);
             }
@@ -852,7 +866,7 @@
                     liveIn.or(blockData.get(block).liveGen);
                 }
 
-                if (TraceLinearScanLevel.getValue() >= 4) {
+                if (getTraceLevel() >= 4) {
                     traceLiveness(changeOccurredInBlock, iterationCount, block);
                 }
             }
@@ -974,7 +988,7 @@
         if (!isProcessed(operand)) {
             return;
         }
-        if (TraceLinearScanLevel.getValue() >= 2 && kind == null) {
+        if (getTraceLevel() >= 2 && kind == null) {
             TTY.println(" use %s from %d to %d (%s)", operand, from, to, registerPriority.name());
         }
 
@@ -993,7 +1007,7 @@
         if (!isProcessed(operand)) {
             return;
         }
-        if (TraceLinearScanLevel.getValue() >= 2) {
+        if (getTraceLevel() >= 2) {
             TTY.println(" temp %s tempPos %d (%s)", operand, tempPos, RegisterPriority.MustHaveRegister.name());
         }
 
@@ -1014,7 +1028,7 @@
         if (!isProcessed(operand)) {
             return;
         }
-        if (TraceLinearScanLevel.getValue() >= 2) {
+        if (getTraceLevel() >= 2) {
             TTY.println(" def %s defPos %d (%s)", operand, defPos, registerPriority.name());
         }
 
@@ -1035,7 +1049,7 @@
             // also add register priority for dead intervals
             interval.addRange(defPos, defPos + 1);
             interval.addUsePos(defPos, registerPriority);
-            if (TraceLinearScanLevel.getValue() >= 2) {
+            if (getTraceLevel() >= 2) {
                 TTY.println("Warning: def of operand %s at %d occurs without use", operand, defPos);
             }
         }
@@ -1096,7 +1110,7 @@
                     assert blockForId(op.id()).getPredecessorCount() == 0 : "move from stack must be in first block";
                     assert isVariable(move.getResult()) : "result of move must be a variable";
 
-                    if (TraceLinearScanLevel.getValue() >= 4) {
+                    if (getTraceLevel() >= 4) {
                         TTY.println("found move from stack slot %s to %s", slot, move.getResult());
                     }
                 }
@@ -1126,7 +1140,7 @@
                             from.setLocationHint(to);
                         }
 
-                        if (TraceLinearScanLevel.getValue() >= 4) {
+                        if (getTraceLevel() >= 4) {
                             TTY.println("operation at opId %d: added hint from interval %d to %d", op.id(), from.operandNumber, to.operandNumber);
                         }
                         return registerHint;
@@ -1159,7 +1173,7 @@
             for (int operandNum = live.nextSetBit(0); operandNum >= 0; operandNum = live.nextSetBit(operandNum + 1)) {
                 assert live.get(operandNum) : "should not stop here otherwise";
                 AllocatableValue operand = operandFor(operandNum);
-                if (TraceLinearScanLevel.getValue() >= 2) {
+                if (getTraceLevel() >= 2) {
                     TTY.println("live in %s to %d", operand, blockTo + 2);
                 }
 
@@ -1187,7 +1201,7 @@
                             addTemp(r.asValue(), opId, RegisterPriority.None, Kind.Illegal);
                         }
                     }
-                    if (TraceLinearScanLevel.getValue() >= 4) {
+                    if (getTraceLevel() >= 4) {
                         TTY.println("operation destroys all caller-save registers");
                     }
                 }
@@ -1438,7 +1452,7 @@
         Interval result = interval.getSplitChildAtOpId(opId, mode, this);
 
         if (result != null) {
-            if (TraceLinearScanLevel.getValue() >= 4) {
+            if (getTraceLevel() >= 4) {
                 TTY.println("Split child at pos " + opId + " of interval " + interval.toString() + " is " + result.toString());
             }
             return result;
@@ -1492,7 +1506,7 @@
 
     void resolveFindInsertPos(Block fromBlock, Block toBlock, MoveResolver moveResolver) {
         if (fromBlock.getSuccessorCount() <= 1) {
-            if (TraceLinearScanLevel.getValue() >= 4) {
+            if (getTraceLevel() >= 4) {
                 TTY.println("inserting moves at end of fromBlock B%d", fromBlock.getId());
             }
 
@@ -1506,7 +1520,7 @@
             }
 
         } else {
-            if (TraceLinearScanLevel.getValue() >= 4) {
+            if (getTraceLevel() >= 4) {
                 TTY.println("inserting moves at beginning of toBlock B%d", toBlock.getId());
             }
 
@@ -1551,7 +1565,7 @@
 
                     // prevent optimization of two consecutive blocks
                     if (!blockCompleted.get(pred.getLinearScanNumber()) && !blockCompleted.get(sux.getLinearScanNumber())) {
-                        if (TraceLinearScanLevel.getValue() >= 3) {
+                        if (getTraceLevel() >= 3) {
                             TTY.println(" optimizing empty block B%d (pred: B%d, sux: B%d)", block.getId(), pred.getId(), sux.getId());
                         }
                         blockCompleted.set(block.getLinearScanNumber());
@@ -1578,7 +1592,7 @@
                     // check for duplicate edges between the same blocks (can happen with switch
                     // blocks)
                     if (!alreadyResolved.get(toBlock.getLinearScanNumber())) {
-                        if (TraceLinearScanLevel.getValue() >= 3) {
+                        if (getTraceLevel() >= 3) {
                             TTY.println(" processing edge between B%d and B%d", fromBlock.getId(), toBlock.getId());
                         }
                         alreadyResolved.set(toBlock.getLinearScanNumber());
@@ -1657,7 +1671,7 @@
     }
 
     void computeOopMap(IntervalWalker iw, LIRInstruction op, BitSet registerRefMap, BitSet frameRefMap) {
-        if (TraceLinearScanLevel.getValue() >= 3) {
+        if (getTraceLevel() >= 3) {
             TTY.println("creating oop map at opId %d", op.id());
         }
 
@@ -1866,7 +1880,7 @@
     }
 
     void printIntervals(String label) {
-        if (TraceLinearScanLevel.getValue() >= 1) {
+        if (getTraceLevel() >= 1) {
             int i;
             TTY.println();
             TTY.println(label);
@@ -1896,27 +1910,27 @@
 
     boolean verify() {
         // (check that all intervals have a correct register and that no registers are overwritten)
-        if (TraceLinearScanLevel.getValue() >= 2) {
+        if (getTraceLevel() >= 2) {
             TTY.println(" verifying intervals *");
         }
         verifyIntervals();
 
-        if (TraceLinearScanLevel.getValue() >= 2) {
+        if (getTraceLevel() >= 2) {
             TTY.println(" verifying that no oops are in fixed intervals *");
         }
         // verifyNoOopsInFixedIntervals();
 
-        if (TraceLinearScanLevel.getValue() >= 2) {
+        if (getTraceLevel() >= 2) {
             TTY.println(" verifying that unpinned constants are not alive across block boundaries");
         }
         verifyConstants();
 
-        if (TraceLinearScanLevel.getValue() >= 2) {
+        if (getTraceLevel() >= 2) {
             TTY.println(" verifying register allocation *");
         }
         verifyRegisters();
 
-        if (TraceLinearScanLevel.getValue() >= 2) {
+        if (getTraceLevel() >= 2) {
             TTY.println(" no errors found *");
         }
 
@@ -2068,7 +2082,7 @@
 
             // visit all operands where the liveAtEdge bit is set
             for (int operandNum = liveAtEdge.nextSetBit(0); operandNum >= 0; operandNum = liveAtEdge.nextSetBit(operandNum + 1)) {
-                if (TraceLinearScanLevel.getValue() >= 4) {
+                if (getTraceLevel() >= 4) {
                     TTY.println("checking interval %d of block B%d", operandNum, block.getId());
                 }
                 Value operand = operandFor(operandNum);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScanWalker.java	Tue Nov 05 19:02:50 2013 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScanWalker.java	Tue Nov 05 19:03:37 2013 +0100
@@ -25,8 +25,6 @@
 import static com.oracle.graal.api.code.CodeUtil.*;
 import static com.oracle.graal.api.code.ValueUtil.*;
 import static com.oracle.graal.lir.LIRValueUtil.*;
-import static com.oracle.graal.phases.GraalOptions.*;
-
 import java.util.*;
 
 import com.oracle.graal.api.code.*;
@@ -295,7 +293,7 @@
         int optimalSplitPos = -1;
         if (minSplitPos == maxSplitPos) {
             // trivial case, no optimization of split position possible
-            if (TraceLinearScanLevel.getValue() >= 4) {
+            if (getTraceLevel() >= 4) {
                 TTY.println("      min-pos and max-pos are equal, no optimization possible");
             }
             optimalSplitPos = minSplitPos;
@@ -319,7 +317,7 @@
             assert minBlock.getLinearScanNumber() <= maxBlock.getLinearScanNumber() : "invalid order";
             if (minBlock == maxBlock) {
                 // split position cannot be moved to block boundary : so split as late as possible
-                if (TraceLinearScanLevel.getValue() >= 4) {
+                if (getTraceLevel() >= 4) {
                     TTY.println("      cannot move split pos to block boundary because minPos and maxPos are in same block");
                 }
                 optimalSplitPos = maxSplitPos;
@@ -331,14 +329,14 @@
                     // as mustHaveRegister) with a hole before each definition. When the register is
                     // needed
                     // for the second definition : an earlier reloading is unnecessary.
-                    if (TraceLinearScanLevel.getValue() >= 4) {
+                    if (getTraceLevel() >= 4) {
                         TTY.println("      interval has hole just before maxSplitPos, so splitting at maxSplitPos");
                     }
                     optimalSplitPos = maxSplitPos;
 
                 } else {
                     // seach optimal block boundary between minSplitPos and maxSplitPos
-                    if (TraceLinearScanLevel.getValue() >= 4) {
+                    if (getTraceLevel() >= 4) {
                         TTY.println("      moving split pos to optimal block boundary between block B%d and B%d", minBlock.getId(), maxBlock.getId());
                     }
 
@@ -347,7 +345,7 @@
                         // max-position :
                         // then split before this loop
                         int loopEndPos = interval.nextUsageExact(RegisterPriority.LiveAtLoopEnd, allocator.getLastLirInstructionId(minBlock) + 2);
-                        if (TraceLinearScanLevel.getValue() >= 4) {
+                        if (getTraceLevel() >= 4) {
                             TTY.println("      loop optimization: loop end found at pos %d", loopEndPos);
                         }
 
@@ -362,7 +360,7 @@
                             // of the interval (normally, only mustHaveRegister causes a reloading)
                             Block loopBlock = allocator.blockForId(loopEndPos);
 
-                            if (TraceLinearScanLevel.getValue() >= 4) {
+                            if (getTraceLevel() >= 4) {
                                 TTY.println("      interval is used in loop that ends in block B%d, so trying to move maxBlock back from B%d to B%d", loopBlock.getId(), maxBlock.getId(),
                                                 loopBlock.getId());
                             }
@@ -371,11 +369,11 @@
                             optimalSplitPos = findOptimalSplitPos(minBlock, loopBlock, allocator.getLastLirInstructionId(loopBlock) + 2);
                             if (optimalSplitPos == allocator.getLastLirInstructionId(loopBlock) + 2) {
                                 optimalSplitPos = -1;
-                                if (TraceLinearScanLevel.getValue() >= 4) {
+                                if (getTraceLevel() >= 4) {
                                     TTY.println("      loop optimization not necessary");
                                 }
                             } else {
-                                if (TraceLinearScanLevel.getValue() >= 4) {
+                                if (getTraceLevel() >= 4) {
                                     TTY.println("      loop optimization successful");
                                 }
                             }
@@ -389,7 +387,7 @@
                 }
             }
         }
-        if (TraceLinearScanLevel.getValue() >= 4) {
+        if (getTraceLevel() >= 4) {
             TTY.println("      optimal split position: %d", optimalSplitPos);
         }
 
@@ -401,13 +399,13 @@
     // 1) the left part has already a location assigned
     // 2) the right part is sorted into to the unhandled-list
     void splitBeforeUsage(Interval interval, int minSplitPos, int maxSplitPos) {
-        if (TraceLinearScanLevel.getValue() >= 2) {
+        if (getTraceLevel() >= 2) {
             TTY.println("----- splitting interval: ");
         }
-        if (TraceLinearScanLevel.getValue() >= 4) {
+        if (getTraceLevel() >= 4) {
             TTY.println(interval.logString(allocator));
         }
-        if (TraceLinearScanLevel.getValue() >= 2) {
+        if (getTraceLevel() >= 2) {
             TTY.println("      between %d and %d", minSplitPos, maxSplitPos);
         }
 
@@ -425,7 +423,7 @@
         if (optimalSplitPos == interval.to() && interval.nextUsage(RegisterPriority.MustHaveRegister, minSplitPos) == Integer.MAX_VALUE) {
             // the split position would be just before the end of the interval
             // . no split at all necessary
-            if (TraceLinearScanLevel.getValue() >= 4) {
+            if (getTraceLevel() >= 4) {
                 TTY.println("      no split necessary because optimal split position is at end of interval");
             }
             return;
@@ -440,7 +438,7 @@
             optimalSplitPos = (optimalSplitPos - 1) | 1;
         }
 
-        if (TraceLinearScanLevel.getValue() >= 4) {
+        if (getTraceLevel() >= 4) {
             TTY.println("      splitting at position %d", optimalSplitPos);
         }
         assert allocator.isBlockBegin(optimalSplitPos) || (optimalSplitPos % 2 == 1) : "split pos must be odd when not on block boundary";
@@ -453,10 +451,10 @@
         assert splitPart.from() >= currentInterval.currentFrom() : "cannot append new interval before current walk position";
         unhandledLists.addToListSortedByStartAndUsePositions(RegisterBinding.Any, splitPart);
 
-        if (TraceLinearScanLevel.getValue() >= 2) {
+        if (getTraceLevel() >= 2) {
             TTY.println("      split interval in two parts (insertMoveWhenActivated: %b)", moveNecessary);
         }
-        if (TraceLinearScanLevel.getValue() >= 2) {
+        if (getTraceLevel() >= 2) {
             TTY.print("      ");
             TTY.println(interval.logString(allocator));
             TTY.print("      ");
@@ -474,7 +472,7 @@
         int maxSplitPos = currentPosition;
         int minSplitPos = Math.max(interval.previousUsage(RegisterPriority.ShouldHaveRegister, maxSplitPos) + 1, interval.from());
 
-        if (TraceLinearScanLevel.getValue() >= 2) {
+        if (getTraceLevel() >= 2) {
             TTY.print("----- splitting and spilling interval: ");
             TTY.println(interval.logString(allocator));
             TTY.println("      between %d and %d", minSplitPos, maxSplitPos);
@@ -488,7 +486,7 @@
 
         if (minSplitPos == interval.from()) {
             // the whole interval is never used, so spill it entirely to memory
-            if (TraceLinearScanLevel.getValue() >= 2) {
+            if (getTraceLevel() >= 2) {
                 TTY.println("      spilling entire interval because split pos is at beginning of interval");
                 TTY.println("      use positions: " + interval.usePosList().size());
             }
@@ -507,7 +505,7 @@
                 if (isRegister(parent.location())) {
                     if (parent.firstUsage(RegisterPriority.ShouldHaveRegister) == Integer.MAX_VALUE) {
                         // parent is never used, so kick it out of its assigned register
-                        if (TraceLinearScanLevel.getValue() >= 4) {
+                        if (getTraceLevel() >= 4) {
                             TTY.println("      kicking out interval %d out of its register because it is never used", parent.operandNumber);
                         }
                         allocator.assignSpillSlot(parent);
@@ -532,7 +530,7 @@
                 optimalSplitPos = (optimalSplitPos - 1) | 1;
             }
 
-            if (TraceLinearScanLevel.getValue() >= 4) {
+            if (getTraceLevel() >= 4) {
                 TTY.println("      splitting at position %d", optimalSplitPos);
             }
             assert allocator.isBlockBegin(optimalSplitPos) || (optimalSplitPos % 2 == 1) : "split pos must be odd when not on block boundary";
@@ -543,7 +541,7 @@
             allocator.changeSpillState(spilledPart, optimalSplitPos);
 
             if (!allocator.isBlockBegin(optimalSplitPos)) {
-                if (TraceLinearScanLevel.getValue() >= 4) {
+                if (getTraceLevel() >= 4) {
                     TTY.println("      inserting move from interval %d to %d", interval.operandNumber, spilledPart.operandNumber);
                 }
                 insertMove(optimalSplitPos, interval, spilledPart);
@@ -553,7 +551,7 @@
             assert spilledPart.currentSplitChild() == interval : "overwriting wrong currentSplitChild";
             spilledPart.makeCurrentSplitChild();
 
-            if (TraceLinearScanLevel.getValue() >= 2) {
+            if (getTraceLevel() >= 2) {
                 TTY.println("      split interval in two parts");
                 TTY.print("      ");
                 TTY.println(interval.logString(allocator));
@@ -602,7 +600,7 @@
     }
 
     boolean allocFreeRegister(Interval interval) {
-        if (TraceLinearScanLevel.getValue() >= 2) {
+        if (getTraceLevel() >= 2) {
             TTY.println("trying to find free register for " + interval.logString(allocator));
         }
 
@@ -618,7 +616,7 @@
         // (either as a fixed register or a normal allocated register in the past)
         // only intervals overlapping with cur are processed, non-overlapping invervals can be
         // ignored safely
-        if (TraceLinearScanLevel.getValue() >= 4) {
+        if (getTraceLevel() >= 4) {
             TTY.println("      state of registers:");
             for (Register register : availableRegs) {
                 int i = register.number;
@@ -630,7 +628,7 @@
         Interval locationHint = interval.locationHint(true);
         if (locationHint != null && locationHint.location() != null && isRegister(locationHint.location())) {
             hint = asRegister(locationHint.location());
-            if (TraceLinearScanLevel.getValue() >= 4) {
+            if (getTraceLevel() >= 4) {
                 TTY.println("      hint register %d from interval %s", hint.number, locationHint.logString(allocator));
             }
         }
@@ -674,7 +672,7 @@
 
         splitPos = usePos[reg.number];
         interval.assignLocation(reg.asValue(interval.kind()));
-        if (TraceLinearScanLevel.getValue() >= 2) {
+        if (getTraceLevel() >= 2) {
             TTY.println("selected register %d", reg.number);
         }
 
@@ -700,7 +698,7 @@
 
     // Split an Interval and spill it to memory so that cur can be placed in a register
     void allocLockedRegister(Interval interval) {
-        if (TraceLinearScanLevel.getValue() >= 2) {
+        if (getTraceLevel() >= 2) {
             TTY.println("need to split and spill to get register for " + interval.logString(allocator));
         }
 
@@ -713,7 +711,7 @@
         spillCollectActiveAny();
         spillCollectInactiveAny(interval);
 
-        if (TraceLinearScanLevel.getValue() >= 4) {
+        if (getTraceLevel() >= 4) {
             TTY.println("      state of registers:");
             for (Register reg : availableRegs) {
                 int i = reg.number;
@@ -746,7 +744,7 @@
 
         if (reg == null || usePos[reg.number] <= firstUsage) {
             // the first use of cur is later than the spilling position -> spill cur
-            if (TraceLinearScanLevel.getValue() >= 4) {
+            if (getTraceLevel() >= 4) {
                 TTY.println("able to spill current interval. firstUsage(register): %d, usePos: %d", firstUsage, reg == null ? 0 : usePos[reg.number]);
             }
 
@@ -765,7 +763,7 @@
 
         int splitPos = blockPos[reg.number];
 
-        if (TraceLinearScanLevel.getValue() >= 4) {
+        if (getTraceLevel() >= 4) {
             TTY.println("decided to use register %d", reg.number);
         }
         assert splitPos > 0 : "invalid splitPos";
@@ -793,7 +791,7 @@
             if (isOdd(pos)) {
                 // the current instruction is a call that blocks all registers
                 if (pos < allocator.maxOpId() && allocator.hasCall(pos + 1) && interval.to() > pos + 1) {
-                    if (TraceLinearScanLevel.getValue() >= 4) {
+                    if (getTraceLevel() >= 4) {
                         TTY.println("      free register cannot be available because all registers blocked by following call");
                     }
 
@@ -885,11 +883,11 @@
         Interval interval = currentInterval;
         boolean result = true;
 
-        if (TraceLinearScanLevel.getValue() >= 2) {
+        if (getTraceLevel() >= 2) {
             TTY.println("+++++ activating interval " + interval.logString(allocator));
         }
 
-        if (TraceLinearScanLevel.getValue() >= 4) {
+        if (getTraceLevel() >= 4) {
             TTY.println("      splitParent: %s, insertMoveWhenActivated: %b", interval.splitParent().operandNumber, interval.insertMoveWhenActivated());
         }
 
@@ -898,7 +896,7 @@
             // activating an interval that has a stack slot assigned . split it at first use
             // position
             // used for method parameters
-            if (TraceLinearScanLevel.getValue() >= 4) {
+            if (getTraceLevel() >= 4) {
                 TTY.println("      interval has spill slot assigned (method parameter) . split it before first use");
             }
             splitStackInterval(interval);
@@ -908,7 +906,7 @@
             if (interval.location() == null) {
                 // interval has not assigned register . normal allocation
                 // (this is the normal case for most intervals)
-                if (TraceLinearScanLevel.getValue() >= 4) {
+                if (getTraceLevel() >= 4) {
                     TTY.println("      normal allocation of register");
                 }
 
@@ -934,7 +932,7 @@
             assert interval.isSplitChild();
             assert interval.currentSplitChild() != null;
             assert !interval.currentSplitChild().operand.equals(operand) : "cannot insert move between same interval";
-            if (TraceLinearScanLevel.getValue() >= 4) {
+            if (getTraceLevel() >= 4) {
                 TTY.println("Inserting move from interval %d to %d because insertMoveWhenActivated is set", interval.currentSplitChild().operandNumber, interval.operandNumber);
             }
 
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/MoveResolver.java	Tue Nov 05 19:02:50 2013 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/MoveResolver.java	Tue Nov 05 19:03:37 2013 +0100
@@ -23,8 +23,6 @@
 package com.oracle.graal.compiler.alloc;
 
 import static com.oracle.graal.api.code.ValueUtil.*;
-import static com.oracle.graal.phases.GraalOptions.*;
-
 import java.util.*;
 
 import com.oracle.graal.api.code.*;
@@ -201,7 +199,7 @@
 
         insertionBuffer.append(insertIdx, allocator.ir.spillMoveFactory.createMove(toOpr, fromOpr));
 
-        if (TraceLinearScanLevel.getValue() >= 4) {
+        if (allocator.getTraceLevel() >= 4) {
             TTY.println("MoveResolver: inserted move from %d (%s) to %d (%s)", fromInterval.operandNumber, fromInterval.location(), toInterval.operandNumber, toInterval.location());
         }
     }
@@ -213,7 +211,7 @@
         AllocatableValue toOpr = toInterval.operand;
         insertionBuffer.append(insertIdx, allocator.ir.spillMoveFactory.createMove(toOpr, fromOpr));
 
-        if (TraceLinearScanLevel.getValue() >= 4) {
+        if (allocator.getTraceLevel() >= 4) {
             TTY.print("MoveResolver: inserted move from constant %s to %d (%s)", fromOpr, toInterval.operandNumber, toInterval.location());
         }
     }
@@ -285,7 +283,7 @@
                 }
                 spillInterval.assignLocation(spillSlot);
 
-                if (TraceLinearScanLevel.getValue() >= 4) {
+                if (allocator.getTraceLevel() >= 4) {
                     TTY.println("created new Interval %s for spilling", spillInterval.operand);
                 }
 
@@ -327,7 +325,7 @@
     }
 
     void addMapping(Interval fromInterval, Interval toInterval) {
-        if (TraceLinearScanLevel.getValue() >= 4) {
+        if (allocator.getTraceLevel() >= 4) {
             TTY.println("MoveResolver: adding mapping from interval %d (%s) to interval %d (%s)", fromInterval.operandNumber, fromInterval.location(), toInterval.operandNumber, toInterval.location());
         }
 
@@ -339,7 +337,7 @@
     }
 
     void addMapping(Value fromOpr, Interval toInterval) {
-        if (TraceLinearScanLevel.getValue() >= 4) {
+        if (allocator.getTraceLevel() >= 4) {
             TTY.println("MoveResolver: adding mapping from %s to %d (%s)", fromOpr, toInterval.operandNumber, toInterval.location());
         }
         assert isConstant(fromOpr) : "only for constants";
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/RegisterVerifier.java	Tue Nov 05 19:02:50 2013 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/RegisterVerifier.java	Tue Nov 05 19:03:37 2013 +0100
@@ -23,8 +23,6 @@
 package com.oracle.graal.compiler.alloc;
 
 import static com.oracle.graal.api.code.ValueUtil.*;
-import static com.oracle.graal.phases.GraalOptions.*;
-
 import java.util.*;
 
 import com.oracle.graal.api.code.*;
@@ -92,7 +90,7 @@
     }
 
     private void processBlock(Block block) {
-        if (TraceLinearScanLevel.getValue() >= 2) {
+        if (allocator.getTraceLevel() >= 2) {
             TTY.println();
             TTY.println("processBlock B%d", block.getId());
         }
@@ -100,7 +98,7 @@
         // must copy state because it is modified
         Interval[] inputState = copy(stateForBlock(block));
 
-        if (TraceLinearScanLevel.getValue() >= 4) {
+        if (allocator.getTraceLevel() >= 4) {
             TTY.println("Input-State of intervals:");
             TTY.print("    ");
             for (int i = 0; i < stateSize(); i++) {
@@ -142,7 +140,7 @@
                         savedStateCorrect = false;
                         savedState[i] = null;
 
-                        if (TraceLinearScanLevel.getValue() >= 4) {
+                        if (allocator.getTraceLevel() >= 4) {
                             TTY.println("processSuccessor B%d: invalidating slot %d", block.getId(), i);
                         }
                     }
@@ -151,12 +149,12 @@
 
             if (savedStateCorrect) {
                 // already processed block with correct inputState
-                if (TraceLinearScanLevel.getValue() >= 2) {
+                if (allocator.getTraceLevel() >= 2) {
                     TTY.println("processSuccessor B%d: previous visit already correct", block.getId());
                 }
             } else {
                 // must re-visit this block
-                if (TraceLinearScanLevel.getValue() >= 2) {
+                if (allocator.getTraceLevel() >= 2) {
                     TTY.println("processSuccessor B%d: must re-visit because input state changed", block.getId());
                 }
                 addToWorkList(block);
@@ -164,7 +162,7 @@
 
         } else {
             // block was not processed before, so set initial inputState
-            if (TraceLinearScanLevel.getValue() >= 2) {
+            if (allocator.getTraceLevel() >= 2) {
                 TTY.println("processSuccessor B%d: initial visit", block.getId());
             }
 
@@ -177,16 +175,16 @@
         return inputState.clone();
     }
 
-    static void statePut(Interval[] inputState, Value location, Interval interval) {
+    static void statePut(Interval[] inputState, Value location, Interval interval, int traceLevel) {
         if (location != null && isRegister(location)) {
             Register reg = asRegister(location);
             int regNum = reg.number;
             if (interval != null) {
-                if (TraceLinearScanLevel.getValue() >= 4) {
+                if (traceLevel >= 4) {
                     TTY.println("        %s = %s", reg, interval.operand);
                 }
             } else if (inputState[regNum] != null) {
-                if (TraceLinearScanLevel.getValue() >= 4) {
+                if (traceLevel >= 4) {
                     TTY.println("        %s = null", reg);
                 }
             }
@@ -209,7 +207,7 @@
         for (int i = 0; i < ops.size(); i++) {
             final LIRInstruction op = ops.get(i);
 
-            if (TraceLinearScanLevel.getValue() >= 4) {
+            if (allocator.getTraceLevel() >= 4) {
                 TTY.println(op.toStringWithIdPrefix());
             }
 
@@ -239,7 +237,7 @@
                             interval = interval.getSplitChildAtOpId(op.id(), mode, allocator);
                         }
 
-                        statePut(inputState, interval.location(), interval.splitParent());
+                        statePut(inputState, interval.location(), interval.splitParent(), allocator.getTraceLevel());
                     }
                     return operand;
                 }
@@ -250,7 +248,7 @@
             // invalidate all caller save registers at calls
             if (op.destroysCallerSavedRegisters()) {
                 for (Register r : allocator.frameMap.registerConfig.getCallerSaveRegisters()) {
-                    statePut(inputState, r.asValue(), null);
+                    statePut(inputState, r.asValue(), null, allocator.getTraceLevel());
                 }
             }
             op.forEachAlive(useProc);
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Tue Nov 05 19:02:50 2013 +0100
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java	Tue Nov 05 19:03:37 2013 +0100
@@ -49,6 +49,7 @@
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.virtual.*;
+import com.oracle.graal.options.*;
 import com.oracle.graal.phases.util.*;
 
 /**
@@ -56,6 +57,15 @@
  */
 public abstract class LIRGenerator implements LIRGeneratorTool {
 
+    public static class Options {
+        // @formatter:off
+        @Option(help = "Print HIR along side LIR as the latter is generated")
+        public static final OptionValue<Boolean> PrintIRWithLIR = new OptionValue<>(false);
+        @Option(help = "The trace level for the LIR generator")
+        public static final OptionValue<Integer> TraceLIRGeneratorLevel = new OptionValue<>(0);
+        // @formatter:on
+    }
+
     public final FrameMap frameMap;
     public final NodeMap<Value> nodeOperands;
     public final LIR lir;
@@ -67,6 +77,8 @@
     protected final DebugInfoBuilder debugInfoBuilder;
 
     protected Block currentBlock;
+    private final int traceLevel;
+    private final boolean printIRWithLIR;
 
     /**
      * Maps constants the variables within the scope of a single block to avoid loading a constant
@@ -106,6 +118,8 @@
         this.nodeOperands = graph.createNodeMap();
         this.lir = lir;
         this.debugInfoBuilder = createDebugInfoBuilder(nodeOperands);
+        this.traceLevel = Options.TraceLIRGeneratorLevel.getValue();
+        this.printIRWithLIR = Options.PrintIRWithLIR.getValue();
     }
 
     @SuppressWarnings("hiding")
@@ -316,7 +330,7 @@
     }
 
     public void append(LIRInstruction op) {
-        if (PrintIRWithLIR.getValue() && !TTY.isSuppressed()) {
+        if (printIRWithLIR && !TTY.isSuppressed()) {
             if (currentInstruction != null && lastInstructionPrinted != currentInstruction) {
                 lastInstructionPrinted = currentInstruction;
                 InstructionPrinter ip = new InstructionPrinter(TTY.out());
@@ -330,7 +344,7 @@
     }
 
     public void doBlock(Block block) {
-        if (PrintIRWithLIR.getValue()) {
+        if (printIRWithLIR) {
             TTY.print(block.toString());
         }
 
@@ -343,7 +357,7 @@
 
         append(new LabelOp(new Label(block.getId()), block.isAligned()));
 
-        if (TraceLIRGeneratorLevel.getValue() >= 1) {
+        if (traceLevel >= 1) {
             TTY.println("BEGIN Generating LIR for block B" + block.getId());
         }
 
@@ -357,7 +371,7 @@
         List<ScheduledNode> nodes = lir.nodesFor(block);
         for (int i = 0; i < nodes.size(); i++) {
             Node instr = nodes.get(i);
-            if (TraceLIRGeneratorLevel.getValue() >= 3) {
+            if (traceLevel >= 3) {
                 TTY.println("LIRGen for " + instr);
             }
             if (!ConstantNodeRecordsUsages && instr instanceof ConstantNode) {
@@ -387,13 +401,13 @@
             emitJump(getLIRBlock((FixedNode) successors.first()));
         }
 
-        if (TraceLIRGeneratorLevel.getValue() >= 1) {
+        if (traceLevel >= 1) {
             TTY.println("END Generating LIR for block B" + block.getId());
         }
 
         currentBlock = null;
 
-        if (PrintIRWithLIR.getValue()) {
+        if (printIRWithLIR) {
             TTY.println();
         }
     }
@@ -416,7 +430,7 @@
     }
 
     private void doRoot(ValueNode instr) {
-        if (TraceLIRGeneratorLevel.getValue() >= 2) {
+        if (traceLevel >= 2) {
             TTY.println("Emitting LIR for instruction " + instr);
         }
         currentInstruction = instr;
@@ -497,7 +511,7 @@
     }
 
     private void moveToPhi(MergeNode merge, AbstractEndNode pred) {
-        if (TraceLIRGeneratorLevel.getValue() >= 1) {
+        if (traceLevel >= 1) {
             TTY.println("MOVE TO PHI from " + pred + " to " + merge);
         }
         PhiResolver resolver = new PhiResolver(this);
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Tue Nov 05 19:02:50 2013 +0100
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Tue Nov 05 19:03:37 2013 +0100
@@ -49,6 +49,7 @@
 import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind;
 import com.oracle.graal.nodes.type.*;
 import com.oracle.graal.nodes.util.*;
+import com.oracle.graal.options.*;
 import com.oracle.graal.phases.*;
 
 /**
@@ -56,6 +57,13 @@
  */
 public class GraphBuilderPhase extends Phase {
 
+    static class Options {
+        // @formatter:off
+        @Option(help = "The trace level for the bytecode parser used when building a graph from bytecode")
+        public static final OptionValue<Integer> TraceBytecodeParserLevel = new OptionValue<>(0);
+        // @formatter:on
+    }
+
     public static final class RuntimeCalls {
 
         public static final ForeignCallDescriptor CREATE_NULL_POINTER_EXCEPTION = new ForeignCallDescriptor("createNullPointerException", Object.class);
@@ -63,14 +71,14 @@
     }
 
     /**
-     * The minimum value to which {@link GraalOptions#TraceBytecodeParserLevel} must be set to trace
-     * the bytecode instructions as they are parsed.
+     * The minimum value to which {@link Options#TraceBytecodeParserLevel} must be set to trace the
+     * bytecode instructions as they are parsed.
      */
     public static final int TRACELEVEL_INSTRUCTIONS = 1;
 
     /**
-     * The minimum value to which {@link GraalOptions#TraceBytecodeParserLevel} must be set to trace
-     * the frame state before each bytecode instruction as it is parsed.
+     * The minimum value to which {@link Options#TraceBytecodeParserLevel} must be set to trace the
+     * frame state before each bytecode instruction as it is parsed.
      */
     public static final int TRACELEVEL_STATE = 2;
 
@@ -1787,8 +1795,10 @@
         }
     }
 
+    private final int traceLevel = Options.TraceBytecodeParserLevel.getValue();
+
     private void traceState() {
-        if (TraceBytecodeParserLevel.getValue() >= TRACELEVEL_STATE && Debug.isLogEnabled()) {
+        if (traceLevel >= TRACELEVEL_STATE && Debug.isLogEnabled()) {
             Debug.log(String.format("|   state [nr locals = %d, stack depth = %d, method = %s]", frameState.localsSize(), frameState.stackSize(), method));
             for (int i = 0; i < frameState.localsSize(); ++i) {
                 ValueNode value = frameState.localAt(i);
@@ -2018,7 +2028,7 @@
     }
 
     private void traceInstruction(int bci, int opcode, boolean blockStart) {
-        if (TraceBytecodeParserLevel.getValue() >= TRACELEVEL_INSTRUCTIONS && Debug.isLogEnabled()) {
+        if (traceLevel >= TRACELEVEL_INSTRUCTIONS && Debug.isLogEnabled()) {
             StringBuilder sb = new StringBuilder(40);
             sb.append(blockStart ? '+' : '|');
             if (bci < 10) {
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Tue Nov 05 19:02:50 2013 +0100
+++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java	Tue Nov 05 19:03:37 2013 +0100
@@ -169,20 +169,12 @@
     @Option(help = "")
     public static final OptionValue<Boolean> PrintProfilingInformation = new OptionValue<>(false);
     @Option(help = "")
-    public static final OptionValue<Boolean> PrintIRWithLIR = new OptionValue<>(false);
-    @Option(help = "")
     public static final OptionValue<Boolean> PrintCodeBytes = new OptionValue<>(false);
     @Option(help = "")
     public static final OptionValue<Boolean> PrintBailout = new OptionValue<>(false);
     @Option(help = "")
-    public static final OptionValue<Integer> TraceLinearScanLevel = new OptionValue<>(0);
-    @Option(help = "")
-    public static final OptionValue<Integer> TraceLIRGeneratorLevel = new OptionValue<>(0);
-    @Option(help = "")
     public static final OptionValue<Boolean> TraceEscapeAnalysis = new OptionValue<>(false);
     @Option(help = "")
-    public static final OptionValue<Integer> TraceBytecodeParserLevel = new OptionValue<>(0);
-    @Option(help = "")
     public static final OptionValue<Boolean> ExitVMOnBailout = new OptionValue<>(false);
     @Option(help = "")
     public static final OptionValue<Boolean> ExitVMOnException = new OptionValue<>(true);