# HG changeset patch # User Josef Eisl # Date 1436372304 -7200 # Node ID a634b6f23af64a406f1b3918e4a05f5017458b0a # Parent 36fff39fa39f37fbaceed3bc87d360a5fe73c6b3 RegisterVerifier: improve error message. diff -r 36fff39fa39f -r a634b6f23af6 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/RegisterVerifier.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/RegisterVerifier.java Tue Jul 07 17:08:44 2015 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/RegisterVerifier.java Wed Jul 08 18:18:24 2015 +0200 @@ -29,6 +29,7 @@ import jdk.internal.jvmci.code.*; import jdk.internal.jvmci.common.*; import jdk.internal.jvmci.debug.*; +import jdk.internal.jvmci.debug.Debug.Scope; import jdk.internal.jvmci.meta.*; import com.oracle.graal.compiler.common.cfg.*; @@ -78,18 +79,20 @@ } void verify(AbstractBlockBase start) { - // setup input registers (method arguments) for first block - Interval[] inputState = new Interval[stateSize()]; - setStateForBlock(start, inputState); - addToWorkList(start); + try (Scope s = Debug.scope("RegisterVerifier")) { + // setup input registers (method arguments) for first block + Interval[] inputState = new Interval[stateSize()]; + setStateForBlock(start, inputState); + addToWorkList(start); - // main loop for verification - do { - AbstractBlockBase block = workList.get(0); - workList.remove(0); + // main loop for verification + do { + AbstractBlockBase block = workList.get(0); + workList.remove(0); - processBlock(block); - } while (!workList.isEmpty()); + processBlock(block); + } while (!workList.isEmpty()); + } } private void processBlock(AbstractBlockBase block) { @@ -98,17 +101,15 @@ Interval[] inputState = copy(stateForBlock(block)); try (Indent indent2 = Debug.logAndIndent("Input-State of intervals:")) { - for (int i = 0; i < stateSize(); i++) { - if (inputState[i] != null) { - Debug.log(" %4d", inputState[i].operandNumber); - } else { - Debug.log(" __"); - } - } + printState(inputState); } // process all operations of the block - processOperations(allocator.ir.getLIRforBlock(block), inputState); + processOperations(block, inputState); + + try (Indent indent2 = Debug.logAndIndent("Output-State of intervals:")) { + printState(inputState); + } // iterate all successors for (AbstractBlockBase succ : block.getSuccessors()) { @@ -117,6 +118,18 @@ } } + protected void printState(Interval[] inputState) { + for (int i = 0; i < stateSize(); i++) { + Register reg = allocator.registers[i]; + assert reg.number == i; + if (inputState[i] != null) { + Debug.log(" %6s %4d -- %s", reg, inputState[i].operandNumber, inputState[i]); + } else { + Debug.log(" %6s __", reg); + } + } + } + private void processSuccessor(AbstractBlockBase block, Interval[] inputState) { Interval[] savedState = stateForBlock(block); @@ -177,16 +190,19 @@ } } - static boolean checkState(Interval[] inputState, Value reg, Interval interval) { + static boolean checkState(AbstractBlockBase block, LIRInstruction op, Interval[] inputState, Value operand, Value reg, Interval interval) { if (reg != null && isRegister(reg)) { if (inputState[asRegister(reg).number] != interval) { - throw new JVMCIError("!! Error in register allocation: register %s does not contain interval %s but interval %s", reg, interval.operand, inputState[asRegister(reg).number]); + throw new JVMCIError( + "Error in register allocation: operation (%s) in block %s expected register %s (operand %s) to contain the value of interval %s but data-flow says it contains interval %s", + op, block, reg, operand, interval, inputState[asRegister(reg).number]); } } return true; } - void processOperations(List ops, final Interval[] inputState) { + void processOperations(AbstractBlockBase block, final Interval[] inputState) { + List ops = allocator.ir.getLIRforBlock(block); InstructionValueConsumer useConsumer = new InstructionValueConsumer() { @Override @@ -198,7 +214,7 @@ interval = interval.getSplitChildAtOpId(op.id(), mode, allocator); } - assert checkState(inputState, interval.location(), interval.splitParent()); + assert checkState(block, op, inputState, interval.operand, interval.location(), interval.splitParent()); } } };