changeset 12569:1c8d5a0891b5

improved error reporting in LSRA
author Doug Simon <doug.simon@oracle.com>
date Thu, 24 Oct 2013 12:25:29 +0200
parents 2d11b9128e01
children af39ea2dc39d
files graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java
diffstat 1 files changed, 57 insertions(+), 55 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java	Thu Oct 24 12:23:52 2013 +0200
+++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java	Thu Oct 24 12:25:29 2013 +0200
@@ -869,8 +869,7 @@
 
         // check that the liveIn set of the first block is empty
         Block startBlock = ir.cfg.getStartBlock();
-        BitSet liveInArgs = new BitSet(blockData.get(startBlock).liveIn.size());
-        if (!blockData.get(startBlock).liveIn.equals(liveInArgs)) {
+        if (blockData.get(startBlock).liveIn.cardinality() != 0) {
             if (DetailedAsserts.getValue()) {
                 reportFailure(numBlocks);
             }
@@ -878,73 +877,76 @@
             TTY.println("preds=" + startBlock.getPredecessorCount() + ", succs=" + startBlock.getSuccessorCount());
             TTY.println("startBlock-ID: " + startBlock.getId());
 
-            // bailout of if this occurs in product mode.
-            throw new GraalInternalError("liveIn set of first block must be empty");
+            // bailout if this occurs in product mode.
+            throw new GraalInternalError("liveIn set of first block must be empty: " + blockData.get(startBlock).liveIn);
         }
     }
 
     private void reportFailure(int numBlocks) {
         TTY.println(gen.getGraph().toString());
-        TTY.println("Error: liveIn set of first block must be empty (when this fails, variables are used before they are defined)");
-        TTY.print("affected registers:");
-        TTY.println(blockData.get(ir.cfg.getStartBlock()).liveIn.toString());
+        TTY.println("Error: liveIn set of first block must be empty (when this fails, variables are used before they are defined):");
+        BitSet startBlockLiveIn = blockData.get(ir.cfg.getStartBlock()).liveIn;
+        for (int operandNum = startBlockLiveIn.nextSetBit(0); operandNum >= 0; operandNum = startBlockLiveIn.nextSetBit(operandNum + 1)) {
+            Value operand = operandFor(operandNum);
+            TTY.println("  var %d; operand=%s; node=%s", operandNum, operand.toString(), gen.valueForOperand(operand));
+        }
 
         // print some additional information to simplify debugging
-        for (int operandNum = 0; operandNum < blockData.get(ir.cfg.getStartBlock()).liveIn.size(); operandNum++) {
-            if (blockData.get(ir.cfg.getStartBlock()).liveIn.get(operandNum)) {
-                Value operand = operandFor(operandNum);
-                TTY.println(" var %d; operand=%s; node=%s", operandNum, operand.toString(), gen.valueForOperand(operand));
+        for (int operandNum = startBlockLiveIn.nextSetBit(0); operandNum >= 0; operandNum = startBlockLiveIn.nextSetBit(operandNum + 1)) {
+            Value operand = operandFor(operandNum);
+            TTY.println("---- Detailed information for var %d; operand=%s; node=%s ----", operandNum, operand.toString(), gen.valueForOperand(operand));
+
+            Deque<Block> definedIn = new ArrayDeque<>();
+            HashSet<Block> usedIn = new HashSet<>();
+            for (Block block : sortedBlocks) {
+                if (blockData.get(block).liveGen.get(operandNum)) {
+                    usedIn.add(block);
+                    TTY.println("used in block B%d {", block.getId());
+                    for (LIRInstruction ins : ir.lir(block)) {
+                        TTY.println("  " + ins.id() + ": " + ins.toString());
+                        ins.forEachState(new ValueProcedure() {
 
-                Deque<Block> definedIn = new ArrayDeque<>();
-                HashSet<Block> usedIn = new HashSet<>();
-                for (Block block : sortedBlocks) {
-                    if (blockData.get(block).liveGen.get(operandNum)) {
-                        usedIn.add(block);
-                        TTY.println("  used in block B%d", block.getId());
-                        for (LIRInstruction ins : ir.lir(block)) {
-                            TTY.println(ins.id() + ": " + ins.toString());
-                            ins.forEachState(new ValueProcedure() {
+                            @Override
+                            public Value doValue(Value liveStateOperand) {
+                                TTY.println("    operand=" + liveStateOperand);
+                                return liveStateOperand;
+                            }
+                        });
+                    }
+                    TTY.println("}");
+                }
+                if (blockData.get(block).liveKill.get(operandNum)) {
+                    definedIn.add(block);
+                    TTY.println("defined in block B%d {", block.getId());
+                    for (LIRInstruction ins : ir.lir(block)) {
+                        TTY.println("  " + ins.id() + ": " + ins.toString());
+                    }
+                    TTY.println("}");
+                }
+            }
 
-                                @Override
-                                public Value doValue(Value liveStateOperand) {
-                                    TTY.println("   operand=" + liveStateOperand);
-                                    return liveStateOperand;
-                                }
-                            });
+            int[] hitCount = new int[numBlocks];
+
+            while (!definedIn.isEmpty()) {
+                Block block = definedIn.removeFirst();
+                usedIn.remove(block);
+                for (Block successor : block.getSuccessors()) {
+                    if (successor.isLoopHeader()) {
+                        if (!block.isLoopEnd()) {
+                            definedIn.add(successor);
                         }
-                    }
-                    if (blockData.get(block).liveKill.get(operandNum)) {
-                        definedIn.add(block);
-                        TTY.println("  defined in block B%d", block.getId());
-                        for (LIRInstruction ins : ir.lir(block)) {
-                            TTY.println(ins.id() + ": " + ins.toString());
+                    } else {
+                        if (++hitCount[successor.getId()] == successor.getPredecessorCount()) {
+                            definedIn.add(successor);
                         }
                     }
                 }
-
-                int[] hitCount = new int[numBlocks];
-
-                while (!definedIn.isEmpty()) {
-                    Block block = definedIn.removeFirst();
-                    usedIn.remove(block);
-                    for (Block successor : block.getSuccessors()) {
-                        if (successor.isLoopHeader()) {
-                            if (!block.isLoopEnd()) {
-                                definedIn.add(successor);
-                            }
-                        } else {
-                            if (++hitCount[successor.getId()] == successor.getPredecessorCount()) {
-                                definedIn.add(successor);
-                            }
-                        }
-                    }
-                }
-                TTY.print("  offending usages are in: ");
-                for (Block block : usedIn) {
-                    TTY.print("B%d ", block.getId());
-                }
-                TTY.println();
             }
+            TTY.print("**** offending usages are in: ");
+            for (Block block : usedIn) {
+                TTY.print("B%d ", block.getId());
+            }
+            TTY.println();
         }
     }