diff graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScanWalker.java @ 13467:7c694e3e97e5

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