# HG changeset patch # User Josef Eisl # Date 1397486856 -7200 # Node ID ca92d97bb0d63a72dbee52222f6ee890fe8f8a2d # Parent e17fe8c1287d6aa65825c08ed701f1e2f3561f70 BaselineCompiler: do not pass constants to blocks with multiple predecessors. diff -r e17fe8c1287d -r ca92d97bb0d6 graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java --- a/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java Thu Apr 10 15:47:41 2014 +0200 +++ b/graal/com.oracle.graal.baseline/src/com/oracle/graal/baseline/BaselineBytecodeParser.java Mon Apr 14 16:47:36 2014 +0200 @@ -261,8 +261,7 @@ @Override protected Value genIntegerMul(Kind kind, Value x, Value y) { - // TODO Auto-generated method stub - throw GraalInternalError.unimplemented("Auto-generated method stub"); + return gen.emitMul(x, y); } @Override @@ -584,9 +583,9 @@ return v; } - private void createTarget(BciBlock block, LIRFrameStateBuilder state) { - assert block != null && state != null; - assert !block.isExceptionEntry || state.stackSize() == 1; + private void createTarget(BciBlock block) { + assert block != null && frameState != null; + assert !block.isExceptionEntry || frameState.stackSize() == 1; if (!blockVisited.get(block)) { /* @@ -594,7 +593,14 @@ * placeholder that later can be replaced with a MergeNode when we see this block again. */ blockVisited.set(block); - block.entryState = state.copy(); + if (block.getPredecessorCount() > 1) { + /* + * If there are more than one predecessors we have to ensure that we are not passing + * constants to the new framestate otherwise we will get interfacing problems. + */ + moveConstantsToVariables(); + } + block.entryState = frameState.copy(); block.entryState.clearNonLiveLocals(block, liveness, true); Debug.log("createTarget %s: first visit", block); @@ -602,12 +608,17 @@ } // We already saw this block before, so we have to merge states. - if (!((LIRFrameStateBuilder) block.entryState).isCompatibleWith(state)) { + if (!((LIRFrameStateBuilder) block.entryState).isCompatibleWith(frameState)) { throw new BailoutException("stacks do not match; bytecodes would not verify"); } if (block.isLoopHeader) { assert currentBlock.getId() >= block.getId() : "must be backward branch"; + if (currentBlock != null && currentBlock.numNormalSuccessors() == 1) { + // this is the only successor of the current block so we can adjust + adaptFramestate((LIRFrameStateBuilder) block.entryState); + return; + } GraalInternalError.unimplemented("Loops not yet supported"); } assert currentBlock == null || currentBlock.getId() < block.getId() : "must not be backward branch"; @@ -629,6 +640,29 @@ Debug.log("createTarget %s: merging state", block); } + private void moveConstantsToVariables() { + Debug.log("moveConstantsToVariables: framestate before: %s", frameState); + for (int i = 0; i < frameState.stackSize(); i++) { + Value src = frameState.stackAt(i); + if (src instanceof Constant) { + AllocatableValue dst = gen.newVariable(src.getPlatformKind()); + gen.emitMove(dst, src); + frameState.storeStack(i, dst); + Debug.log("introduce new variabe %s for stackslot %d (end of block %s", dst, i, currentBlock); + } + } + for (int i = 0; i < frameState.localsSize(); i++) { + Value src = frameState.localAt(i); + if (src instanceof Constant) { + AllocatableValue dst = gen.newVariable(src.getPlatformKind()); + gen.emitMove(dst, src); + frameState.storeLocal(i, dst); + Debug.log("introduce new variabe %s for local %d (end of block %s", dst, i, currentBlock); + } + } + Debug.log("moveConstantsToVariables: framestate after: %s", frameState); + } + private void adaptValues(Value dst, Value src) { if (dst == null) { return; @@ -636,7 +670,7 @@ assert src != null : "Source is null but Destination is not!"; if (!dst.equals(src)) { - assert dst instanceof AllocatableValue; + assert dst instanceof AllocatableValue : "Not an AllocatableValue: " + dst; gen.emitMove((AllocatableValue) dst, src); } } @@ -725,7 +759,7 @@ } LabelRef getSuccessor(int index) { - createTarget(currentBlock.getSuccessor(index), frameState); + createTarget(currentBlock.getSuccessor(index)); return LabelRef.forSuccessor(lirGenRes.getLIR(), currentBlock, index); }